Skip to content

Commit da82865

Browse files
Assert that we always construct dyn types with the right number of projections
1 parent f889883 commit da82865

File tree

2 files changed

+32
-1
lines changed

2 files changed

+32
-1
lines changed

compiler/rustc_middle/src/ty/relate.rs

+3
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ impl<'tcx> Relate<TyCtxt<'tcx>> for &'tcx ty::List<ty::PolyExistentialPredicate<
7979
b: Self,
8080
) -> RelateResult<'tcx, Self> {
8181
let tcx = relation.cx();
82+
// Fast path for when the auto traits do not match, or if the principals
83+
// are from different traits and therefore the projections definitely don't
84+
// match up.
8285
if a.len() != b.len() {
8386
return Err(TypeError::ExistentialMismatch(ExpectedFound::new(a, b)));
8487
}

compiler/rustc_middle/src/ty/sty.rs

+29-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, extension
1818
use rustc_span::{DUMMY_SP, Span, Symbol, sym};
1919
use rustc_type_ir::TyKind::*;
2020
use rustc_type_ir::visit::TypeVisitableExt;
21-
use rustc_type_ir::{self as ir, BoundVar, CollectAndApply, DynKind};
21+
use rustc_type_ir::{self as ir, BoundVar, CollectAndApply, DynKind, elaborate};
2222
use tracing::instrument;
2323
use ty::util::{AsyncDropGlueMorphology, IntTypeExt};
2424

@@ -720,6 +720,34 @@ impl<'tcx> Ty<'tcx> {
720720
reg: ty::Region<'tcx>,
721721
repr: DynKind,
722722
) -> Ty<'tcx> {
723+
if cfg!(debug_assertions) {
724+
let projection_count = obj.projection_bounds().count();
725+
let expected_count: usize = obj
726+
.principal_def_id()
727+
.into_iter()
728+
.flat_map(|principal_def_id| {
729+
// NOTE: This should agree with `needed_associated_types` in
730+
// dyn trait lowering, or else we'll have ICEs.
731+
elaborate::supertraits(
732+
tcx,
733+
ty::Binder::dummy(ty::TraitRef::identity(tcx, principal_def_id)),
734+
)
735+
.map(|principal| {
736+
tcx.associated_items(principal.def_id())
737+
.in_definition_order()
738+
.filter(|item| item.kind == ty::AssocKind::Type)
739+
.filter(|item| !item.is_impl_trait_in_trait())
740+
.filter(|item| !tcx.generics_require_sized_self(item.def_id))
741+
.count()
742+
})
743+
})
744+
.sum();
745+
assert_eq!(
746+
projection_count, expected_count,
747+
"expected {obj:?} to have {expected_count} projections, \
748+
but it has {projection_count}"
749+
);
750+
}
723751
Ty::new(tcx, Dynamic(obj, reg, repr))
724752
}
725753

0 commit comments

Comments
 (0)