Skip to content

Commit a3d8cff

Browse files
committed
Use variables in predicates as well
1 parent 86348f5 commit a3d8cff

File tree

5 files changed

+52
-63
lines changed

5 files changed

+52
-63
lines changed

crates/ra_hir_ty/src/db.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,10 @@ pub trait HirDatabase: DefDatabase {
5050
fn generic_predicates_for_param(
5151
&self,
5252
param_id: TypeParamId,
53-
) -> Arc<[GenericPredicate]>;
53+
) -> Arc<[Binders<GenericPredicate>]>;
5454

5555
#[salsa::invoke(crate::lower::generic_predicates_query)]
56-
fn generic_predicates(&self, def: GenericDefId) -> Arc<[GenericPredicate]>;
56+
fn generic_predicates(&self, def: GenericDefId) -> Arc<[Binders<GenericPredicate>]>;
5757

5858
#[salsa::invoke(crate::lower::generic_defaults_query)]
5959
fn generic_defaults(&self, def: GenericDefId) -> Substs;

crates/ra_hir_ty/src/infer/expr.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use crate::{
2020
traits::InEnvironment,
2121
utils::{generics, variant_data, Generics},
2222
ApplicationTy, CallableDef, InferTy, IntTy, Mutability, Obligation, Substs, TraitRef, Ty,
23-
TypeCtor, TypeWalk, Uncertain, Binders,
23+
TypeCtor, Uncertain, Binders,
2424
};
2525

2626
use super::{BindingMode, Expectation, InferenceContext, InferenceDiagnostic, TypeMismatch};
@@ -686,7 +686,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
686686
if let TypeCtor::FnDef(def) = a_ty.ctor {
687687
let generic_predicates = self.db.generic_predicates(def.into());
688688
for predicate in generic_predicates.iter() {
689-
let predicate = predicate.clone().subst_type_params(self.db, def.into(), &a_ty.parameters);
689+
let predicate = predicate.clone().subst(&a_ty.parameters);
690690
if let Some(obligation) = Obligation::from_predicate(predicate) {
691691
self.obligations.push(obligation);
692692
}

crates/ra_hir_ty/src/lib.rs

Lines changed: 4 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -749,28 +749,7 @@ pub trait TypeWalk {
749749
self
750750
}
751751

752-
/// Replaces type parameters in this type using the given `Substs`. (So e.g.
753-
/// if `self` is `&[T]`, where type parameter T has index 0, and the
754-
/// `Substs` contain `u32` at index 0, we'll have `&[u32]` afterwards.)
755-
// TODO: this should mostly not be used anymore
756-
fn subst_type_params(self, db: &impl HirDatabase, def: GenericDefId, substs: &Substs) -> Self
757-
where
758-
Self: Sized,
759-
{
760-
let generics = generics(db, def);
761-
self.fold(&mut |ty| match ty {
762-
Ty::Param(id) => {
763-
if let Some(idx) = generics.param_idx(id) {
764-
substs.get(idx as usize).cloned().unwrap_or(Ty::Param(id))
765-
} else {
766-
ty
767-
}
768-
}
769-
ty => ty,
770-
})
771-
}
772-
773-
/// Substitutes `Ty::Bound` vars (as opposed to type parameters).
752+
/// Substitutes `Ty::Bound` vars with the given substitution.
774753
fn subst_bound_vars(mut self, substs: &Substs) -> Self
775754
where
776755
Self: Sized,
@@ -1045,9 +1024,10 @@ impl HirDisplay for Ty {
10451024
write!(f, "{}", param_data.name.clone().unwrap_or_else(Name::missing))?
10461025
}
10471026
TypeParamProvenance::ArgumentImplTrait => {
1048-
let bounds = f.db.generic_predicates_for_param(*id);
10491027
write!(f, "impl ")?;
1050-
write_bounds_like_dyn_trait(&bounds, f)?;
1028+
let bounds = f.db.generic_predicates_for_param(*id);
1029+
let substs = Substs::type_params(&generics);
1030+
write_bounds_like_dyn_trait(&bounds.iter().map(|b| b.clone().subst(&substs)).collect::<Vec<_>>(), f)?;
10511031
}
10521032
}
10531033
}

crates/ra_hir_ty/src/lower.rs

Lines changed: 41 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@ use std::sync::Arc;
1010

