Skip to content

Commit 022fbef

Browse files
committed
Apply suggestions from code review
1 parent 4b07c1e commit 022fbef

File tree

3 files changed

+328
-65
lines changed

3 files changed

+328
-65
lines changed

crates/ra_hir/src/code_model.rs

Lines changed: 50 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ use hir_ty::{
2626
autoderef,
2727
display::{HirDisplayError, HirFormatter},
2828
expr::ExprValidator,
29-
method_resolution, ApplicationTy, Canonical, InEnvironment, Substs, TraitEnvironment, TraitRef,
30-
Ty, TyDefId, TypeCtor,
29+
method_resolution, ApplicationTy, Canonical, GenericPredicate, InEnvironment, Substs,
30+
TraitEnvironment, Ty, TyDefId, TypeCtor,
3131
};
3232
use ra_db::{CrateId, CrateName, Edition, FileId};
3333
use ra_prof::profile;
@@ -1379,8 +1379,17 @@ impl Type {
13791379
self.ty.value.dyn_trait().map(Into::into)
13801380
}
13811381

1382-
pub fn as_impl_trait(&self, db: &dyn HirDatabase) -> Option<Trait> {
1383-
self.ty.value.impl_trait_ref(db).map(|it| it.trait_.into())
1382+
pub fn as_impl_traits(&self, db: &dyn HirDatabase) -> Option<Vec<Trait>> {
1383+
self.ty.value.impl_trait_bounds(db).map(|it| {
1384+
it.into_iter()
1385+
.filter_map(|pred| match pred {
1386+
hir_ty::GenericPredicate::Implemented(trait_ref) => {
1387+
Some(Trait::from(trait_ref.trait_))
1388+
}
1389+
_ => None,
1390+
})
1391+
.collect()
1392+
})
13841393
}
13851394

13861395
pub fn as_associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<Trait> {
@@ -1410,71 +1419,77 @@ impl Type {
14101419
}
14111420

14121421
pub fn walk(&self, db: &dyn HirDatabase, mut cb: impl FnMut(Type)) {
1413-
// TypeWalk::walk does not preserve items order!
1414-
fn walk_substs(db: &dyn HirDatabase, substs: &Substs, cb: &mut impl FnMut(Type)) {
1422+
// TypeWalk::walk for a Ty at first visits parameters and only after that the Ty itself.
1423+
// We need a different order here.
1424+
1425+
fn walk_substs(
1426+
db: &dyn HirDatabase,
1427+
type_: &Type,
1428+
substs: &Substs,
1429+
cb: &mut impl FnMut(Type),
1430+
) {
14151431
for ty in substs.iter() {
1416-
walk_ty(db, ty, cb);
1432+
walk_type(db, &type_.derived(ty.clone()), cb);
14171433
}
14181434
}
14191435

1420-
fn walk_trait(
1436+
fn walk_bounds(
14211437
db: &dyn HirDatabase,
1422-
ty: Ty,
1423-
trait_ref: &TraitRef,
1438+
type_: &Type,
1439+
bounds: &[GenericPredicate],
14241440
cb: &mut impl FnMut(Type),
14251441
) {
1426-
let def_db: &dyn DefDatabase = db.upcast();
1427-
let resolver = trait_ref.trait_.resolver(def_db);
1428-
let krate = trait_ref.trait_.lookup(def_db).container.module(def_db).krate;
1429-
cb(Type::new_with_resolver_inner(db, krate, &resolver, ty));
1430-
walk_substs(db, &trait_ref.substs, cb);
1442+
for pred in bounds {
1443+
match pred {
1444+
GenericPredicate::Implemented(trait_ref) => {
1445+
cb(type_.clone());
1446+
walk_substs(db, type_, &trait_ref.substs, cb);
1447+
}
1448+
_ => (),
1449+
}
1450+
}
14311451
}
14321452

1433-
fn walk_ty(db: &dyn HirDatabase, ty: &Ty, cb: &mut impl FnMut(Type)) {
1434-
let def_db: &dyn DefDatabase = db.upcast();
1435-
let ty = ty.strip_references();
1453+
fn walk_type(db: &dyn HirDatabase, type_: &Type, cb: &mut impl FnMut(Type)) {
1454+
let ty = type_.ty.value.strip_references();
14361455
match ty {
14371456
Ty::Apply(ApplicationTy { ctor, parameters }) => {
14381457
match ctor {
1439-
TypeCtor::Adt(adt) => {
1440-
cb(Type::from_def(db, adt.module(def_db).krate, *adt));
1458+
TypeCtor::Adt(_) => {
1459+
cb(type_.derived(ty.clone()));
14411460
}
14421461
TypeCtor::AssociatedType(_) => {
1443-
if let Some(trait_id) = ty.associated_type_parent_trait(db) {
1444-
let resolver = trait_id.resolver(def_db);
1445-
let krate = trait_id.lookup(def_db).container.module(def_db).krate;
1446-
cb(Type::new_with_resolver_inner(db, krate, &resolver, ty.clone()));
1462+
if let Some(_) = ty.associated_type_parent_trait(db) {
1463+
cb(type_.derived(ty.clone()));
14471464
}
14481465
}
14491466
_ => (),
14501467
}
14511468

14521469
// adt params, tuples, etc...
1453-
walk_substs(db, parameters, cb);
1470+
walk_substs(db, type_, parameters, cb);
14541471
}
14551472
Ty::Opaque(opaque_ty) => {
1456-
if let Some(trait_ref) = ty.impl_trait_ref(db) {
1457-
walk_trait(db, ty.clone(), &trait_ref, cb);
1473+
if let Some(bounds) = ty.impl_trait_bounds(db) {
1474+
walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb);
14581475
}
14591476

1460-
walk_substs(db, &opaque_ty.parameters, cb);
1477+
walk_substs(db, type_, &opaque_ty.parameters, cb);
14611478
}
14621479
Ty::Placeholder(_) => {
1463-
if let Some(trait_ref) = ty.impl_trait_ref(db) {
1464-
walk_trait(db, ty.clone(), &trait_ref, cb);
1480+
if let Some(bounds) = ty.impl_trait_bounds(db) {
1481+
walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb);
14651482
}
14661483
}
1467-
Ty::Dyn(_) => {
1468-
if let Some(trait_ref) = ty.dyn_trait_ref() {
1469-
walk_trait(db, ty.clone(), trait_ref, cb);
1470-
}
1484+
Ty::Dyn(bounds) => {
1485+
walk_bounds(db, &type_.derived(ty.clone()), bounds.as_ref(), cb);
14711486
}
14721487

14731488
_ => (),
14741489
}
14751490
}
14761491

1477-
walk_ty(db, &self.ty.value, &mut cb);
1492+
walk_type(db, self, &mut cb);
14781493
}
14791494
}
14801495

crates/ra_hir_ty/src/lib.rs

Lines changed: 25 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ pub use lower::{
7373
pub use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment};
7474

7575
pub use chalk_ir::{BoundVar, DebruijnIndex};
76+
use itertools::Itertools;
7677

7778
/// A type constructor or type name: this might be something like the primitive
7879
/// type `bool`, a struct like `Vec`, or things like function pointers or
@@ -815,6 +816,11 @@ impl Ty {
815816
}
816817
}
817818

819+
/// If this is a `dyn Trait`, returns that trait.
820+
pub fn dyn_trait(&self) -> Option<TraitId> {
821+
self.dyn_trait_ref().map(|it| it.trait_)
822+
}
823+
818824
fn builtin_deref(&self) -> Option<Ty> {
819825
match self {
820826
Ty::Apply(a_ty) => match a_ty.ctor {
@@ -867,18 +873,7 @@ impl Ty {
867873
}
868874
}
869875

870-
/// If this is a `dyn Trait`, returns that trait.
871-
pub fn dyn_trait(&self) -> Option<TraitId> {
872-
match self {
873-
Ty::Dyn(predicates) => predicates.iter().find_map(|pred| match pred {
874-
GenericPredicate::Implemented(tr) => Some(tr.trait_),
875-
_ => None,
876-
}),
877-
_ => None,
878-
}
879-
}
880-
881-
pub fn impl_trait_ref(&self, db: &dyn HirDatabase) -> Option<TraitRef> {
876+
pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<GenericPredicate>> {
882877
match self {
883878
Ty::Opaque(opaque_ty) => {
884879
let predicates = match opaque_ty.opaque_ty_id {
@@ -892,25 +887,21 @@ impl Ty {
892887
}
893888
};
894889

895-
predicates.and_then(|it| {
896-
it.value.iter().find_map(|pred| match pred {
897-
GenericPredicate::Implemented(tr) => Some(tr.clone()),
898-
_ => None,
899-
})
900-
})
890+
predicates.map(|it| it.value)
901891
}
902892
Ty::Placeholder(id) => {
903893
let generic_params = db.generic_params(id.parent);
904894
let param_data = &generic_params.types[id.local_id];
905895
match param_data.provenance {
906-
hir_def::generics::TypeParamProvenance::ArgumentImplTrait => db
907-
.generic_predicates_for_param(*id)
908-
.into_iter()
909-
.map(|pred| pred.value.clone())
910-
.find_map(|pred| match pred {
911-
GenericPredicate::Implemented(tr) => Some(tr.clone()),
912-
_ => None,
913-
}),
896+
hir_def::generics::TypeParamProvenance::ArgumentImplTrait => {
897+
let predicates = db
898+
.generic_predicates_for_param(*id)
899+
.into_iter()
900+
.map(|pred| pred.value.clone())
901+
.collect_vec();
902+
903+
Some(predicates)
904+
}
914905
_ => None,
915906
}
916907
}
@@ -926,6 +917,12 @@ impl Ty {
926917
_ => None,
927918
}
928919
}
920+
Ty::Projection(projection_ty) => {
921+
match projection_ty.associated_ty.lookup(db.upcast()).container {
922+
AssocContainerId::TraitId(trait_id) => Some(trait_id),
923+
_ => None,
924+
}
925+
}
929926
_ => None,
930927
}
931928
}
@@ -1104,10 +1101,10 @@ pub enum OpaqueTyId {
11041101

11051102
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
11061103
pub struct ReturnTypeImplTraits {
1107-
pub impl_traits: Vec<ReturnTypeImplTrait>,
1104+
pub(crate) impl_traits: Vec<ReturnTypeImplTrait>,
11081105
}
11091106

11101107
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
1111-
pub struct ReturnTypeImplTrait {
1108+
pub(crate) struct ReturnTypeImplTrait {
11121109
pub bounds: Binders<Vec<GenericPredicate>>,
11131110
}

0 commit comments

Comments
 (0)