From 6354e06f123d76685ae62ee6d232a31cae45d0a2 Mon Sep 17 00:00:00 2001
From: cui fliter <imcusg@gmail.com>
Date: Thu, 17 Aug 2023 15:10:31 +0800
Subject: [PATCH 01/12] doc: update lld-flavor ref

Signed-off-by: cui fliter <imcusg@gmail.com>
---
 src/doc/rustc/src/codegen-options/index.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md
index f882a31de5a8b..d72543c7e0255 100644
--- a/src/doc/rustc/src/codegen-options/index.md
+++ b/src/doc/rustc/src/codegen-options/index.md
@@ -263,7 +263,7 @@ flavor. Valid options are:
 * `lld-link`: use the LLVM `lld` executable with the [`-flavor link`
   flag][lld-flavor] for Microsoft's `link.exe`.
 
-[lld-flavor]: https://lld.llvm.org/Driver.html
+[lld-flavor]: https://releases.llvm.org/12.0.0/tools/lld/docs/Driver.html
 
 ## linker-plugin-lto
 

From 0848ebd056638e776dcb78a18431d31a97523ec8 Mon Sep 17 00:00:00 2001
From: David Wood <david.wood@huawei.com>
Date: Thu, 24 Aug 2023 14:12:42 +0100
Subject: [PATCH 02/12] tests: add test for #67992

Signed-off-by: David Wood <david@davidtw.co>
---
 .../regression-bad-location-list-67992.rs     | 31 +++++++++++++++++++
 1 file changed, 31 insertions(+)
 create mode 100644 tests/debuginfo/regression-bad-location-list-67992.rs

diff --git a/tests/debuginfo/regression-bad-location-list-67992.rs b/tests/debuginfo/regression-bad-location-list-67992.rs
new file mode 100644
index 0000000000000..cc7c4a0d71a34
--- /dev/null
+++ b/tests/debuginfo/regression-bad-location-list-67992.rs
@@ -0,0 +1,31 @@
+// compile-flags:-g
+
+// === GDB TESTS ===================================================================================
+
+// gdb-command:run
+
+// gdb-command:print a
+// gdb-check:$1 = regression_bad_location_list_67992::Foo {x: [0 <repeats 1024 times>]}
+
+// === LLDB TESTS ==================================================================================
+
+// lldb-command:run
+// lldb-command:print a
+// lldbg-check:(regression_bad_location_list_67992::Foo) $0 = [...]
+// lldbr-check:(regression_bad_location_list_67992::Foo) a = [...]
+
+const ARRAY_SIZE: usize = 1024;
+
+struct Foo {
+    x: [u64; ARRAY_SIZE],
+}
+
+fn foo(a: Foo, i: usize) -> u64 {
+    a.x[i] // #break
+}
+
+fn main() {
+    println!("Hello, world!");
+
+    println!("{}", foo(Foo { x: [0; ARRAY_SIZE] }, 42));
+}

From 7a653feffbe936eb2d1f88e47f28dd3ffd81d9eb Mon Sep 17 00:00:00 2001
From: Santiago Pastorino <spastorino@gmail.com>
Date: Mon, 28 Aug 2023 14:55:08 -0300
Subject: [PATCH 03/12] Remove stable_mir::generics_of/predicates_of those
 shouldn't be exposed

---
 compiler/rustc_smir/src/stable_mir/mod.rs | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/compiler/rustc_smir/src/stable_mir/mod.rs b/compiler/rustc_smir/src/stable_mir/mod.rs
index 44938eaa03538..c6b0e229e8838 100644
--- a/compiler/rustc_smir/src/stable_mir/mod.rs
+++ b/compiler/rustc_smir/src/stable_mir/mod.rs
@@ -109,14 +109,6 @@ pub fn trait_impl(trait_impl: &ImplDef) -> ImplTrait {
     with(|cx| cx.trait_impl(trait_impl))
 }
 
