]> git.lizzy.rs Git - rust.git/blobdiff - crates/hir/src/lib.rs
Use hir formatter more
[rust.git] / crates / hir / src / lib.rs
index 638398e292abe7a5751586c7d7c306a4ac0f221b..98135602a5367539b8bcef5b05b7b5f13207289d 100644 (file)
@@ -29,6 +29,8 @@
 pub mod diagnostics;
 pub mod db;
 
+mod display;
+
 use std::{iter, sync::Arc};
 
 use arrayvec::ArrayVec;
 use hir_expand::{diagnostics::DiagnosticSink, name::name, MacroDefKind};
 use hir_ty::{
     autoderef,
-    display::{write_bounds_like_dyn_trait_with_prefix, HirDisplayError, HirFormatter},
-    method_resolution,
+    method_resolution::{self, TyFingerprint},
+    to_assoc_type_id,
     traits::{FnTrait, Solution, SolutionVariables},
     AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, DebruijnIndex, GenericPredicate,
-    InEnvironment, Obligation, ProjectionPredicate, ProjectionTy, Scalar, Substs, TraitEnvironment,
-    Ty, TyDefId, TyVariableKind,
+    InEnvironment, Interner, Obligation, ProjectionPredicate, ProjectionTy, Scalar, Substs, Ty,
+    TyDefId, TyKind, TyVariableKind,
 };
 use rustc_hash::FxHashSet;
 use stdx::{format_to, impl_from};
@@ -266,8 +268,7 @@ pub fn module(self, db: &dyn HirDatabase) -> Option<Module> {
     }
 
     pub fn canonical_path(&self, db: &dyn HirDatabase) -> Option<String> {
-        let mut segments = Vec::new();
-        segments.push(self.name(db)?.to_string());
+        let mut segments = vec![self.name(db)?.to_string()];
         for m in self.module(db)?.path_to_root(db) {
             segments.extend(m.name(db).map(|it| it.to_string()))
         }
@@ -305,7 +306,6 @@ pub fn name(self, db: &dyn HirDatabase) -> Option<Name> {
             ModuleDef::Module(it) => it.name(db),
             ModuleDef::Const(it) => it.name(db),
             ModuleDef::Static(it) => it.name(db),
-
             ModuleDef::BuiltinType(it) => Some(it.name()),
         }
     }
