+++ /dev/null
-use crate::clauses::ClauseBuilder;
-use crate::{Interner, RustIrDatabase, TraitRef, WellKnownTrait};
-use chalk_ir::{
- AliasTy, Floundered, Normalize, ProjectionTy, Substitution, Ty, TyKind, TyVariableKind,
-};
-
-pub fn add_discriminant_clauses<I: Interner>(
- db: &dyn RustIrDatabase<I>,
- builder: &mut ClauseBuilder<'_, I>,
- self_ty: Ty<I>,
-) -> Result<(), Floundered> {
- let interner = db.interner();
-
- let can_determine_discriminant = match self_ty.data(interner).kind {
- TyKind::Adt(..)
- | TyKind::Array(..)
- | TyKind::Tuple(..)
- | TyKind::Slice(..)
- | TyKind::Raw(..)
- | TyKind::Ref(..)
- | TyKind::Scalar(_)
- | TyKind::Str
- | TyKind::Never
- | TyKind::FnDef(..)
- | TyKind::Generator(..)
- | TyKind::Closure(..)
- | TyKind::GeneratorWitness(..)
- | TyKind::Foreign(_)
- | TyKind::Dyn(_)
- | TyKind::Function(..)
- | TyKind::InferenceVar(_, TyVariableKind::Integer)
- | TyKind::InferenceVar(_, TyVariableKind::Float) => true,
- TyKind::OpaqueType(..)
- | TyKind::Alias(_)
- | TyKind::BoundVar(_)
- | TyKind::Placeholder(_)
- | TyKind::AssociatedType(..)
- | TyKind::Error
- | TyKind::InferenceVar(..) => false,
- };
-
- if !can_determine_discriminant {
- return Err(Floundered);
- }
-
- let disc_ty = db.discriminant_type(self_ty.clone());
-
- let trait_id = db
- .well_known_trait_id(WellKnownTrait::DiscriminantKind)
- .unwrap();
- let trait_datum = db.trait_datum(trait_id);
-
- let associated_ty_id = trait_datum.associated_ty_ids[0];
- let substitution = Substitution::from1(interner, self_ty);
-
- let trait_ref = TraitRef {
- trait_id,
- substitution: substitution.clone(),
- };
-
- let normalize = Normalize {
- alias: AliasTy::Projection(ProjectionTy {
- associated_ty_id,
- substitution,
- }),
- ty: disc_ty,
- };
-
- builder.push_fact(trait_ref);
- builder.push_fact(normalize);
-
- Ok(())
-}