-pub fn generics_of(generic_def: &GenericDef) -> Generics {
-    with(|cx| cx.generics_of(generic_def))
-}
-
-pub fn predicates_of(trait_def: &TraitDef) -> GenericPredicates {
-    with(|cx| cx.predicates_of(trait_def))
-}
-
 pub trait Context {
     fn entry_fn(&mut self) -> Option<CrateItem>;
     /// Retrieve all items of the local crate that have a MIR associated with them.

From e9710f1faa607d88d0c6a42f89886e45019a68d2 Mon Sep 17 00:00:00 2001
From: Santiago Pastorino <spastorino@gmail.com>
Date: Mon, 28 Aug 2023 14:55:40 -0300
Subject: [PATCH 04/12] Context::generics _of/predicates_of should receive
 stable_mir::DefId

---
 compiler/rustc_smir/src/rustc_smir/mod.rs | 16 ++++++++--------
 compiler/rustc_smir/src/stable_mir/mod.rs |  6 +++---
 compiler/rustc_smir/src/stable_mir/ty.rs  |  2 +-
 3 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs
index 925d4a3bdd86f..2bf4fd23baf18 100644
--- a/compiler/rustc_smir/src/rustc_smir/mod.rs
+++ b/compiler/rustc_smir/src/rustc_smir/mod.rs
@@ -10,7 +10,7 @@
 use crate::rustc_internal::{self, opaque};
 use crate::stable_mir::mir::{CopyNonOverlapping, UserTypeProjection, VariantIdx};
 use crate::stable_mir::ty::{
-    allocation_filter, new_allocation, Const, FloatTy, GenericDef, GenericParamDef, IntTy,
+    allocation_filter, new_allocation, Const, FloatTy, GenericParamDef, IntTy,
     Movability, RigidTy, TyKind, UintTy,
 };
 use crate::stable_mir::{self, Context};
@@ -102,18 +102,18 @@ impl<'tcx> Context for Tables<'tcx> {
         ty.stable(self)
     }
 
-    fn generics_of(&mut self, generic_def: &GenericDef) -> stable_mir::ty::Generics {
-        let def_id = self.generic_def_id(generic_def);
-        let generic_def = self.tcx.generics_of(def_id);
-        generic_def.stable(self)
+    fn generics_of(&mut self, def_id: stable_mir::DefId) -> stable_mir::ty::Generics {
+        let def_id = self.def_ids[def_id];
+        let generics = self.tcx.generics_of(def_id);
+        generics.stable(self)
     }
 
     fn predicates_of(
         &mut self,
-        trait_def: &stable_mir::ty::TraitDef,
+        def_id: stable_mir::DefId,
     ) -> stable_mir::GenericPredicates {
-        let trait_def_id = self.trait_def_id(trait_def);
-        let ty::GenericPredicates { parent, predicates } = self.tcx.predicates_of(trait_def_id);
+        let def_id = self.def_ids[def_id];
+        let ty::GenericPredicates { parent, predicates } = self.tcx.predicates_of(def_id);
         stable_mir::GenericPredicates {
             parent: parent.map(|did| self.trait_def(did)),
             predicates: predicates
diff --git a/compiler/rustc_smir/src/stable_mir/mod.rs b/compiler/rustc_smir/src/stable_mir/mod.rs
index c6b0e229e8838..d891f88346834 100644
--- a/compiler/rustc_smir/src/stable_mir/mod.rs
+++ b/compiler/rustc_smir/src/stable_mir/mod.rs
@@ -16,7 +16,7 @@ use std::cell::Cell;
 use crate::rustc_smir::Tables;
 
 use self::ty::{
-    GenericDef, Generics, ImplDef, ImplTrait, PredicateKind, Span, TraitDecl, TraitDef, Ty, TyKind,
+    Generics, ImplDef, ImplTrait, PredicateKind, Span, TraitDecl, TraitDef, Ty, TyKind,
 };
 
 pub mod mir;
@@ -118,8 +118,8 @@ pub trait Context {
     fn trait_decl(&mut self, trait_def: &TraitDef) -> TraitDecl;
     fn all_trait_impls(&mut self) -> ImplTraitDecls;
     fn trait_impl(&mut self, trait_impl: &ImplDef) -> ImplTrait;
-    fn generics_of(&mut self, generic_def: &GenericDef) -> Generics;
-    fn predicates_of(&mut self, trait_def: &TraitDef) -> GenericPredicates;
+    fn generics_of(&mut self, def_id: DefId) -> Generics;
+    fn predicates_of(&mut self, def_id: DefId) -> GenericPredicates;
     /// Get information about the local crate.
     fn local_crate(&self) -> Crate;
     /// Retrieve a list of all external crates.
diff --git a/compiler/rustc_smir/src/stable_mir/ty.rs b/compiler/rustc_smir/src/stable_mir/ty.rs
index 5929823b1bbc1..c73c6b3fd9f39 100644
--- a/compiler/rustc_smir/src/stable_mir/ty.rs
+++ b/compiler/rustc_smir/src/stable_mir/ty.rs
@@ -137,7 +137,7 @@ impl ImplDef {
 
 impl GenericDef {
     pub fn generics_of(&self) -> Generics {
-        with(|tcx| tcx.generics_of(self))
+        with(|cx| cx.generics_of(self.0))
     }
 }
 

From 56b767322b87917ea82bad6472593efa839437f9 Mon Sep 17 00:00:00 2001
From: Katherine Philip <katherinephilip98@gmail.com>
Date: Mon, 28 Aug 2023 12:40:39 -0700
Subject: [PATCH 05/12] Don't ICE on layout computation failure

---
 .../rustc_codegen_cranelift/src/common.rs     |  2 +-
 compiler/rustc_codegen_gcc/src/context.rs     |  3 +-
 compiler/rustc_codegen_llvm/src/context.rs    |  3 +-
 compiler/rustc_codegen_ssa/messages.ftl       |  2 ++
 compiler/rustc_codegen_ssa/src/errors.rs      | 10 ++++++
 compiler/rustc_middle/src/ty/layout.rs        | 10 +++++-
 tests/ui/layout/layout-cycle.rs               | 31 +++++++++++++++++++
 tests/ui/layout/layout-cycle.stderr           | 11 +++++++
 8 files changed, 68 insertions(+), 4 deletions(-)
 create mode 100644 tests/ui/layout/layout-cycle.rs
 create mode 100644 tests/ui/layout/layout-cycle.stderr

diff --git a/compiler/rustc_codegen_cranelift/src/common.rs b/compiler/rustc_codegen_cranelift/src/common.rs
index 3081dcfa2b7a3..ec2da39398b2d 100644
--- a/compiler/rustc_codegen_cranelift/src/common.rs
+++ b/compiler/rustc_codegen_cranelift/src/common.rs
@@ -480,7 +480,7 @@ impl<'tcx> LayoutOfHelpers<'tcx> for RevealAllLayoutCx<'tcx> {
         if let LayoutError::SizeOverflow(_) | LayoutError::ReferencesError(_) = err {
             self.0.sess.span_fatal(span, err.to_string())
         } else {
-            span_bug!(span, "failed to get layout for `{}`: {}", ty, err)
+            self.0.sess.span_fatal(span, format!("failed to get layout for `{}`: {}", ty, err))
         }
     }
 }
diff --git a/compiler/rustc_codegen_gcc/src/context.rs b/compiler/rustc_codegen_gcc/src/context.rs
index 88dcafa7370e5..dcebd92a61c69 100644
--- a/compiler/rustc_codegen_gcc/src/context.rs
+++ b/compiler/rustc_codegen_gcc/src/context.rs
@@ -7,6 +7,7 @@ use rustc_codegen_ssa::traits::{
     BaseTypeMethods,
     MiscMethods,
 };
+use rustc_codegen_ssa::errors as ssa_errors;
 use rustc_data_structures::base_n;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_middle::span_bug;
@@ -479,7 +480,7 @@ impl<'gcc, 'tcx> LayoutOfHelpers<'tcx> for CodegenCx<'gcc, 'tcx> {
         if let LayoutError::SizeOverflow(_) | LayoutError::ReferencesError(_) = err {
             self.sess().emit_fatal(respan(span, err.into_diagnostic()))
         } else {
-            span_bug!(span, "failed to get layout for `{}`: {}", ty, err)
+            self.tcx.sess.emit_fatal(ssa_errors::FailedToGetLayout { span, ty, err })
         }
     }
 }
diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs
index 24fd5bbf8c526..8e8290279abd2 100644
--- a/compiler/rustc_codegen_llvm/src/context.rs
+++ b/compiler/rustc_codegen_llvm/src/context.rs
@@ -10,6 +10,7 @@ use crate::value::Value;
 
 use cstr::cstr;
 use rustc_codegen_ssa::base::{wants_msvc_seh, wants_wasm_eh};
+use rustc_codegen_ssa::errors as ssa_errors;
 use rustc_codegen_ssa::traits::*;
 use rustc_data_structures::base_n;
 use rustc_data_structures::fx::FxHashMap;
@@ -1000,7 +1001,7 @@ impl<'tcx> LayoutOfHelpers<'tcx> for CodegenCx<'_, 'tcx> {
         if let LayoutError::SizeOverflow(_) | LayoutError::ReferencesError(_) = err {
             self.sess().emit_fatal(Spanned { span, node: err.into_diagnostic() })
         } else {
-            span_bug!(span, "failed to get layout for `{ty}`: {err:?}")
+            self.tcx.sess.emit_fatal(ssa_errors::FailedToGetLayout { span, ty, err })
         }
     }
 }
diff --git a/compiler/rustc_codegen_ssa/messages.ftl b/compiler/rustc_codegen_ssa/messages.ftl
index b6c70c6224977..3dc83f50b21b7 100644
--- a/compiler/rustc_codegen_ssa/messages.ftl
+++ b/compiler/rustc_codegen_ssa/messages.ftl
@@ -35,6 +35,8 @@ codegen_ssa_extract_bundled_libs_parse_archive = failed to parse archive '{$rlib
 codegen_ssa_extract_bundled_libs_read_entry = failed to read entry '{$rlib}': {$error}
 codegen_ssa_extract_bundled_libs_write_file = failed to write file '{$rlib}': {$error}
 
+codegen_ssa_failed_to_get_layout = failed to get layout for {$ty}: {$err}
+
 codegen_ssa_failed_to_write = failed to write {$path}: {$error}
 
 codegen_ssa_ignoring_emit_path = ignoring emit path because multiple .{$extension} files were produced
diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs
index b7d8b9b45bf16..41602321dedff 100644
--- a/compiler/rustc_codegen_ssa/src/errors.rs
+++ b/compiler/rustc_codegen_ssa/src/errors.rs
@@ -7,6 +7,7 @@ use rustc_errors::{
     IntoDiagnosticArg,
 };
 use rustc_macros::Diagnostic;
+use rustc_middle::ty::layout::LayoutError;
 use rustc_middle::ty::Ty;
 use rustc_span::{Span, Symbol};
 use rustc_type_ir::FloatTy;
@@ -1030,6 +1031,15 @@ pub struct TargetFeatureSafeTrait {
     pub def: Span,
 }
 
+#[derive(Diagnostic)]
+#[diag(codegen_ssa_failed_to_get_layout)]
+pub struct FailedToGetLayout<'tcx> {
+    #[primary_span]
+    pub span: Span,
+    pub ty: Ty<'tcx>,
+    pub err: LayoutError<'tcx>,
+}
+
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_error_creating_remark_dir)]
 pub struct ErrorCreatingRemarkDir {
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index e362b3477c9f7..9a0e72d7b640a 100644
--- a/compiler/rustc_middle/src/ty/layout.rs
+++ b/compiler/rustc_middle/src/ty/layout.rs
@@ -4,7 +4,9 @@ use crate::query::TyCtxtAt;
 use crate::ty::normalize_erasing_regions::NormalizationError;
 use crate::ty::{self, ConstKind, ReprOptions, Ty, TyCtxt, TypeVisitableExt};
 use rustc_error_messages::DiagnosticMessage;
-use rustc_errors::{DiagnosticBuilder, Handler, IntoDiagnostic};
+use rustc_errors::{
+    DiagnosticArgValue, DiagnosticBuilder, Handler, IntoDiagnostic, IntoDiagnosticArg,
+};
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_index::IndexVec;
@@ -265,6 +267,12 @@ impl<'tcx> fmt::Display for LayoutError<'tcx> {
     }
 }
 
+impl<'tcx> IntoDiagnosticArg for LayoutError<'tcx> {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+        self.to_string().into_diagnostic_arg()
+    }
+}
+
 #[derive(Clone, Copy)]
 pub struct LayoutCx<'tcx, C> {
     pub tcx: C,
diff --git a/tests/ui/layout/layout-cycle.rs b/tests/ui/layout/layout-cycle.rs
new file mode 100644
index 0000000000000..85685058e49f5
--- /dev/null
+++ b/tests/ui/layout/layout-cycle.rs
@@ -0,0 +1,31 @@
+// build-fail
+//~^ ERROR: a cycle occurred during layout computation
+//~| ERROR: cycle detected when computing layout of
+
+// Issue #111176 -- ensure that we do not emit ICE on layout cycles
+
+use std::mem;
+
+pub struct S<T: Tr> {
+    pub f: <T as Tr>::I,
+}
+
+pub trait Tr {
+    type I: Tr;
+}
+
+impl<T: Tr> Tr for S<T> {
+    type I = S<S<T>>;
+}
+
+impl Tr for () {
+    type I = ();
+}
+
+fn foo<T: Tr>() -> usize {
+    mem::size_of::<S<T>>()
+}
+
+fn main() {
+    println!("{}", foo::<S<()>>());
+}
diff --git a/tests/ui/layout/layout-cycle.stderr b/tests/ui/layout/layout-cycle.stderr
new file mode 100644
index 0000000000000..a3cdb7edcc232
--- /dev/null
+++ b/tests/ui/layout/layout-cycle.stderr
@@ -0,0 +1,11 @@
+error[E0391]: cycle detected when computing layout of `S<S<()>>`
+   |
+   = note: ...which requires computing layout of `<S<()> as Tr>::I`...
+   = note: ...which again requires computing layout of `S<S<()>>`, completing the cycle
+   = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
+
+error: failed to get layout for S<S<()>>: a cycle occurred during layout computation
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0391`.

From af6299a1f7c37fd002828db89c3391a75eef5f4c Mon Sep 17 00:00:00 2001
From: Santiago Pastorino <spastorino@gmail.com>
Date: Mon, 28 Aug 2023 15:56:45 -0300
Subject: [PATCH 06/12] Add stable_mir::DefId as new type wrapper

---
 compiler/rustc_smir/src/rustc_internal/mod.rs | 22 ++++++++++++++-----
 compiler/rustc_smir/src/rustc_smir/mod.rs     | 13 +++++------
 compiler/rustc_smir/src/stable_mir/mod.rs     |  3 ++-
 3 files changed, 23 insertions(+), 15 deletions(-)

diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs
index ebacb7cce836a..f9d71d77efa34 100644
--- a/compiler/rustc_smir/src/rustc_internal/mod.rs
+++ b/compiler/rustc_smir/src/rustc_internal/mod.rs
@@ -4,6 +4,7 @@
 //! until stable MIR is complete.
 
 use std::fmt::Debug;
+use std::ops::Index;
 use std::string::ToString;
 
 use crate::{
@@ -67,21 +68,30 @@ pub fn impl_def(did: DefId) -> stable_mir::ty::ImplDef {
     with_tables(|t| t.impl_def(did))
 }
 
+impl<'tcx> Index<stable_mir::DefId> for Tables<'tcx> {
+    type Output = DefId;
+
+    #[inline(always)]
+    fn index(&self, index: stable_mir::DefId) -> &Self::Output {
+        &self.def_ids[index.0]
+    }
+}
+
 impl<'tcx> Tables<'tcx> {
     pub fn item_def_id(&self, item: &stable_mir::CrateItem) -> DefId {
-        self.def_ids[item.0]
+        self[item.0]
     }
 
     pub fn trait_def_id(&self, trait_def: &stable_mir::ty::TraitDef) -> DefId {
-        self.def_ids[trait_def.0]
+        self[trait_def.0]
     }
 
     pub fn impl_trait_def_id(&self, impl_def: &stable_mir::ty::ImplDef) -> DefId {
-        self.def_ids[impl_def.0]
+        self[impl_def.0]
     }
 
     pub fn generic_def_id(&self, generic_def: &stable_mir::ty::GenericDef) -> DefId {
-        self.def_ids[generic_def.0]
+        self[generic_def.0]
     }
 
     pub fn crate_item(&mut self, did: DefId) -> stable_mir::CrateItem {
@@ -140,12 +150,12 @@ impl<'tcx> Tables<'tcx> {
         // FIXME: this becomes inefficient when we have too many ids
         for (i, &d) in self.def_ids.iter().enumerate() {
             if d == did {
-                return i;
+                return stable_mir::DefId(i);
             }
         }
         let id = self.def_ids.len();
         self.def_ids.push(did);
-        id
+        stable_mir::DefId(id)
     }
 }
 
diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs
index 2bf4fd23baf18..0efd44dc4f026 100644
--- a/compiler/rustc_smir/src/rustc_smir/mod.rs
+++ b/compiler/rustc_smir/src/rustc_smir/mod.rs
@@ -10,8 +10,8 @@
 use crate::rustc_internal::{self, opaque};
 use crate::stable_mir::mir::{CopyNonOverlapping, UserTypeProjection, VariantIdx};
 use crate::stable_mir::ty::{
-    allocation_filter, new_allocation, Const, FloatTy, GenericParamDef, IntTy,
-    Movability, RigidTy, TyKind, UintTy,
+    allocation_filter, new_allocation, Const, FloatTy, GenericParamDef, IntTy, Movability, RigidTy,
+    TyKind, UintTy,
 };
 use crate::stable_mir::{self, Context};
 use rustc_hir as hir;
@@ -103,16 +103,13 @@ impl<'tcx> Context for Tables<'tcx> {
     }
 
     fn generics_of(&mut self, def_id: stable_mir::DefId) -> stable_mir::ty::Generics {
-        let def_id = self.def_ids[def_id];
+        let def_id = self[def_id];
         let generics = self.tcx.generics_of(def_id);
         generics.stable(self)
     }
 
-    fn predicates_of(
-        &mut self,
-        def_id: stable_mir::DefId,
-    ) -> stable_mir::GenericPredicates {
-        let def_id = self.def_ids[def_id];
+    fn predicates_of(&mut self, def_id: stable_mir::DefId) -> stable_mir::GenericPredicates {
+        let def_id = self[def_id];
         let ty::GenericPredicates { parent, predicates } = self.tcx.predicates_of(def_id);
         stable_mir::GenericPredicates {
             parent: parent.map(|did| self.trait_def(did)),
diff --git a/compiler/rustc_smir/src/stable_mir/mod.rs b/compiler/rustc_smir/src/stable_mir/mod.rs
index d891f88346834..0eee5cc91c7a3 100644
--- a/compiler/rustc_smir/src/stable_mir/mod.rs
+++ b/compiler/rustc_smir/src/stable_mir/mod.rs
@@ -29,7 +29,8 @@ pub type Symbol = String;
 pub type CrateNum = usize;
 
 /// A unique identification number for each item accessible for the current compilation unit.
-pub type DefId = usize;
+#[derive(Clone, Copy, PartialEq, Eq, Debug)]
+pub struct DefId(pub(crate) usize);
 
 /// A list of crate items.
 pub type CrateItems = Vec<CrateItem>;

From 17ffb59d39ae3884939edb888b8d5859a1f860a7 Mon Sep 17 00:00:00 2001
From: Santiago Pastorino <spastorino@gmail.com>
Date: Mon, 28 Aug 2023 15:58:48 -0300
Subject: [PATCH 07/12] Index def_ids directly

---
 compiler/rustc_smir/src/rustc_internal/mod.rs | 18 +-----------------
 compiler/rustc_smir/src/rustc_smir/mod.rs     |  6 +++---
 2 files changed, 4 insertions(+), 20 deletions(-)

diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs
index f9d71d77efa34..2087f7019b277 100644
--- a/compiler/rustc_smir/src/rustc_internal/mod.rs
+++ b/compiler/rustc_smir/src/rustc_internal/mod.rs
@@ -21,7 +21,7 @@ fn with_tables<R>(mut f: impl FnMut(&mut Tables<'_>) -> R) -> R {
 }
 
 pub fn item_def_id(item: &stable_mir::CrateItem) -> DefId {
-    with_tables(|t| t.item_def_id(item))
+    with_tables(|t| t[item.0])
 }
 
 pub fn crate_item(did: DefId) -> stable_mir::CrateItem {
@@ -78,22 +78,6 @@ impl<'tcx> Index<stable_mir::DefId> for Tables<'tcx> {
 }
 
 impl<'tcx> Tables<'tcx> {
-    pub fn item_def_id(&self, item: &stable_mir::CrateItem) -> DefId {
-        self[item.0]
-    }
-
-    pub fn trait_def_id(&self, trait_def: &stable_mir::ty::TraitDef) -> DefId {
-        self[trait_def.0]
-    }
-
-    pub fn impl_trait_def_id(&self, impl_def: &stable_mir::ty::ImplDef) -> DefId {
-        self[impl_def.0]
-    }
-
-    pub fn generic_def_id(&self, generic_def: &stable_mir::ty::GenericDef) -> DefId {
-        self[generic_def.0]
-    }
-
     pub fn crate_item(&mut self, did: DefId) -> stable_mir::CrateItem {
         stable_mir::CrateItem(self.create_def_id(did))
     }
diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs
index 0efd44dc4f026..4eb9eff48402e 100644
--- a/compiler/rustc_smir/src/rustc_smir/mod.rs
+++ b/compiler/rustc_smir/src/rustc_smir/mod.rs
@@ -54,7 +54,7 @@ impl<'tcx> Context for Tables<'tcx> {
     }
 
     fn trait_decl(&mut self, trait_def: &stable_mir::ty::TraitDef) -> stable_mir::ty::TraitDecl {
-        let def_id = self.trait_def_id(trait_def);
+        let def_id = self[trait_def.0];
         let trait_def = self.tcx.trait_def(def_id);
         trait_def.stable(self)
     }
@@ -68,13 +68,13 @@ impl<'tcx> Context for Tables<'tcx> {
     }
 
     fn trait_impl(&mut self, impl_def: &stable_mir::ty::ImplDef) -> stable_mir::ty::ImplTrait {
-        let def_id = self.impl_trait_def_id(impl_def);
+        let def_id = self[impl_def.0];
         let impl_trait = self.tcx.impl_trait_ref(def_id).unwrap();
         impl_trait.stable(self)
     }
 
     fn mir_body(&mut self, item: &stable_mir::CrateItem) -> stable_mir::mir::Body {
-        let def_id = self.item_def_id(item);
+        let def_id = self[item.0];
         let mir = self.tcx.optimized_mir(def_id);
         stable_mir::mir::Body {
             blocks: mir

From 0c301e9d3605b798bfbceb9dfd13bb0897d29d31 Mon Sep 17 00:00:00 2001
From: Santiago Pastorino <spastorino@gmail.com>
Date: Mon, 28 Aug 2023 17:39:17 -0300
Subject: [PATCH 08/12] Deduplicate GenericPredicates

---
 compiler/rustc_smir/src/rustc_smir/mod.rs | 4 ++--
 compiler/rustc_smir/src/stable_mir/mod.rs | 8 +-------
 compiler/rustc_smir/src/stable_mir/ty.rs  | 4 ++--
 3 files changed, 5 insertions(+), 11 deletions(-)

diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs
index 4eb9eff48402e..7877c91c2cf1a 100644
--- a/compiler/rustc_smir/src/rustc_smir/mod.rs
+++ b/compiler/rustc_smir/src/rustc_smir/mod.rs
@@ -108,10 +108,10 @@ impl<'tcx> Context for Tables<'tcx> {
         generics.stable(self)
     }
 
-    fn predicates_of(&mut self, def_id: stable_mir::DefId) -> stable_mir::GenericPredicates {
+    fn predicates_of(&mut self, def_id: stable_mir::DefId) -> stable_mir::ty::GenericPredicates {
         let def_id = self[def_id];
         let ty::GenericPredicates { parent, predicates } = self.tcx.predicates_of(def_id);
-        stable_mir::GenericPredicates {
+        stable_mir::ty::GenericPredicates {
             parent: parent.map(|did| self.trait_def(did)),
             predicates: predicates
                 .iter()
diff --git a/compiler/rustc_smir/src/stable_mir/mod.rs b/compiler/rustc_smir/src/stable_mir/mod.rs
index 0eee5cc91c7a3..a6a829fe81d06 100644
--- a/compiler/rustc_smir/src/stable_mir/mod.rs
+++ b/compiler/rustc_smir/src/stable_mir/mod.rs
@@ -16,7 +16,7 @@ use std::cell::Cell;
 use crate::rustc_smir::Tables;
 
 use self::ty::{
-    Generics, ImplDef, ImplTrait, PredicateKind, Span, TraitDecl, TraitDef, Ty, TyKind,
+    GenericPredicates, Generics, ImplDef, ImplTrait, Span, TraitDecl, TraitDef, Ty, TyKind,
 };
 
 pub mod mir;
@@ -41,12 +41,6 @@ pub type TraitDecls = Vec<TraitDef>;
 /// A list of impl trait decls.
 pub type ImplTraitDecls = Vec<ImplDef>;
 
-/// A list of predicates.
-pub struct GenericPredicates {
-    pub parent: Option<TraitDef>,
-    pub predicates: Vec<(PredicateKind, Span)>,
-}
-
 /// Holds information about a crate.
 #[derive(Clone, PartialEq, Eq, Debug)]
 pub struct Crate {
diff --git a/compiler/rustc_smir/src/stable_mir/ty.rs b/compiler/rustc_smir/src/stable_mir/ty.rs
index c73c6b3fd9f39..c1739e9c5ac04 100644
--- a/compiler/rustc_smir/src/stable_mir/ty.rs
+++ b/compiler/rustc_smir/src/stable_mir/ty.rs
@@ -499,8 +499,8 @@ pub struct GenericParamDef {
 }
 
 pub struct GenericPredicates {
-    pub parent: Option<DefId>,
-    pub predicates: Vec<PredicateKind>,
+    pub parent: Option<TraitDef>,
+    pub predicates: Vec<(PredicateKind, Span)>,
 }
 
 #[derive(Clone, Debug)]

From 079e3732cc5b605efdae115a83e1fd21bcdda459 Mon Sep 17 00:00:00 2001
From: Santiago Pastorino <spastorino@gmail.com>
Date: Mon, 28 Aug 2023 17:39:52 -0300
Subject: [PATCH 09/12] Implement generics_of and predicates_of only for
 TraitDecl for now

---
 compiler/rustc_smir/src/stable_mir/ty.rs | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/compiler/rustc_smir/src/stable_mir/ty.rs b/compiler/rustc_smir/src/stable_mir/ty.rs
index c1739e9c5ac04..197e12b1c4f5c 100644
--- a/compiler/rustc_smir/src/stable_mir/ty.rs
+++ b/compiler/rustc_smir/src/stable_mir/ty.rs
@@ -135,12 +135,6 @@ impl ImplDef {
     }
 }
 
-impl GenericDef {
-    pub fn generics_of(&self) -> Generics {
-        with(|cx| cx.generics_of(self.0))
-    }
-}
-
 #[derive(Clone, Debug)]
 pub struct GenericArgs(pub Vec<GenericArgKind>);
 
@@ -463,6 +457,16 @@ pub struct TraitDecl {
     pub deny_explicit_impl: bool,
 }
 
+impl TraitDecl {
+    pub fn generics_of(&self) -> Generics {
+        with(|cx| cx.generics_of(self.def_id.0))
+    }
+
+    pub fn predicates_of(&self) -> GenericPredicates {
+        with(|cx| cx.predicates_of(self.def_id.0))
+    }
+}
+
 pub type ImplTrait = EarlyBinder<TraitRef>;
 
 #[derive(Clone, Debug)]

From 5ab9616d03c27f755386a087bfc6f5971edb9137 Mon Sep 17 00:00:00 2001
From: Santiago Pastorino <spastorino@gmail.com>
Date: Mon, 28 Aug 2023 17:49:36 -0300
Subject: [PATCH 10/12] Call these methods from high level
 stable_mir::trait_decl(trait_def) and so on

---
 compiler/rustc_smir/src/stable_mir/ty.rs | 12 ------------
 1 file changed, 12 deletions(-)

diff --git a/compiler/rustc_smir/src/stable_mir/ty.rs b/compiler/rustc_smir/src/stable_mir/ty.rs
index 197e12b1c4f5c..fce5375f848f8 100644
--- a/compiler/rustc_smir/src/stable_mir/ty.rs
+++ b/compiler/rustc_smir/src/stable_mir/ty.rs
@@ -120,21 +120,9 @@ pub struct GenericDef(pub(crate) DefId);
 #[derive(Clone, Copy, PartialEq, Eq, Debug)]
 pub struct ConstDef(pub(crate) DefId);
 
-impl TraitDef {
-    pub fn trait_decl(&self) -> TraitDecl {
-        with(|cx| cx.trait_decl(self))
-    }
-}
-
 #[derive(Clone, PartialEq, Eq, Debug)]
 pub struct ImplDef(pub(crate) DefId);
 
-impl ImplDef {
-    pub fn trait_impl(&self) -> ImplTrait {
-        with(|cx| cx.trait_impl(self))
-    }
-}
-
 #[derive(Clone, Debug)]
 pub struct GenericArgs(pub Vec<GenericArgKind>);
 

From d1c4fe94c3b44c0469e66c942a364e9260040991 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Tue, 29 Aug 2023 14:09:41 +0200
Subject: [PATCH 11/12] some more is_zst that should be is_1zst

---
 compiler/rustc_hir_analysis/src/coherence/builtin.rs | 4 ++--
 compiler/rustc_lint/src/types.rs                     | 6 +++---
 compiler/rustc_ty_utils/src/abi.rs                   | 4 ++--
 compiler/rustc_ty_utils/src/layout.rs                | 2 +-
 4 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs
index c930537d4aee8..67aef0a7c4349 100644
--- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs
@@ -195,8 +195,8 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef
                     let ty_b = field.ty(tcx, args_b);
 
                     if let Ok(layout) = tcx.layout_of(param_env.and(ty_a)) {
-                        if layout.is_zst() && layout.align.abi.bytes() == 1 {
-                            // ignore ZST fields with alignment of 1 byte
+                        if layout.is_1zst() {
+                            // ignore 1-ZST fields
                             return false;
                         }
                     }
diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs
index 1ba746eddebd4..fc4c29eb36d61 100644
--- a/compiler/rustc_lint/src/types.rs
+++ b/compiler/rustc_lint/src/types.rs
@@ -804,7 +804,7 @@ pub(crate) fn nonnull_optimization_guaranteed<'tcx>(
     tcx.has_attr(def.did(), sym::rustc_nonnull_optimization_guaranteed)
 }
 
-/// `repr(transparent)` structs can have a single non-ZST field, this function returns that
+/// `repr(transparent)` structs can have a single non-1-ZST field, this function returns that
 /// field.
 pub fn transparent_newtype_field<'a, 'tcx>(
     tcx: TyCtxt<'tcx>,
@@ -813,8 +813,8 @@ pub fn transparent_newtype_field<'a, 'tcx>(
     let param_env = tcx.param_env(variant.def_id);
     variant.fields.iter().find(|field| {
         let field_ty = tcx.type_of(field.did).instantiate_identity();
-        let is_zst = tcx.layout_of(param_env.and(field_ty)).is_ok_and(|layout| layout.is_zst());
-        !is_zst
+        let is_1zst = tcx.layout_of(param_env.and(field_ty)).is_ok_and(|layout| layout.is_1zst());
+        !is_1zst
     })
 }
 
diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs
index a03da41652c4d..802391f1aadea 100644
--- a/compiler/rustc_ty_utils/src/abi.rs
+++ b/compiler/rustc_ty_utils/src/abi.rs
@@ -592,13 +592,13 @@ fn make_thin_self_ptr<'tcx>(
             for i in 0..fat_pointer_layout.fields.count() {
                 let field_layout = fat_pointer_layout.field(cx, i);
 
-                if !field_layout.is_zst() {
+                if !field_layout.is_1zst() {
                     fat_pointer_layout = field_layout;
                     continue 'descend_newtypes;
                 }
             }
 
-            bug!("receiver has no non-zero-sized fields {:?}", fat_pointer_layout);
+            bug!("receiver has no non-1-ZST fields {:?}", fat_pointer_layout);
         }
 
         fat_pointer_layout.ty
diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs
index 6b4273c03e4fa..ed7b3496894dd 100644
--- a/compiler/rustc_ty_utils/src/layout.rs
+++ b/compiler/rustc_ty_utils/src/layout.rs
@@ -192,7 +192,7 @@ fn layout_of_uncached<'tcx>(
 
                 let metadata_layout = cx.layout_of(metadata_ty)?;
                 // If the metadata is a 1-zst, then the pointer is thin.
-                if metadata_layout.is_zst() && metadata_layout.align.abi.bytes() == 1 {
+                if metadata_layout.is_1zst() {
                     return Ok(tcx.mk_layout(LayoutS::scalar(cx, data_ptr)));
                 }
 

From c2fe0bf25347cf85205b928d132ac13d8de1c354 Mon Sep 17 00:00:00 2001
From: ouz-a <ouz.agz@gmail.com>
Date: Thu, 24 Aug 2023 21:36:00 +0300
Subject: [PATCH 12/12] Create StableMir replacer for SMirCalls

---
 Cargo.lock                                    |  3 ++
 compiler/rustc_smir/Cargo.toml                |  6 +++
 compiler/rustc_smir/src/rustc_internal/mod.rs | 41 +++++++++++++++++++
 compiler/rustc_smir/src/stable_mir/mod.rs     |  3 +-
 tests/ui-fulldeps/stable-mir/crate-info.rs    | 34 ++-------------
 5 files changed, 54 insertions(+), 33 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index 7337901bc3a59..f47c84c6b6411 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -4251,8 +4251,11 @@ dependencies = [
 name = "rustc_smir"
 version = "0.0.0"
 dependencies = [
+ "rustc_driver",
  "rustc_hir",
+ "rustc_interface",
  "rustc_middle",
+ "rustc_session",
  "rustc_span",
  "rustc_target",
  "scoped-tls",
diff --git a/compiler/rustc_smir/Cargo.toml b/compiler/rustc_smir/Cargo.toml
index 80d4e7ed02fe2..21ec904e43c58 100644
--- a/compiler/rustc_smir/Cargo.toml
+++ b/compiler/rustc_smir/Cargo.toml
@@ -9,6 +9,9 @@ rustc_hir = { path = "../rustc_hir", optional = true }
 rustc_middle = { path = "../rustc_middle", optional = true }
 rustc_span = { path = "../rustc_span", optional = true }
 rustc_target = { path = "../rustc_target", optional = true }
+rustc_driver = { path = "../rustc_driver", optional = true }
+rustc_interface = { path = "../rustc_interface", optional = true}
+rustc_session = {path = "../rustc_session", optional = true}
 tracing = "0.1"
 scoped-tls = "1.0"
 
@@ -18,4 +21,7 @@ default = [
     "rustc_middle",
     "rustc_span",
     "rustc_target",
+    "rustc_driver",
+    "rustc_interface",
+    "rustc_session",
 ]
diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs
index ebacb7cce836a..4385d3f51edc0 100644
--- a/compiler/rustc_smir/src/rustc_internal/mod.rs
+++ b/compiler/rustc_smir/src/rustc_internal/mod.rs
@@ -6,11 +6,15 @@
 use std::fmt::Debug;
 use std::string::ToString;
 
+use crate::rustc_internal;
 use crate::{
     rustc_smir::Tables,
     stable_mir::{self, with},
 };
+use rustc_driver::{Callbacks, Compilation, RunCompiler};
+use rustc_interface::{interface, Queries};
 use rustc_middle::ty::TyCtxt;
+use rustc_session::EarlyErrorHandler;
 pub use rustc_span::def_id::{CrateNum, DefId};
 
 fn with_tables<R>(mut f: impl FnMut(&mut Tables<'_>) -> R) -> R {
@@ -163,3 +167,40 @@ pub type Opaque = impl Debug + ToString + Clone;
 pub(crate) fn opaque<T: Debug>(value: &T) -> Opaque {
     format!("{value:?}")
 }
+
+pub struct StableMir {
+    args: Vec<String>,
+    callback: fn(TyCtxt<'_>),
+}
+
+impl StableMir {
+    /// Creates a new `StableMir` instance, with given test_function and arguments.
+    pub fn new(args: Vec<String>, callback: fn(TyCtxt<'_>)) -> Self {
+        StableMir { args, callback }
+    }
+
+    /// Runs the compiler against given target and tests it with `test_function`
+    pub fn run(&mut self) {
+        rustc_driver::catch_fatal_errors(|| {
+            RunCompiler::new(&self.args.clone(), self).run().unwrap();
+        })
+        .unwrap();
+    }
+}
+
+impl Callbacks for StableMir {
+    /// Called after analysis. Return value instructs the compiler whether to
+    /// continue the compilation afterwards (defaults to `Compilation::Continue`)
+    fn after_analysis<'tcx>(
+        &mut self,
+        _handler: &EarlyErrorHandler,
+        _compiler: &interface::Compiler,
+        queries: &'tcx Queries<'tcx>,
+    ) -> Compilation {
+        queries.global_ctxt().unwrap().enter(|tcx| {
+            rustc_internal::run(tcx, || (self.callback)(tcx));
+        });
+        // No need to keep going.
+        Compilation::Stop
+    }
+}
diff --git a/compiler/rustc_smir/src/stable_mir/mod.rs b/compiler/rustc_smir/src/stable_mir/mod.rs
index 44938eaa03538..9a2c5b2c7c13c 100644
--- a/compiler/rustc_smir/src/stable_mir/mod.rs
+++ b/compiler/rustc_smir/src/stable_mir/mod.rs
@@ -13,11 +13,10 @@
 
 use std::cell::Cell;
 
-use crate::rustc_smir::Tables;
-
 use self::ty::{
     GenericDef, Generics, ImplDef, ImplTrait, PredicateKind, Span, TraitDecl, TraitDef, Ty, TyKind,
 };
+use crate::rustc_smir::Tables;
 
 pub mod mir;
 pub mod ty;
diff --git a/tests/ui-fulldeps/stable-mir/crate-info.rs b/tests/ui-fulldeps/stable-mir/crate-info.rs
index f55d7d599f1e4..00dce3e004e63 100644
--- a/tests/ui-fulldeps/stable-mir/crate-info.rs
+++ b/tests/ui-fulldeps/stable-mir/crate-info.rs
@@ -9,18 +9,12 @@
 #![feature(rustc_private)]
 #![feature(assert_matches)]
 
-extern crate rustc_driver;
 extern crate rustc_hir;
-extern crate rustc_interface;
 extern crate rustc_middle;
-extern crate rustc_session;
 extern crate rustc_smir;
 
-use rustc_driver::{Callbacks, Compilation, RunCompiler};
 use rustc_hir::def::DefKind;
-use rustc_interface::{interface, Queries};
 use rustc_middle::ty::TyCtxt;
-use rustc_session::EarlyErrorHandler;
 use rustc_smir::{rustc_internal, stable_mir};
 use std::assert_matches::assert_matches;
 use std::io::Write;
@@ -130,8 +124,8 @@ fn get_item<'a>(
 
 /// This test will generate and analyze a dummy crate using the stable mir.
 /// For that, it will first write the dummy crate into a file.
-/// It will invoke the compiler using a custom Callback implementation, which will
-/// invoke Stable MIR APIs after the compiler has finished its analysis.
+/// Then it will create a `StableMir` using custom arguments and then
+/// it will run the compiler.
 fn main() {
     let path = "input.rs";
     generate_input(&path).unwrap();
@@ -142,29 +136,7 @@ fn main() {
         CRATE_NAME.to_string(),
         path.to_string(),
     ];
-    rustc_driver::catch_fatal_errors(|| {
-        RunCompiler::new(&args, &mut SMirCalls {}).run().unwrap();
-    })
-    .unwrap();
-}
-
-struct SMirCalls {}
-
-impl Callbacks for SMirCalls {
-    /// Called after analysis. Return value instructs the compiler whether to
-    /// continue the compilation afterwards (defaults to `Compilation::Continue`)
-    fn after_analysis<'tcx>(
-        &mut self,
-        _handler: &EarlyErrorHandler,
-        _compiler: &interface::Compiler,
-        queries: &'tcx Queries<'tcx>,
-    ) -> Compilation {
-        queries.global_ctxt().unwrap().enter(|tcx| {
-            rustc_smir::rustc_internal::run(tcx, || test_stable_mir(tcx));
-        });
-        // No need to keep going.
-        Compilation::Stop
-    }
+    rustc_internal::StableMir::new(args, test_stable_mir).run();
 }
 
 fn generate_input(path: &str) -> std::io::Result<()> {