1111
use hir_def::{
1212
builtin_type::BuiltinType,
13-
generics::{WherePredicate, WherePredicateTarget, TypeParamProvenance},
13+
generics::{TypeParamProvenance, WherePredicate, WherePredicateTarget},
1414
path::{GenericArg, Path, PathSegment, PathSegments},
1515
resolver::{HasResolver, Resolver, TypeNs},
1616
type_ref::{TypeBound, TypeRef},
1717
AdtId, ConstId, EnumId, EnumVariantId, FunctionId, GenericDefId, HasModule, ImplId,
18-
LocalStructFieldId, Lookup, StaticId, StructId, TraitId, TypeAliasId, UnionId, VariantId,
19-
TypeParamId
18+
LocalStructFieldId, Lookup, StaticId, StructId, TraitId, TypeAliasId, TypeParamId, UnionId,
19+
VariantId,
2020
};
2121
use ra_arena::map::ArenaMap;
2222
use ra_db::CrateId;
@@ -148,7 +148,9 @@ impl Ty {
148148
let generics = generics(ctx.db, def);
149149
let param = generics
150150
.iter()
151-
.filter(|(_, data)| data.provenance == TypeParamProvenance::ArgumentImplTrait)
151+
.filter(|(_, data)| {
152+
data.provenance == TypeParamProvenance::ArgumentImplTrait
153+
})
152154
.nth(idx as usize)
153155
.map_or(Ty::Unknown, |(id, _)| Ty::Param(id));
154156
param
@@ -338,19 +340,12 @@ impl Ty {
338340
return Ty::Unknown;
339341
};
340342
param_id
341-
},
343+
}
342344
_ => return Ty::Unknown, // Error: Ambiguous associated type
343345
};
344346
let predicates = ctx.db.generic_predicates_for_param(param_id);
345-
let traits_from_env = predicates.iter().filter_map(|pred| match pred {
346-
GenericPredicate::Implemented(tr) => {
347-
if let Ty::Param(id) = tr.self_ty() {
348-
if *id == param_id {
349-
return Some(tr.trait_);
350-
}
351-
}
352-
None
353-
}
347+
let traits_from_env = predicates.iter().filter_map(|pred| match &pred.value {
348+
GenericPredicate::Implemented(tr) => Some(tr.trait_),
354349
_ => None,
355350
});
356351
let traits = traits_from_env.flat_map(|t| all_super_traits(ctx.db, t));
@@ -620,8 +615,8 @@ pub(crate) fn field_types_query(
620615
};
621616
let generics = generics(db, def);
622617
let mut res = ArenaMap::default();
623-
let ctx = TyLoweringContext::new(db, &resolver)
624-
.with_type_param_mode(TypeParamLoweringMode::Variable);
618+
let ctx =
619+
TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
625620
for (field_id, field_data) in var_data.fields().iter() {
626621
res.insert(field_id, Binders::new(generics.len(), Ty::from_hir(&ctx, &field_data.type_ref)))
627622
}
@@ -639,36 +634,39 @@ pub(crate) fn field_types_query(
639634
pub(crate) fn generic_predicates_for_param_query(
640635
db: &impl HirDatabase,
641636
param_id: TypeParamId,
642-
) -> Arc<[GenericPredicate]> {
637+
) -> Arc<[Binders<GenericPredicate>]> {
643638
let resolver = param_id.parent.resolver(db);
644-
let ctx = TyLoweringContext::new(db, &resolver);
645-
// let generics = generics(db, def);
639+
let ctx =
640+
TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
641+
let generics = generics(db, param_id.parent);
646642
resolver
647643
.where_predicates_in_scope()
648644
// we have to filter out all other predicates *first*, before attempting to lower them
649645
.filter(|pred| match &pred.target {
650646
WherePredicateTarget::TypeRef(type_ref) => {
651647
Ty::from_hir_only_param(&ctx, type_ref) == Some(param_id)
652648
}
653-
WherePredicateTarget::TypeParam(local_id) => {
654-
*local_id == param_id.local_id
655-
}
649+
WherePredicateTarget::TypeParam(local_id) => *local_id == param_id.local_id,
650+
})
651+
.flat_map(|pred| {
652+
GenericPredicate::from_where_predicate(&ctx, pred)
653+
.map(|p| Binders::new(generics.len(), p))
656654
})
657-
.flat_map(|pred| GenericPredicate::from_where_predicate(&ctx, pred))
658655
.collect()
659656
}
660657

661658
pub(crate) fn generic_predicates_for_param_recover(
662659
_db: &impl HirDatabase,
663660
_cycle: &[String],
664661
_param_id: &TypeParamId,
665-
) -> Arc<[GenericPredicate]> {
662+
) -> Arc<[Binders<GenericPredicate>]> {
666663
Arc::new([])
667664
}
668665

669666
impl TraitEnvironment {
670667
pub fn lower(db: &impl HirDatabase, resolver: &Resolver) -> Arc<TraitEnvironment> {
671-
let ctx = TyLoweringContext::new(db, &resolver);
668+
let ctx = TyLoweringContext::new(db, &resolver)
669+
.with_type_param_mode(TypeParamLoweringMode::Placeholder);
672670
let predicates = resolver
673671
.where_predicates_in_scope()
674672
.flat_map(|pred| GenericPredicate::from_where_predicate(&ctx, pred))
@@ -682,12 +680,17 @@ impl TraitEnvironment {
682680
pub(crate) fn generic_predicates_query(
683681
db: &impl HirDatabase,
684682
def: GenericDefId,
685-
) -> Arc<[GenericPredicate]> {
683+
) -> Arc<[Binders<GenericPredicate>]> {
686684
let resolver = def.resolver(db);
687-
let ctx = TyLoweringContext::new(db, &resolver);
685+
let ctx =
686+
TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
687+
let generics = generics(db, def);
688688
resolver
689689
.where_predicates_in_scope()
690-
.flat_map(|pred| GenericPredicate::from_where_predicate(&ctx, pred))
690+
.flat_map(|pred| {
691+
GenericPredicate::from_where_predicate(&ctx, pred)
692+
.map(|p| Binders::new(generics.len(), p))
693+
})
691694
.collect()
692695
}
693696

@@ -915,12 +918,18 @@ pub(crate) fn impl_self_ty_recover(
915918
Binders::new(generics.len(), Ty::Unknown)
916919
}
917920

918-
pub(crate) fn impl_trait_query(db: &impl HirDatabase, impl_id: ImplId) -> Option<Binders<TraitRef>> {
921+
pub(crate) fn impl_trait_query(
922+
db: &impl HirDatabase,
923+
impl_id: ImplId,
924+
) -> Option<Binders<TraitRef>> {
919925
let impl_data = db.impl_data(impl_id);
920926
let resolver = impl_id.resolver(db);
921-
let ctx = TyLoweringContext::new(db, &resolver)
922-
.with_type_param_mode(TypeParamLoweringMode::Variable);
927+
let ctx =
928+
TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
923929
let self_ty = db.impl_self_ty(impl_id);
924930
let target_trait = impl_data.target_trait.as_ref()?;
925-
Some(Binders::new(self_ty.num_binders, TraitRef::from_hir(&ctx, target_trait, Some(self_ty.value.clone()))?))
931+
Some(Binders::new(
932+
self_ty.num_binders,
933+
TraitRef::from_hir(&ctx, target_trait, Some(self_ty.value.clone()))?,
934+
))
926935
}

crates/ra_hir_ty/src/traits/chalk.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use ra_db::{
1414
use super::{builtin, AssocTyValue, Canonical, ChalkContext, Impl, Obligation};
1515
use crate::{
1616
db::HirDatabase, display::HirDisplay, utils::generics, ApplicationTy, GenericPredicate,
17-
ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk,
17+
ProjectionTy, Substs, TraitRef, Ty, TypeCtor,
1818
};
1919

2020
#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)]
@@ -522,11 +522,11 @@ fn convert_where_clauses(
522522
let generic_predicates = db.generic_predicates(def);
523523
let mut result = Vec::with_capacity(generic_predicates.len());
524524
for pred in generic_predicates.iter() {
525-
if pred.is_error() {
525+
if pred.value.is_error() {
526526
// skip errored predicates completely
527527
continue;
528528
}
529-
result.push(pred.clone().subst_type_params(db, def, substs).to_chalk(db));
529+
result.push(pred.clone().subst(substs).to_chalk(db));
530530
}
531531
result
532532
}

0 commit comments

Comments
 (0)