diff options
| author | Michael Goulet <michael@errs.io> | 2025-02-05 00:43:32 +0000 |
|---|---|---|
| committer | Michael Goulet <michael@errs.io> | 2025-02-21 19:32:45 +0000 |
| commit | a2a0cfe82563146325674b8d437f9f9f6e703703 (patch) | |
| tree | 06fefc01a61568e7515240ccb6a9f431f2048778 | |
| parent | 72bd174c43406068727e17cbf6fc2f4e1a36f6af (diff) | |
| download | rust-a2a0cfe82563146325674b8d437f9f9f6e703703.tar.gz rust-a2a0cfe82563146325674b8d437f9f9f6e703703.zip | |
Assert that we always construct dyn types with the right number of projections
| -rw-r--r-- | compiler/rustc_middle/src/ty/relate.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/sty.rs | 30 |
2 files changed, 32 insertions, 1 deletions
diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index 1d1aad916bc..839c1c346a4 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -79,6 +79,9 @@ impl<'tcx> Relate<TyCtxt<'tcx>> for &'tcx ty::List<ty::PolyExistentialPredicate< b: Self, ) -> RelateResult<'tcx, Self> { let tcx = relation.cx(); + // Fast path for when the auto traits do not match, or if the principals + // are from different traits and therefore the projections definitely don't + // match up. if a.len() != b.len() { return Err(TypeError::ExistentialMismatch(ExpectedFound::new(a, b))); } diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 8a31b296018..9eda7608707 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -18,7 +18,7 @@ use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, extension use rustc_span::{DUMMY_SP, Span, Symbol, sym}; use rustc_type_ir::TyKind::*; use rustc_type_ir::visit::TypeVisitableExt; -use rustc_type_ir::{self as ir, BoundVar, CollectAndApply, DynKind}; +use rustc_type_ir::{self as ir, BoundVar, CollectAndApply, DynKind, elaborate}; use tracing::instrument; use ty::util::{AsyncDropGlueMorphology, IntTypeExt}; @@ -720,6 +720,34 @@ impl<'tcx> Ty<'tcx> { reg: ty::Region<'tcx>, repr: DynKind, ) -> Ty<'tcx> { + if cfg!(debug_assertions) { + let projection_count = obj.projection_bounds().count(); + let expected_count: usize = obj + .principal_def_id() + .into_iter() + .flat_map(|principal_def_id| { + // NOTE: This should agree with `needed_associated_types` in + // dyn trait lowering, or else we'll have ICEs. + elaborate::supertraits( + tcx, + ty::Binder::dummy(ty::TraitRef::identity(tcx, principal_def_id)), + ) + .map(|principal| { + tcx.associated_items(principal.def_id()) + .in_definition_order() + .filter(|item| item.kind == ty::AssocKind::Type) + .filter(|item| !item.is_impl_trait_in_trait()) + .filter(|item| !tcx.generics_require_sized_self(item.def_id)) + .count() + }) + }) + .sum(); + assert_eq!( + projection_count, expected_count, + "expected {obj:?} to have {expected_count} projections, \ + but it has {projection_count}" + ); + } Ty::new(tcx, Dynamic(obj, reg, repr)) } |
