aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/lower.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/lower.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/lower.rs')
-rw-r--r--crates/hir_ty/src/lower.rs25
1 files changed, 19 insertions, 6 deletions
diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs
index cbbb535e5..2bdfcd310 100644
--- a/crates/hir_ty/src/lower.rs
+++ b/crates/hir_ty/src/lower.rs
@@ -189,7 +189,10 @@ impl<'a> TyLoweringContext<'a> {
189 let self_ty = 189 let self_ty =
190 TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(&Interner); 190 TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(&Interner);
191 let predicates = self.with_shifted_in(DebruijnIndex::ONE, |ctx| { 191 let predicates = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
192 bounds.iter().flat_map(|b| ctx.lower_type_bound(b, self_ty.clone())).collect() 192 bounds
193 .iter()
194 .flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false))
195 .collect()
193 }); 196 });
194 TyKind::Dyn(predicates).intern(&Interner) 197 TyKind::Dyn(predicates).intern(&Interner)
195 } 198 }
@@ -666,6 +669,7 @@ impl<'a> TyLoweringContext<'a> {
666 pub(crate) fn lower_where_predicate( 669 pub(crate) fn lower_where_predicate(
667 &'a self, 670 &'a self,
668 where_predicate: &'a WherePredicate, 671 where_predicate: &'a WherePredicate,
672 ignore_bindings: bool,
669 ) -> impl Iterator<Item = WhereClause> + 'a { 673 ) -> impl Iterator<Item = WhereClause> + 'a {
670 match where_predicate { 674 match where_predicate {
671 WherePredicate::ForLifetime { target, bound, .. } 675 WherePredicate::ForLifetime { target, bound, .. }
@@ -688,7 +692,9 @@ impl<'a> TyLoweringContext<'a> {
688 .intern(&Interner) 692 .intern(&Interner)
689 } 693 }
690 }; 694 };
691 self.lower_type_bound(bound, self_ty).collect::<Vec<_>>().into_iter() 695 self.lower_type_bound(bound, self_ty, ignore_bindings)
696 .collect::<Vec<_>>()
697 .into_iter()
692 } 698 }
693 WherePredicate::Lifetime { .. } => vec![].into_iter(), 699 WherePredicate::Lifetime { .. } => vec![].into_iter(),
694 } 700 }
@@ -698,6 +704,7 @@ impl<'a> TyLoweringContext<'a> {
698 &'a self, 704 &'a self,
699 bound: &'a TypeBound, 705 bound: &'a TypeBound,
700 self_ty: Ty, 706 self_ty: Ty,
707 ignore_bindings: bool,
701 ) -> impl Iterator<Item = WhereClause> + 'a { 708 ) -> impl Iterator<Item = WhereClause> + 'a {
702 let mut bindings = None; 709 let mut bindings = None;
703 let trait_ref = match bound { 710 let trait_ref = match bound {
@@ -711,6 +718,7 @@ impl<'a> TyLoweringContext<'a> {
711 trait_ref.into_iter().chain( 718 trait_ref.into_iter().chain(
712 bindings 719 bindings
713 .into_iter() 720 .into_iter()
721 .filter(move |_| !ignore_bindings)
714 .flat_map(move |tr| self.assoc_type_bindings_from_type_bound(bound, tr)), 722 .flat_map(move |tr| self.assoc_type_bindings_from_type_bound(bound, tr)),
715 ) 723 )
716 } 724 }
@@ -755,6 +763,7 @@ impl<'a> TyLoweringContext<'a> {
755 preds.extend(self.lower_type_bound( 763 preds.extend(self.lower_type_bound(
756 bound, 764 bound,
757 TyKind::Alias(AliasTy::Projection(projection_ty.clone())).intern(&Interner), 765 TyKind::Alias(AliasTy::Projection(projection_ty.clone())).intern(&Interner),
766 false,
758 )); 767 ));
759 } 768 }
760 preds 769 preds
@@ -766,7 +775,7 @@ impl<'a> TyLoweringContext<'a> {
766 let self_ty = 775 let self_ty =
767 TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(&Interner); 776 TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(&Interner);
768 let predicates = self.with_shifted_in(DebruijnIndex::ONE, |ctx| { 777 let predicates = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
769 bounds.iter().flat_map(|b| ctx.lower_type_bound(b, self_ty.clone())).collect() 778 bounds.iter().flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false)).collect()
770 }); 779 });
771 ReturnTypeImplTrait { bounds: Binders::new(1, predicates) } 780 ReturnTypeImplTrait { bounds: Binders::new(1, predicates) }
772 } 781 }
@@ -896,7 +905,9 @@ pub(crate) fn generic_predicates_for_param_query(
896 }, 905 },
897 WherePredicate::Lifetime { .. } => false, 906 WherePredicate::Lifetime { .. } => false,
898 }) 907 })
899 .flat_map(|pred| ctx.lower_where_predicate(pred).map(|p| Binders::new(generics.len(), p))) 908 .flat_map(|pred| {
909 ctx.lower_where_predicate(pred, true).map(|p| Binders::new(generics.len(), p))
910 })
900 .collect() 911 .collect()
901} 912}
902 913
@@ -918,7 +929,7 @@ pub(crate) fn trait_environment_query(
918 let mut traits_in_scope = Vec::new(); 929 let mut traits_in_scope = Vec::new();
919 let mut clauses = Vec::new(); 930 let mut clauses = Vec::new();
920 for pred in resolver.where_predicates_in_scope() { 931 for pred in resolver.where_predicates_in_scope() {
921 for pred in ctx.lower_where_predicate(pred) { 932 for pred in ctx.lower_where_predicate(pred, false) {
922 if let WhereClause::Implemented(tr) = &pred { 933 if let WhereClause::Implemented(tr) = &pred {
923 traits_in_scope.push((tr.self_type_parameter().clone(), tr.hir_trait_id())); 934 traits_in_scope.push((tr.self_type_parameter().clone(), tr.hir_trait_id()));
924 } 935 }
@@ -967,7 +978,9 @@ pub(crate) fn generic_predicates_query(
967 let generics = generics(db.upcast(), def); 978 let generics = generics(db.upcast(), def);
968 resolver 979 resolver
969 .where_predicates_in_scope() 980 .where_predicates_in_scope()
970 .flat_map(|pred| ctx.lower_where_predicate(pred).map(|p| Binders::new(generics.len(), p))) 981 .flat_map(|pred| {
982 ctx.lower_where_predicate(pred, false).map(|p| Binders::new(generics.len(), p))
983 })
971 .collect() 984 .collect()
972} 985}
973 986