diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-03-21 16:42:08 +0000 |
---|---|---|
committer | GitHub <[email protected]> | 2021-03-21 16:42:08 +0000 |
commit | 35868c4f7dc479dd5f731a2785ec6a203046ea9c (patch) | |
tree | e78313acecc4fa84a11a2d8e7da7c85c98f940e0 /crates/hir_ty/src/display.rs | |
parent | 1ae20d2b894171f0b8368309da727cd365b95fc1 (diff) | |
parent | d8f8b495ad5c9e3676ddf7af53b23bb5b7f2fde0 (diff) |
Merge #8133
8133: Ignore type bindings in generic_predicates_for_param (fix panic on ena and crates depending on it) r=flodiebold a=flodiebold
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.
Co-authored-by: Florian Diebold <[email protected]>
Diffstat (limited to 'crates/hir_ty/src/display.rs')
-rw-r--r-- | crates/hir_ty/src/display.rs | 21 |
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 | } |