@@ -535,7 +535,7 @@ pub struct Struct {
 
 impl Struct {
     pub fn module(self, db: &dyn HirDatabase) -> Module {
-        Module { id: self.id.lookup(db.upcast()).container.module(db.upcast()) }
+        Module { id: self.id.lookup(db.upcast()).container }
     }
 
     pub fn krate(self, db: &dyn HirDatabase) -> Option<Crate> {
@@ -556,11 +556,7 @@ pub fn fields(self, db: &dyn HirDatabase) -> Vec<Field> {
     }
 
     pub fn ty(self, db: &dyn HirDatabase) -> Type {
-        Type::from_def(
-            db,
-            self.id.lookup(db.upcast()).container.module(db.upcast()).krate(),
-            self.id,
-        )
+        Type::from_def(db, self.id.lookup(db.upcast()).container.krate(), self.id)
     }
 
     pub fn repr(self, db: &dyn HirDatabase) -> Option<ReprKind> {
@@ -576,6 +572,12 @@ fn variant_data(self, db: &dyn HirDatabase) -> Arc<VariantData> {
     }
 }
 
+impl HasVisibility for Struct {
+    fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
+        db.struct_data(self.id).visibility.resolve(db.upcast(), &self.id.resolver(db.upcast()))
+    }
+}
+
 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 pub struct Union {
     pub(crate) id: UnionId,
@@ -587,15 +589,11 @@ pub fn name(self, db: &dyn HirDatabase) -> Name {
     }
 
     pub fn module(self, db: &dyn HirDatabase) -> Module {
-        Module { id: self.id.lookup(db.upcast()).container.module(db.upcast()) }
+        Module { id: self.id.lookup(db.upcast()).container }
     }
 
     pub fn ty(self, db: &dyn HirDatabase) -> Type {
-        Type::from_def(
-            db,
-            self.id.lookup(db.upcast()).container.module(db.upcast()).krate(),
-            self.id,
-        )
+        Type::from_def(db, self.id.lookup(db.upcast()).container.krate(), self.id)
     }
 
     pub fn fields(self, db: &dyn HirDatabase) -> Vec<Field> {
@@ -612,6 +610,12 @@ fn variant_data(self, db: &dyn HirDatabase) -> Arc<VariantData> {
     }
 }
 
+impl HasVisibility for Union {
+    fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
+        db.union_data(self.id).visibility.resolve(db.upcast(), &self.id.resolver(db.upcast()))
+    }
+}
+
 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 pub struct Enum {
     pub(crate) id: EnumId,
@@ -619,7 +623,7 @@ pub struct Enum {
 
 impl Enum {
     pub fn module(self, db: &dyn HirDatabase) -> Module {
-        Module { id: self.id.lookup(db.upcast()).container.module(db.upcast()) }
+        Module { id: self.id.lookup(db.upcast()).container }
     }
 
     pub fn krate(self, db: &dyn HirDatabase) -> Option<Crate> {
@@ -635,11 +639,13 @@ pub fn variants(self, db: &dyn HirDatabase) -> Vec<Variant> {
     }
 
     pub fn ty(self, db: &dyn HirDatabase) -> Type {
-        Type::from_def(
-            db,
-            self.id.lookup(db.upcast()).container.module(db.upcast()).krate(),
-            self.id,
-        )
+        Type::from_def(db, self.id.lookup(db.upcast()).container.krate(), self.id)
+    }
+}
+
+impl HasVisibility for Enum {
+    fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
+        db.enum_data(self.id).visibility.resolve(db.upcast(), &self.id.resolver(db.upcast()))
     }
 }
 
@@ -690,7 +696,7 @@ pub enum Adt {
 impl Adt {
     pub fn has_non_default_type_params(self, db: &dyn HirDatabase) -> bool {
         let subst = db.generic_defaults(self.into());
-        subst.iter().any(|ty| &ty.value == &Ty::Unknown)
+        subst.iter().any(|ty| ty.value.is_unknown())
     }
 
     /// Turns this ADT into a type. Any type parameters of the ADT will be
@@ -709,8 +715,8 @@ pub fn module(self, db: &dyn HirDatabase) -> Module {
         }
     }
 
-    pub fn krate(self, db: &dyn HirDatabase) -> Option<Crate> {
-        Some(self.module(db).krate())
+    pub fn krate(self, db: &dyn HirDatabase) -> Crate {
+        self.module(db).krate()
     }
 
     pub fn name(self, db: &dyn HirDatabase) -> Name {
@@ -815,7 +821,7 @@ pub fn ret_type(self, db: &dyn HirDatabase) -> Type {
         let krate = self.id.lookup(db.upcast()).container.module(db.upcast()).krate();
         let ret_type = &db.function_data(self.id).ret_type;
         let ctx = hir_ty::TyLoweringContext::new(db, &resolver);
-        let ty = Ty::from_hir_ext(&ctx, ret_type).0;
+        let ty = ctx.lower_ty(ret_type);
         Type::new_with_resolver_inner(db, krate, &resolver, ty)
     }
 
@@ -830,19 +836,20 @@ pub fn assoc_fn_params(self, db: &dyn HirDatabase) -> Vec<Param> {
         let resolver = self.id.resolver(db.upcast());
         let krate = self.id.lookup(db.upcast()).container.module(db.upcast()).krate();
         let ctx = hir_ty::TyLoweringContext::new(db, &resolver);
-        let environment = TraitEnvironment::lower(db, &resolver);
+        let environment = db.trait_environment(self.id.into());
         db.function_data(self.id)
             .params
             .iter()
-            .map(|type_ref| {
+            .enumerate()
+            .map(|(idx, type_ref)| {
                 let ty = Type {
                     krate,
                     ty: InEnvironment {
-                        value: Ty::from_hir_ext(&ctx, type_ref).0,
+                        value: ctx.lower_ty(type_ref),
                         environment: environment.clone(),
                     },
                 };
-                Param { ty }
+                Param { func: self, ty, idx }
             })
             .collect()
     }
@@ -856,7 +863,7 @@ pub fn method_params(self, db: &dyn HirDatabase) -> Option<Vec<Param>> {
     }
 
     pub fn is_unsafe(self, db: &dyn HirDatabase) -> bool {
-        db.function_data(self.id).is_unsafe
+        db.function_data(self.id).qualifier.is_unsafe
     }
 
     pub fn diagnostics(self, db: &dyn HirDatabase, sink: &mut DiagnosticSink) {
@@ -905,6 +912,9 @@ fn from(mutability: hir_ty::Mutability) -> Access {
 
 #[derive(Debug)]
 pub struct Param {
+    func: Function,
+    /// The index in parameter list, including self parameter.
+    idx: usize,
     ty: Type,
 }
 
@@ -912,6 +922,15 @@ impl Param {
     pub fn ty(&self) -> &Type {
         &self.ty
     }
+
+    pub fn pattern_source(&self, db: &dyn HirDatabase) -> Option<ast::Pat> {
+        let params = self.func.source(db)?.value.param_list()?;
+        if params.self_param().is_some() {
+            params.params().nth(self.idx.checked_sub(1)?)?.pat()
+        } else {
+            params.params().nth(self.idx)?.pat()
+        }
+    }
 }
 
 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -961,6 +980,10 @@ pub fn krate(self, db: &dyn HirDatabase) -> Option<Crate> {
     pub fn name(self, db: &dyn HirDatabase) -> Option<Name> {
         db.const_data(self.id).name.clone()
     }
+
+    pub fn type_ref(self, db: &dyn HirDatabase) -> TypeRef {
+        db.const_data(self.id).type_ref.clone()
+    }
 }
 
 impl HasVisibility for Const {
@@ -994,6 +1017,12 @@ pub fn is_mut(self, db: &dyn HirDatabase) -> bool {
     }
 }
 
+impl HasVisibility for Static {
+    fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
+        db.static_data(self.id).visibility.resolve(db.upcast(), &self.id.resolver(db.upcast()))
+    }
+}
+
 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 pub struct Trait {
     pub(crate) id: TraitId,
@@ -1001,7 +1030,7 @@ pub struct Trait {
 
 impl Trait {
     pub fn module(self, db: &dyn HirDatabase) -> Module {
-        Module { id: self.id.lookup(db.upcast()).container.module(db.upcast()) }
+        Module { id: self.id.lookup(db.upcast()).container }
     }
 
     pub fn name(self, db: &dyn HirDatabase) -> Name {
@@ -1013,7 +1042,13 @@ pub fn items(self, db: &dyn HirDatabase) -> Vec<AssocItem> {
     }
 
     pub fn is_auto(self, db: &dyn HirDatabase) -> bool {
-        db.trait_data(self.id).auto
+        db.trait_data(self.id).is_auto
+    }
+}
+
+impl HasVisibility for Trait {
+    fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
+        db.trait_data(self.id).visibility.resolve(db.upcast(), &self.id.resolver(db.upcast()))
     }
 }
 
@@ -1025,15 +1060,15 @@ pub struct TypeAlias {
 impl TypeAlias {
     pub fn has_non_default_type_params(self, db: &dyn HirDatabase) -> bool {
         let subst = db.generic_defaults(self.id.into());
-        subst.iter().any(|ty| &ty.value == &Ty::Unknown)
+        subst.iter().any(|ty| ty.value.is_unknown())
     }
 
     pub fn module(self, db: &dyn HirDatabase) -> Module {
         Module { id: self.id.lookup(db.upcast()).module(db.upcast()) }
     }
 
-    pub fn krate(self, db: &dyn HirDatabase) -> Option<Crate> {
-        Some(self.module(db).krate())
+    pub fn krate(self, db: &dyn HirDatabase) -> Crate {
+        self.module(db).krate()
     }
 
     pub fn type_ref(self, db: &dyn HirDatabase) -> Option<TypeRef> {
@@ -1157,7 +1192,7 @@ fn as_assoc_item<ID, DEF, CTOR, AST>(db: &dyn HirDatabase, ctor: CTOR, id: ID) -
 {
     match id.lookup(db.upcast()).container {
         AssocContainerId::TraitId(_) | AssocContainerId::ImplId(_) => Some(ctor(DEF::from(id))),
-        AssocContainerId::ContainerId(_) => None,
+        AssocContainerId::ModuleId(_) => None,
     }
 }
 
@@ -1185,7 +1220,7 @@ pub fn container(self, db: &dyn HirDatabase) -> AssocItemContainer {
         match container {
             AssocContainerId::TraitId(id) => AssocItemContainer::Trait(id.into()),
             AssocContainerId::ImplId(id) => AssocItemContainer::Impl(id.into()),
-            AssocContainerId::ContainerId(_) => panic!("invalid AssocItem"),
+            AssocContainerId::ModuleId(_) => panic!("invalid AssocItem"),
         }
     }
 
@@ -1397,7 +1432,7 @@ pub fn module(self, db: &dyn HirDatabase) -> Module {
     pub fn ty(self, db: &dyn HirDatabase) -> Type {
         let resolver = self.id.parent.resolver(db.upcast());
         let krate = self.id.parent.module(db.upcast()).krate();
-        let ty = Ty::Placeholder(self.id);
+        let ty = TyKind::Placeholder(hir_ty::to_placeholder_idx(db, self.id)).intern(&Interner);
         Type::new_with_resolver_inner(db, krate, &resolver, ty)
     }
 
@@ -1425,19 +1460,6 @@ pub fn default(self, db: &dyn HirDatabase) -> Option<Type> {
     }
 }
 
-impl HirDisplay for TypeParam {
-    fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
-        write!(f, "{}", self.name(f.db))?;
-        let bounds = f.db.generic_predicates_for_param(self.id);
-        let substs = Substs::type_params(f.db, self.id.parent);
-        let predicates = bounds.iter().cloned().map(|b| b.subst(&substs)).collect::<Vec<_>>();
-        if !(predicates.is_empty() || f.omit_verbose_types()) {
-            write_bounds_like_dyn_trait_with_prefix(":", &predicates, f)?;
-        }
-        Ok(())
-    }
-}
-
 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
 pub struct LifetimeParam {
     pub(crate) id: LifetimeParamId,
@@ -1496,9 +1518,44 @@ pub fn all_in_crate(db: &dyn HirDatabase, krate: Crate) -> Vec<Impl> {
 
         inherent.all_impls().chain(trait_.all_impls()).map(Self::from).collect()
     }
-    pub fn for_trait(db: &dyn HirDatabase, krate: Crate, trait_: Trait) -> Vec<Impl> {
-        let impls = db.trait_impls_in_crate(krate.id);
-        impls.for_trait(trait_.id).map(Self::from).collect()
+
+    pub fn all_for_type(db: &dyn HirDatabase, Type { krate, ty }: Type) -> Vec<Impl> {
+        let def_crates = match ty.value.def_crates(db, krate) {
+            Some(def_crates) => def_crates,
+            None => return Vec::new(),
+        };
+
+        let filter = |impl_def: &Impl| {
+            let target_ty = impl_def.target_ty(db);
+            let rref = target_ty.remove_ref();
+            ty.value.equals_ctor(rref.as_ref().map_or(&target_ty.ty.value, |it| &it.ty.value))
+        };
+
+        let mut all = Vec::new();
+        def_crates.into_iter().for_each(|id| {
+            all.extend(db.inherent_impls_in_crate(id).all_impls().map(Self::from).filter(filter))
+        });
+        let fp = TyFingerprint::for_impl(&ty.value);
+        for id in db.crate_graph().iter() {
+            match fp {
+                Some(fp) => all.extend(
+                    db.trait_impls_in_crate(id).for_self_ty(fp).map(Self::from).filter(filter),
+                ),
+                None => all
+                    .extend(db.trait_impls_in_crate(id).all_impls().map(Self::from).filter(filter)),
+            }
+        }
+        all
+    }
+
+    pub fn all_for_trait(db: &dyn HirDatabase, trait_: Trait) -> Vec<Impl> {
+        let krate = trait_.module(db).krate();
+        let mut all = Vec::new();
+        for Crate { id } in krate.reverse_dependencies(db).into_iter().chain(Some(krate)) {
+            let impls = db.trait_impls_in_crate(id);
+            all.extend(impls.for_trait(trait_.id).map(Self::from))
+        }
+        all
     }
 
     // FIXME: the return type is wrong. This should be a hir version of
@@ -1510,9 +1567,9 @@ pub fn target_trait(self, db: &dyn HirDatabase) -> Option<TypeRef> {
     pub fn target_ty(self, db: &dyn HirDatabase) -> Type {
         let impl_data = db.impl_data(self.id);
         let resolver = self.id.resolver(db.upcast());
-        let krate = self.id.lookup(db.upcast()).container.module(db.upcast()).krate();
+        let krate = self.id.lookup(db.upcast()).container.krate();
         let ctx = hir_ty::TyLoweringContext::new(db, &resolver);
-        let ty = Ty::from_hir(&ctx, &impl_data.target_type);
+        let ty = ctx.lower_ty(&impl_data.target_type);
         Type::new_with_resolver_inner(db, krate, &resolver, ty)
     }
 
@@ -1525,7 +1582,7 @@ pub fn is_negative(self, db: &dyn HirDatabase) -> bool {
     }
 
     pub fn module(self, db: &dyn HirDatabase) -> Module {
-        self.id.lookup(db.upcast()).container.module(db.upcast()).into()
+        self.id.lookup(db.upcast()).container.into()
     }
 
     pub fn krate(self, db: &dyn HirDatabase) -> Crate {
@@ -1576,13 +1633,15 @@ pub(crate) fn new_with_resolver_inner(
         resolver: &Resolver,
         ty: Ty,
     ) -> Type {
-        let environment = TraitEnvironment::lower(db, &resolver);
+        let environment =
+            resolver.generic_def().map_or_else(Default::default, |d| db.trait_environment(d));
         Type { krate, ty: InEnvironment { value: ty, environment } }
     }
 
     fn new(db: &dyn HirDatabase, krate: CrateId, lexical_env: impl HasResolver, ty: Ty) -> Type {
         let resolver = lexical_env.resolver(db.upcast());
-        let environment = TraitEnvironment::lower(db, &resolver);
+        let environment =
+            resolver.generic_def().map_or_else(Default::default, |d| db.trait_environment(d));
         Type { krate, ty: InEnvironment { value: ty, environment } }
     }
 
@@ -1597,25 +1656,25 @@ fn from_def(
     }
 
     pub fn is_unit(&self) -> bool {
-        matches!(self.ty.value, Ty::Tuple(0, ..))
+        matches!(self.ty.value.interned(&Interner), TyKind::Tuple(0, ..))
     }
     pub fn is_bool(&self) -> bool {
-        matches!(self.ty.value, Ty::Scalar(Scalar::Bool))
+        matches!(self.ty.value.interned(&Interner), TyKind::Scalar(Scalar::Bool))
     }
 
     pub fn is_mutable_reference(&self) -> bool {
-        matches!(self.ty.value, Ty::Ref(hir_ty::Mutability::Mut, ..))
+        matches!(self.ty.value.interned(&Interner), TyKind::Ref(hir_ty::Mutability::Mut, ..))
     }
 
     pub fn remove_ref(&self) -> Option<Type> {
-        match &self.ty.value {
-            Ty::Ref(.., substs) => Some(self.derived(substs[0].clone())),
+        match &self.ty.value.interned(&Interner) {
+            TyKind::Ref(.., ty) => Some(self.derived(ty.clone())),
             _ => None,
         }
     }
 
     pub fn is_unknown(&self) -> bool {
-        matches!(self.ty.value, Ty::Unknown)
+        self.ty.value.is_unknown()
     }
 
     /// Checks that particular type `ty` implements `std::future::Future`.
@@ -1696,8 +1755,11 @@ pub fn normalize_trait_assoc_type(
             .fill(args.iter().map(|t| t.ty.value.clone()))
             .build();
         let predicate = ProjectionPredicate {
-            projection_ty: ProjectionTy { associated_ty: alias.id, parameters: subst },
-            ty: Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)),
+            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(
@@ -1725,26 +1787,23 @@ pub fn is_copy(&self, db: &dyn HirDatabase) -> bool {
     }
 
     pub fn as_callable(&self, db: &dyn HirDatabase) -> Option<Callable> {
-        let def = match self.ty.value {
-            Ty::FnDef(def, _) => Some(def),
-            _ => None,
-        };
+        let def = self.ty.value.callable_def(db);
 
         let sig = self.ty.value.callable_sig(db)?;
         Some(Callable { ty: self.clone(), sig, def, is_bound_method: false })
     }
 
     pub fn is_closure(&self) -> bool {
-        matches!(&self.ty.value, Ty::Closure { .. })
+        matches!(&self.ty.value.interned(&Interner), TyKind::Closure { .. })
     }
 
     pub fn is_fn(&self) -> bool {
-        matches!(&self.ty.value, Ty::FnDef(..) | Ty::Function { .. })
+        matches!(&self.ty.value.interned(&Interner), TyKind::FnDef(..) | TyKind::Function { .. })
     }
 
     pub fn is_packed(&self, db: &dyn HirDatabase) -> bool {
-        let adt_id = match self.ty.value {
-            Ty::Adt(hir_ty::AdtId(adt_id), ..) => adt_id,
+        let adt_id = match self.ty.value.interned(&Interner) {
+            &TyKind::Adt(hir_ty::AdtId(adt_id), ..) => adt_id,
             _ => return false,
         };
 
@@ -1756,24 +1815,45 @@ pub fn is_packed(&self, db: &dyn HirDatabase) -> bool {
     }
 
     pub fn is_raw_ptr(&self) -> bool {
-        matches!(&self.ty.value, Ty::Raw(..))
+        matches!(&self.ty.value.interned(&Interner), TyKind::Raw(..))
     }
 
     pub fn contains_unknown(&self) -> bool {
         return go(&self.ty.value);
 
         fn go(ty: &Ty) -> bool {
-            match ty {
-                Ty::Unknown => true,
-                _ => ty.substs().map_or(false, |substs| substs.iter().any(go)),
+            match ty.interned(&Interner) {
+                TyKind::Unknown => true,
+
+                TyKind::Adt(_, substs)
+                | TyKind::AssociatedType(_, substs)
+                | TyKind::Tuple(_, substs)
+                | TyKind::OpaqueType(_, substs)
+                | TyKind::FnDef(_, substs)
+                | TyKind::Closure(_, substs) => substs.iter().any(go),
+
+                TyKind::Array(ty) | TyKind::Slice(ty) | TyKind::Raw(_, ty) | TyKind::Ref(_, ty) => {
+                    go(ty)
+                }
+
+                TyKind::Scalar(_)
+                | TyKind::Str
+                | TyKind::Never
+                | TyKind::Placeholder(_)
+                | TyKind::BoundVar(_)
+                | TyKind::InferenceVar(_, _)
+                | TyKind::Dyn(_)
+                | TyKind::Function(_)
+                | TyKind::Alias(_)
+                | TyKind::ForeignType(_) => false,
             }
         }
     }
 
     pub fn fields(&self, db: &dyn HirDatabase) -> Vec<(Field, Type)> {
-        let (variant_id, substs) = match self.ty.value {
-            Ty::Adt(hir_ty::AdtId(AdtId::StructId(s)), ref substs) => (s.into(), substs),
-            Ty::Adt(hir_ty::AdtId(AdtId::UnionId(u)), ref substs) => (u.into(), substs),
+        let (variant_id, substs) = match self.ty.value.interned(&Interner) {
+            &TyKind::Adt(hir_ty::AdtId(AdtId::StructId(s)), ref substs) => (s.into(), substs),
+            &TyKind::Adt(hir_ty::AdtId(AdtId::UnionId(u)), ref substs) => (u.into(), substs),
             _ => return Vec::new(),
         };
 
@@ -1788,7 +1868,7 @@ pub fn fields(&self, db: &dyn HirDatabase) -> Vec<(Field, Type)> {
     }
 
     pub fn tuple_fields(&self, _db: &dyn HirDatabase) -> Vec<Type> {
-        if let Ty::Tuple(_, substs) = &self.ty.value {
+        if let TyKind::Tuple(_, substs) = &self.ty.value.interned(&Interner) {
             substs.iter().map(|ty| self.derived(ty.clone())).collect()
         } else {
             Vec::new()
@@ -1923,12 +2003,6 @@ pub fn as_associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<Tr
         self.ty.value.associated_type_parent_trait(db).map(Into::into)
     }
 
-    // FIXME: provide required accessors such that it becomes implementable from outside.
-    pub fn is_equal_for_find_impls(&self, other: &Type) -> bool {
-        let rref = other.remove_ref();
-        self.ty.value.equals_ctor(rref.as_ref().map_or(&other.ty.value, |it| &it.ty.value))
-    }
-
     fn derived(&self, ty: Ty) -> Type {
         Type {
             krate: self.krate,
@@ -1970,36 +2044,40 @@ fn walk_bounds(
 
         fn walk_type(db: &dyn HirDatabase, type_: &Type, cb: &mut impl FnMut(Type)) {
             let ty = type_.ty.value.strip_references();
-            match ty {
-                Ty::Adt(..) => {
+            match ty.interned(&Interner) {
+                TyKind::Adt(..) => {
                     cb(type_.derived(ty.clone()));
                 }
-                Ty::AssociatedType(..) => {
+                TyKind::AssociatedType(..) => {
                     if let Some(_) = ty.associated_type_parent_trait(db) {
                         cb(type_.derived(ty.clone()));
                     }
                 }
-                Ty::OpaqueType(..) => {
+                TyKind::OpaqueType(..) => {
                     if let Some(bounds) = ty.impl_trait_bounds(db) {
                         walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb);
                     }
                 }
-                Ty::Alias(AliasTy::Opaque(opaque_ty)) => {
+                TyKind::Alias(AliasTy::Opaque(opaque_ty)) => {
                     if let Some(bounds) = ty.impl_trait_bounds(db) {
                         walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb);
                     }
 
-                    walk_substs(db, type_, &opaque_ty.parameters, cb);
+                    walk_substs(db, type_, &opaque_ty.substitution, cb);
                 }
-                Ty::Placeholder(_) => {
+                TyKind::Placeholder(_) => {
                     if let Some(bounds) = ty.impl_trait_bounds(db) {
                         walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb);
                     }
                 }
-                Ty::Dyn(bounds) => {
+                TyKind::Dyn(bounds) => {
                     walk_bounds(db, &type_.derived(ty.clone()), bounds.as_ref(), cb);
                 }
 
+                TyKind::Ref(_, ty) | TyKind::Raw(_, ty) | TyKind::Array(ty) | TyKind::Slice(ty) => {
+                    walk_type(db, &type_.derived(ty.clone()), cb);
+                }
+
                 _ => {}
             }
             if let Some(substs) = ty.substs() {
@@ -2011,12 +2089,6 @@ fn walk_type(db: &dyn HirDatabase, type_: &Type, cb: &mut impl FnMut(Type)) {
     }
 }
 
-impl HirDisplay for Type {
-    fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
-        self.ty.value.hir_fmt(f)
-    }
-}
-
 // FIXME: closures
 #[derive(Debug)]
 pub struct Callable {