mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-02 06:41:48 +00:00
Introduce QuantifiedWhereClause and DynTy analogous to Chalk
This introduces a bunch of new binders in lots of places, which we have to be careful about, but we had to add them at some point.
This commit is contained in:
parent
35868c4f7d
commit
590c416359
8 changed files with 213 additions and 105 deletions
|
@ -33,9 +33,10 @@ use crate::{
|
|||
all_super_trait_refs, associated_type_by_name_including_super_traits, generics,
|
||||
variant_data,
|
||||
},
|
||||
AliasEq, AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, FnPointer, FnSig, ImplTraitId,
|
||||
OpaqueTy, PolyFnSig, ProjectionTy, ReturnTypeImplTrait, ReturnTypeImplTraits, Substitution,
|
||||
TraitEnvironment, TraitRef, Ty, TyKind, TypeWalk, WhereClause,
|
||||
AliasEq, AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, DynTy, FnPointer, FnSig,
|
||||
ImplTraitId, OpaqueTy, PolyFnSig, ProjectionTy, QuantifiedWhereClause, QuantifiedWhereClauses,
|
||||
ReturnTypeImplTrait, ReturnTypeImplTraits, Substitution, TraitEnvironment, TraitRef, Ty,
|
||||
TyKind, TypeWalk, WhereClause,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -188,13 +189,14 @@ impl<'a> TyLoweringContext<'a> {
|
|||
TypeRef::DynTrait(bounds) => {
|
||||
let self_ty =
|
||||
TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(&Interner);
|
||||
let predicates = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
|
||||
bounds
|
||||
.iter()
|
||||
.flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false))
|
||||
.collect()
|
||||
let bounds = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
|
||||
QuantifiedWhereClauses::from_iter(
|
||||
&Interner,
|
||||
bounds.iter().flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false)),
|
||||
)
|
||||
});
|
||||
TyKind::Dyn(predicates).intern(&Interner)
|
||||
let bounds = Binders::new(1, bounds);
|
||||
TyKind::Dyn(DynTy { bounds }).intern(&Interner)
|
||||
}
|
||||
TypeRef::ImplTrait(bounds) => {
|
||||
match self.impl_trait_mode {
|
||||
|
@ -376,7 +378,16 @@ impl<'a> TyLoweringContext<'a> {
|
|||
// FIXME report error (ambiguous associated type)
|
||||
TyKind::Unknown.intern(&Interner)
|
||||
} else {
|
||||
TyKind::Dyn(Arc::new([WhereClause::Implemented(trait_ref)])).intern(&Interner)
|
||||
let dyn_ty = DynTy {
|
||||
bounds: Binders::new(
|
||||
1,
|
||||
QuantifiedWhereClauses::from_iter(
|
||||
&Interner,
|
||||
Some(Binders::wrap_empty(WhereClause::Implemented(trait_ref))),
|
||||
),
|
||||
),
|
||||
};
|
||||
TyKind::Dyn(dyn_ty).intern(&Interner)
|
||||
};
|
||||
return (ty, None);
|
||||
}
|
||||
|
@ -670,7 +681,7 @@ impl<'a> TyLoweringContext<'a> {
|
|||
&'a self,
|
||||
where_predicate: &'a WherePredicate,
|
||||
ignore_bindings: bool,
|
||||
) -> impl Iterator<Item = WhereClause> + 'a {
|
||||
) -> impl Iterator<Item = QuantifiedWhereClause> + 'a {
|
||||
match where_predicate {
|
||||
WherePredicate::ForLifetime { target, bound, .. }
|
||||
| WherePredicate::TypeBound { target, bound } => {
|
||||
|
@ -705,12 +716,12 @@ impl<'a> TyLoweringContext<'a> {
|
|||
bound: &'a TypeBound,
|
||||
self_ty: Ty,
|
||||
ignore_bindings: bool,
|
||||
) -> impl Iterator<Item = WhereClause> + 'a {
|
||||
) -> impl Iterator<Item = QuantifiedWhereClause> + 'a {
|
||||
let mut bindings = None;
|
||||
let trait_ref = match bound {
|
||||
TypeBound::Path(path) => {
|
||||
bindings = self.lower_trait_ref_from_path(path, Some(self_ty));
|
||||
bindings.clone().map(WhereClause::Implemented)
|
||||
bindings.clone().map(WhereClause::Implemented).map(|b| Binders::wrap_empty(b))
|
||||
}
|
||||
TypeBound::Lifetime(_) => None,
|
||||
TypeBound::Error => None,
|
||||
|
@ -727,7 +738,7 @@ impl<'a> TyLoweringContext<'a> {
|
|||
&'a self,
|
||||
bound: &'a TypeBound,
|
||||
trait_ref: TraitRef,
|
||||
) -> impl Iterator<Item = WhereClause> + 'a {
|
||||
) -> impl Iterator<Item = QuantifiedWhereClause> + 'a {
|
||||
let last_segment = match bound {
|
||||
TypeBound::Path(path) => path.segments().last(),
|
||||
TypeBound::Error | TypeBound::Lifetime(_) => None,
|
||||
|
@ -743,7 +754,7 @@ impl<'a> TyLoweringContext<'a> {
|
|||
&binding.name,
|
||||
);
|
||||
let (super_trait_ref, associated_ty) = match found {
|
||||
None => return SmallVec::<[WhereClause; 1]>::new(),
|
||||
None => return SmallVec::<[QuantifiedWhereClause; 1]>::new(),
|
||||
Some(t) => t,
|
||||
};
|
||||
let projection_ty = ProjectionTy {
|
||||
|
@ -757,7 +768,7 @@ impl<'a> TyLoweringContext<'a> {
|
|||
let ty = self.lower_ty(type_ref);
|
||||
let alias_eq =
|
||||
AliasEq { alias: AliasTy::Projection(projection_ty.clone()), ty };
|
||||
preds.push(WhereClause::AliasEq(alias_eq));
|
||||
preds.push(Binders::wrap_empty(WhereClause::AliasEq(alias_eq)));
|
||||
}
|
||||
for bound in &binding.bounds {
|
||||
preds.extend(self.lower_type_bound(
|
||||
|
@ -888,6 +899,9 @@ pub(crate) fn generic_predicates_for_param_query(
|
|||
db: &dyn HirDatabase,
|
||||
param_id: TypeParamId,
|
||||
) -> Arc<[Binders<WhereClause>]> {
|
||||
// FIXME: these binders are for the type parameters of the def. We need to
|
||||
// introduce another level of binders for quantified where clauses (for<'a>
|
||||
// ...)
|
||||
let resolver = param_id.parent.resolver(db.upcast());
|
||||
let ctx =
|
||||
TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
|
||||
|
@ -906,7 +920,7 @@ pub(crate) fn generic_predicates_for_param_query(
|
|||
WherePredicate::Lifetime { .. } => false,
|
||||
})
|
||||
.flat_map(|pred| {
|
||||
ctx.lower_where_predicate(pred, true).map(|p| Binders::new(generics.len(), p))
|
||||
ctx.lower_where_predicate(pred, true).map(|p| Binders::new(generics.len(), p.value))
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
@ -930,7 +944,7 @@ pub(crate) fn trait_environment_query(
|
|||
let mut clauses = Vec::new();
|
||||
for pred in resolver.where_predicates_in_scope() {
|
||||
for pred in ctx.lower_where_predicate(pred, false) {
|
||||
if let WhereClause::Implemented(tr) = &pred {
|
||||
if let WhereClause::Implemented(tr) = &pred.skip_binders() {
|
||||
traits_in_scope.push((tr.self_type_parameter().clone(), tr.hir_trait_id()));
|
||||
}
|
||||
let program_clause: chalk_ir::ProgramClause<Interner> =
|
||||
|
@ -971,6 +985,9 @@ pub(crate) fn generic_predicates_query(
|
|||
db: &dyn HirDatabase,
|
||||
def: GenericDefId,
|
||||
) -> Arc<[Binders<WhereClause>]> {
|
||||
// FIXME: these binders are for the type parameters of the def. We need to
|
||||
// introduce another level of binders for quantified where clauses (for<'a>
|
||||
// ...)
|
||||
let resolver = def.resolver(db.upcast());
|
||||
let ctx =
|
||||
TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
|
||||
|
@ -978,7 +995,7 @@ pub(crate) fn generic_predicates_query(
|
|||
resolver
|
||||
.where_predicates_in_scope()
|
||||
.flat_map(|pred| {
|
||||
ctx.lower_where_predicate(pred, false).map(|p| Binders::new(generics.len(), p))
|
||||
ctx.lower_where_predicate(pred, false).map(|p| Binders::new(generics.len(), p.value))
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue