Skip to content

Commit 6560e4f

Browse files
bors[bot]matklad
andauthored
Merge #2413
2413: Remove another helper r=matklad a=matklad Co-authored-by: Aleksey Kladov <[email protected]>
2 parents 4d753fa + 24b1e79 commit 6560e4f

File tree

9 files changed

+156
-124
lines changed

9 files changed

+156
-124
lines changed

crates/ra_hir/src/code_model.rs

Lines changed: 2 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use hir_def::{
99
builtin_type::BuiltinType,
1010
docs::Documentation,
1111
per_ns::PerNs,
12-
resolver::{HasResolver, TypeNs},
12+
resolver::HasResolver,
1313
type_ref::{Mutability, TypeRef},
1414
AdtId, AstItemDef, ConstId, ContainerId, DefWithBodyId, EnumId, FunctionId, GenericDefId,
1515
HasModule, ImplId, LocalEnumVariantId, LocalImportId, LocalModuleId, LocalStructFieldId,
@@ -737,64 +737,7 @@ impl Trait {
737737
}
738738

739739
pub fn items(self, db: &impl DefDatabase) -> Vec<AssocItem> {
740-
db.trait_data(self.id).items.iter().map(|it| (*it).into()).collect()
741-
}
742-
743-
fn direct_super_traits(self, db: &impl HirDatabase) -> Vec<Trait> {
744-
let resolver = self.id.resolver(db);
745-
// returning the iterator directly doesn't easily work because of
746-
// lifetime problems, but since there usually shouldn't be more than a
747-
// few direct traits this should be fine (we could even use some kind of
748-
// SmallVec if performance is a concern)
749-
db.generic_params(self.id.into())
750-
.where_predicates
751-
.iter()
752-
.filter_map(|pred| match &pred.type_ref {
753-
TypeRef::Path(p) if p.as_ident() == Some(&name::SELF_TYPE) => pred.bound.as_path(),
754-
_ => None,
755-
})
756-
.filter_map(|path| match resolver.resolve_path_in_type_ns_fully(db, path) {
757-
Some(TypeNs::TraitId(t)) => Some(t),
758-
_ => None,
759-
})
760-
.map(Trait::from)
761-
.collect()
762-
}
763-
764-
/// Returns an iterator over the whole super trait hierarchy (including the
765-
/// trait itself).
766-
pub fn all_super_traits(self, db: &impl HirDatabase) -> Vec<Trait> {
767-
// we need to take care a bit here to avoid infinite loops in case of cycles
768-
// (i.e. if we have `trait A: B; trait B: A;`)
769-
let mut result = vec![self];
770-
let mut i = 0;
771-
while i < result.len() {
772-
let t = result[i];
773-
// yeah this is quadratic, but trait hierarchies should be flat
774-
// enough that this doesn't matter
775-
for tt in t.direct_super_traits(db) {
776-
if !result.contains(&tt) {
777-
result.push(tt);
778-
}
779-
}
780-
i += 1;
781-
}
782-
result
783-
}
784-
785-
pub fn associated_type_by_name(self, db: &impl DefDatabase, name: &Name) -> Option<TypeAlias> {
786-
let trait_data = db.trait_data(self.id);
787-
let res =
788-
trait_data.associated_types().map(TypeAlias::from).find(|t| &t.name(db) == name)?;
789-
Some(res)
790-
}
791-
792-
pub fn associated_type_by_name_including_super_traits(
793-
self,
794-
db: &impl HirDatabase,
795-
name: &Name,
796-
) -> Option<TypeAlias> {
797-
self.all_super_traits(db).into_iter().find_map(|t| t.associated_type_by_name(db, name))
740+
db.trait_data(self.id).items.iter().map(|(_name, it)| (*it).into()).collect()
798741
}
799742

800743
pub fn trait_ref(self, db: &impl HirDatabase) -> TraitRef {

crates/ra_hir/src/ty.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ mod op;
99
mod lower;
1010
mod infer;
1111
pub(crate) mod display;
12+
pub(crate) mod utils;
1213

1314
#[cfg(test)]
1415
mod tests;

crates/ra_hir/src/ty/autoderef.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use hir_expand::name;
1010
use log::{info, warn};
1111
use ra_db::CrateId;
1212

13-
use crate::{db::HirDatabase, Trait};
13+
use crate::db::HirDatabase;
1414

1515
use super::{
1616
traits::{InEnvironment, Solution},
@@ -49,12 +49,12 @@ fn deref_by_trait(
4949
ty: InEnvironment<&Canonical<Ty>>,
5050
) -> Option<Canonical<Ty>> {
5151
let deref_trait = match db.lang_item(krate.into(), "deref".into())? {
52-
LangItemTarget::TraitId(t) => Trait::from(t),
52+
LangItemTarget::TraitId(it) => it,
5353
_ => return None,
5454
};
55-
let target = deref_trait.associated_type_by_name(db, &name::TARGET_TYPE)?;
55+
let target = db.trait_data(deref_trait).associated_type_by_name(&name::TARGET_TYPE)?;
5656

57-
let generic_params = db.generic_params(target.id.into());
57+
let generic_params = db.generic_params(target.into());
5858
if generic_params.count_params_including_parent() != 1 {
5959
// the Target type + Deref trait should only have one generic parameter,
6060
// namely Deref's Self type
@@ -69,7 +69,7 @@ fn deref_by_trait(
6969

7070
let projection = super::traits::ProjectionPredicate {
7171
ty: Ty::Bound(0),
72-
projection_ty: super::ProjectionTy { associated_ty: target.id, parameters },
72+
projection_ty: super::ProjectionTy { associated_ty: target, parameters },
7373
};
7474

7575
let obligation = super::Obligation::Projection(projection);

crates/ra_hir/src/ty/infer.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ use crate::{
4343
db::HirDatabase,
4444
expr::{BindingAnnotation, Body, ExprId, PatId},
4545
ty::infer::diagnostics::InferenceDiagnostic,
46-
Adt, AssocItem, DefWithBody, FloatTy, Function, IntTy, Path, StructField, Trait, VariantDef,
46+
Adt, AssocItem, DefWithBody, FloatTy, Function, IntTy, Path, StructField, VariantDef,
4747
};
4848

4949
macro_rules! ty_app {
@@ -582,20 +582,20 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
582582

583583
fn resolve_into_iter_item(&self) -> Option<TypeAlias> {
584584
let path = known::std_iter_into_iterator();
585-
let trait_: Trait = self.resolver.resolve_known_trait(self.db, &path)?.into();
586-
trait_.associated_type_by_name(self.db, &name::ITEM_TYPE)
585+
let trait_ = self.resolver.resolve_known_trait(self.db, &path)?;
586+
self.db.trait_data(trait_).associated_type_by_name(&name::ITEM_TYPE).map(TypeAlias::from)
587587
}
588588

589589
fn resolve_ops_try_ok(&self) -> Option<TypeAlias> {
590590
let path = known::std_ops_try();
591-
let trait_: Trait = self.resolver.resolve_known_trait(self.db, &path)?.into();
592-
trait_.associated_type_by_name(self.db, &name::OK_TYPE)
591+
let trait_ = self.resolver.resolve_known_trait(self.db, &path)?;
592+
self.db.trait_data(trait_).associated_type_by_name(&name::OK_TYPE).map(TypeAlias::from)
593593
}
594594

595595
fn resolve_future_future_output(&self) -> Option<TypeAlias> {
596596
let path = known::std_future_future();
597-
let trait_: Trait = self.resolver.resolve_known_trait(self.db, &path)?.into();
598-
trait_.associated_type_by_name(self.db, &name::OUTPUT_TYPE)
597+
let trait_ = self.resolver.resolve_known_trait(self.db, &path)?;
598+
self.db.trait_data(trait_).associated_type_by_name(&name::OUTPUT_TYPE).map(TypeAlias::from)
599599
}
600600

601601
fn resolve_boxed_box(&self) -> Option<AdtId> {

crates/ra_hir/src/ty/lower.rs

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ use crate::{
2828
db::HirDatabase,
2929
ty::{
3030
primitive::{FloatTy, IntTy},
31+
utils::{all_super_traits, associated_type_by_name_including_super_traits},
3132
Adt,
3233
},
3334
util::make_mut_slice,
@@ -169,14 +170,16 @@ impl Ty {
169170
);
170171
return if remaining_segments.len() == 1 {
171172
let segment = &remaining_segments[0];
172-
match trait_ref
173-
.trait_
174-
.associated_type_by_name_including_super_traits(db, &segment.name)
175-
{
173+
let associated_ty = associated_type_by_name_including_super_traits(
174+
db,
175+
trait_ref.trait_.id,
176+
&segment.name,
177+
);
178+
match associated_ty {
176179
Some(associated_ty) => {
177180
// FIXME handle type parameters on the segment
178181
Ty::Projection(ProjectionTy {
179-
associated_ty: associated_ty.id,
182+
associated_ty,
180183
parameters: trait_ref.substs,
181184
})
182185
}
@@ -260,18 +263,16 @@ impl Ty {
260263
GenericPredicate::Implemented(tr) if tr.self_ty() == &self_ty => Some(tr.trait_),
261264
_ => None,
262265
});
263-
let traits = traits_from_env.flat_map(|t| t.all_super_traits(db));
266+
let traits = traits_from_env.flat_map(|t| all_super_traits(db, t.id)).map(Trait::from);
264267
for t in traits {
265-
if let Some(associated_ty) = t.associated_type_by_name(db, &segment.name) {
268+
if let Some(associated_ty) = db.trait_data(t.id).associated_type_by_name(&segment.name)
269+
{
266270
let substs = Substs::build_for_def(db, t.id)
267271
.push(self_ty.clone())
268272
.fill_with_unknown()
269273
.build();
270274
// FIXME handle type parameters on the segment
271-
return Ty::Projection(ProjectionTy {
272-
associated_ty: associated_ty.id,
273-
parameters: substs,
274-
});
275+
return Ty::Projection(ProjectionTy { associated_ty, parameters: substs });
275276
}
276277
}
277278
Ty::Unknown
@@ -509,10 +510,11 @@ fn assoc_type_bindings_from_type_bound<'a>(
509510
.flat_map(|args_and_bindings| args_and_bindings.bindings.iter())
510511
.map(move |(name, type_ref)| {
511512
let associated_ty =
512-
match trait_ref.trait_.associated_type_by_name_including_super_traits(db, &name) {
513-
None => return GenericPredicate::Error,
514-
Some(t) => t.id,
515-
};
513+
associated_type_by_name_including_super_traits(db, trait_ref.trait_.id, &name);
514+
let associated_ty = match associated_ty {
515+
None => return GenericPredicate::Error,
516+
Some(t) => t,
517+
};
516518
let projection_ty =
517519
ProjectionTy { associated_ty, parameters: trait_ref.substs.clone() };
518520
let ty = Ty::from_hir(db, resolver, type_ref);

crates/ra_hir/src/ty/method_resolution.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use rustc_hash::FxHashMap;
1616
use crate::{
1717
db::HirDatabase,
1818
ty::primitive::{FloatBitness, Uncertain},
19-
ty::{Ty, TypeCtor},
19+
ty::{utils::all_super_traits, Ty, TypeCtor},
2020
AssocItem, Crate, Function, Mutability, Name, Trait,
2121
};
2222

@@ -249,7 +249,8 @@ fn iterate_trait_method_candidates<T>(
249249
let traits_from_env = env
250250
.trait_predicates_for_self_ty(&ty.value)
251251
.map(|tr| tr.trait_)
252-
.flat_map(|t| t.all_super_traits(db));
252+
.flat_map(|t| all_super_traits(db, t.id))
253+
.map(Trait::from);
253254
let traits = inherent_trait
254255
.chain(traits_from_env)
255256
.chain(resolver.traits_in_scope(db).into_iter().map(Trait::from));
@@ -260,8 +261,8 @@ fn iterate_trait_method_candidates<T>(
260261
// trait, but if we find out it doesn't, we'll skip the rest of the
261262
// iteration
262263
let mut known_implemented = false;
263-
for &item in data.items.iter() {
264-
if !is_valid_candidate(db, name, mode, item.into()) {
264+
for (_name, item) in data.items.iter() {
265+
if !is_valid_candidate(db, name, mode, (*item).into()) {
265266
continue;
266267
}
267268
if !known_implemented {
@@ -271,7 +272,7 @@ fn iterate_trait_method_candidates<T>(
271272
}
272273
}
273274
known_implemented = true;
274-
if let Some(result) = callback(&ty.value, item.into()) {
275+
if let Some(result) = callback(&ty.value, (*item).into()) {
275276
return Some(result);
276277
}
277278
}

crates/ra_hir/src/ty/traits/chalk.rs

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use chalk_ir::{
99
};
1010
use chalk_rust_ir::{AssociatedTyDatum, AssociatedTyValue, ImplDatum, StructDatum, TraitDatum};
1111

12-
use hir_def::{lang_item::LangItemTarget, ContainerId, GenericDefId, Lookup, TypeAliasId};
12+
use hir_def::{lang_item::LangItemTarget, ContainerId, GenericDefId, Lookup, TraitId, TypeAliasId};
1313
use hir_expand::name;
1414

1515
use ra_db::salsa::{InternId, InternKey};
@@ -459,7 +459,7 @@ where
459459
[super::FnTrait::FnOnce, super::FnTrait::FnMut, super::FnTrait::Fn].iter()
460460
{
461461
if let Some(actual_trait) = get_fn_trait(self.db, self.krate, fn_trait) {
462-
if trait_ == actual_trait {
462+
if trait_.id == actual_trait {
463463
let impl_ = super::ClosureFnTraitImplData { def, expr, fn_trait };
464464
result.push(Impl::ClosureFnTraitImpl(impl_).to_chalk(self.db));
465465
}
@@ -661,6 +661,7 @@ fn impl_block_datum(
661661
};
662662

663663
let impl_datum_bound = chalk_rust_ir::ImplDatumBound { trait_ref, where_clauses };
664+
let trait_data = db.trait_data(trait_.id);
664665
let associated_ty_value_ids = impl_block
665666
.items(db)
666667
.into_iter()
@@ -670,7 +671,7 @@ fn impl_block_datum(
670671
})
671672
.filter(|type_alias| {
672673
// don't include associated types that don't exist in the trait
673-
trait_.associated_type_by_name(db, &type_alias.name(db)).is_some()
674+
trait_data.associated_type_by_name(&type_alias.name(db)).is_some()
674675
})
675676
.map(|type_alias| AssocTyValue::TypeAlias(type_alias).to_chalk(db))
676677
.collect();
@@ -713,7 +714,7 @@ fn closure_fn_trait_impl_datum(
713714
// and don't want to return a valid value only to find out later that FnOnce
714715
// is broken
715716
let fn_once_trait = get_fn_trait(db, krate, super::FnTrait::FnOnce)?;
716-
fn_once_trait.associated_type_by_name(db, &name::OUTPUT_TYPE)?;
717+
let _output = db.trait_data(fn_once_trait).associated_type_by_name(&name::OUTPUT_TYPE)?;
717718

718719
let num_args: u16 = match &db.body(data.def.into())[data.expr] {
719720
crate::expr::Expr::Lambda { args, .. } => args.len() as u16,
@@ -735,8 +736,8 @@ fn closure_fn_trait_impl_datum(
735736
let self_ty = Ty::apply_one(TypeCtor::Closure { def: data.def, expr: data.expr }, sig_ty);
736737

737738
let trait_ref = TraitRef {
738-
trait_,
739-
substs: Substs::build_for_def(db, trait_.id).push(self_ty).push(arg_ty).build(),
739+
trait_: trait_.into(),
740+
substs: Substs::build_for_def(db, trait_).push(self_ty).push(arg_ty).build(),
740741
};
741742

742743
let output_ty_id = AssocTyValue::ClosureFnTraitImplOutput(data.clone()).to_chalk(db);
@@ -783,10 +784,10 @@ fn type_alias_associated_ty_value(
783784
.target_trait_ref(db)
784785
.expect("assoc ty value should not exist") // we don't return any assoc ty values if the impl'd trait can't be resolved
785786
.trait_;
786-
let assoc_ty = trait_
787-
.associated_type_by_name(db, &type_alias.name(db))
788-
.expect("assoc ty value should not exist") // validated when building the impl data as well
789-
.id;
787+
let assoc_ty = db
788+
.trait_data(trait_.id)
789+
.associated_type_by_name(&type_alias.name(db))
790+
.expect("assoc ty value should not exist"); // validated when building the impl data as well
790791
let generic_params = db.generic_params(impl_block.id.into());
791792
let bound_vars = Substs::bound_vars(&generic_params);
792793
let ty = db.type_for_def(type_alias.into(), crate::ty::Namespace::Types).subst(&bound_vars);
@@ -819,10 +820,10 @@ fn closure_fn_trait_output_assoc_ty_value(
819820
let fn_once_trait =
820821
get_fn_trait(db, krate, super::FnTrait::FnOnce).expect("assoc ty value should not exist");
821822

822-
let output_ty_id = fn_once_trait
823-
.associated_type_by_name(db, &name::OUTPUT_TYPE)
824-
.expect("assoc ty value should not exist")
825-
.id;
823+
let output_ty_id = db
824+
.trait_data(fn_once_trait)
825+
.associated_type_by_name(&name::OUTPUT_TYPE)
826+
.expect("assoc ty value should not exist");
826827

827828
let value_bound = chalk_rust_ir::AssociatedTyValueBound { ty: output_ty.to_chalk(db) };
828829

@@ -834,10 +835,10 @@ fn closure_fn_trait_output_assoc_ty_value(
834835
Arc::new(value)
835836
}
836837

837-
fn get_fn_trait(db: &impl HirDatabase, krate: Crate, fn_trait: super::FnTrait) -> Option<Trait> {
838+
fn get_fn_trait(db: &impl HirDatabase, krate: Crate, fn_trait: super::FnTrait) -> Option<TraitId> {
838839
let target = db.lang_item(krate.crate_id, fn_trait.lang_item_name().into())?;
839840
match target {
840-
LangItemTarget::TraitId(t) => Some(t.into()),
841+
LangItemTarget::TraitId(t) => Some(t),
841842
_ => None,
842843
}
843844
}

0 commit comments

Comments
 (0)