about summary refs log tree commit diff
path: root/compiler/rustc_middle/src/ty/sty.rs
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2025-02-05 00:43:32 +0000
committerMichael Goulet <michael@errs.io>2025-02-21 19:32:45 +0000
commita2a0cfe82563146325674b8d437f9f9f6e703703 (patch)
tree06fefc01a61568e7515240ccb6a9f431f2048778 /compiler/rustc_middle/src/ty/sty.rs
parent72bd174c43406068727e17cbf6fc2f4e1a36f6af (diff)
downloadrust-a2a0cfe82563146325674b8d437f9f9f6e703703.tar.gz
rust-a2a0cfe82563146325674b8d437f9f9f6e703703.zip
Assert that we always construct dyn types with the right number of projections
Diffstat (limited to 'compiler/rustc_middle/src/ty/sty.rs')
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs30
1 files changed, 29 insertions, 1 deletions
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))
     }