mirror of https://github.com/rust-lang/rust.git
Assert that explicit_super_predicates_of and explicit_item_bounds truly only bounds for the type itself
This commit is contained in:
parent
f48c99a004
commit
a846d55d46
|
@ -10,6 +10,7 @@ use rustc_span::Span;
|
|||
use rustc_type_ir::Upcast;
|
||||
use tracing::{debug, instrument};
|
||||
|
||||
use super::predicates_of::assert_only_contains_predicates_from;
|
||||
use super::ItemCtxt;
|
||||
use crate::hir_ty_lowering::{HirTyLowerer, PredicateFilter};
|
||||
|
||||
|
@ -56,6 +57,9 @@ fn associated_type_bounds<'tcx>(
|
|||
tcx.def_path_str(assoc_item_def_id.to_def_id()),
|
||||
all_bounds
|
||||
);
|
||||
|
||||
assert_only_contains_predicates_from(filter, all_bounds, item_ty);
|
||||
|
||||
all_bounds
|
||||
}
|
||||
|
||||
|
@ -108,18 +112,21 @@ pub(super) fn explicit_item_bounds_with_filter(
|
|||
Some(ty::ImplTraitInTraitData::Trait { opaque_def_id, .. }) => {
|
||||
let item = tcx.hir_node_by_def_id(opaque_def_id.expect_local()).expect_item();
|
||||
let opaque_ty = item.expect_opaque_ty();
|
||||
return ty::EarlyBinder::bind(opaque_type_bounds(
|
||||
let item_ty = Ty::new_projection_from_args(
|
||||
tcx,
|
||||
def_id.to_def_id(),
|
||||
ty::GenericArgs::identity_for_item(tcx, def_id),
|
||||
);
|
||||
let bounds = opaque_type_bounds(
|
||||
tcx,
|
||||
opaque_def_id.expect_local(),
|
||||
opaque_ty.bounds,
|
||||
Ty::new_projection_from_args(
|
||||
tcx,
|
||||
def_id.to_def_id(),
|
||||
ty::GenericArgs::identity_for_item(tcx, def_id),
|
||||
),
|
||||
item_ty,
|
||||
item.span,
|
||||
filter,
|
||||
));
|
||||
);
|
||||
assert_only_contains_predicates_from(filter, bounds, item_ty);
|
||||
return ty::EarlyBinder::bind(bounds);
|
||||
}
|
||||
Some(ty::ImplTraitInTraitData::Impl { .. }) => span_bug!(
|
||||
tcx.def_span(def_id),
|
||||
|
@ -167,7 +174,9 @@ pub(super) fn explicit_item_bounds_with_filter(
|
|||
}) => {
|
||||
let args = GenericArgs::identity_for_item(tcx, def_id);
|
||||
let item_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args);
|
||||
opaque_type_bounds(tcx, def_id, bounds, item_ty, *span, filter)
|
||||
let bounds = opaque_type_bounds(tcx, def_id, bounds, item_ty, *span, filter);
|
||||
assert_only_contains_predicates_from(filter, bounds, item_ty);
|
||||
bounds
|
||||
}
|
||||
// Since RPITITs are lowered as projections in `<dyn HirTyLowerer>::lower_ty`, when we're
|
||||
// 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(
|
|||
};
|
||||
let args = GenericArgs::identity_for_item(tcx, def_id);
|
||||
let item_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args);
|
||||
tcx.arena.alloc_slice(
|
||||
let bounds = &*tcx.arena.alloc_slice(
|
||||
&opaque_type_bounds(tcx, def_id, bounds, item_ty, *span, filter)
|
||||
.to_vec()
|
||||
.fold_with(&mut AssocTyToOpaque { tcx, fn_def_id: fn_def_id.to_def_id() }),
|
||||
)
|
||||
);
|
||||
assert_only_contains_predicates_from(filter, bounds, item_ty);
|
||||
bounds
|
||||
}
|
||||
hir::Node::Item(hir::Item { kind: hir::ItemKind::TyAlias(..), .. }) => &[],
|
||||
_ => bug!("item_bounds called on {:?}", def_id),
|
||||
};
|
||||
|
||||
ty::EarlyBinder::bind(bounds)
|
||||
}
|
||||
|
||||
|
|
|
@ -676,9 +676,63 @@ pub(super) fn implied_predicates_with_filter<'tcx>(
|
|||
_ => {}
|
||||
}
|
||||
|
||||
assert_only_contains_predicates_from(filter, implied_bounds, tcx.types.self_param);
|
||||
|
||||
ty::EarlyBinder::bind(implied_bounds)
|
||||
}
|
||||
|
||||
// Make sure when elaborating supertraits, probing for associated types, etc.,
|
||||
// we really truly are elaborating clauses that have `Self` as their self type.
|
||||
// This is very important since downstream code relies on this being correct.
|
||||
pub(super) fn assert_only_contains_predicates_from<'tcx>(
|
||||
filter: PredicateFilter,
|
||||
bounds: &'tcx [(ty::Clause<'tcx>, Span)],
|
||||
ty: Ty<'tcx>,
|
||||
) {
|
||||
if !cfg!(debug_assertions) {
|
||||
return;
|
||||
}
|
||||
|
||||
match filter {
|
||||
PredicateFilter::SelfOnly | PredicateFilter::SelfThatDefines(_) => {
|
||||
for (clause, _) in bounds {
|
||||
match clause.kind().skip_binder() {
|
||||
ty::ClauseKind::Trait(trait_predicate) => {
|
||||
assert_eq!(
|
||||
trait_predicate.self_ty(),
|
||||
ty,
|
||||
"expected `Self` predicate when computing `{filter:?}` implied bounds: {clause:?}"
|
||||
);
|
||||
}
|
||||
ty::ClauseKind::Projection(projection_predicate) => {
|
||||
assert_eq!(
|
||||
projection_predicate.self_ty(),
|
||||
ty,
|
||||
"expected `Self` predicate when computing `{filter:?}` implied bounds: {clause:?}"
|
||||
);
|
||||
}
|
||||
ty::ClauseKind::TypeOutlives(outlives_predicate) => {
|
||||
assert_eq!(
|
||||
outlives_predicate.0, ty,
|
||||
"expected `Self` predicate when computing `{filter:?}` implied bounds: {clause:?}"
|
||||
);
|
||||
}
|
||||
|
||||
ty::ClauseKind::RegionOutlives(_)
|
||||
| ty::ClauseKind::ConstArgHasType(_, _)
|
||||
| ty::ClauseKind::WellFormed(_)
|
||||
| ty::ClauseKind::ConstEvaluatable(_) => {
|
||||
bug!(
|
||||
"unexpected non-`Self` predicate when computing `{filter:?}` implied bounds: {clause:?}"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
PredicateFilter::All | PredicateFilter::SelfAndAssociatedTypeBounds => {}
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the predicates defined on `item_def_id` of the form
|
||||
/// `X: Foo` where `X` is the type parameter `def_id`.
|
||||
#[instrument(level = "trace", skip(tcx))]
|
||||
|
|
Loading…
Reference in New Issue