From 7ec3b66f7a3ac0a33cf435bc3596fdac542fc52a Mon Sep 17 00:00:00 2001
From: Florian Diebold <flodiebold@gmail.com>
Date: Sat, 20 Mar 2021 11:23:59 +0100
Subject: Turn Obligation into something similar to chalk_ir::DomainGoal

This includes starting to make use of Chalk's `Cast` trait.
---
 crates/hir/src/lib.rs                     | 11 ++++---
 crates/hir_ty/src/autoderef.rs            |  9 +++---
 crates/hir_ty/src/chalk_cast.rs           | 53 +++++++++++++++++++++++++++++++
 crates/hir_ty/src/db.rs                   |  2 +-
 crates/hir_ty/src/display.rs              | 20 +++---------
 crates/hir_ty/src/infer.rs                | 12 +++----
 crates/hir_ty/src/infer/coerce.rs         |  7 ++--
 crates/hir_ty/src/infer/expr.rs           | 25 +++++++--------
 crates/hir_ty/src/infer/path.rs           | 12 ++++---
 crates/hir_ty/src/infer/unify.rs          | 13 +++-----
 crates/hir_ty/src/lib.rs                  |  7 ++--
 crates/hir_ty/src/method_resolution.rs    |  6 ++--
 crates/hir_ty/src/traits.rs               | 34 ++++++++------------
 crates/hir_ty/src/traits/chalk/mapping.rs | 10 +++---
 14 files changed, 130 insertions(+), 91 deletions(-)
 create mode 100644 crates/hir_ty/src/chalk_cast.rs

diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 268a2b901..30e577671 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -56,8 +56,8 @@ use hir_ty::{
     primitive::UintTy,
     to_assoc_type_id,
     traits::{FnTrait, Solution, SolutionVariables},
-    AliasEq, AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, DebruijnIndex,
-    InEnvironment, Interner, Obligation, ProjectionTy, Scalar, Substitution, Ty, TyDefId, TyKind,
+    AliasEq, AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, Cast, DebruijnIndex,
+    InEnvironment, Interner, ProjectionTy, Scalar, Substitution, Ty, TyDefId, TyKind,
     TyVariableKind, WhereClause,
 };
 use itertools::Itertools;
@@ -1767,7 +1767,7 @@ impl Type {
         let goal = Canonical {
             value: hir_ty::InEnvironment::new(
                 self.ty.environment.clone(),
-                hir_ty::Obligation::Trait(trait_ref),
+                trait_ref.cast(&Interner),
             ),
             kinds: Arc::new([]),
         };
@@ -1789,14 +1789,15 @@ impl Type {
         let goal = Canonical {
             value: InEnvironment::new(
                 self.ty.environment.clone(),
-                Obligation::AliasEq(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),
-                }),
+                }
+                .cast(&Interner),
             ),
             kinds: Arc::new([TyVariableKind::General]),
         };
diff --git a/crates/hir_ty/src/autoderef.rs b/crates/hir_ty/src/autoderef.rs
index 33b966026..23ab042c1 100644
--- a/crates/hir_ty/src/autoderef.rs
+++ b/crates/hir_ty/src/autoderef.rs
@@ -6,6 +6,7 @@
 use std::iter::successors;
 
 use base_db::CrateId;
+use chalk_ir::cast::Cast;
 use hir_def::lang_item::LangItemTarget;
 use hir_expand::name::name;
 use log::{info, warn};
@@ -15,8 +16,8 @@ use crate::{
     to_assoc_type_id, to_chalk_trait_id,
     traits::{InEnvironment, Solution},
     utils::generics,
-    AliasEq, AliasTy, BoundVar, Canonical, DebruijnIndex, Interner, Obligation, ProjectionTy,
-    Substitution, TraitRef, Ty, TyKind,
+    AliasEq, AliasTy, BoundVar, Canonical, DebruijnIndex, Interner, ProjectionTy, Substitution,
+    TraitRef, Ty, TyKind,
 };
 
 const AUTODEREF_RECURSION_LIMIT: usize = 10;
