From d8f8b495ad5c9e3676ddf7af53b23bb5b7f2fde0 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Sat, 20 Mar 2021 20:07:36 +0100 Subject: Ignore type bindings in generic_predicates_for_param This allows us to handle more cases without a query cycle, which includes certain cases that rustc accepted. That in turn means we avoid triggering salsa-rs/salsa#257 on valid code (it will still happen if the user writes an actual cycle). We actually accept more definitions than rustc now; that's because rustc only ignores bindings when looking up super traits, whereas we now also ignore them when looking for predicates to disambiguate associated type shorthand. We could introduce a separate query for super traits if necessary, but for now I think this should be fine. --- crates/hir_ty/src/display.rs | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) (limited to 'crates/hir_ty/src/display.rs') diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs index 3845009ae..9d3b79be3 100644 --- a/crates/hir_ty/src/display.rs +++ b/crates/hir_ty/src/display.rs @@ -571,13 +571,22 @@ impl HirDisplay for Ty { write!(f, "{}", param_data.name.clone().unwrap_or_else(Name::missing))? } TypeParamProvenance::ArgumentImplTrait => { - let bounds = f.db.generic_predicates_for_param(id); let substs = Substitution::type_params_for_generics(f.db, &generics); - write_bounds_like_dyn_trait_with_prefix( - "impl", - &bounds.iter().map(|b| b.clone().subst(&substs)).collect::>(), - f, - )?; + let bounds = f + .db + .generic_predicates(id.parent) + .into_iter() + .map(|pred| pred.clone().subst(&substs)) + .filter(|wc| match &wc { + WhereClause::Implemented(tr) => tr.self_type_parameter() == self, + WhereClause::AliasEq(AliasEq { + alias: AliasTy::Projection(proj), + ty: _, + }) => proj.self_type_parameter() == self, + _ => false, + }) + .collect::>(); + write_bounds_like_dyn_trait_with_prefix("impl", &bounds, f)?; } } } -- cgit v1.2.3