From 1d5c4a77fb33cab7bf8f9d2edc6dd26b09ef65f3 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Sun, 21 Mar 2021 17:40:14 +0100 Subject: 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. --- crates/hir/src/display.rs | 6 +----- crates/hir/src/lib.rs | 2 +- crates/hir_ty/src/db.rs | 11 +++++++---- crates/hir_ty/src/display.rs | 12 ++---------- crates/hir_ty/src/infer/expr.rs | 5 ++++- crates/hir_ty/src/lib.rs | 7 +++++-- crates/hir_ty/src/lower.rs | 18 ++++++------------ crates/hir_ty/src/traits/chalk/mapping.rs | 2 +- crates/hir_ty/src/utils.rs | 2 +- 9 files changed, 28 insertions(+), 37 deletions(-) diff --git a/crates/hir/src/display.rs b/crates/hir/src/display.rs index c96ebb50a..9f6d7be48 100644 --- a/crates/hir/src/display.rs +++ b/crates/hir/src/display.rs @@ -236,11 +236,7 @@ impl HirDisplay for TypeParam { write!(f, "{}", self.name(f.db))?; let bounds = f.db.generic_predicates_for_param(self.id); let substs = Substitution::type_params(f.db, self.id.parent); - let predicates = bounds - .iter() - .cloned() - .map(|b| hir_ty::Binders::new(0, b.subst(&substs))) - .collect::>(); + let predicates = bounds.iter().cloned().map(|b| b.subst(&substs)).collect::>(); if !(predicates.is_empty() || f.omit_verbose_types()) { write_bounds_like_dyn_trait_with_prefix(":", &predicates, f)?; } diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 1844942a6..a325b6691 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -1460,7 +1460,7 @@ impl TypeParam { pub fn trait_bounds(self, db: &dyn HirDatabase) -> Vec { db.generic_predicates_for_param(self.id) .into_iter() - .filter_map(|pred| match &pred.value { + .filter_map(|pred| match &pred.skip_binders().skip_binders() { hir_ty::WhereClause::Implemented(trait_ref) => { Some(Trait::from(trait_ref.hir_trait_id())) } diff --git a/crates/hir_ty/src/db.rs b/crates/hir_ty/src/db.rs index 91a2e0b5b..58e4247c6 100644 --- a/crates/hir_ty/src/db.rs +++ b/crates/hir_ty/src/db.rs @@ -12,8 +12,8 @@ use la_arena::ArenaMap; use crate::{ method_resolution::{InherentImpls, TraitImpls}, traits::chalk, - Binders, CallableDefId, FnDefId, ImplTraitId, InferenceResult, PolyFnSig, ReturnTypeImplTraits, - TraitRef, Ty, TyDefId, ValueTyDefId, WhereClause, + Binders, CallableDefId, FnDefId, ImplTraitId, InferenceResult, PolyFnSig, + QuantifiedWhereClause, ReturnTypeImplTraits, TraitRef, Ty, TyDefId, ValueTyDefId, }; use hir_expand::name::Name; @@ -57,10 +57,13 @@ pub trait HirDatabase: DefDatabase + Upcast { #[salsa::invoke(crate::lower::generic_predicates_for_param_query)] #[salsa::cycle(crate::lower::generic_predicates_for_param_recover)] - fn generic_predicates_for_param(&self, param_id: TypeParamId) -> Arc<[Binders]>; + fn generic_predicates_for_param( + &self, + param_id: TypeParamId, + ) -> Arc<[Binders]>; #[salsa::invoke(crate::lower::generic_predicates_query)] - fn generic_predicates(&self, def: GenericDefId) -> Arc<[Binders]>; + fn generic_predicates(&self, def: GenericDefId) -> Arc<[Binders]>; #[salsa::invoke(crate::lower::trait_environment_query)] fn trait_environment(&self, def: GenericDefId) -> Arc; diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs index 372671405..cc6b93d37 100644 --- a/crates/hir_ty/src/display.rs +++ b/crates/hir_ty/src/display.rs @@ -581,7 +581,7 @@ impl HirDisplay for Ty { .generic_predicates(id.parent) .into_iter() .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::AliasEq(AliasEq { alias: AliasTy::Projection(proj), @@ -590,15 +590,7 @@ impl HirDisplay for Ty { _ => false, }) .collect::>(); - write_bounds_like_dyn_trait_with_prefix( - "impl", - &bounds - .iter() - .cloned() - .map(crate::Binders::wrap_empty) - .collect::>(), - f, - )?; + write_bounds_like_dyn_trait_with_prefix("impl", &bounds, f)?; } } } diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs index 79bbc5dab..17849d552 100644 --- a/crates/hir_ty/src/infer/expr.rs +++ b/crates/hir_ty/src/infer/expr.rs @@ -11,6 +11,7 @@ use hir_def::{ AssocContainerId, FieldId, Lookup, }; use hir_expand::name::{name, Name}; +use stdx::always; use syntax::ast::RangeOp; use crate::{ @@ -936,7 +937,9 @@ impl<'a> InferenceContext<'a> { let def: CallableDefId = from_chalk(self.db, *fn_def); let generic_predicates = self.db.generic_predicates(def.into()); 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)); } // add obligation for trait implementation, if this is a trait method diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs index e4b1f92e4..90b5b17e2 100644 --- a/crates/hir_ty/src/lib.rs +++ b/crates/hir_ty/src/lib.rs @@ -518,6 +518,10 @@ impl Binders { pub fn skip_binders(&self) -> &T { &self.value } + + pub fn into_value_and_skipped_binders(self) -> (T, usize) { + (self.value, self.num_binders) + } } impl Binders<&T> { @@ -985,7 +989,7 @@ impl Ty { .generic_predicates(id.parent) .into_iter() .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::AliasEq(AliasEq { alias: AliasTy::Projection(proj), @@ -993,7 +997,6 @@ impl Ty { }) => proj.self_type_parameter() == self, _ => false, }) - .map(Binders::wrap_empty) .collect_vec(); Some(predicates) diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs index 45591e920..f60cec649 100644 --- a/crates/hir_ty/src/lower.rs +++ b/crates/hir_ty/src/lower.rs @@ -825,7 +825,7 @@ pub fn associated_type_shorthand_candidates( let predicates = db.generic_predicates_for_param(param_id); let mut traits_: Vec<_> = predicates .iter() - .filter_map(|pred| match &pred.value { + .filter_map(|pred| match &pred.value.value { WhereClause::Implemented(tr) => Some(tr.clone()), _ => None, }) @@ -898,10 +898,7 @@ pub(crate) fn field_types_query( pub(crate) fn generic_predicates_for_param_query( db: &dyn HirDatabase, param_id: TypeParamId, -) -> Arc<[Binders]> { - // 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> - // ...) +) -> Arc<[Binders]> { let resolver = param_id.parent.resolver(db.upcast()); let ctx = 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, }) .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() } @@ -929,7 +926,7 @@ pub(crate) fn generic_predicates_for_param_recover( _db: &dyn HirDatabase, _cycle: &[String], _param_id: &TypeParamId, -) -> Arc<[Binders]> { +) -> Arc<[Binders]> { Arc::new([]) } @@ -984,10 +981,7 @@ pub(crate) fn trait_environment_query( pub(crate) fn generic_predicates_query( db: &dyn HirDatabase, def: GenericDefId, -) -> Arc<[Binders]> { - // 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> - // ...) +) -> Arc<[Binders]> { let resolver = def.resolver(db.upcast()); let ctx = TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); @@ -995,7 +989,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.value)) + ctx.lower_where_predicate(pred, false).map(|p| Binders::new(generics.len(), p)) }) .collect() } diff --git a/crates/hir_ty/src/traits/chalk/mapping.rs b/crates/hir_ty/src/traits/chalk/mapping.rs index 5b9c7e831..7209dd14e 100644 --- a/crates/hir_ty/src/traits/chalk/mapping.rs +++ b/crates/hir_ty/src/traits/chalk/mapping.rs @@ -537,7 +537,7 @@ pub(super) fn convert_where_clauses( let generic_predicates = db.generic_predicates(def); let mut result = Vec::with_capacity(generic_predicates.len()); 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 } diff --git a/crates/hir_ty/src/utils.rs b/crates/hir_ty/src/utils.rs index 1ec1ecd43..19874e42b 100644 --- a/crates/hir_ty/src/utils.rs +++ b/crates/hir_ty/src/utils.rs @@ -63,7 +63,7 @@ fn direct_super_trait_refs(db: &dyn HirDatabase, trait_ref: &TraitRef) -> Vec Some(tr.clone()), _ => None, }) -- cgit v1.2.3