aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/display.rs
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2021-03-20 19:07:36 +0000
committerFlorian Diebold <[email protected]>2021-03-21 14:29:03 +0000
commitd8f8b495ad5c9e3676ddf7af53b23bb5b7f2fde0 (patch)
tree66d68e003d7fa1b311e1b4b99c01de6ea0984372 /crates/hir_ty/src/display.rs
parent0623bb4d71725d6b07e8cef5665094581f951fc0 (diff)
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.
Diffstat (limited to 'crates/hir_ty/src/display.rs')
-rw-r--r--crates/hir_ty/src/display.rs21
1 files changed, 15 insertions, 6 deletions
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 {
571 write!(f, "{}", param_data.name.clone().unwrap_or_else(Name::missing))? 571 write!(f, "{}", param_data.name.clone().unwrap_or_else(Name::missing))?
572 } 572 }
573 TypeParamProvenance::ArgumentImplTrait => { 573 TypeParamProvenance::ArgumentImplTrait => {
574 let bounds = f.db.generic_predicates_for_param(id);
575 let substs = Substitution::type_params_for_generics(f.db, &generics); 574 let substs = Substitution::type_params_for_generics(f.db, &generics);
576 write_bounds_like_dyn_trait_with_prefix( 575 let bounds = f
577 "impl", 576 .db
578 &bounds.iter().map(|b| b.clone().subst(&substs)).collect::<Vec<_>>(), 577 .generic_predicates(id.parent)
579 f, 578 .into_iter()
580 )?; 579 .map(|pred| pred.clone().subst(&substs))
580 .filter(|wc| match &wc {
581 WhereClause::Implemented(tr) => tr.self_type_parameter() == self,
582 WhereClause::AliasEq(AliasEq {
583 alias: AliasTy::Projection(proj),
584 ty: _,
585 }) => proj.self_type_parameter() == self,
586 _ => false,
587 })
588 .collect::<Vec<_>>();
589 write_bounds_like_dyn_trait_with_prefix("impl", &bounds, f)?;
581 } 590 }
582 } 591 }
583 } 592 }