summaryrefslogtreecommitdiffstats
path: root/vendor/chalk-solve-0.87.0/src/clauses/builtin_traits/discriminant_kind.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/chalk-solve-0.87.0/src/clauses/builtin_traits/discriminant_kind.rs')
-rw-r--r--vendor/chalk-solve-0.87.0/src/clauses/builtin_traits/discriminant_kind.rs73
1 files changed, 73 insertions, 0 deletions
diff --git a/vendor/chalk-solve-0.87.0/src/clauses/builtin_traits/discriminant_kind.rs b/vendor/chalk-solve-0.87.0/src/clauses/builtin_traits/discriminant_kind.rs
new file mode 100644
index 000000000..27d49df75
--- /dev/null
+++ b/vendor/chalk-solve-0.87.0/src/clauses/builtin_traits/discriminant_kind.rs
@@ -0,0 +1,73 @@
+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(())
+}