@@ -74,7 +75,7 @@ fn deref_by_trait(
     let implements_goal = Canonical {
         kinds: ty.value.kinds.clone(),
         value: InEnvironment {
-            value: Obligation::Trait(trait_ref),
+            value: trait_ref.cast(&Interner),
             environment: ty.environment.clone(),
         },
     };
@@ -92,7 +93,7 @@ fn deref_by_trait(
             .intern(&Interner),
     };
 
-    let obligation = super::Obligation::AliasEq(projection);
+    let obligation = projection.cast(&Interner);
 
     let in_env = InEnvironment { value: obligation, environment: ty.environment };
 
diff --git a/crates/hir_ty/src/chalk_cast.rs b/crates/hir_ty/src/chalk_cast.rs
new file mode 100644
index 000000000..bf884ae15
--- /dev/null
+++ b/crates/hir_ty/src/chalk_cast.rs
@@ -0,0 +1,53 @@
+//! Implementations of the Chalk `Cast` trait for our types.
+
+use chalk_ir::{
+    cast::{Cast, CastTo},
+    interner::HasInterner,
+};
+
+use crate::{AliasEq, DomainGoal, Interner, TraitRef, WhereClause};
+
+macro_rules! has_interner {
+    ($t:ty) => {
+        impl HasInterner for $t {
+            type Interner = crate::Interner;
+        }
+    };
+}
+
+has_interner!(WhereClause);
+has_interner!(DomainGoal);
+
+impl CastTo<WhereClause> for TraitRef {
+    fn cast_to(self, _interner: &Interner) -> WhereClause {
+        WhereClause::Implemented(self)
+    }
+}
+
+impl CastTo<WhereClause> for AliasEq {
+    fn cast_to(self, _interner: &Interner) -> WhereClause {
+        WhereClause::AliasEq(self)
+    }
+}
+
+impl CastTo<DomainGoal> for WhereClause {
+    fn cast_to(self, _interner: &Interner) -> DomainGoal {
+        DomainGoal::Holds(self)
+    }
+}
+
+macro_rules! transitive_impl {
+    ($a:ty, $b:ty, $c:ty) => {
+        impl CastTo<$c> for $a {
+            fn cast_to(self, interner: &Interner) -> $c {
+                self.cast::<$b>(interner).cast(interner)
+            }
+        }
+    };
+}
+
+// In Chalk, these can be done as blanket impls, but that doesn't work here
+// because of coherence
+
+transitive_impl!(TraitRef, WhereClause, DomainGoal);
+transitive_impl!(AliasEq, WhereClause, DomainGoal);
diff --git a/crates/hir_ty/src/db.rs b/crates/hir_ty/src/db.rs
index 300da0f38..91a2e0b5b 100644
--- a/crates/hir_ty/src/db.rs
+++ b/crates/hir_ty/src/db.rs
@@ -119,7 +119,7 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
     fn trait_solve(
         &self,
         krate: CrateId,
-        goal: crate::Canonical<crate::InEnvironment<crate::Obligation>>,
+        goal: crate::Canonical<crate::InEnvironment<crate::DomainGoal>>,
     ) -> Option<crate::traits::Solution>;
 
     #[salsa::invoke(crate::traits::chalk::program_clauses_for_chalk_env_query)]
diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs
index 4765c99a4..3845009ae 100644
--- a/crates/hir_ty/src/display.rs
+++ b/crates/hir_ty/src/display.rs
@@ -19,7 +19,7 @@ use hir_expand::name::Name;
 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, AliasEq, AliasTy,
-    CallableDefId, CallableSig, ImplTraitId, Interner, Lifetime, Obligation, OpaqueTy,
+    CallableDefId, CallableSig, DomainGoal, ImplTraitId, Interner, Lifetime, OpaqueTy,
     ProjectionTy, Scalar, Substitution, TraitRef, Ty, TyKind, WhereClause,
 };
 
@@ -805,22 +805,12 @@ impl HirDisplay for Lifetime {
     }
 }
 
