Skip to content

Commit a846d55

Browse files
Assert that explicit_super_predicates_of and explicit_item_bounds truly only bounds for the type itself
1 parent f48c99a commit a846d55

File tree

2 files changed

+76
-10
lines changed

2 files changed

+76
-10
lines changed

compiler/rustc_hir_analysis/src/collect/item_bounds.rs

+22-10
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use rustc_span::Span;
1010
use rustc_type_ir::Upcast;
1111
use tracing::{debug, instrument};
1212

13+
use super::predicates_of::assert_only_contains_predicates_from;
1314
use super::ItemCtxt;
1415
use crate::hir_ty_lowering::{HirTyLowerer, PredicateFilter};
1516

@@ -56,6 +57,9 @@ fn associated_type_bounds<'tcx>(
5657
tcx.def_path_str(assoc_item_def_id.to_def_id()),
5758
all_bounds
5859
);
60+
61+
assert_only_contains_predicates_from(filter, all_bounds, item_ty);
62+
5963
all_bounds
6064
}
6165

@@ -108,18 +112,21 @@ pub(super) fn explicit_item_bounds_with_filter(
108112
Some(ty::ImplTraitInTraitData::Trait { opaque_def_id, .. }) => {
109113
let item = tcx.hir_node_by_def_id(opaque_def_id.expect_local()).expect_item();
110114
let opaque_ty = item.expect_opaque_ty();
111-
return ty::EarlyBinder::bind(opaque_type_bounds(
115+
let item_ty = Ty::new_projection_from_args(
116+
tcx,
117+
def_id.to_def_id(),
118+
ty::GenericArgs::identity_for_item(tcx, def_id),
119+
);
120+
let bounds = opaque_type_bounds(
112121
tcx,
113122
opaque_def_id.expect_local(),
114123
opaque_ty.bounds,
115-
Ty::new_projection_from_args(
116-
tcx,
117-
def_id.to_def_id(),
118-
ty::GenericArgs::identity_for_item(tcx, def_id),
119-
),
124+
item_ty,
120125
item.span,
121126
filter,
122-
));
127+
);
128+
assert_only_contains_predicates_from(filter, bounds, item_ty);
129+
return ty::EarlyBinder::bind(bounds);
123130
}
124131
Some(ty::ImplTraitInTraitData::Impl { .. }) => span_bug!(
125132
tcx.def_span(def_id),
@@ -167,7 +174,9 @@ pub(super) fn explicit_item_bounds_with_filter(
167174
}) => {
168175
let args = GenericArgs::identity_for_item(tcx, def_id);
169176
let item_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args);
170-
opaque_type_bounds(tcx, def_id, bounds, item_ty, *span, filter)
177+
let bounds = opaque_type_bounds(tcx, def_id, bounds, item_ty, *span, filter);
178+
assert_only_contains_predicates_from(filter, bounds, item_ty);
179+
bounds
171180
}
172181
// Since RPITITs are lowered as projections in `<dyn HirTyLowerer>::lower_ty`, when we're
173182
// asking for the item bounds of the *opaques* in a trait's default method signature, we
@@ -184,15 +193,18 @@ pub(super) fn explicit_item_bounds_with_filter(
184193
};
185194
let args = GenericArgs::identity_for_item(tcx, def_id);
186195
let item_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args);
187-
tcx.arena.alloc_slice(
196+
let bounds = &*tcx.arena.alloc_slice(
188197
&opaque_type_bounds(tcx, def_id, bounds, item_ty, *span, filter)
189198
.to_vec()
190199
.fold_with(&mut AssocTyToOpaque { tcx, fn_def_id: fn_def_id.to_def_id() }),
191-
)
200+
);
201+
assert_only_contains_predicates_from(filter, bounds, item_ty);
202+
bounds
192203
}
193204
hir::Node::Item(hir::Item { kind: hir::ItemKind::TyAlias(..), .. }) => &[],
194205
_ => bug!("item_bounds called on {:?}", def_id),
195206
};
207+
196208
ty::EarlyBinder::bind(bounds)
197209
}
198210

compiler/rustc_hir_analysis/src/collect/predicates_of.rs

+54
Original file line numberDiff line numberDiff line change
@@ -676,9 +676,63 @@ pub(super) fn implied_predicates_with_filter<'tcx>(
676676
_ => {}
677677
}
678678

679+
assert_only_contains_predicates_from(filter, implied_bounds, tcx.types.self_param);
680+
679681
ty::EarlyBinder::bind(implied_bounds)
680682
}
681683

684+
// Make sure when elaborating supertraits, probing for associated types, etc.,
685+
// we really truly are elaborating clauses that have `Self` as their self type.
686+
// This is very important since downstream code relies on this being correct.
687+
pub(super) fn assert_only_contains_predicates_from<'tcx>(
688+
filter: PredicateFilter,
689+
bounds: &'tcx [(ty::Clause<'tcx>, Span)],
690+
ty: Ty<'tcx>,
691+
) {
692+
if !cfg!(debug_assertions) {
693+
return;
694+
}
695+
696+
match filter {
697+
PredicateFilter::SelfOnly | PredicateFilter::SelfThatDefines(_) => {
698+
for (clause, _) in bounds {
699+
match clause.kind().skip_binder() {
700+
ty::ClauseKind::Trait(trait_predicate) => {
701+
assert_eq!(
702+
trait_predicate.self_ty(),
703+
ty,
704+
"expected `Self` predicate when computing `{filter:?}` implied bounds: {clause:?}"
705+
);
706+
}
707+
ty::ClauseKind::Projection(projection_predicate) => {
708+
assert_eq!(
709+
projection_predicate.self_ty(),
710+
ty,
711+
"expected `Self` predicate when computing `{filter:?}` implied bounds: {clause:?}"
712+
);
713+
}
714+
ty::ClauseKind::TypeOutlives(outlives_predicate) => {
715+
assert_eq!(
716+
outlives_predicate.0, ty,
717+
"expected `Self` predicate when computing `{filter:?}` implied bounds: {clause:?}"
718+
);
719+
}
720+
721+
ty::ClauseKind::RegionOutlives(_)
722+
| ty::ClauseKind::ConstArgHasType(_, _)
723+
| ty::ClauseKind::WellFormed(_)
724+
| ty::ClauseKind::ConstEvaluatable(_) => {
725+
bug!(
726+
"unexpected non-`Self` predicate when computing `{filter:?}` implied bounds: {clause:?}"
727+
);
728+
}
729+
}
730+
}
731+
}
732+
PredicateFilter::All | PredicateFilter::SelfAndAssociatedTypeBounds => {}
733+
}
734+
}
735+
682736
/// Returns the predicates defined on `item_def_id` of the form
683737
/// `X: Foo` where `X` is the type parameter `def_id`.
684738
#[instrument(level = "trace", skip(tcx))]

0 commit comments

Comments
 (0)