]> git.lizzy.rs Git - rust.git/commitdiff
Replace Projection variant in GenericPredicate with AliasEq
authorLukas Wirth <lukastw97@gmail.com>
Fri, 19 Mar 2021 01:07:15 +0000 (02:07 +0100)
committerLukas Wirth <lukastw97@gmail.com>
Fri, 19 Mar 2021 11:12:18 +0000 (12:12 +0100)
crates/hir/src/lib.rs
crates/hir_ty/src/autoderef.rs
crates/hir_ty/src/display.rs
crates/hir_ty/src/infer.rs
crates/hir_ty/src/infer/unify.rs
crates/hir_ty/src/lib.rs
crates/hir_ty/src/lower.rs
crates/hir_ty/src/traits.rs
crates/hir_ty/src/traits/chalk.rs
crates/hir_ty/src/traits/chalk/mapping.rs

index 67ec8e82a2d663a3ff04d3e07ad4a376202a6751..5ebd0a3b891ee196179319e01b5962cd35510c30 100644 (file)
@@ -56,9 +56,9 @@
     primitive::UintTy,
     to_assoc_type_id,
     traits::{FnTrait, Solution, SolutionVariables},
-    AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, DebruijnIndex, GenericPredicate,
-    InEnvironment, Interner, Obligation, ProjectionPredicate, ProjectionTy, Scalar, Substitution,
-    Ty, TyDefId, TyKind, TyVariableKind,
+    AliasEq, AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, DebruijnIndex,
+    GenericPredicate, InEnvironment, Interner, Obligation, ProjectionTy, Scalar, Substitution, Ty,
+    TyDefId, TyKind, TyVariableKind,
 };
 use itertools::Itertools;
 use rustc_hash::FxHashSet;
@@ -1786,17 +1786,17 @@ pub fn normalize_trait_assoc_type(
             .push(self.ty.value.clone())
             .fill(args.iter().map(|t| t.ty.value.clone()))
             .build();
-        let predicate = ProjectionPredicate {
-            projection_ty: ProjectionTy {
-                associated_ty_id: to_assoc_type_id(alias.id),
-                substitution: subst,
-            },
-            ty: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(&Interner),
-        };
         let goal = Canonical {
             value: InEnvironment::new(
                 self.ty.environment.clone(),
-                Obligation::Projection(predicate),
+                Obligation::AliasEq(AliasEq {
+                    alias: AliasTy::Projection(ProjectionTy {
+                        associated_ty_id: to_assoc_type_id(alias.id),
+                        substitution: subst,
+                    }),
+                    ty: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0))
+                        .intern(&Interner),
+                }),
             ),
             kinds: Arc::new([TyVariableKind::General]),
         };
index ad4e6f23bbdfa02e0b9905679b87f542ac74a754..33b9660263fba3eadf78d9b192bd5539086af75c 100644 (file)
@@ -15,7 +15,8 @@
     to_assoc_type_id, to_chalk_trait_id,
     traits::{InEnvironment, Solution},
     utils::generics,
-    BoundVar, Canonical, DebruijnIndex, Interner, Obligation, Substitution, TraitRef, Ty, TyKind,
+    AliasEq, AliasTy, BoundVar, Canonical, DebruijnIndex, Interner, Obligation, ProjectionTy,
+    Substitution, TraitRef, Ty, TyKind,
 };
 
 const AUTODEREF_RECURSION_LIMIT: usize = 10;
@@ -82,16 +83,16 @@ fn deref_by_trait(
     }
 
     // Now do the assoc type projection
-    let projection = super::traits::ProjectionPredicate {
-        ty: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, ty.value.kinds.len()))
-            .intern(&Interner),
-        projection_ty: super::ProjectionTy {
+    let projection = AliasEq {
+        alias: AliasTy::Projection(ProjectionTy {
             associated_ty_id: to_assoc_type_id(target),
             substitution: parameters,
-        },
+        }),
+        ty: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, ty.value.kinds.len()))
+            .intern(&Interner),
     };
 
-    let obligation = super::Obligation::Projection(projection);
+    let obligation = super::Obligation::AliasEq(projection);
 
     let in_env = InEnvironment { value: obligation, environment: ty.environment };
 
