about summary refs log tree commit diff
path: root/compiler/rustc_ty_utils/src
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_ty_utils/src')
-rw-r--r--compiler/rustc_ty_utils/src/instance.rs8
-rw-r--r--compiler/rustc_ty_utils/src/layout.rs32
-rw-r--r--compiler/rustc_ty_utils/src/needs_drop.rs2
-rw-r--r--compiler/rustc_ty_utils/src/ty.rs2
4 files changed, 33 insertions, 11 deletions
diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs
index c6f2b16ca21..2da98d33429 100644
--- a/compiler/rustc_ty_utils/src/instance.rs
+++ b/compiler/rustc_ty_utils/src/instance.rs
@@ -44,7 +44,13 @@ fn inner_resolve_instance<'tcx>(
 
     let result = if let Some(trait_def_id) = tcx.trait_of_item(def.did) {
         debug!(" => associated item, attempting to find impl in param_env {:#?}", param_env);
-        resolve_associated_item(tcx, def.did, param_env, trait_def_id, substs)
+        resolve_associated_item(
+            tcx,
+            def.did,
+            param_env,
+            trait_def_id,
+            tcx.normalize_erasing_regions(param_env, substs),
+        )
     } else {
         let ty = tcx.type_of(def.def_id_for_type_of());
         let item_type = tcx.subst_and_normalize_erasing_regions(substs, param_env, ty);
diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs
index f4672a70072..c761a4dbe45 100644
--- a/compiler/rustc_ty_utils/src/layout.rs
+++ b/compiler/rustc_ty_utils/src/layout.rs
@@ -444,7 +444,7 @@ fn layout_of_uncached<'tcx>(
         }
 
         // Types with no meaningful known layout.
-        ty::Projection(_) | ty::Opaque(..) => {
+        ty::Alias(..) => {
             // NOTE(eddyb) `layout_of` query should've normalized these away,
             // if that was possible, so there's no reason to try again here.
             return Err(LayoutError::Unknown(ty));
@@ -919,7 +919,7 @@ fn variant_info_for_generator<'tcx>(
     def_id: DefId,
     substs: ty::SubstsRef<'tcx>,
 ) -> (Vec<VariantInfo>, Option<Size>) {
-    let Variants::Multiple { tag, ref tag_encoding, .. } = layout.variants else {
+    let Variants::Multiple { tag, ref tag_encoding, tag_field, .. } = layout.variants else {
         return (vec![], None);
     };
 
@@ -975,12 +975,28 @@ fn variant_info_for_generator<'tcx>(
             if variant_size == Size::ZERO {
                 variant_size = upvars_size;
             }
-            // We need to add the discriminant size back into min_size, since it is subtracted
-            // later during printing.
-            variant_size += match tag_encoding {
-                TagEncoding::Direct => tag.size(cx),
-                _ => Size::ZERO,
-            };
+
+            // This `if` deserves some explanation.
+            //
+            // The layout code has a choice of where to place the discriminant of this generator.
+            // If the discriminant of the generator is placed early in the layout (before the
+            // variant's own fields), then it'll implicitly be counted towards the size of the
+            // variant, since we use the maximum offset to calculate size.
+            //    (side-note: I know this is a bit problematic given upvars placement, etc).
+            //
+            // This is important, since the layout printing code always subtracts this discriminant
+            // size from the variant size if the struct is "enum"-like, so failing to account for it
+            // will either lead to numerical underflow, or an underreported variant size...
+            //
+            // However, if the discriminant is placed past the end of the variant, then we need
+            // to factor in the size of the discriminant manually. This really should be refactored
+            // better, but this "works" for now.
+            if layout.fields.offset(tag_field) >= variant_size {
+                variant_size += match tag_encoding {
+                    TagEncoding::Direct => tag.size(cx),
+                    _ => Size::ZERO,
+                };
+            }
 
             VariantInfo {
                 name: Some(Symbol::intern(&ty::GeneratorSubsts::variant_name(variant_idx))),
diff --git a/compiler/rustc_ty_utils/src/needs_drop.rs b/compiler/rustc_ty_utils/src/needs_drop.rs
index 024dcd591bd..0df060fc5fb 100644
--- a/compiler/rustc_ty_utils/src/needs_drop.rs
+++ b/compiler/rustc_ty_utils/src/needs_drop.rs
@@ -152,7 +152,7 @@ where
                             queue_type(self, required);
                         }
                     }
-                    ty::Array(..) | ty::Opaque(..) | ty::Projection(..) | ty::Param(_) => {
+                    ty::Array(..) | ty::Alias(..) | ty::Param(_) => {
                         if ty == component {
                             // Return the type to the caller: they may be able
                             // to normalize further than we can.
diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs
index 5fc9bcac1b1..5279fc69a31 100644
--- a/compiler/rustc_ty_utils/src/ty.rs
+++ b/compiler/rustc_ty_utils/src/ty.rs
@@ -37,7 +37,7 @@ fn sized_constraint_for_ty<'tcx>(
                 .collect()
         }
 
-        Projection(..) | Opaque(..) => {
+        Alias(..) => {
             // must calculate explicitly.
             // FIXME: consider special-casing always-Sized projections
             vec![ty]