From 72d8e7e69abca9f27fb3ea386a6879324741e152 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 26 Nov 2019 18:00:36 +0300 Subject: Use TraitId in TraitRef --- crates/ra_hir/src/code_model.rs | 2 +- crates/ra_hir/src/ty.rs | 13 ++++---- crates/ra_hir/src/ty/infer/path.rs | 39 +++++++++++++----------- crates/ra_hir/src/ty/lower.rs | 14 ++++----- crates/ra_hir/src/ty/method_resolution.rs | 18 +++++------ crates/ra_hir/src/ty/traits/chalk.rs | 50 ++++++++++++++----------------- 6 files changed, 68 insertions(+), 68 deletions(-) (limited to 'crates/ra_hir') diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index 9578c20b0..7b5d78543 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs @@ -741,7 +741,7 @@ impl Trait { } pub fn trait_ref(self, db: &impl HirDatabase) -> TraitRef { - TraitRef::for_trait(db, self) + TraitRef::for_trait(db, self.id) } pub fn is_auto(self, db: &impl DefDatabase) -> bool { diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index 2a2dc26b4..3711068fa 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs @@ -26,7 +26,7 @@ use ra_db::{impl_intern_key, salsa}; use crate::{ db::HirDatabase, expr::ExprId, util::make_mut_slice, Adt, Crate, FloatTy, IntTy, Mutability, - Name, Trait, Uncertain, + Name, Uncertain, }; use display::{HirDisplay, HirFormatter}; @@ -445,7 +445,7 @@ impl Deref for Substs { #[derive(Clone, PartialEq, Eq, Debug, Hash)] pub struct TraitRef { /// FIXME name? - pub trait_: Trait, + pub trait_: TraitId, pub substs: Substs, } @@ -676,7 +676,7 @@ impl Ty { } /// If this is an `impl Trait` or `dyn Trait`, returns that trait. - pub fn inherent_trait(&self) -> Option { + pub fn inherent_trait(&self) -> Option { match self { Ty::Dyn(predicates) | Ty::Opaque(predicates) => { predicates.iter().find_map(|pred| match pred { @@ -988,7 +988,10 @@ impl HirDisplay for Ty { write!( f, "{}", - trait_ref.trait_.name(f.db).unwrap_or_else(Name::missing) + f.db.trait_data(trait_ref.trait_) + .name + .clone() + .unwrap_or_else(Name::missing) )?; if trait_ref.substs.len() > 1 { write!(f, "<")?; @@ -1049,7 +1052,7 @@ impl TraitRef { } else { write!(f, ": ")?; } - write!(f, "{}", self.trait_.name(f.db).unwrap_or_else(Name::missing))?; + write!(f, "{}", f.db.trait_data(self.trait_).name.clone().unwrap_or_else(Name::missing))?; if self.substs.len() > 1 { write!(f, "<")?; f.write_joined(&self.substs[1..], ", ")?; diff --git a/crates/ra_hir/src/ty/infer/path.rs b/crates/ra_hir/src/ty/infer/path.rs index 6165eba4f..202fff4f3 100644 --- a/crates/ra_hir/src/ty/infer/path.rs +++ b/crates/ra_hir/src/ty/infer/path.rs @@ -143,24 +143,27 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { id: ExprOrPatId, ) -> Option<(ValueNs, Option)> { let trait_ = trait_ref.trait_; - let item = trait_.items(self.db).iter().copied().find_map(|item| match item { - AssocItem::Function(func) => { - if segment.name == func.name(self.db) { - Some(AssocItem::Function(func)) - } else { - None - } - } + let item = + self.db.trait_data(trait_).items.iter().map(|(_name, id)| (*id).into()).find_map( + |item| match item { + AssocItem::Function(func) => { + if segment.name == func.name(self.db) { + Some(AssocItem::Function(func)) + } else { + None + } + } - AssocItem::Const(konst) => { - if konst.name(self.db).map_or(false, |n| n == segment.name) { - Some(AssocItem::Const(konst)) - } else { - None - } - } - AssocItem::TypeAlias(_) => None, - })?; + AssocItem::Const(konst) => { + if konst.name(self.db).map_or(false, |n| n == segment.name) { + Some(AssocItem::Const(konst)) + } else { + None + } + } + AssocItem::TypeAlias(_) => None, + }, + )?; let def = match item { AssocItem::Function(f) => ValueNs::FunctionId(f.id), AssocItem::Const(c) => ValueNs::ConstId(c.id), @@ -212,7 +215,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { .fill_with_params() .build(); self.obligations.push(super::Obligation::Trait(TraitRef { - trait_: t, + trait_: t.id, substs: trait_substs, })); Some(substs) diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index 805a73ff5..a7149614d 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs @@ -15,7 +15,7 @@ use hir_def::{ resolver::{HasResolver, Resolver, TypeNs}, type_ref::{TypeBound, TypeRef}, AdtId, AstItemDef, EnumVariantId, FunctionId, GenericDefId, HasModule, LocalStructFieldId, - Lookup, StructId, VariantId, + Lookup, StructId, TraitId, VariantId, }; use ra_arena::map::ArenaMap; use ra_db::CrateId; @@ -172,7 +172,7 @@ impl Ty { let segment = &remaining_segments[0]; let associated_ty = associated_type_by_name_including_super_traits( db, - trait_ref.trait_.id, + trait_ref.trait_, &segment.name, ); match associated_ty { @@ -263,7 +263,7 @@ impl Ty { GenericPredicate::Implemented(tr) if tr.self_ty() == &self_ty => Some(tr.trait_), _ => None, }); - let traits = traits_from_env.flat_map(|t| all_super_traits(db, t.id)).map(Trait::from); + let traits = traits_from_env.flat_map(|t| all_super_traits(db, t)).map(Trait::from); for t in traits { if let Some(associated_ty) = db.trait_data(t.id).associated_type_by_name(&segment.name) { @@ -423,7 +423,7 @@ impl TraitRef { if let Some(self_ty) = explicit_self_ty { make_mut_slice(&mut substs.0)[0] = self_ty; } - TraitRef { trait_: resolved, substs } + TraitRef { trait_: resolved.id, substs } } pub(crate) fn from_hir( @@ -450,8 +450,8 @@ impl TraitRef { substs_from_path_segment(db, resolver, segment, Some(resolved.id.into()), !has_self_param) } - pub(crate) fn for_trait(db: &impl HirDatabase, trait_: Trait) -> TraitRef { - let substs = Substs::identity(&db.generic_params(trait_.id.into())); + pub(crate) fn for_trait(db: &impl HirDatabase, trait_: TraitId) -> TraitRef { + let substs = Substs::identity(&db.generic_params(trait_.into())); TraitRef { trait_, substs } } @@ -510,7 +510,7 @@ fn assoc_type_bindings_from_type_bound<'a>( .flat_map(|args_and_bindings| args_and_bindings.bindings.iter()) .map(move |(name, type_ref)| { let associated_ty = - associated_type_by_name_including_super_traits(db, trait_ref.trait_.id, &name); + associated_type_by_name_including_super_traits(db, trait_ref.trait_, &name); let associated_ty = match associated_ty { None => return GenericPredicate::Error, Some(t) => t, diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs index 9988570e8..f1bc638ee 100644 --- a/crates/ra_hir/src/ty/method_resolution.rs +++ b/crates/ra_hir/src/ty/method_resolution.rs @@ -68,7 +68,7 @@ impl CrateImplBlocks { if let Some(tr) = TraitRef::from_hir(db, &resolver, &trait_ref, Some(target_ty)) { - res.impls_by_trait.entry(tr.trait_.id).or_default().push(impl_id); + res.impls_by_trait.entry(tr.trait_).or_default().push(impl_id); } } None => { @@ -249,13 +249,11 @@ fn iterate_trait_method_candidates( let traits_from_env = env .trait_predicates_for_self_ty(&ty.value) .map(|tr| tr.trait_) - .flat_map(|t| all_super_traits(db, t.id)) - .map(Trait::from); - let traits = inherent_trait - .chain(traits_from_env) - .chain(resolver.traits_in_scope(db).into_iter().map(Trait::from)); + .flat_map(|t| all_super_traits(db, t)); + let traits = + inherent_trait.chain(traits_from_env).chain(resolver.traits_in_scope(db).into_iter()); 'traits: for t in traits { - let data = db.trait_data(t.id); + let data = db.trait_data(t); // we'll be lazy about checking whether the type implements the // trait, but if we find out it doesn't, we'll skip the rest of the @@ -330,7 +328,7 @@ pub(crate) fn implements_trait( db: &impl HirDatabase, resolver: &Resolver, krate: Crate, - trait_: Trait, + trait_: TraitId, ) -> bool { if ty.value.inherent_trait() == Some(trait_) { // FIXME this is a bit of a hack, since Chalk should say the same thing @@ -373,11 +371,11 @@ impl Ty { fn generic_implements_goal( db: &impl HirDatabase, env: Arc, - trait_: Trait, + trait_: TraitId, self_ty: Canonical, ) -> Canonical> { let num_vars = self_ty.num_vars; - let substs = super::Substs::build_for_def(db, trait_.id) + let substs = super::Substs::build_for_def(db, trait_) .push(self_ty.value) .fill_with_bound_vars(num_vars as u32) .build(); diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs index 78f4b3e27..02d37dead 100644 --- a/crates/ra_hir/src/ty/traits/chalk.rs +++ b/crates/ra_hir/src/ty/traits/chalk.rs @@ -9,7 +9,9 @@ use chalk_ir::{ }; use chalk_rust_ir::{AssociatedTyDatum, AssociatedTyValue, ImplDatum, StructDatum, TraitDatum}; -use hir_def::{lang_item::LangItemTarget, ContainerId, GenericDefId, Lookup, TraitId, TypeAliasId}; +use hir_def::{ + lang_item::LangItemTarget, AstItemDef, ContainerId, GenericDefId, Lookup, TraitId, TypeAliasId, +}; use hir_expand::name; use ra_db::salsa::{InternId, InternKey}; @@ -19,7 +21,7 @@ use crate::{ db::HirDatabase, ty::display::HirDisplay, ty::{ApplicationTy, GenericPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk}, - Crate, ImplBlock, Trait, TypeAlias, + Crate, ImplBlock, TypeAlias, }; /// This represents a trait whose name we could not resolve. @@ -167,15 +169,15 @@ impl ToChalk for TraitRef { } } -impl ToChalk for Trait { +impl ToChalk for TraitId { type Chalk = chalk_ir::TraitId; fn to_chalk(self, _db: &impl HirDatabase) -> chalk_ir::TraitId { - chalk_ir::TraitId(id_to_chalk(self.id)) + chalk_ir::TraitId(id_to_chalk(self)) } - fn from_chalk(_db: &impl HirDatabase, trait_id: chalk_ir::TraitId) -> Trait { - Trait { id: id_from_chalk(trait_id.0) } + fn from_chalk(_db: &impl HirDatabase, trait_id: chalk_ir::TraitId) -> TraitId { + id_from_chalk(trait_id.0) } } @@ -443,10 +445,10 @@ where if trait_id == UNKNOWN_TRAIT { return Vec::new(); } - let trait_: Trait = from_chalk(self.db, trait_id); + let trait_: TraitId = from_chalk(self.db, trait_id); let mut result: Vec<_> = self .db - .impls_for_trait(self.krate, trait_) + .impls_for_trait(self.krate, trait_.into()) .iter() .copied() .map(Impl::ImplBlock) @@ -459,7 +461,7 @@ where [super::FnTrait::FnOnce, super::FnTrait::FnMut, super::FnTrait::Fn].iter() { if let Some(actual_trait) = get_fn_trait(self.db, self.krate, fn_trait) { - if trait_.id == actual_trait { + if trait_ == actual_trait { let impl_ = super::ClosureFnTraitImplData { def, expr, fn_trait }; result.push(Impl::ClosureFnTraitImpl(impl_).to_chalk(self.db)); } @@ -516,7 +518,7 @@ pub(crate) fn associated_ty_data_query( where_clauses: vec![], }; let datum = AssociatedTyDatum { - trait_id: Trait::from(trait_).to_chalk(db), + trait_id: trait_.to_chalk(db), id, name: lalrpop_intern::intern(&db.type_alias_data(type_alias).name.to_string()), binders: make_binders(bound_data, generic_params.count_params_including_parent()), @@ -548,29 +550,23 @@ pub(crate) fn trait_datum_query( associated_ty_ids: vec![], }); } - let trait_: Trait = from_chalk(db, trait_id); - debug!("trait {:?} = {:?}", trait_id, trait_.name(db)); - let generic_params = db.generic_params(trait_.id.into()); + let trait_: TraitId = from_chalk(db, trait_id); + let trait_data = db.trait_data(trait_); + debug!("trait {:?} = {:?}", trait_id, trait_data.name); + let generic_params = db.generic_params(trait_.into()); let bound_vars = Substs::bound_vars(&generic_params); let flags = chalk_rust_ir::TraitFlags { - auto: trait_.is_auto(db), - upstream: trait_.module(db).krate() != krate, + auto: trait_data.auto, + upstream: trait_.module(db).krate != krate.crate_id, non_enumerable: true, coinductive: false, // only relevant for Chalk testing // FIXME set these flags correctly marker: false, fundamental: false, }; - let where_clauses = convert_where_clauses(db, trait_.id.into(), &bound_vars); - let associated_ty_ids = trait_ - .items(db) - .into_iter() - .filter_map(|trait_item| match trait_item { - crate::AssocItem::TypeAlias(type_alias) => Some(type_alias.id), - _ => None, - }) - .map(|type_alias| type_alias.to_chalk(db)) - .collect(); + let where_clauses = convert_where_clauses(db, trait_.into(), &bound_vars); + let associated_ty_ids = + trait_data.associated_types().map(|type_alias| type_alias.to_chalk(db)).collect(); let trait_datum_bound = chalk_rust_ir::TraitDatumBound { where_clauses }; let trait_datum = TraitDatum { id: trait_id, @@ -661,7 +657,7 @@ fn impl_block_datum( }; let impl_datum_bound = chalk_rust_ir::ImplDatumBound { trait_ref, where_clauses }; - let trait_data = db.trait_data(trait_.id); + let trait_data = db.trait_data(trait_); let associated_ty_value_ids = impl_block .items(db) .into_iter() @@ -785,7 +781,7 @@ fn type_alias_associated_ty_value( .expect("assoc ty value should not exist") // we don't return any assoc ty values if the impl'd trait can't be resolved .trait_; let assoc_ty = db - .trait_data(trait_.id) + .trait_data(trait_) .associated_type_by_name(&type_alias.name(db)) .expect("assoc ty value should not exist"); // validated when building the impl data as well let generic_params = db.generic_params(impl_block.id.into()); -- cgit v1.2.3 From b60b26b8abc9d2bed46278c07415b7b39752040c Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 26 Nov 2019 18:02:50 +0300 Subject: Reduce visibility --- crates/ra_hir/src/ty/traits.rs | 5 +++-- crates/ra_hir/src/ty/utils.rs | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'crates/ra_hir') diff --git a/crates/ra_hir/src/ty/traits.rs b/crates/ra_hir/src/ty/traits.rs index 2eeb03099..a91c2476b 100644 --- a/crates/ra_hir/src/ty/traits.rs +++ b/crates/ra_hir/src/ty/traits.rs @@ -2,14 +2,15 @@ use std::sync::{Arc, Mutex}; use chalk_ir::{cast::Cast, family::ChalkIr}; -use hir_def::DefWithBodyId; +use hir_def::{expr::ExprId, DefWithBodyId}; use log::debug; use ra_db::{impl_intern_key, salsa}; use ra_prof::profile; use rustc_hash::FxHashSet; +use crate::{db::HirDatabase, Crate, ImplBlock, Trait, TypeAlias}; + use super::{Canonical, GenericPredicate, HirDisplay, ProjectionTy, TraitRef, Ty, TypeWalk}; -use crate::{db::HirDatabase, expr::ExprId, Crate, ImplBlock, Trait, TypeAlias}; use self::chalk::{from_chalk, ToChalk}; diff --git a/crates/ra_hir/src/ty/utils.rs b/crates/ra_hir/src/ty/utils.rs index 52994b9e3..80ffceb4b 100644 --- a/crates/ra_hir/src/ty/utils.rs +++ b/crates/ra_hir/src/ty/utils.rs @@ -33,7 +33,7 @@ fn direct_super_traits(db: &impl DefDatabase, trait_: TraitId) -> Vec { /// Returns an iterator over the whole super trait hierarchy (including the /// trait itself). -pub(crate) fn all_super_traits(db: &impl DefDatabase, trait_: TraitId) -> Vec { +pub(super) fn all_super_traits(db: &impl DefDatabase, trait_: TraitId) -> Vec { // we need to take care a bit here to avoid infinite loops in case of cycles // (i.e. if we have `trait A: B; trait B: A;`) let mut result = vec![trait_]; @@ -52,7 +52,7 @@ pub(crate) fn all_super_traits(db: &impl DefDatabase, trait_: TraitId) -> Vec Date: Tue, 26 Nov 2019 18:06:12 +0300 Subject: Cleanup imports --- crates/ra_hir/src/ty.rs | 10 ++++++---- crates/ra_hir/src/ty/lower.rs | 3 +-- 2 files changed, 7 insertions(+), 6 deletions(-) (limited to 'crates/ra_hir') diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index 3711068fa..e420c796f 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs @@ -19,14 +19,16 @@ use std::sync::Arc; use std::{fmt, iter, mem}; use hir_def::{ - generics::GenericParams, AdtId, ContainerId, DefWithBodyId, GenericDefId, HasModule, Lookup, - TraitId, TypeAliasId, + expr::ExprId, generics::GenericParams, type_ref::Mutability, 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, FloatTy, IntTy, Mutability, - Name, Uncertain, + db::HirDatabase, + ty::primitive::{FloatTy, IntTy, Uncertain}, + util::make_mut_slice, + Adt, Crate, Name, }; use display::{HirDisplay, HirFormatter}; diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index a7149614d..c3c47a576 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs @@ -29,10 +29,9 @@ use crate::{ ty::{ primitive::{FloatTy, IntTy}, utils::{all_super_traits, associated_type_by_name_including_super_traits}, - Adt, }, util::make_mut_slice, - Const, Enum, EnumVariant, Function, ImplBlock, ModuleDef, Path, Static, Struct, Trait, + Adt, Const, Enum, EnumVariant, Function, ImplBlock, ModuleDef, Path, Static, Struct, Trait, TypeAlias, Union, }; -- cgit v1.2.3 From 4e415a269e2d821f31963c05843517c6fde0132d Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 26 Nov 2019 21:04:24 +0300 Subject: Remove ns-polymorphic type_for_def --- crates/ra_hir/src/code_model.rs | 15 ++- crates/ra_hir/src/db.rs | 11 +- crates/ra_hir/src/ty.rs | 4 +- crates/ra_hir/src/ty/infer.rs | 53 +++------- crates/ra_hir/src/ty/infer/expr.rs | 10 +- crates/ra_hir/src/ty/infer/path.rs | 7 +- crates/ra_hir/src/ty/lower.rs | 189 +++++++++++++++++------------------ crates/ra_hir/src/ty/traits/chalk.rs | 2 +- 8 files changed, 127 insertions(+), 164 deletions(-) (limited to 'crates/ra_hir') diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index 7b5d78543..c5cf39ee1 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs @@ -28,8 +28,7 @@ use crate::{ expr::{BindingAnnotation, Body, BodySourceMap, ExprValidator, Pat, PatId}, ty::display::HirFormatter, ty::{ - self, InEnvironment, InferenceResult, Namespace, TraitEnvironment, TraitRef, Ty, TypeCtor, - TypeWalk, + self, InEnvironment, InferenceResult, TraitEnvironment, TraitRef, Ty, TypeCtor, TypeWalk, }, CallableDef, Either, HirDisplay, Name, Source, }; @@ -354,11 +353,11 @@ impl Struct { } pub fn ty(self, db: &impl HirDatabase) -> Ty { - db.type_for_def(self.into(), Namespace::Types) + db.ty(self.id.into()) } pub fn constructor_ty(self, db: &impl HirDatabase) -> Ty { - db.type_for_def(self.into(), Namespace::Values) + db.value_ty(self.id.into()) } fn variant_data(self, db: &impl DefDatabase) -> Arc { @@ -381,7 +380,7 @@ impl Union { } pub fn ty(self, db: &impl HirDatabase) -> Ty { - db.type_for_def(self.into(), Namespace::Types) + db.ty(self.id.into()) } pub fn fields(self, db: &impl HirDatabase) -> Vec { @@ -442,7 +441,7 @@ impl Enum { } pub fn ty(self, db: &impl HirDatabase) -> Ty { - db.type_for_def(self.into(), Namespace::Types) + db.ty(self.id.into()) } } @@ -617,7 +616,7 @@ impl Function { } pub fn ty(self, db: &impl HirDatabase) -> Ty { - db.type_for_def(self.into(), Namespace::Values) + db.value_ty(self.id.into()) } pub fn infer(self, db: &impl HirDatabase) -> Arc { @@ -797,7 +796,7 @@ impl TypeAlias { } pub fn ty(self, db: &impl HirDatabase) -> Ty { - db.type_for_def(self.into(), Namespace::Types) + db.ty(self.id.into()) } pub fn name(self, db: &impl DefDatabase) -> Name { diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index 32f05a4d8..3b5aa7516 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs @@ -9,8 +9,8 @@ use crate::{ ty::{ method_resolution::CrateImplBlocks, traits::{AssocTyValue, Impl}, - CallableDef, FnSig, GenericPredicate, InferenceResult, Namespace, Substs, Ty, TypableDef, - TypeCtor, + CallableDef, FnSig, GenericPredicate, InferenceResult, Substs, Ty, TyDefId, TypeCtor, + ValueTyDefId, }, Crate, DefWithBody, ImplBlock, Trait, }; @@ -37,8 +37,11 @@ pub trait HirDatabase: DefDatabase { #[salsa::invoke(crate::ty::infer_query)] fn infer(&self, def: DefWithBody) -> Arc; - #[salsa::invoke(crate::ty::type_for_def)] - fn type_for_def(&self, def: TypableDef, ns: Namespace) -> Ty; + #[salsa::invoke(crate::ty::ty_query)] + fn ty(&self, def: TyDefId) -> Ty; + + #[salsa::invoke(crate::ty::value_ty_query)] + fn value_ty(&self, def: ValueTyDefId) -> Ty; #[salsa::invoke(crate::ty::field_types_query)] fn field_types(&self, var: VariantId) -> Arc>; diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index e420c796f..680ddc2f9 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs @@ -37,8 +37,8 @@ pub(crate) use infer::{infer_query, InferTy, InferenceResult}; pub use lower::CallableDef; pub(crate) use lower::{ callable_item_sig, field_types_query, generic_defaults_query, - generic_predicates_for_param_query, generic_predicates_query, type_for_def, Namespace, - TypableDef, + generic_predicates_for_param_query, generic_predicates_query, ty_query, value_ty_query, + TyDefId, TypableDef, ValueTyDefId, }; pub(crate) use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment}; diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index b023ae690..beb2efb7a 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs @@ -35,15 +35,15 @@ use test_utils::tested_by; use super::{ traits::{Guidance, Obligation, ProjectionPredicate, Solution}, - ApplicationTy, InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypableDef, - TypeCtor, TypeWalk, Uncertain, + ApplicationTy, InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeCtor, + TypeWalk, Uncertain, }; use crate::{ code_model::TypeAlias, db::HirDatabase, expr::{BindingAnnotation, Body, ExprId, PatId}, ty::infer::diagnostics::InferenceDiagnostic, - Adt, AssocItem, DefWithBody, FloatTy, Function, IntTy, Path, StructField, VariantDef, + AssocItem, DefWithBody, FloatTy, Function, IntTy, Path, StructField, VariantDef, }; macro_rules! ty_app { @@ -520,45 +520,22 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { None => return (Ty::Unknown, None), }; let resolver = &self.resolver; - let def: TypableDef = - // FIXME: this should resolve assoc items as well, see this example: - // https://play.rust-lang.org/?gist=087992e9e22495446c01c0d4e2d69521 - match resolver.resolve_path_in_type_ns_fully(self.db, &path) { - Some(TypeNs::AdtId(AdtId::StructId(it))) => it.into(), - Some(TypeNs::AdtId(AdtId::UnionId(it))) => it.into(), - Some(TypeNs::AdtSelfType(adt)) => adt.into(), - Some(TypeNs::EnumVariantId(it)) => it.into(), - Some(TypeNs::TypeAliasId(it)) => it.into(), - - Some(TypeNs::SelfType(_)) | - Some(TypeNs::GenericParam(_)) | - Some(TypeNs::BuiltinType(_)) | - Some(TypeNs::TraitId(_)) | - Some(TypeNs::AdtId(AdtId::EnumId(_))) | - None => { - return (Ty::Unknown, None) - } - }; - // FIXME remove the duplication between here and `Ty::from_path`? - let substs = Ty::substs_from_path(self.db, resolver, path, def); - match def { - TypableDef::Adt(Adt::Struct(s)) => { - let ty = s.ty(self.db); + // FIXME: this should resolve assoc items as well, see this example: + // https://play.rust-lang.org/?gist=087992e9e22495446c01c0d4e2d69521 + match resolver.resolve_path_in_type_ns_fully(self.db, &path) { + Some(TypeNs::AdtId(AdtId::StructId(strukt))) => { + let substs = Ty::substs_from_path(self.db, resolver, path, strukt.into()); + let ty = self.db.ty(strukt.into()); let ty = self.insert_type_vars(ty.apply_substs(substs)); - (ty, Some(s.into())) + (ty, Some(VariantDef::Struct(strukt.into()))) } - TypableDef::EnumVariant(var) => { - let ty = var.parent_enum(self.db).ty(self.db); + Some(TypeNs::EnumVariantId(var)) => { + let substs = Ty::substs_from_path(self.db, resolver, path, var.into()); + let ty = self.db.ty(var.parent.into()); let ty = self.insert_type_vars(ty.apply_substs(substs)); - (ty, Some(var.into())) + (ty, Some(VariantDef::EnumVariant(var.into()))) } - TypableDef::Adt(Adt::Enum(_)) - | TypableDef::Adt(Adt::Union(_)) - | TypableDef::TypeAlias(_) - | TypableDef::Function(_) - | TypableDef::Const(_) - | TypableDef::Static(_) - | TypableDef::BuiltinType(_) => (Ty::Unknown, None), + Some(_) | None => (Ty::Unknown, None), } } diff --git a/crates/ra_hir/src/ty/infer/expr.rs b/crates/ra_hir/src/ty/infer/expr.rs index 3d0895dc6..eb221d6bc 100644 --- a/crates/ra_hir/src/ty/infer/expr.rs +++ b/crates/ra_hir/src/ty/infer/expr.rs @@ -17,8 +17,8 @@ use crate::{ expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp}, ty::{ autoderef, method_resolution, op, traits::InEnvironment, CallableDef, InferTy, IntTy, - Mutability, Namespace, Obligation, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, - TypeCtor, TypeWalk, Uncertain, + Mutability, Obligation, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, + TypeWalk, Uncertain, }, Name, }; @@ -558,11 +558,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { Some((ty, func)) => { let ty = canonicalized_receiver.decanonicalize_ty(ty); self.write_method_resolution(tgt_expr, func); - ( - ty, - self.db.type_for_def(func.into(), Namespace::Values), - Some(self.db.generic_params(func.id.into())), - ) + (ty, self.db.value_ty(func.id.into()), Some(self.db.generic_params(func.id.into()))) } None => (receiver_ty, Ty::Unknown, None), }; diff --git a/crates/ra_hir/src/ty/infer/path.rs b/crates/ra_hir/src/ty/infer/path.rs index 202fff4f3..be2067dd4 100644 --- a/crates/ra_hir/src/ty/infer/path.rs +++ b/crates/ra_hir/src/ty/infer/path.rs @@ -7,7 +7,7 @@ use hir_def::{ use crate::{ db::HirDatabase, - ty::{method_resolution, Namespace, Substs, Ty, TypableDef, TypeWalk}, + ty::{method_resolution, Substs, Ty, TypeWalk, ValueTyDefId}, AssocItem, Container, Function, Name, Path, }; @@ -56,7 +56,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { } }; - let typable: TypableDef = match value { + let typable: ValueTyDefId = match value { ValueNs::LocalBinding(pat) => { let ty = self.result.type_of_pat.get(pat)?.clone(); let ty = self.resolve_ty_as_possible(&mut vec![], ty); @@ -69,11 +69,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { ValueNs::EnumVariantId(it) => it.into(), }; - let mut ty = self.db.type_for_def(typable, Namespace::Values); + let mut ty = self.db.value_ty(typable); if let Some(self_subst) = self_subst { ty = ty.subst(&self_subst); } - let substs = Ty::substs_from_path(self.db, &self.resolver, path, typable); let ty = ty.subst(&substs); Some(ty) diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index c3c47a576..709492d21 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs @@ -14,8 +14,8 @@ use hir_def::{ path::{GenericArg, PathSegment}, resolver::{HasResolver, Resolver, TypeNs}, type_ref::{TypeBound, TypeRef}, - AdtId, AstItemDef, EnumVariantId, FunctionId, GenericDefId, HasModule, LocalStructFieldId, - Lookup, StructId, TraitId, VariantId, + AdtId, AstItemDef, ConstId, EnumId, EnumVariantId, FunctionId, GenericDefId, HasModule, + LocalStructFieldId, Lookup, StaticId, StructId, TraitId, TypeAliasId, UnionId, VariantId, }; use ra_arena::map::ArenaMap; use ra_db::CrateId; @@ -35,17 +35,6 @@ use crate::{ TypeAlias, Union, }; -// FIXME: this is only really used in `type_for_def`, which contains a bunch of -// impossible cases. Perhaps we should recombine `TypeableDef` and `Namespace` -// into a `AsTypeDef`, `AsValueDef` enums? -#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub enum Namespace { - Types, - Values, - // Note that only type inference uses this enum, and it doesn't care about macros. - // Macro, -} - impl Ty { pub(crate) fn from_hir(db: &impl HirDatabase, resolver: &Resolver, type_ref: &TypeRef) -> Self { match type_ref { @@ -281,27 +270,15 @@ impl Ty { db: &impl HirDatabase, resolver: &Resolver, segment: &PathSegment, - typable: TypableDef, + typable: TyDefId, ) -> Ty { - let ty = db.type_for_def(typable, Namespace::Types); - let substs = Ty::substs_from_path_segment(db, resolver, segment, typable); - ty.subst(&substs) - } - - pub(super) fn substs_from_path_segment( - db: &impl HirDatabase, - resolver: &Resolver, - segment: &PathSegment, - resolved: TypableDef, - ) -> Substs { - let def_generic: Option = match resolved { - TypableDef::Function(func) => Some(func.id.into()), - TypableDef::Adt(adt) => Some(adt.into()), - TypableDef::EnumVariant(var) => Some(var.parent_enum(db).id.into()), - TypableDef::TypeAlias(t) => Some(t.id.into()), - TypableDef::Const(_) | TypableDef::Static(_) | TypableDef::BuiltinType(_) => None, + let generic_def = match typable { + TyDefId::BuiltinType(_) => None, + TyDefId::AdtId(it) => Some(it.into()), + TyDefId::TypeAliasId(it) => Some(it.into()), }; - substs_from_path_segment(db, resolver, segment, def_generic, false) + let substs = substs_from_path_segment(db, resolver, segment, generic_def, false); + db.ty(typable).subst(&substs) } /// Collect generic arguments from a path into a `Substs`. See also @@ -310,17 +287,18 @@ impl Ty { db: &impl HirDatabase, resolver: &Resolver, path: &Path, - resolved: TypableDef, + // Note that we don't call `db.value_type(resolved)` here, + // `ValueTyDefId` is just a convenient way to pass generics and + // special-case enum variants + resolved: ValueTyDefId, ) -> Substs { let last = path.segments.last().expect("path should have at least one segment"); - let segment = match resolved { - TypableDef::Function(_) - | TypableDef::Adt(_) - | TypableDef::Const(_) - | TypableDef::Static(_) - | TypableDef::TypeAlias(_) - | TypableDef::BuiltinType(_) => last, - TypableDef::EnumVariant(_) => { + let (segment, generic_def) = match resolved { + ValueTyDefId::FunctionId(it) => (last, Some(it.into())), + ValueTyDefId::StructId(it) => (last, Some(it.into())), + ValueTyDefId::ConstId(it) => (last, Some(it.into())), + ValueTyDefId::StaticId(_) => (last, None), + ValueTyDefId::EnumVariantId(var) => { // the generic args for an enum variant may be either specified // on the segment referring to the enum, or on the segment // referring to the variant. So `Option::::None` and @@ -334,10 +312,10 @@ impl Ty { // Option::None:: last }; - segment + (segment, Some(var.parent.into())) } }; - Ty::substs_from_path_segment(db, resolver, segment, resolved) + substs_from_path_segment(db, resolver, segment, generic_def, false) } } @@ -522,33 +500,6 @@ fn assoc_type_bindings_from_type_bound<'a>( }) } -/// Build the declared type of an item. This depends on the namespace; e.g. for -/// `struct Foo(usize)`, we have two types: The type of the struct itself, and -/// the constructor function `(usize) -> Foo` which lives in the values -/// namespace. -pub(crate) fn type_for_def(db: &impl HirDatabase, def: TypableDef, ns: Namespace) -> Ty { - match (def, ns) { - (TypableDef::Function(f), Namespace::Values) => type_for_fn(db, f), - (TypableDef::Adt(Adt::Struct(s)), Namespace::Values) => type_for_struct_constructor(db, s), - (TypableDef::Adt(adt), Namespace::Types) => type_for_adt(db, adt), - (TypableDef::EnumVariant(v), Namespace::Values) => type_for_enum_variant_constructor(db, v), - (TypableDef::TypeAlias(t), Namespace::Types) => type_for_type_alias(db, t), - (TypableDef::Const(c), Namespace::Values) => type_for_const(db, c), - (TypableDef::Static(c), Namespace::Values) => type_for_static(db, c), - (TypableDef::BuiltinType(t), Namespace::Types) => type_for_builtin(t), - - // 'error' cases: - (TypableDef::Function(_), Namespace::Types) => Ty::Unknown, - (TypableDef::Adt(Adt::Union(_)), Namespace::Values) => Ty::Unknown, - (TypableDef::Adt(Adt::Enum(_)), Namespace::Values) => Ty::Unknown, - (TypableDef::EnumVariant(_), Namespace::Types) => Ty::Unknown, - (TypableDef::TypeAlias(_), Namespace::Values) => Ty::Unknown, - (TypableDef::Const(_), Namespace::Types) => Ty::Unknown, - (TypableDef::Static(_), Namespace::Types) => Ty::Unknown, - (TypableDef::BuiltinType(_), Namespace::Values) => Ty::Unknown, - } -} - /// Build the signature of a callable item (function, struct or enum variant). pub(crate) fn callable_item_sig(db: &impl HirDatabase, def: CallableDef) -> FnSig { match def { @@ -647,24 +598,24 @@ fn fn_sig_for_fn(db: &impl HirDatabase, def: FunctionId) -> FnSig { /// Build the declared type of a function. This should not need to look at the /// function body. -fn type_for_fn(db: &impl HirDatabase, def: Function) -> Ty { - let generics = db.generic_params(def.id.into()); +fn type_for_fn(db: &impl HirDatabase, def: FunctionId) -> Ty { + let generics = db.generic_params(def.into()); let substs = Substs::identity(&generics); - Ty::apply(TypeCtor::FnDef(def.id.into()), substs) + Ty::apply(TypeCtor::FnDef(def.into()), substs) } /// Build the declared type of a const. -fn type_for_const(db: &impl HirDatabase, def: Const) -> Ty { - let data = db.const_data(def.id); - let resolver = def.id.resolver(db); +fn type_for_const(db: &impl HirDatabase, def: ConstId) -> Ty { + let data = db.const_data(def); + let resolver = def.resolver(db); Ty::from_hir(db, &resolver, &data.type_ref) } /// Build the declared type of a static. -fn type_for_static(db: &impl HirDatabase, def: Static) -> Ty { - let data = db.static_data(def.id); - let resolver = def.id.resolver(db); +fn type_for_static(db: &impl HirDatabase, def: StaticId) -> Ty { + let data = db.static_data(def); + let resolver = def.resolver(db); Ty::from_hir(db, &resolver, &data.type_ref) } @@ -688,19 +639,19 @@ fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: StructId) -> FnSig .iter() .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref)) .collect::>(); - let ret = type_for_adt(db, Struct::from(def)); + let ret = type_for_adt(db, def.into()); FnSig::from_params_and_return(params, ret) } /// Build the type of a tuple struct constructor. -fn type_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> Ty { - let struct_data = db.struct_data(def.id.into()); +fn type_for_struct_constructor(db: &impl HirDatabase, def: StructId) -> Ty { + let struct_data = db.struct_data(def.into()); if struct_data.variant_data.is_unit() { - return type_for_adt(db, def); // Unit struct + return type_for_adt(db, def.into()); // Unit struct } - let generics = db.generic_params(def.id.into()); + let generics = db.generic_params(def.into()); let substs = Substs::identity(&generics); - Ty::apply(TypeCtor::FnDef(def.id.into()), substs) + Ty::apply(TypeCtor::FnDef(def.into()), substs) } fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariantId) -> FnSig { @@ -714,34 +665,33 @@ fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariantId .collect::>(); let generics = db.generic_params(def.parent.into()); let substs = Substs::identity(&generics); - let ret = type_for_adt(db, Enum::from(def.parent)).subst(&substs); + let ret = type_for_adt(db, def.parent.into()).subst(&substs); FnSig::from_params_and_return(params, ret) } /// Build the type of a tuple enum variant constructor. -fn type_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) -> Ty { - let var_data = def.variant_data(db); +fn type_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariantId) -> Ty { + let enum_data = db.enum_data(def.parent); + let var_data = &enum_data.variants[def.local_id].variant_data; if var_data.is_unit() { - return type_for_adt(db, def.parent_enum(db)); // Unit variant + return type_for_adt(db, def.parent.into()); // Unit variant } - let generics = db.generic_params(def.parent_enum(db).id.into()); + let generics = db.generic_params(def.parent.into()); let substs = Substs::identity(&generics); Ty::apply(TypeCtor::FnDef(EnumVariantId::from(def).into()), substs) } -fn type_for_adt(db: &impl HirDatabase, adt: impl Into) -> Ty { - let adt = adt.into(); - let adt_id: AdtId = adt.into(); - let generics = db.generic_params(adt_id.into()); - Ty::apply(TypeCtor::Adt(adt_id), Substs::identity(&generics)) +fn type_for_adt(db: &impl HirDatabase, adt: AdtId) -> Ty { + let generics = db.generic_params(adt.into()); + Ty::apply(TypeCtor::Adt(adt), Substs::identity(&generics)) } -fn type_for_type_alias(db: &impl HirDatabase, t: TypeAlias) -> Ty { - let generics = db.generic_params(t.id.into()); - let resolver = t.id.resolver(db); - let type_ref = t.type_ref(db); +fn type_for_type_alias(db: &impl HirDatabase, t: TypeAliasId) -> Ty { + let generics = db.generic_params(t.into()); + let resolver = t.resolver(db); + let type_ref = &db.type_alias_data(t).type_ref; let substs = Substs::identity(&generics); - let inner = Ty::from_hir(db, &resolver, &type_ref.unwrap_or(TypeRef::Error)); + let inner = Ty::from_hir(db, &resolver, type_ref.as_ref().unwrap_or(&TypeRef::Error)); inner.subst(&substs) } @@ -808,3 +758,42 @@ impl From for GenericDefId { } } } + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum TyDefId { + BuiltinType(BuiltinType), + AdtId(AdtId), + TypeAliasId(TypeAliasId), +} +impl_froms!(TyDefId: BuiltinType, AdtId(StructId, EnumId, UnionId), TypeAliasId); + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum ValueTyDefId { + FunctionId(FunctionId), + StructId(StructId), + EnumVariantId(EnumVariantId), + ConstId(ConstId), + StaticId(StaticId), +} +impl_froms!(ValueTyDefId: FunctionId, StructId, EnumVariantId, ConstId, StaticId); + +/// Build the declared type of an item. This depends on the namespace; e.g. for +/// `struct Foo(usize)`, we have two types: The type of the struct itself, and +/// the constructor function `(usize) -> Foo` which lives in the values +/// namespace. +pub(crate) fn ty_query(db: &impl HirDatabase, def: TyDefId) -> Ty { + match def { + TyDefId::BuiltinType(it) => type_for_builtin(it), + TyDefId::AdtId(it) => type_for_adt(db, it), + TyDefId::TypeAliasId(it) => type_for_type_alias(db, it), + } +} +pub(crate) fn value_ty_query(db: &impl HirDatabase, def: ValueTyDefId) -> Ty { + match def { + ValueTyDefId::FunctionId(it) => type_for_fn(db, it), + ValueTyDefId::StructId(it) => type_for_struct_constructor(db, it), + ValueTyDefId::EnumVariantId(it) => type_for_enum_variant_constructor(db, it), + ValueTyDefId::ConstId(it) => type_for_const(db, it), + ValueTyDefId::StaticId(it) => type_for_static(db, it), + } +} diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs index 02d37dead..4b0f4f56c 100644 --- a/crates/ra_hir/src/ty/traits/chalk.rs +++ b/crates/ra_hir/src/ty/traits/chalk.rs @@ -786,7 +786,7 @@ fn type_alias_associated_ty_value( .expect("assoc ty value should not exist"); // validated when building the impl data as well 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); + let ty = db.ty(type_alias.id.into()).subst(&bound_vars); let value_bound = chalk_rust_ir::AssociatedTyValueBound { ty: ty.to_chalk(db) }; let value = chalk_rust_ir::AssociatedTyValue { impl_id, -- cgit v1.2.3