index c6b4f37e58a91cd7dd4efec7f5475ac0b20a9030..59a1bd9b0da9e93efda06db112472bd205949457 100644 (file)
@@ -18,9 +18,9 @@
 
 use crate::{
     db::HirDatabase, from_assoc_type_id, from_foreign_def_id, from_placeholder_idx, primitive,
-    to_assoc_type_id, traits::chalk::from_chalk, utils::generics, AdtId, AliasTy, CallableDefId,
-    CallableSig, GenericPredicate, ImplTraitId, Interner, Lifetime, Obligation, OpaqueTy,
-    ProjectionTy, Scalar, Substitution, TraitRef, Ty, TyKind,
+    to_assoc_type_id, traits::chalk::from_chalk, utils::generics, AdtId, AliasEq, AliasTy,
+    CallableDefId, CallableSig, GenericPredicate, ImplTraitId, Interner, Lifetime, Obligation,
+    OpaqueTy, ProjectionTy, Scalar, Substitution, TraitRef, Ty, TyKind,
 };
 
 pub struct HirFormatter<'a> {
@@ -268,6 +268,16 @@ fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
     }
 }
 
+impl HirDisplay for OpaqueTy {
+    fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
+        if f.should_truncate() {
+            return write!(f, "{}", TYPE_HINT_TRUNCATION);
+        }
+
+        self.substitution[0].hir_fmt(f)
+    }
+}
+
 impl HirDisplay for Ty {
     fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
         if f.should_truncate() {
@@ -700,12 +710,12 @@ fn write_bounds_like_dyn_trait(
                     }
                 }
             }
-            GenericPredicate::Projection(projection_pred) if is_fn_trait => {
+            GenericPredicate::AliasEq(alias_eq) if is_fn_trait => {
                 is_fn_trait = false;
                 write!(f, " -> ")?;
-                projection_pred.ty.hir_fmt(f)?;
+                alias_eq.ty.hir_fmt(f)?;
             }
-            GenericPredicate::Projection(projection_pred) => {
+            GenericPredicate::AliasEq(AliasEq { ty, alias }) => {
                 // in types in actual Rust, these will always come
                 // after the corresponding Implemented predicate
                 if angle_open {
@@ -714,11 +724,12 @@ fn write_bounds_like_dyn_trait(
                     write!(f, "<")?;
                     angle_open = true;
                 }
-                let type_alias = f.db.type_alias_data(from_assoc_type_id(
-                    projection_pred.projection_ty.associated_ty_id,
-                ));
-                write!(f, "{} = ", type_alias.name)?;
-                projection_pred.ty.hir_fmt(f)?;
+                if let AliasTy::Projection(proj) = alias {
+                    let type_alias =
+                        f.db.type_alias_data(from_assoc_type_id(proj.associated_ty_id));
+                    write!(f, "{} = ", type_alias.name)?;
+                }
+                ty.hir_fmt(f)?;
             }
             GenericPredicate::Error => {
                 if angle_open {
@@ -775,20 +786,20 @@ fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
 
         match self {
             GenericPredicate::Implemented(trait_ref) => trait_ref.hir_fmt(f)?,
-            GenericPredicate::Projection(projection_pred) => {
+            GenericPredicate::AliasEq(AliasEq {
+                alias: AliasTy::Projection(projection_ty),
+                ty,
+            }) => {
                 write!(f, "<")?;
-                projection_pred.projection_ty.trait_ref(f.db).hir_fmt_ext(f, true)?;
+                projection_ty.trait_ref(f.db).hir_fmt_ext(f, true)?;
                 write!(
                     f,
                     ">::{} = ",
-                    f.db.type_alias_data(from_assoc_type_id(
-                        projection_pred.projection_ty.associated_ty_id
-                    ))
-                    .name,
+                    f.db.type_alias_data(from_assoc_type_id(projection_ty.associated_ty_id)).name,
                 )?;
-                projection_pred.ty.hir_fmt(f)?;
+                ty.hir_fmt(f)?;
             }
-            GenericPredicate::Error => write!(f, "{{error}}")?,
+            GenericPredicate::AliasEq(_) | GenericPredicate::Error => write!(f, "{{error}}")?,
         }
         Ok(())
     }
@@ -815,11 +826,14 @@ fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
                 tr.hir_fmt(f)?;
                 write!(f, ")")
             }
-            Obligation::Projection(proj) => {
+            Obligation::AliasEq(AliasEq { alias, ty }) => {
                 write!(f, "Normalize(")?;
-                proj.projection_ty.hir_fmt(f)?;
+                match alias {
+                    AliasTy::Projection(projection_ty) => projection_ty.hir_fmt(f)?,
+                    AliasTy::Opaque(opaque) => opaque.hir_fmt(f)?,
+                }
                 write!(f, " => ")?;
-                proj.ty.hir_fmt(f)?;
+                ty.hir_fmt(f)?;
                 write!(f, ")")
             }
         }
index b6ae4fc6559fced19561261dbc7537f990d9f0cf..82186979ab462439619b349d0718d641ff16f7dc 100644 (file)
 use syntax::SmolStr;
 
 use super::{
-    traits::{Guidance, Obligation, ProjectionPredicate, Solution},
+    traits::{Guidance, Obligation, Solution},
     InEnvironment, ProjectionTy, Substitution, TraitEnvironment, TraitRef, Ty, TypeWalk,
 };
 use crate::{
     db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode,
-    to_assoc_type_id, to_chalk_trait_id, AliasTy, Interner, TyKind,
+    to_assoc_type_id, to_chalk_trait_id, AliasEq, AliasTy, Interner, TyKind,
 };
 
 pub(crate) use unify::unify;
@@ -396,15 +396,15 @@ fn resolve_associated_type_with_params(
                     .build();
                 let trait_ref =
                     TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs.clone() };
-                let projection = ProjectionPredicate {
-                    ty: ty.clone(),
-                    projection_ty: ProjectionTy {
+                let alias_eq = AliasEq {
+                    alias: AliasTy::Projection(ProjectionTy {
                         associated_ty_id: to_assoc_type_id(res_assoc_ty),
                         substitution: substs,
-                    },
+                    }),
+                    ty: ty.clone(),
                 };
                 self.obligations.push(Obligation::Trait(trait_ref));
-                self.obligations.push(Obligation::Projection(projection));
+                self.obligations.push(Obligation::AliasEq(alias_eq));
                 self.resolve_ty_as_possible(ty)
             }
             None => self.err_ty(),
@@ -429,8 +429,8 @@ fn normalize_associated_types_in(&mut self, ty: Ty) -> Ty {
 
     fn normalize_projection_ty(&mut self, proj_ty: ProjectionTy) -> Ty {
         let var = self.table.new_type_var();
-        let predicate = ProjectionPredicate { projection_ty: proj_ty, ty: var.clone() };
-        let obligation = Obligation::Projection(predicate);
+        let alias_eq = AliasEq { alias: AliasTy::Projection(proj_ty), ty: var.clone() };
+        let obligation = Obligation::AliasEq(alias_eq);
         self.obligations.push(obligation);
         var
     }
index f5ea096982bd9b5e87316ba4c0521872a7dea933..4738ec08aca832923e696a3d2abd5d8acd631f38 100644 (file)
@@ -7,8 +7,8 @@
 
 use super::{InferenceContext, Obligation};
 use crate::{
-    BoundVar, Canonical, DebruijnIndex, FnPointer, GenericPredicate, InEnvironment, InferenceVar,
-    Interner, Scalar, Substitution, Ty, TyKind, TypeWalk,
+    AliasEq, AliasTy, BoundVar, Canonical, DebruijnIndex, FnPointer, GenericPredicate,
+    InEnvironment, InferenceVar, Interner, Scalar, Substitution, Ty, TyKind, TypeWalk,
 };
 
 impl<'a> InferenceContext<'a> {
@@ -93,8 +93,8 @@ pub(crate) fn canonicalize_obligation(
             Obligation::Trait(tr) => {
                 Obligation::Trait(self.do_canonicalize(tr, DebruijnIndex::INNERMOST))
             }
-            Obligation::Projection(pr) => {
-                Obligation::Projection(self.do_canonicalize(pr, DebruijnIndex::INNERMOST))
+            Obligation::AliasEq(alias_eq) => {
+                Obligation::AliasEq(self.do_canonicalize(alias_eq, DebruijnIndex::INNERMOST))
             }
         };
         self.into_canonicalized(InEnvironment {
@@ -394,14 +394,25 @@ fn unify_preds(
             {
                 self.unify_substs(&tr1.substitution, &tr2.substitution, depth + 1)
             }
-            (GenericPredicate::Projection(proj1), GenericPredicate::Projection(proj2))
-                if proj1.projection_ty.associated_ty_id == proj2.projection_ty.associated_ty_id =>
-            {
-                self.unify_substs(
-                    &proj1.projection_ty.substitution,
-                    &proj2.projection_ty.substitution,
-                    depth + 1,
-                ) && self.unify_inner(&proj1.ty, &proj2.ty, depth + 1)
+            (
+                GenericPredicate::AliasEq(AliasEq { alias: alias1, ty: ty1 }),
+                GenericPredicate::AliasEq(AliasEq { alias: alias2, ty: ty2 }),
+            ) => {
+                let (substitution1, substitution2) = match (alias1, alias2) {
+                    (AliasTy::Projection(projection_ty1), AliasTy::Projection(projection_ty2))
+                        if projection_ty1.associated_ty_id == projection_ty2.associated_ty_id =>
+                    {
+                        (&projection_ty1.substitution, &projection_ty2.substitution)
+                    }
+                    (AliasTy::Opaque(opaque1), AliasTy::Opaque(opaque2))
+                        if opaque1.opaque_ty_id == opaque2.opaque_ty_id =>
+                    {
+                        (&opaque1.substitution, &opaque2.substitution)
+                    }
+                    _ => return false,
+                };
+                self.unify_substs(&substitution1, &substitution2, depth + 1)
+                    && self.unify_inner(&ty1, &ty2, depth + 1)
             }
             _ => false,
         }
index 3859dbfa14d4c6a31a7ced10b8d71e1f6b49ff87..2afcb5413784b6ec92cc032ffc314777c2b2fe01 100644 (file)
@@ -45,7 +45,7 @@ macro_rules! eprintln {
     associated_type_shorthand_candidates, callable_item_sig, CallableDefId, ImplTraitLoweringMode,
     TyDefId, TyLoweringContext, ValueTyDefId,
 };
-pub use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment};
+pub use traits::{AliasEq, InEnvironment, Obligation, TraitEnvironment};
 
 pub use chalk_ir::{AdtId, BoundVar, DebruijnIndex, Mutability, Safety, Scalar, TyVariableKind};
 
@@ -72,6 +72,20 @@ pub struct OpaqueTy {
     pub substitution: Substitution,
 }
 
+impl TypeWalk for OpaqueTy {
+    fn walk(&self, f: &mut impl FnMut(&Ty)) {
+        self.substitution.walk(f);
+    }
+
+    fn walk_mut_binders(
+        &mut self,
+        f: &mut impl FnMut(&mut Ty, DebruijnIndex),
+        binders: DebruijnIndex,
+    ) {
+        self.substitution.walk_mut_binders(f, binders);
+    }
+}
+
 /// A "projection" type corresponds to an (unnormalized)
 /// projection like `<P0 as Trait<P1..Pn>>::Foo`. Note that the
 /// trait and all its parameters are fully known.
@@ -133,6 +147,25 @@ pub enum AliasTy {
     Opaque(OpaqueTy),
 }
 
+impl TypeWalk for AliasTy {
+    fn walk(&self, f: &mut impl FnMut(&Ty)) {
+        match self {
+            AliasTy::Projection(it) => it.walk(f),
+            AliasTy::Opaque(it) => it.walk(f),
+        }
+    }
+
+    fn walk_mut_binders(
+        &mut self,
+        f: &mut impl FnMut(&mut Ty, DebruijnIndex),
+        binders: DebruijnIndex,
+    ) {
+        match self {
+            AliasTy::Projection(it) => it.walk_mut_binders(f, binders),
+            AliasTy::Opaque(it) => it.walk_mut_binders(f, binders),
+        }
+    }
+}
 /// A type.
 ///
 /// See also the `TyKind` enum in rustc (librustc/ty/sty.rs), which represents
@@ -535,7 +568,7 @@ pub enum GenericPredicate {
     /// The given trait needs to be implemented for its type parameters.
     Implemented(TraitRef),
     /// An associated type bindings like in `Iterator<Item = T>`.
-    Projection(ProjectionPredicate),
+    AliasEq(AliasEq),
     /// We couldn't resolve the trait reference. (If some type parameters can't
     /// be resolved, they will just be Unknown).
     Error,
@@ -553,8 +586,10 @@ pub fn is_implemented(&self) -> bool {
     pub fn trait_ref(&self, db: &dyn HirDatabase) -> Option<TraitRef> {
         match self {
             GenericPredicate::Implemented(tr) => Some(tr.clone()),
-            GenericPredicate::Projection(proj) => Some(proj.projection_ty.trait_ref(db)),
-            GenericPredicate::Error => None,
+            GenericPredicate::AliasEq(AliasEq { alias: AliasTy::Projection(proj), .. }) => {
+                Some(proj.trait_ref(db))
+            }
+            GenericPredicate::AliasEq(_) | GenericPredicate::Error => None,
         }
     }
 }
@@ -563,7 +598,7 @@ impl TypeWalk for GenericPredicate {
     fn walk(&self, f: &mut impl FnMut(&Ty)) {
         match self {
             GenericPredicate::Implemented(trait_ref) => trait_ref.walk(f),
-            GenericPredicate::Projection(projection_pred) => projection_pred.walk(f),
+            GenericPredicate::AliasEq(alias_eq) => alias_eq.walk(f),
             GenericPredicate::Error => {}
         }
     }
@@ -575,9 +610,7 @@ fn walk_mut_binders(
     ) {
         match self {
             GenericPredicate::Implemented(trait_ref) => trait_ref.walk_mut_binders(f, binders),
-            GenericPredicate::Projection(projection_pred) => {
-                projection_pred.walk_mut_binders(f, binders)
-            }
+            GenericPredicate::AliasEq(alias_eq) => alias_eq.walk_mut_binders(f, binders),
             GenericPredicate::Error => {}
         }
     }
index 5d950a017554374fa2dd7badd4a6b0b8cafa3f28..7d22c3df598cf2959b4fe0ff18cac6efbc1cf64d 100644 (file)
@@ -33,8 +33,8 @@
         all_super_trait_refs, associated_type_by_name_including_super_traits, generics,
         variant_data,
     },
-    AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, FnPointer, FnSig, GenericPredicate,
-    ImplTraitId, OpaqueTy, PolyFnSig, ProjectionPredicate, ProjectionTy, ReturnTypeImplTrait,
+    AliasEq, AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, FnPointer, FnSig,
+    GenericPredicate, ImplTraitId, OpaqueTy, PolyFnSig, ProjectionTy, ReturnTypeImplTrait,
     ReturnTypeImplTraits, Substitution, TraitEnvironment, TraitRef, Ty, TyKind, TypeWalk,
 };
 
@@ -750,9 +750,9 @@ fn assoc_type_bindings_from_type_bound(
                 );
                 if let Some(type_ref) = &binding.type_ref {
                     let ty = self.lower_ty(type_ref);
-                    let projection_predicate =
-                        ProjectionPredicate { projection_ty: projection_ty.clone(), ty };
-                    preds.push(GenericPredicate::Projection(projection_predicate));
+                    let alias_eq =
+                        AliasEq { alias: AliasTy::Projection(projection_ty.clone()), ty };
+                    preds.push(GenericPredicate::AliasEq(alias_eq));
                 }
                 for bound in &binding.bounds {
                     preds.extend(self.lower_type_bound(
index a7287dea1c10e05654b68e58ce80f657e17b77e1..ac7de7605687a5010a90718a20077fe3a9e15af8 100644 (file)
@@ -8,10 +8,9 @@
 use hir_def::{lang_item::LangItemTarget, TraitId};
 use stdx::panic_context;
 
-use crate::{db::HirDatabase, DebruijnIndex, Substitution};
-
-use super::{
-    Canonical, GenericPredicate, HirDisplay, ProjectionTy, TraitRef, Ty, TyKind, TypeWalk,
+use crate::{
+    db::HirDatabase, AliasTy, Canonical, DebruijnIndex, GenericPredicate, HirDisplay, Substitution,
+    TraitRef, Ty, TyKind, TypeWalk,
 };
 
 use self::chalk::{from_chalk, Interner, ToChalk};
@@ -93,31 +92,32 @@ pub enum Obligation {
     /// Prove that a certain type implements a trait (the type is the `Self` type
     /// parameter to the `TraitRef`).
     Trait(TraitRef),
-    Projection(ProjectionPredicate),
+    AliasEq(AliasEq),
 }
 
 impl Obligation {
     pub fn from_predicate(predicate: GenericPredicate) -> Option<Obligation> {
         match predicate {
             GenericPredicate::Implemented(trait_ref) => Some(Obligation::Trait(trait_ref)),
-            GenericPredicate::Projection(projection_pred) => {
-                Some(Obligation::Projection(projection_pred))
-            }
+            GenericPredicate::AliasEq(alias_eq) => Some(Obligation::AliasEq(alias_eq)),
             GenericPredicate::Error => None,
         }
     }
 }
 
 #[derive(Clone, Debug, PartialEq, Eq, Hash)]
-pub struct ProjectionPredicate {
-    pub projection_ty: ProjectionTy,
+pub struct AliasEq {
+    pub alias: AliasTy,
     pub ty: Ty,
 }
 
-impl TypeWalk for ProjectionPredicate {
+impl TypeWalk for AliasEq {
     fn walk(&self, f: &mut impl FnMut(&Ty)) {
-        self.projection_ty.walk(f);
         self.ty.walk(f);
+        match &self.alias {
+            AliasTy::Projection(projection_ty) => projection_ty.walk(f),
+            AliasTy::Opaque(opaque) => opaque.walk(f),
+        }
     }
 
     fn walk_mut_binders(
@@ -125,8 +125,11 @@ fn walk_mut_binders(
         f: &mut impl FnMut(&mut Ty, DebruijnIndex),
         binders: DebruijnIndex,
     ) {
-        self.projection_ty.walk_mut_binders(f, binders);
         self.ty.walk_mut_binders(f, binders);
+        match &mut self.alias {
+            AliasTy::Projection(projection_ty) => projection_ty.walk_mut_binders(f, binders),
+            AliasTy::Opaque(opaque) => opaque.walk_mut_binders(f, binders),
+        }
     }
 }
 
@@ -138,12 +141,14 @@ pub(crate) fn trait_solve_query(
 ) -> Option<Solution> {
     let _p = profile::span("trait_solve_query").detail(|| match &goal.value.value {
         Obligation::Trait(it) => db.trait_data(it.hir_trait_id()).name.to_string(),
-        Obligation::Projection(_) => "projection".to_string(),
+        Obligation::AliasEq(_) => "alias_eq".to_string(),
     });
     log::info!("trait_solve_query({})", goal.value.value.display(db));
 
-    if let Obligation::Projection(pred) = &goal.value.value {
-        if let TyKind::BoundVar(_) = &pred.projection_ty.substitution[0].interned(&Interner) {
+    if let Obligation::AliasEq(AliasEq { alias: AliasTy::Projection(projection_ty), .. }) =
+        &goal.value.value
+    {
+        if let TyKind::BoundVar(_) = &projection_ty.substitution[0].interned(&Interner) {
             // Hack: don't ask Chalk to normalize with an unknown self type, it'll say that's impossible
             return Some(Solution::Ambig(Guidance::Unknown));
         }
index bac70f5aa4260c7c431f7dc9217f0a93ba45a573..080764e762362a00b2af2000f3c4060e4426f983 100644 (file)
@@ -21,8 +21,8 @@
     method_resolution::{TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS},
     to_assoc_type_id, to_chalk_trait_id,
     utils::generics,
-    BoundVar, CallableDefId, CallableSig, DebruijnIndex, FnDefId, GenericPredicate,
-    ProjectionPredicate, ProjectionTy, Substitution, TraitRef, Ty, TyKind,
+    AliasEq, AliasTy, BoundVar, CallableDefId, CallableSig, DebruijnIndex, FnDefId,
+    GenericPredicate, ProjectionTy, Substitution, TraitRef, Ty, TyKind,
 };
 use mapping::{
     convert_where_clauses, generic_predicate_to_inline_bound, make_binders, TypeAliasAsValue,
@@ -229,18 +229,18 @@ fn opaque_ty_data(&self, id: chalk_ir::OpaqueTyId<Interner>) -> Arc<OpaqueTyDatu
                             .intern(&Interner),
                         ),
                     });
-                    let proj_bound = GenericPredicate::Projection(ProjectionPredicate {
-                        // The parameter of the opaque type.
-                        ty: TyKind::BoundVar(BoundVar { debruijn: DebruijnIndex::ONE, index: 0 })
-                            .intern(&Interner),
-                        projection_ty: ProjectionTy {
+                    let proj_bound = GenericPredicate::AliasEq(AliasEq {
+                        alias: AliasTy::Projection(ProjectionTy {
                             associated_ty_id: to_assoc_type_id(future_output),
                             // Self type as the first parameter.
                             substitution: Substitution::single(
                                 TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0))
                                     .intern(&Interner),
                             ),
-                        },
+                        }),
+                        // The parameter of the opaque type.
+                        ty: TyKind::BoundVar(BoundVar { debruijn: DebruijnIndex::ONE, index: 0 })
+                            .intern(&Interner),
                     });
                     let bound = OpaqueTyDatumBound {
                         bounds: make_binders(
index 0086ce1e9d6ed286711377a9cdc07a3a18445d04..62b779008fb9c4904e4682b61698bc9a6df8a2d9 100644 (file)
@@ -14,8 +14,8 @@
     from_assoc_type_id,
     primitive::UintTy,
     traits::{Canonical, Obligation},
-    AliasTy, CallableDefId, FnPointer, GenericPredicate, InEnvironment, OpaqueTy,
-    ProjectionPredicate, ProjectionTy, Scalar, Substitution, TraitRef, Ty,
+    AliasTy, CallableDefId, FnPointer, GenericPredicate, InEnvironment, OpaqueTy, ProjectionTy,
+    Scalar, Substitution, TraitRef, Ty,
 };
 
 use super::interner::*;
@@ -314,12 +314,10 @@ fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::QuantifiedWhereClause<Inter
                 let chalk_trait_ref = chalk_trait_ref.shifted_in(&Interner);
                 make_binders(chalk_ir::WhereClause::Implemented(chalk_trait_ref), 0)
             }
-            GenericPredicate::Projection(projection_pred) => {
-                let ty = projection_pred.ty.to_chalk(db).shifted_in(&Interner);
-                let projection = projection_pred.projection_ty.to_chalk(db).shifted_in(&Interner);
-                let alias = chalk_ir::AliasTy::Projection(projection);
-                make_binders(chalk_ir::WhereClause::AliasEq(chalk_ir::AliasEq { alias, ty }), 0)
-            }
+            GenericPredicate::AliasEq(alias_eq) => make_binders(
+                chalk_ir::WhereClause::AliasEq(alias_eq.to_chalk(db).shifted_in(&Interner)),
+                0,
+            ),
             GenericPredicate::Error => panic!("tried passing GenericPredicate::Error to Chalk"),
         }
     }
@@ -338,16 +336,8 @@ fn from_chalk(
             chalk_ir::WhereClause::Implemented(tr) => {
                 GenericPredicate::Implemented(from_chalk(db, tr))
             }
-            chalk_ir::WhereClause::AliasEq(projection_eq) => {
-                let projection_ty = from_chalk(
-                    db,
-                    match projection_eq.alias {
-                        chalk_ir::AliasTy::Projection(p) => p,
-                        _ => unimplemented!(),
-                    },
-                );
-                let ty = from_chalk(db, projection_eq.ty);
-                GenericPredicate::Projection(ProjectionPredicate { projection_ty, ty })
+            chalk_ir::WhereClause::AliasEq(alias_eq) => {
+                GenericPredicate::AliasEq(from_chalk(db, alias_eq))
             }
 
             chalk_ir::WhereClause::LifetimeOutlives(_) => {
@@ -383,19 +373,55 @@ fn from_chalk(
         }
     }
 }
+impl ToChalk for OpaqueTy {
+    type Chalk = chalk_ir::OpaqueTy<Interner>;
+
+    fn to_chalk(self, db: &dyn HirDatabase) -> Self::Chalk {
+        chalk_ir::OpaqueTy {
+            opaque_ty_id: self.opaque_ty_id,
+            substitution: self.substitution.to_chalk(db),
+        }
+    }
+
+    fn from_chalk(db: &dyn HirDatabase, chalk: Self::Chalk) -> Self {
+        OpaqueTy {
+            opaque_ty_id: chalk.opaque_ty_id,
+            substitution: from_chalk(db, chalk.substitution),
+        }
+    }
+}
+
+impl ToChalk for AliasTy {
+    type Chalk = chalk_ir::AliasTy<Interner>;
+
+    fn to_chalk(self, db: &dyn HirDatabase) -> Self::Chalk {
+        match self {
+            AliasTy::Projection(projection_ty) => {
+                chalk_ir::AliasTy::Projection(projection_ty.to_chalk(db))
+            }
+            AliasTy::Opaque(opaque_ty) => chalk_ir::AliasTy::Opaque(opaque_ty.to_chalk(db)),
+        }
+    }
+
+    fn from_chalk(db: &dyn HirDatabase, chalk: Self::Chalk) -> Self {
+        match chalk {
+            chalk_ir::AliasTy::Projection(projection_ty) => {
+                AliasTy::Projection(from_chalk(db, projection_ty))
+            }
+            chalk_ir::AliasTy::Opaque(opaque_ty) => AliasTy::Opaque(from_chalk(db, opaque_ty)),
+        }
+    }
+}
 
-impl ToChalk for ProjectionPredicate {
+impl ToChalk for AliasEq {
     type Chalk = chalk_ir::AliasEq<Interner>;
 
     fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::AliasEq<Interner> {
-        chalk_ir::AliasEq {
-            alias: chalk_ir::AliasTy::Projection(self.projection_ty.to_chalk(db)),
-            ty: self.ty.to_chalk(db),
-        }
+        chalk_ir::AliasEq { alias: self.alias.to_chalk(db), ty: self.ty.to_chalk(db) }
     }
 
-    fn from_chalk(_db: &dyn HirDatabase, _normalize: chalk_ir::AliasEq<Interner>) -> Self {
-        unimplemented!()
+    fn from_chalk(db: &dyn HirDatabase, alias_eq: chalk_ir::AliasEq<Interner>) -> Self {
+        AliasEq { alias: from_chalk(db, alias_eq.alias), ty: from_chalk(db, alias_eq.ty) }
     }
 }
 
@@ -405,7 +431,7 @@ impl ToChalk for Obligation {
     fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::DomainGoal<Interner> {
         match self {
             Obligation::Trait(tr) => tr.to_chalk(db).cast(&Interner),
-            Obligation::Projection(pr) => pr.to_chalk(db).cast(&Interner),
+            Obligation::AliasEq(alias_eq) => alias_eq.to_chalk(db).cast(&Interner),
         }
     }
 
@@ -527,29 +553,29 @@ pub(super) fn generic_predicate_to_inline_bound(
             let trait_bound = rust_ir::TraitBound { trait_id: trait_ref.trait_id, args_no_self };
             Some(rust_ir::InlineBound::TraitBound(trait_bound))
         }
-        GenericPredicate::Projection(proj) => {
-            if &proj.projection_ty.substitution[0] != self_ty {
+        GenericPredicate::AliasEq(AliasEq { alias: AliasTy::Projection(projection_ty), ty }) => {
+            if &projection_ty.substitution[0] != self_ty {
                 return None;
             }
-            let trait_ = match from_assoc_type_id(proj.projection_ty.associated_ty_id)
+            let trait_ = match from_assoc_type_id(projection_ty.associated_ty_id)
                 .lookup(db.upcast())
                 .container
             {
                 AssocContainerId::TraitId(t) => t,
                 _ => panic!("associated type not in trait"),
             };
-            let args_no_self = proj.projection_ty.substitution[1..]
+            let args_no_self = projection_ty.substitution[1..]
                 .iter()
                 .map(|ty| ty.clone().to_chalk(db).cast(&Interner))
                 .collect();
             let alias_eq_bound = rust_ir::AliasEqBound {
-                value: proj.ty.clone().to_chalk(db),
+                value: ty.clone().to_chalk(db),
                 trait_bound: rust_ir::TraitBound { trait_id: trait_.to_chalk(db), args_no_self },
-                associated_ty_id: proj.projection_ty.associated_ty_id,
+                associated_ty_id: projection_ty.associated_ty_id,
                 parameters: Vec::new(), // FIXME we don't support generic associated types yet
             };
             Some(rust_ir::InlineBound::AliasEqBound(alias_eq_bound))
         }
-        GenericPredicate::Error => None,
+        _ => None,
     }
 }