mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-28 04:44:57 +00:00
Use QuantifiedWhereClause in generic_predicates as well
Still far too much binder skipping going on; I find it hard to imagine this is all correct, but the tests pass.
This commit is contained in:
parent
590c416359
commit
1d5c4a77fb
9 changed files with 28 additions and 37 deletions
|
@ -236,11 +236,7 @@ impl HirDisplay for TypeParam {
|
||||||
write!(f, "{}", self.name(f.db))?;
|
write!(f, "{}", self.name(f.db))?;
|
||||||
let bounds = f.db.generic_predicates_for_param(self.id);
|
let bounds = f.db.generic_predicates_for_param(self.id);
|
||||||
let substs = Substitution::type_params(f.db, self.id.parent);
|
let substs = Substitution::type_params(f.db, self.id.parent);
|
||||||
let predicates = bounds
|
let predicates = bounds.iter().cloned().map(|b| b.subst(&substs)).collect::<Vec<_>>();
|
||||||
.iter()
|
|
||||||
.cloned()
|
|
||||||
.map(|b| hir_ty::Binders::new(0, b.subst(&substs)))
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
if !(predicates.is_empty() || f.omit_verbose_types()) {
|
if !(predicates.is_empty() || f.omit_verbose_types()) {
|
||||||
write_bounds_like_dyn_trait_with_prefix(":", &predicates, f)?;
|
write_bounds_like_dyn_trait_with_prefix(":", &predicates, f)?;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1460,7 +1460,7 @@ impl TypeParam {
|
||||||
pub fn trait_bounds(self, db: &dyn HirDatabase) -> Vec<Trait> {
|
pub fn trait_bounds(self, db: &dyn HirDatabase) -> Vec<Trait> {
|
||||||
db.generic_predicates_for_param(self.id)
|
db.generic_predicates_for_param(self.id)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(|pred| match &pred.value {
|
.filter_map(|pred| match &pred.skip_binders().skip_binders() {
|
||||||
hir_ty::WhereClause::Implemented(trait_ref) => {
|
hir_ty::WhereClause::Implemented(trait_ref) => {
|
||||||
Some(Trait::from(trait_ref.hir_trait_id()))
|
Some(Trait::from(trait_ref.hir_trait_id()))
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,8 +12,8 @@ use la_arena::ArenaMap;
|
||||||
use crate::{
|
use crate::{
|
||||||
method_resolution::{InherentImpls, TraitImpls},
|
method_resolution::{InherentImpls, TraitImpls},
|
||||||
traits::chalk,
|
traits::chalk,
|
||||||
Binders, CallableDefId, FnDefId, ImplTraitId, InferenceResult, PolyFnSig, ReturnTypeImplTraits,
|
Binders, CallableDefId, FnDefId, ImplTraitId, InferenceResult, PolyFnSig,
|
||||||
TraitRef, Ty, TyDefId, ValueTyDefId, WhereClause,
|
QuantifiedWhereClause, ReturnTypeImplTraits, TraitRef, Ty, TyDefId, ValueTyDefId,
|
||||||
};
|
};
|
||||||
use hir_expand::name::Name;
|
use hir_expand::name::Name;
|
||||||
|
|
||||||
|
@ -57,10 +57,13 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
|
||||||
|
|
||||||
#[salsa::invoke(crate::lower::generic_predicates_for_param_query)]
|
#[salsa::invoke(crate::lower::generic_predicates_for_param_query)]
|
||||||
#[salsa::cycle(crate::lower::generic_predicates_for_param_recover)]
|
#[salsa::cycle(crate::lower::generic_predicates_for_param_recover)]
|
||||||
fn generic_predicates_for_param(&self, param_id: TypeParamId) -> Arc<[Binders<WhereClause>]>;
|
fn generic_predicates_for_param(
|
||||||
|
&self,
|
||||||
|
param_id: TypeParamId,
|
||||||
|
) -> Arc<[Binders<QuantifiedWhereClause>]>;
|
||||||
|
|
||||||
#[salsa::invoke(crate::lower::generic_predicates_query)]
|
#[salsa::invoke(crate::lower::generic_predicates_query)]
|
||||||
fn generic_predicates(&self, def: GenericDefId) -> Arc<[Binders<WhereClause>]>;
|
fn generic_predicates(&self, def: GenericDefId) -> Arc<[Binders<QuantifiedWhereClause>]>;
|
||||||
|
|
||||||
#[salsa::invoke(crate::lower::trait_environment_query)]
|
#[salsa::invoke(crate::lower::trait_environment_query)]
|
||||||
fn trait_environment(&self, def: GenericDefId) -> Arc<crate::TraitEnvironment>;
|
fn trait_environment(&self, def: GenericDefId) -> Arc<crate::TraitEnvironment>;
|
||||||
|
|
|
@ -581,7 +581,7 @@ impl HirDisplay for Ty {
|
||||||
.generic_predicates(id.parent)
|
.generic_predicates(id.parent)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|pred| pred.clone().subst(&substs))
|
.map(|pred| pred.clone().subst(&substs))
|
||||||
.filter(|wc| match &wc {
|
.filter(|wc| match &wc.skip_binders() {
|
||||||
WhereClause::Implemented(tr) => tr.self_type_parameter() == self,
|
WhereClause::Implemented(tr) => tr.self_type_parameter() == self,
|
||||||
WhereClause::AliasEq(AliasEq {
|
WhereClause::AliasEq(AliasEq {
|
||||||
alias: AliasTy::Projection(proj),
|
alias: AliasTy::Projection(proj),
|
||||||
|
@ -590,15 +590,7 @@ impl HirDisplay for Ty {
|
||||||
_ => false,
|
_ => false,
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
write_bounds_like_dyn_trait_with_prefix(
|
write_bounds_like_dyn_trait_with_prefix("impl", &bounds, f)?;
|
||||||
"impl",
|
|
||||||
&bounds
|
|
||||||
.iter()
|
|
||||||
.cloned()
|
|
||||||
.map(crate::Binders::wrap_empty)
|
|
||||||
.collect::<Vec<_>>(),
|
|
||||||
f,
|
|
||||||
)?;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ use hir_def::{
|
||||||
AssocContainerId, FieldId, Lookup,
|
AssocContainerId, FieldId, Lookup,
|
||||||
};
|
};
|
||||||
use hir_expand::name::{name, Name};
|
use hir_expand::name::{name, Name};
|
||||||
|
use stdx::always;
|
||||||
use syntax::ast::RangeOp;
|
use syntax::ast::RangeOp;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -936,7 +937,9 @@ impl<'a> InferenceContext<'a> {
|
||||||
let def: CallableDefId = from_chalk(self.db, *fn_def);
|
let def: CallableDefId = from_chalk(self.db, *fn_def);
|
||||||
let generic_predicates = self.db.generic_predicates(def.into());
|
let generic_predicates = self.db.generic_predicates(def.into());
|
||||||
for predicate in generic_predicates.iter() {
|
for predicate in generic_predicates.iter() {
|
||||||
let predicate = predicate.clone().subst(parameters);
|
let (predicate, binders) =
|
||||||
|
predicate.clone().subst(parameters).into_value_and_skipped_binders();
|
||||||
|
always!(binders == 0); // quantified where clauses not yet handled
|
||||||
self.obligations.push(predicate.cast(&Interner));
|
self.obligations.push(predicate.cast(&Interner));
|
||||||
}
|
}
|
||||||
// add obligation for trait implementation, if this is a trait method
|
// add obligation for trait implementation, if this is a trait method
|
||||||
|
|
|
@ -518,6 +518,10 @@ impl<T> Binders<T> {
|
||||||
pub fn skip_binders(&self) -> &T {
|
pub fn skip_binders(&self) -> &T {
|
||||||
&self.value
|
&self.value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn into_value_and_skipped_binders(self) -> (T, usize) {
|
||||||
|
(self.value, self.num_binders)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Clone> Binders<&T> {
|
impl<T: Clone> Binders<&T> {
|
||||||
|
@ -985,7 +989,7 @@ impl Ty {
|
||||||
.generic_predicates(id.parent)
|
.generic_predicates(id.parent)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|pred| pred.clone().subst(&substs))
|
.map(|pred| pred.clone().subst(&substs))
|
||||||
.filter(|wc| match &wc {
|
.filter(|wc| match &wc.skip_binders() {
|
||||||
WhereClause::Implemented(tr) => tr.self_type_parameter() == self,
|
WhereClause::Implemented(tr) => tr.self_type_parameter() == self,
|
||||||
WhereClause::AliasEq(AliasEq {
|
WhereClause::AliasEq(AliasEq {
|
||||||
alias: AliasTy::Projection(proj),
|
alias: AliasTy::Projection(proj),
|
||||||
|
@ -993,7 +997,6 @@ impl Ty {
|
||||||
}) => proj.self_type_parameter() == self,
|
}) => proj.self_type_parameter() == self,
|
||||||
_ => false,
|
_ => false,
|
||||||
})
|
})
|
||||||
.map(Binders::wrap_empty)
|
|
||||||
.collect_vec();
|
.collect_vec();
|
||||||
|
|
||||||
Some(predicates)
|
Some(predicates)
|
||||||
|
|
|
@ -825,7 +825,7 @@ pub fn associated_type_shorthand_candidates<R>(
|
||||||
let predicates = db.generic_predicates_for_param(param_id);
|
let predicates = db.generic_predicates_for_param(param_id);
|
||||||
let mut traits_: Vec<_> = predicates
|
let mut traits_: Vec<_> = predicates
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|pred| match &pred.value {
|
.filter_map(|pred| match &pred.value.value {
|
||||||
WhereClause::Implemented(tr) => Some(tr.clone()),
|
WhereClause::Implemented(tr) => Some(tr.clone()),
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
|
@ -898,10 +898,7 @@ pub(crate) fn field_types_query(
|
||||||
pub(crate) fn generic_predicates_for_param_query(
|
pub(crate) fn generic_predicates_for_param_query(
|
||||||
db: &dyn HirDatabase,
|
db: &dyn HirDatabase,
|
||||||
param_id: TypeParamId,
|
param_id: TypeParamId,
|
||||||
) -> Arc<[Binders<WhereClause>]> {
|
) -> Arc<[Binders<QuantifiedWhereClause>]> {
|
||||||
// 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 resolver = param_id.parent.resolver(db.upcast());
|
||||||
let ctx =
|
let ctx =
|
||||||
TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
|
TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
|
||||||
|
@ -920,7 +917,7 @@ pub(crate) fn generic_predicates_for_param_query(
|
||||||
WherePredicate::Lifetime { .. } => false,
|
WherePredicate::Lifetime { .. } => false,
|
||||||
})
|
})
|
||||||
.flat_map(|pred| {
|
.flat_map(|pred| {
|
||||||
ctx.lower_where_predicate(pred, true).map(|p| Binders::new(generics.len(), p.value))
|
ctx.lower_where_predicate(pred, true).map(|p| Binders::new(generics.len(), p))
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
@ -929,7 +926,7 @@ pub(crate) fn generic_predicates_for_param_recover(
|
||||||
_db: &dyn HirDatabase,
|
_db: &dyn HirDatabase,
|
||||||
_cycle: &[String],
|
_cycle: &[String],
|
||||||
_param_id: &TypeParamId,
|
_param_id: &TypeParamId,
|
||||||
) -> Arc<[Binders<WhereClause>]> {
|
) -> Arc<[Binders<QuantifiedWhereClause>]> {
|
||||||
Arc::new([])
|
Arc::new([])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -984,10 +981,7 @@ pub(crate) fn trait_environment_query(
|
||||||
pub(crate) fn generic_predicates_query(
|
pub(crate) fn generic_predicates_query(
|
||||||
db: &dyn HirDatabase,
|
db: &dyn HirDatabase,
|
||||||
def: GenericDefId,
|
def: GenericDefId,
|
||||||
) -> Arc<[Binders<WhereClause>]> {
|
) -> Arc<[Binders<QuantifiedWhereClause>]> {
|
||||||
// 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 resolver = def.resolver(db.upcast());
|
||||||
let ctx =
|
let ctx =
|
||||||
TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
|
TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
|
||||||
|
@ -995,7 +989,7 @@ pub(crate) fn generic_predicates_query(
|
||||||
resolver
|
resolver
|
||||||
.where_predicates_in_scope()
|
.where_predicates_in_scope()
|
||||||
.flat_map(|pred| {
|
.flat_map(|pred| {
|
||||||
ctx.lower_where_predicate(pred, false).map(|p| Binders::new(generics.len(), p.value))
|
ctx.lower_where_predicate(pred, false).map(|p| Binders::new(generics.len(), p))
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
|
@ -537,7 +537,7 @@ pub(super) fn convert_where_clauses(
|
||||||
let generic_predicates = db.generic_predicates(def);
|
let generic_predicates = db.generic_predicates(def);
|
||||||
let mut result = Vec::with_capacity(generic_predicates.len());
|
let mut result = Vec::with_capacity(generic_predicates.len());
|
||||||
for pred in generic_predicates.iter() {
|
for pred in generic_predicates.iter() {
|
||||||
result.push(crate::Binders::wrap_empty(pred.clone().subst(substs)).to_chalk(db));
|
result.push(pred.clone().subst(substs).to_chalk(db));
|
||||||
}
|
}
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,7 +63,7 @@ fn direct_super_trait_refs(db: &dyn HirDatabase, trait_ref: &TraitRef) -> Vec<Tr
|
||||||
db.generic_predicates_for_param(trait_self)
|
db.generic_predicates_for_param(trait_self)
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|pred| {
|
.filter_map(|pred| {
|
||||||
pred.as_ref().filter_map(|pred| match pred {
|
pred.as_ref().filter_map(|pred| match pred.skip_binders() {
|
||||||
WhereClause::Implemented(tr) => Some(tr.clone()),
|
WhereClause::Implemented(tr) => Some(tr.clone()),
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue