diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index ae730beb51..f7fc80d4ee 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs @@ -538,14 +538,6 @@ pub enum DefWithBody { impl_froms!(DefWithBody: Function, Const, Static); impl DefWithBody { - pub(crate) fn krate(self, db: &impl HirDatabase) -> Option { - match self { - DefWithBody::Const(c) => c.krate(db), - DefWithBody::Function(f) => f.krate(db), - DefWithBody::Static(s) => s.krate(db), - } - } - pub fn module(self, db: &impl HirDatabase) -> Module { match self { DefWithBody::Const(c) => c.module(db), diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index 3cbcbd1d01..388530f310 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs @@ -17,12 +17,15 @@ use std::ops::Deref; use std::sync::Arc; use std::{fmt, iter, mem}; -use hir_def::{generics::GenericParams, AdtId, GenericDefId}; +use hir_def::{ + generics::GenericParams, AdtId, ContainerId, DefWithBodyId, GenericDefId, HasModule, Lookup, + TraitId, TypeAliasId, +}; use ra_db::{impl_intern_key, salsa}; use crate::{ - db::HirDatabase, expr::ExprId, util::make_mut_slice, Adt, Crate, DefWithBody, FloatTy, IntTy, - Mutability, Name, Trait, TypeAlias, Uncertain, + db::HirDatabase, expr::ExprId, util::make_mut_slice, Adt, Crate, FloatTy, IntTy, Mutability, + Name, Trait, Uncertain, }; use display::{HirDisplay, HirFormatter}; @@ -107,13 +110,13 @@ pub enum TypeCtor { /// when we have tried to normalize a projection like `T::Item` but /// couldn't find a better representation. In that case, we generate /// an **application type** like `(Iterator::Item)`. - AssociatedType(TypeAlias), + AssociatedType(TypeAliasId), /// The type of a specific closure. /// /// The closure signature is stored in a `FnPtr` type in the first type /// parameter. - Closure { def: DefWithBody, expr: ExprId }, + Closure { def: DefWithBodyId, expr: ExprId }, } /// This exists just for Chalk, because Chalk just has a single `StructId` where @@ -147,7 +150,7 @@ impl TypeCtor { generic_params.count_params_including_parent() } TypeCtor::AssociatedType(type_alias) => { - let generic_params = db.generic_params(type_alias.id.into()); + let generic_params = db.generic_params(type_alias.into()); generic_params.count_params_including_parent() } TypeCtor::FnPtr { num_args } => num_args as usize + 1, @@ -169,10 +172,13 @@ impl TypeCtor { | TypeCtor::Ref(_) | TypeCtor::FnPtr { .. } | TypeCtor::Tuple { .. } => None, - TypeCtor::Closure { def, .. } => def.krate(db), + // Closure's krate is irrelevant for coherence I would think? + TypeCtor::Closure { .. } => None, TypeCtor::Adt(adt) => adt.krate(db), TypeCtor::FnDef(callable) => Some(callable.krate(db).into()), - TypeCtor::AssociatedType(type_alias) => type_alias.krate(db), + TypeCtor::AssociatedType(type_alias) => { + Some(type_alias.lookup(db).module(db).krate.into()) + } } } @@ -193,7 +199,7 @@ impl TypeCtor { | TypeCtor::Closure { .. } => None, TypeCtor::Adt(adt) => Some(adt.into()), TypeCtor::FnDef(callable) => Some(callable.into()), - TypeCtor::AssociatedType(type_alias) => Some(type_alias.id.into()), + TypeCtor::AssociatedType(type_alias) => Some(type_alias.into()), } } } @@ -212,18 +218,19 @@ pub struct ApplicationTy { /// trait and all its parameters are fully known. #[derive(Clone, PartialEq, Eq, Debug, Hash)] pub struct ProjectionTy { - pub associated_ty: TypeAlias, + pub associated_ty: TypeAliasId, pub parameters: Substs, } impl ProjectionTy { pub fn trait_ref(&self, db: &impl HirDatabase) -> TraitRef { - TraitRef { - trait_: self - .associated_ty - .parent_trait(db) - .expect("projection ty without parent trait"), - substs: self.parameters.clone(), + TraitRef { trait_: self.trait_(db).into(), substs: self.parameters.clone() } + } + + fn trait_(&self, db: &impl HirDatabase) -> TraitId { + match self.associated_ty.lookup(db).container { + ContainerId::TraitId(it) => it, + _ => panic!("projection ty without parent trait"), } } } @@ -895,11 +902,12 @@ impl HirDisplay for ApplicationTy { } } TypeCtor::AssociatedType(type_alias) => { - let trait_name = type_alias - .parent_trait(f.db) - .and_then(|t| t.name(f.db)) - .unwrap_or_else(Name::missing); - let name = type_alias.name(f.db); + let trait_ = match type_alias.lookup(f.db).container { + ContainerId::TraitId(it) => it, + _ => panic!("not an associated type"), + }; + let trait_name = f.db.trait_data(trait_).name.clone().unwrap_or_else(Name::missing); + let name = f.db.type_alias_data(type_alias).name.clone(); write!(f, "{}::{}", trait_name, name)?; if self.parameters.len() > 0 { write!(f, "<")?; @@ -926,18 +934,15 @@ impl HirDisplay for ProjectionTy { return write!(f, "…"); } - let trait_name = self - .associated_ty - .parent_trait(f.db) - .and_then(|t| t.name(f.db)) - .unwrap_or_else(Name::missing); + let trait_name = + f.db.trait_data(self.trait_(f.db)).name.clone().unwrap_or_else(Name::missing); write!(f, "<{} as {}", self.parameters[0].display(f.db), trait_name,)?; if self.parameters.len() > 1 { write!(f, "<")?; f.write_joined(&self.parameters[1..], ", ")?; write!(f, ">")?; } - write!(f, ">::{}", self.associated_ty.name(f.db))?; + write!(f, ">::{}", f.db.type_alias_data(self.associated_ty).name)?; Ok(()) } } @@ -1000,7 +1005,10 @@ impl HirDisplay for Ty { write!(f, "<")?; angle_open = true; } - let name = projection_pred.projection_ty.associated_ty.name(f.db); + let name = + f.db.type_alias_data(projection_pred.projection_ty.associated_ty) + .name + .clone(); write!(f, "{} = ", name)?; projection_pred.ty.hir_fmt(f)?; } @@ -1076,7 +1084,7 @@ impl HirDisplay for GenericPredicate { write!( f, ">::{} = {}", - projection_pred.projection_ty.associated_ty.name(f.db), + f.db.type_alias_data(projection_pred.projection_ty.associated_ty).name, projection_pred.ty.display(f.db) )?; } diff --git a/crates/ra_hir/src/ty/autoderef.rs b/crates/ra_hir/src/ty/autoderef.rs index 44547197ca..9e7593b8b0 100644 --- a/crates/ra_hir/src/ty/autoderef.rs +++ b/crates/ra_hir/src/ty/autoderef.rs @@ -69,7 +69,7 @@ fn deref_by_trait( let projection = super::traits::ProjectionPredicate { ty: Ty::Bound(0), - projection_ty: super::ProjectionTy { associated_ty: target, parameters }, + projection_ty: super::ProjectionTy { associated_ty: target.id, parameters }, }; let obligation = super::Obligation::Projection(projection); diff --git a/crates/ra_hir/src/ty/infer/expr.rs b/crates/ra_hir/src/ty/infer/expr.rs index 994a6d7e95..316cdc8800 100644 --- a/crates/ra_hir/src/ty/infer/expr.rs +++ b/crates/ra_hir/src/ty/infer/expr.rs @@ -101,7 +101,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { let projection = ProjectionPredicate { ty: pat_ty.clone(), projection_ty: ProjectionTy { - associated_ty: into_iter_item_alias, + associated_ty: into_iter_item_alias.id, parameters: Substs::single(iterable_ty), }, }; @@ -137,8 +137,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { TypeCtor::FnPtr { num_args: sig_tys.len() as u16 - 1 }, Substs(sig_tys.into()), ); - let closure_ty = - Ty::apply_one(TypeCtor::Closure { def: self.owner, expr: tgt_expr }, sig_ty); + let closure_ty = Ty::apply_one( + TypeCtor::Closure { def: self.owner.into(), expr: tgt_expr }, + sig_ty, + ); // Eagerly try to relate the closure type with the expected // type, otherwise we often won't have enough information to @@ -281,7 +283,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { let projection = ProjectionPredicate { ty: ty.clone(), projection_ty: ProjectionTy { - associated_ty: future_future_output_alias, + associated_ty: future_future_output_alias.id, parameters: Substs::single(inner_ty), }, }; @@ -300,7 +302,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { let projection = ProjectionPredicate { ty: ty.clone(), projection_ty: ProjectionTy { - associated_ty: ops_try_ok_alias, + associated_ty: ops_try_ok_alias.id, parameters: Substs::single(inner_ty), }, }; diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index eb51d31bd0..d7d4bb0d66 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs @@ -176,7 +176,7 @@ impl Ty { Some(associated_ty) => { // FIXME handle type parameters on the segment Ty::Projection(ProjectionTy { - associated_ty, + associated_ty: associated_ty.id, parameters: trait_ref.substs, }) } @@ -268,7 +268,10 @@ impl Ty { .fill_with_unknown() .build(); // FIXME handle type parameters on the segment - return Ty::Projection(ProjectionTy { associated_ty, parameters: substs }); + return Ty::Projection(ProjectionTy { + associated_ty: associated_ty.id, + parameters: substs, + }); } } Ty::Unknown @@ -508,7 +511,7 @@ fn assoc_type_bindings_from_type_bound<'a>( let associated_ty = match trait_ref.trait_.associated_type_by_name_including_super_traits(db, &name) { None => return GenericPredicate::Error, - Some(t) => t, + Some(t) => t.id, }; let projection_ty = ProjectionTy { associated_ty, parameters: trait_ref.substs.clone() }; diff --git a/crates/ra_hir/src/ty/traits.rs b/crates/ra_hir/src/ty/traits.rs index 268fa09e4a..b9a5d651f4 100644 --- a/crates/ra_hir/src/ty/traits.rs +++ b/crates/ra_hir/src/ty/traits.rs @@ -2,13 +2,14 @@ use std::sync::{Arc, Mutex}; use chalk_ir::{cast::Cast, family::ChalkIr}; +use hir_def::DefWithBodyId; use log::debug; use ra_db::{impl_intern_key, salsa}; use ra_prof::profile; use rustc_hash::FxHashSet; use super::{Canonical, GenericPredicate, HirDisplay, ProjectionTy, TraitRef, Ty, TypeWalk}; -use crate::{db::HirDatabase, expr::ExprId, Crate, DefWithBody, ImplBlock, Trait, TypeAlias}; +use crate::{db::HirDatabase, expr::ExprId, Crate, ImplBlock, Trait, TypeAlias}; use self::chalk::{from_chalk, ToChalk}; @@ -290,7 +291,7 @@ impl FnTrait { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct ClosureFnTraitImplData { - def: DefWithBody, + def: DefWithBodyId, expr: ExprId, fn_trait: FnTrait, } diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs index 0272dd9aef..06388a3ce2 100644 --- a/crates/ra_hir/src/ty/traits/chalk.rs +++ b/crates/ra_hir/src/ty/traits/chalk.rs @@ -9,7 +9,7 @@ use chalk_ir::{ }; use chalk_rust_ir::{AssociatedTyDatum, AssociatedTyValue, ImplDatum, StructDatum, TraitDatum}; -use hir_def::{lang_item::LangItemTarget, GenericDefId}; +use hir_def::{lang_item::LangItemTarget, ContainerId, GenericDefId, Lookup, TypeAliasId}; use hir_expand::name; use ra_db::salsa::{InternId, InternKey}; @@ -203,15 +203,15 @@ impl ToChalk for Impl { } } -impl ToChalk for TypeAlias { +impl ToChalk for TypeAliasId { type Chalk = chalk_ir::TypeId; fn to_chalk(self, _db: &impl HirDatabase) -> chalk_ir::TypeId { - chalk_ir::TypeId(id_to_chalk(self.id)) + chalk_ir::TypeId(id_to_chalk(self)) } - fn from_chalk(_db: &impl HirDatabase, type_alias_id: chalk_ir::TypeId) -> TypeAlias { - TypeAlias { id: id_from_chalk(type_alias_id.0) } + fn from_chalk(_db: &impl HirDatabase, type_alias_id: chalk_ir::TypeId) -> TypeAliasId { + id_from_chalk(type_alias_id.0) } } @@ -504,21 +504,21 @@ pub(crate) fn associated_ty_data_query( id: TypeId, ) -> Arc> { debug!("associated_ty_data {:?}", id); - let type_alias: TypeAlias = from_chalk(db, id); - let trait_ = match type_alias.container(db) { - Some(crate::Container::Trait(t)) => t, + let type_alias: TypeAliasId = from_chalk(db, id); + let trait_ = match type_alias.lookup(db).container { + ContainerId::TraitId(t) => t, _ => panic!("associated type not in trait"), }; - let generic_params = db.generic_params(type_alias.id.into()); + let generic_params = db.generic_params(type_alias.into()); let bound_data = chalk_rust_ir::AssociatedTyDatumBound { // FIXME add bounds and where clauses bounds: vec![], where_clauses: vec![], }; let datum = AssociatedTyDatum { - trait_id: trait_.to_chalk(db), + trait_id: Trait::from(trait_).to_chalk(db), id, - name: lalrpop_intern::intern(&type_alias.name(db).to_string()), + name: lalrpop_intern::intern(&db.type_alias_data(type_alias).name.to_string()), binders: make_binders(bound_data, generic_params.count_params_including_parent()), }; Arc::new(datum) @@ -566,7 +566,7 @@ pub(crate) fn trait_datum_query( .items(db) .into_iter() .filter_map(|trait_item| match trait_item { - crate::AssocItem::TypeAlias(type_alias) => Some(type_alias), + crate::AssocItem::TypeAlias(type_alias) => Some(type_alias.id), _ => None, }) .map(|type_alias| type_alias.to_chalk(db)) @@ -785,7 +785,8 @@ fn type_alias_associated_ty_value( .trait_; let assoc_ty = trait_ .associated_type_by_name(db, &type_alias.name(db)) - .expect("assoc ty value should not exist"); // validated when building the impl data as well + .expect("assoc ty value should not exist") // validated when building the impl data as well + .id; let generic_params = db.generic_params(impl_block.id.into()); let bound_vars = Substs::bound_vars(&generic_params); let ty = db.type_for_def(type_alias.into(), crate::ty::Namespace::Types).subst(&bound_vars); @@ -820,7 +821,8 @@ fn closure_fn_trait_output_assoc_ty_value( let output_ty_id = fn_once_trait .associated_type_by_name(db, &name::OUTPUT_TYPE) - .expect("assoc ty value should not exist"); + .expect("assoc ty value should not exist") + .id; let value_bound = chalk_rust_ir::AssociatedTyValueBound { ty: output_ty.to_chalk(db) };