-impl HirDisplay for Obligation {
+impl HirDisplay for DomainGoal {
     fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
         match self {
-            Obligation::Trait(tr) => {
-                write!(f, "Implements(")?;
-                tr.hir_fmt(f)?;
-                write!(f, ")")
-            }
-            Obligation::AliasEq(AliasEq { alias, ty }) => {
-                write!(f, "Normalize(")?;
-                match alias {
-                    AliasTy::Projection(projection_ty) => projection_ty.hir_fmt(f)?,
-                    AliasTy::Opaque(opaque) => opaque.hir_fmt(f)?,
-                }
-                write!(f, " => ")?;
-                ty.hir_fmt(f)?;
+            DomainGoal::Holds(wc) => {
+                write!(f, "Holds(")?;
+                wc.hir_fmt(f)?;
                 write!(f, ")")
             }
         }
diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs
index 82186979a..b9e434c78 100644
--- a/crates/hir_ty/src/infer.rs
+++ b/crates/hir_ty/src/infer.rs
@@ -18,7 +18,7 @@ use std::mem;
 use std::ops::Index;
 use std::sync::Arc;
 
-use chalk_ir::Mutability;
+use chalk_ir::{cast::Cast, Mutability};
 use hir_def::{
     body::Body,
     data::{ConstData, FunctionData, StaticData},
@@ -37,7 +37,7 @@ use stdx::impl_from;
 use syntax::SmolStr;
 
 use super::{
-    traits::{Guidance, Obligation, Solution},
+    traits::{DomainGoal, Guidance, Solution},
     InEnvironment, ProjectionTy, Substitution, TraitEnvironment, TraitRef, Ty, TypeWalk,
 };
 use crate::{
@@ -204,7 +204,7 @@ struct InferenceContext<'a> {
     resolver: Resolver,
     table: unify::InferenceTable,
     trait_env: Arc<TraitEnvironment>,
-    obligations: Vec<Obligation>,
+    obligations: Vec<DomainGoal>,
     result: InferenceResult,
     /// The return type of the function being inferred, or the closure if we're
     /// currently within one.
@@ -403,8 +403,8 @@ impl<'a> InferenceContext<'a> {
                     }),
                     ty: ty.clone(),
                 };
-                self.obligations.push(Obligation::Trait(trait_ref));
-                self.obligations.push(Obligation::AliasEq(alias_eq));
+                self.obligations.push(trait_ref.cast(&Interner));
+                self.obligations.push(alias_eq.cast(&Interner));
                 self.resolve_ty_as_possible(ty)
             }
             None => self.err_ty(),
@@ -430,7 +430,7 @@ impl<'a> InferenceContext<'a> {
     fn normalize_projection_ty(&mut self, proj_ty: ProjectionTy) -> Ty {
         let var = self.table.new_type_var();
         let alias_eq = AliasEq { alias: AliasTy::Projection(proj_ty), ty: var.clone() };
-        let obligation = Obligation::AliasEq(alias_eq);
+        let obligation = alias_eq.cast(&Interner);
         self.obligations.push(obligation);
         var
     }
diff --git a/crates/hir_ty/src/infer/coerce.rs b/crates/hir_ty/src/infer/coerce.rs
index b86474ed4..07eb96573 100644
--- a/crates/hir_ty/src/infer/coerce.rs
+++ b/crates/hir_ty/src/infer/coerce.rs
@@ -4,12 +4,11 @@
 //!
 //! See: https://doc.rust-lang.org/nomicon/coercions.html
 
-use chalk_ir::{Mutability, TyVariableKind};
+use chalk_ir::{cast::Cast, Mutability, TyVariableKind};
 use hir_def::lang_item::LangItemTarget;
 
 use crate::{
-    autoderef, to_chalk_trait_id, traits::Solution, Interner, Obligation, Substitution, TraitRef,
-    Ty, TyKind,
+    autoderef, to_chalk_trait_id, traits::Solution, Interner, Substitution, TraitRef, Ty, TyKind,
 };
 
 use super::{InEnvironment, InferenceContext};
@@ -143,7 +142,7 @@ impl<'a> InferenceContext<'a> {
             .build();
         let trait_ref =
             TraitRef { trait_id: to_chalk_trait_id(coerce_unsized_trait), substitution: substs };
-        let goal = InEnvironment::new(self.trait_env.clone(), Obligation::Trait(trait_ref));
+        let goal = InEnvironment::new(self.trait_env.clone(), trait_ref.cast(&Interner));
 
         let canonicalizer = self.canonicalizer();
         let canonicalized = canonicalizer.canonicalize_obligation(goal);
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index 93548b6c0..79bbc5dab 100644
--- a/crates/hir_ty/src/infer/expr.rs
+++ b/crates/hir_ty/src/infer/expr.rs
@@ -3,7 +3,7 @@
 use std::iter::{repeat, repeat_with};
 use std::{mem, sync::Arc};
 
-use chalk_ir::{Mutability, TyVariableKind};
+use chalk_ir::{cast::Cast, Mutability, TyVariableKind};
 use hir_def::{
     expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp},
     path::{GenericArg, GenericArgs},
@@ -21,7 +21,7 @@ use crate::{
     to_assoc_type_id, to_chalk_trait_id,
     traits::{chalk::from_chalk, FnTrait, InEnvironment},
     utils::{generics, variant_data, Generics},
-    AdtId, Binders, CallableDefId, FnPointer, FnSig, Interner, Obligation, Rawness, Scalar,
+    AdtId, Binders, CallableDefId, DomainGoal, FnPointer, FnSig, Interner, Rawness, Scalar,
     Substitution, TraitRef, Ty, TyKind,
 };
 
@@ -90,10 +90,9 @@ impl<'a> InferenceContext<'a> {
             Substitution::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build();
 
         let trait_env = Arc::clone(&self.trait_env);
-        let implements_fn_trait = Obligation::Trait(TraitRef {
-            trait_id: to_chalk_trait_id(fn_once_trait),
-            substitution: substs.clone(),
-        });
+        let implements_fn_trait: DomainGoal =
+            TraitRef { trait_id: to_chalk_trait_id(fn_once_trait), substitution: substs.clone() }
+                .cast(&Interner);
         let goal = self.canonicalizer().canonicalize_obligation(InEnvironment {
             value: implements_fn_trait.clone(),
             environment: trait_env,
@@ -938,22 +937,20 @@ impl<'a> InferenceContext<'a> {
             let generic_predicates = self.db.generic_predicates(def.into());
             for predicate in generic_predicates.iter() {
                 let predicate = predicate.clone().subst(parameters);
-                if let Some(obligation) = Obligation::from_predicate(predicate) {
-                    self.obligations.push(obligation);
-                }
+                self.obligations.push(predicate.cast(&Interner));
             }
             // add obligation for trait implementation, if this is a trait method
             match def {
                 CallableDefId::FunctionId(f) => {
                     if let AssocContainerId::TraitId(trait_) = f.lookup(self.db.upcast()).container
                     {
-                        // construct a TraitDef
+                        // construct a TraitRef
                         let substs =
                             parameters.prefix(generics(self.db.upcast(), trait_.into()).len());
-                        self.obligations.push(Obligation::Trait(TraitRef {
-                            trait_id: to_chalk_trait_id(trait_),
-                            substitution: substs,
-                        }));
+                        self.obligations.push(
+                            TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs }
+                                .cast(&Interner),
+                        );
                     }
                 }
                 CallableDefId::StructId(_) | CallableDefId::EnumVariantId(_) => {}
diff --git a/crates/hir_ty/src/infer/path.rs b/crates/hir_ty/src/infer/path.rs
index e15135fc1..58cce56ab 100644
--- a/crates/hir_ty/src/infer/path.rs
+++ b/crates/hir_ty/src/infer/path.rs
@@ -2,6 +2,7 @@
 
 use std::iter;
 
+use chalk_ir::cast::Cast;
 use hir_def::{
     path::{Path, PathSegment},
     resolver::{ResolveValueResult, Resolver, TypeNs, ValueNs},
@@ -256,10 +257,13 @@ impl<'a> InferenceContext<'a> {
                             .push(ty.clone())
                             .fill(std::iter::repeat_with(|| self.table.new_type_var()))
                             .build();
-                        self.obligations.push(super::Obligation::Trait(TraitRef {
-                            trait_id: to_chalk_trait_id(trait_),
-                            substitution: trait_substs.clone(),
-                        }));
+                        self.obligations.push(
+                            TraitRef {
+                                trait_id: to_chalk_trait_id(trait_),
+                                substitution: trait_substs.clone(),
+                            }
+                            .cast(&Interner),
+                        );
                         Some(trait_substs)
                     }
                     AssocContainerId::ModuleId(_) => None,
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs
index 5b7b423fa..1fc03c8f4 100644
--- a/crates/hir_ty/src/infer/unify.rs
+++ b/crates/hir_ty/src/infer/unify.rs
@@ -5,7 +5,7 @@ use std::borrow::Cow;
 use chalk_ir::{FloatTy, IntTy, TyVariableKind};
 use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue};
 
-use super::{InferenceContext, Obligation};
+use super::{DomainGoal, InferenceContext};
 use crate::{
     AliasEq, AliasTy, BoundVar, Canonical, DebruijnIndex, FnPointer, InEnvironment, InferenceVar,
     Interner, Scalar, Substitution, Ty, TyKind, TypeWalk, WhereClause,
@@ -87,14 +87,11 @@ impl<'a, 'b> Canonicalizer<'a, 'b> {
 
     pub(crate) fn canonicalize_obligation(
         mut self,
-        obligation: InEnvironment<Obligation>,
-    ) -> Canonicalized<InEnvironment<Obligation>> {
+        obligation: InEnvironment<DomainGoal>,
+    ) -> Canonicalized<InEnvironment<DomainGoal>> {
         let result = match obligation.value {
-            Obligation::Trait(tr) => {
-                Obligation::Trait(self.do_canonicalize(tr, DebruijnIndex::INNERMOST))
-            }
-            Obligation::AliasEq(alias_eq) => {
-                Obligation::AliasEq(self.do_canonicalize(alias_eq, DebruijnIndex::INNERMOST))
+            DomainGoal::Holds(wc) => {
+                DomainGoal::Holds(self.do_canonicalize(wc, DebruijnIndex::INNERMOST))
             }
         };
         self.into_canonicalized(InEnvironment {
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs
index 8de2d422f..c46529879 100644
--- a/crates/hir_ty/src/lib.rs
+++ b/crates/hir_ty/src/lib.rs
@@ -13,6 +13,7 @@ mod op;
 mod lower;
 pub(crate) mod infer;
 pub(crate) mod utils;
+mod chalk_cast;
 
 pub mod display;
 pub mod db;
@@ -45,9 +46,11 @@ pub use lower::{
     associated_type_shorthand_candidates, callable_item_sig, CallableDefId, ImplTraitLoweringMode,
     TyDefId, TyLoweringContext, ValueTyDefId,
 };
-pub use traits::{AliasEq, InEnvironment, Obligation, TraitEnvironment};
+pub use traits::{AliasEq, DomainGoal, InEnvironment, TraitEnvironment};
 
-pub use chalk_ir::{AdtId, BoundVar, DebruijnIndex, Mutability, Safety, Scalar, TyVariableKind};
+pub use chalk_ir::{
+    cast::Cast, AdtId, BoundVar, DebruijnIndex, Mutability, Safety, Scalar, TyVariableKind,
+};
 
 pub use crate::traits::chalk::Interner;
 
diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs
index 01b78fb44..da6bc2a4a 100644
--- a/crates/hir_ty/src/method_resolution.rs
+++ b/crates/hir_ty/src/method_resolution.rs
@@ -6,7 +6,7 @@ use std::{iter, sync::Arc};
 
 use arrayvec::ArrayVec;
 use base_db::CrateId;
-use chalk_ir::Mutability;
+use chalk_ir::{cast::Cast, Mutability};
 use hir_def::{
     lang_item::LangItemTarget, AssocContainerId, AssocItemId, FunctionId, GenericDefId, HasModule,
     ImplId, Lookup, ModuleId, TraitId,
@@ -767,7 +767,7 @@ fn generic_implements_goal(
     env: Arc<TraitEnvironment>,
     trait_: TraitId,
     self_ty: Canonical<Ty>,
-) -> Canonical<InEnvironment<super::Obligation>> {
+) -> Canonical<InEnvironment<super::DomainGoal>> {
     let mut kinds = self_ty.kinds.to_vec();
     let substs = super::Substitution::build_for_def(db, trait_)
         .push(self_ty.value)
@@ -775,7 +775,7 @@ fn generic_implements_goal(
         .build();
     kinds.extend(iter::repeat(chalk_ir::TyVariableKind::General).take(substs.len() - 1));
     let trait_ref = TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs };
-    let obligation = super::Obligation::Trait(trait_ref);
+    let obligation = trait_ref.cast(&Interner);
     Canonical { kinds: kinds.into(), value: InEnvironment::new(env, obligation) }
 }
 
diff --git a/crates/hir_ty/src/traits.rs b/crates/hir_ty/src/traits.rs
index 87c92bd12..7dadd1ffb 100644
--- a/crates/hir_ty/src/traits.rs
+++ b/crates/hir_ty/src/traits.rs
@@ -9,8 +9,8 @@ use hir_def::{lang_item::LangItemTarget, TraitId};
 use stdx::panic_context;
 
 use crate::{
-    db::HirDatabase, AliasTy, Canonical, DebruijnIndex, HirDisplay, Substitution, TraitRef, Ty,
-    TyKind, TypeWalk, WhereClause,
+    db::HirDatabase, AliasTy, Canonical, DebruijnIndex, HirDisplay, Substitution, Ty, TyKind,
+    TypeWalk, WhereClause,
 };
 
 use self::chalk::{from_chalk, Interner, ToChalk};
@@ -88,20 +88,8 @@ impl<T> InEnvironment<T> {
 /// a certain type implements a certain trait. Proving the Obligation might
 /// result in additional information about inference variables.
 #[derive(Clone, Debug, PartialEq, Eq, Hash)]
-pub enum Obligation {
-    /// Prove that a certain type implements a trait (the type is the `Self` type
-    /// parameter to the `TraitRef`).
-    Trait(TraitRef),
-    AliasEq(AliasEq),
-}
-
-impl Obligation {
-    pub fn from_predicate(predicate: WhereClause) -> Option<Obligation> {
-        match predicate {
-            WhereClause::Implemented(trait_ref) => Some(Obligation::Trait(trait_ref)),
-            WhereClause::AliasEq(alias_eq) => Some(Obligation::AliasEq(alias_eq)),
-        }
-    }
+pub enum DomainGoal {
+    Holds(WhereClause),
 }
 
 #[derive(Clone, Debug, PartialEq, Eq, Hash)]
@@ -136,16 +124,20 @@ impl TypeWalk for AliasEq {
 pub(crate) fn trait_solve_query(
     db: &dyn HirDatabase,
     krate: CrateId,
-    goal: Canonical<InEnvironment<Obligation>>,
+    goal: Canonical<InEnvironment<DomainGoal>>,
 ) -> 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::AliasEq(_) => "alias_eq".to_string(),
+        DomainGoal::Holds(WhereClause::Implemented(it)) => {
+            db.trait_data(it.hir_trait_id()).name.to_string()
+        }
+        DomainGoal::Holds(WhereClause::AliasEq(_)) => "alias_eq".to_string(),
     });
     log::info!("trait_solve_query({})", goal.value.value.display(db));
 
-    if let Obligation::AliasEq(AliasEq { alias: AliasTy::Projection(projection_ty), .. }) =
-        &goal.value.value
+    if let DomainGoal::Holds(WhereClause::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
diff --git a/crates/hir_ty/src/traits/chalk/mapping.rs b/crates/hir_ty/src/traits/chalk/mapping.rs
index 7841c216c..65feb82e5 100644
--- a/crates/hir_ty/src/traits/chalk/mapping.rs
+++ b/crates/hir_ty/src/traits/chalk/mapping.rs
@@ -13,7 +13,7 @@ use crate::{
     db::HirDatabase,
     from_assoc_type_id,
     primitive::UintTy,
-    traits::{Canonical, Obligation},
+    traits::{Canonical, DomainGoal},
     AliasTy, CallableDefId, FnPointer, InEnvironment, OpaqueTy, ProjectionTy, Scalar, Substitution,
     TraitRef, Ty, WhereClause,
 };
@@ -422,13 +422,15 @@ impl ToChalk for AliasEq {
     }
 }
 
-impl ToChalk for Obligation {
+impl ToChalk for DomainGoal {
     type Chalk = chalk_ir::DomainGoal<Interner>;
 
     fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::DomainGoal<Interner> {
         match self {
-            Obligation::Trait(tr) => tr.to_chalk(db).cast(&Interner),
-            Obligation::AliasEq(alias_eq) => alias_eq.to_chalk(db).cast(&Interner),
+            DomainGoal::Holds(WhereClause::Implemented(tr)) => tr.to_chalk(db).cast(&Interner),
+            DomainGoal::Holds(WhereClause::AliasEq(alias_eq)) => {
+                alias_eq.to_chalk(db).cast(&Interner)
+            }
         }
     }
 
-- 
cgit v1.2.3