From ba2f14e065ef4a798b23fad8b786616e79c59dd5 Mon Sep 17 00:00:00 2001
From: Chase Wilson <me@chasewilson.dev>
Date: Sat, 4 Jun 2022 12:33:01 -0500
Subject: [PATCH 01/11] Fixed premature assertions that caused -Z
 randomize-layout to fail on alloc

---
 compiler/rustc_codegen_ssa/src/base.rs | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs
index 420adec456f61..ecb7863304d69 100644
--- a/compiler/rustc_codegen_ssa/src/base.rs
+++ b/compiler/rustc_codegen_ssa/src/base.rs
@@ -216,11 +216,12 @@ pub fn unsize_ptr<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
             let mut result = None;
             for i in 0..src_layout.fields.count() {
                 let src_f = src_layout.field(bx.cx(), i);
-                assert_eq!(src_layout.fields.offset(i).bytes(), 0);
-                assert_eq!(dst_layout.fields.offset(i).bytes(), 0);
                 if src_f.is_zst() {
                     continue;
                 }
+
+                assert_eq!(src_layout.fields.offset(i).bytes(), 0);
+                assert_eq!(dst_layout.fields.offset(i).bytes(), 0);
                 assert_eq!(src_layout.size, src_f.size);
 
                 let dst_f = dst_layout.field(bx.cx(), i);

From 857453d36c5b396d2009e08b38b672695c5cddba Mon Sep 17 00:00:00 2001
From: Chase Wilson <me@chasewilson.dev>
Date: Sat, 4 Jun 2022 13:33:56 -0500
Subject: [PATCH 02/11] Added test for #97732

---
 src/test/ui/unsized/issue-97732.rs | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)
 create mode 100644 src/test/ui/unsized/issue-97732.rs

diff --git a/src/test/ui/unsized/issue-97732.rs b/src/test/ui/unsized/issue-97732.rs
new file mode 100644
index 0000000000000..172f0724d4263
--- /dev/null
+++ b/src/test/ui/unsized/issue-97732.rs
@@ -0,0 +1,23 @@
+// check-pass
+
+#![feature(coerce_unsized)]
+
+// Ensure that unsizing structs that contain ZSTs at non-zero offsets don't ICE
+
+use std::ops::CoerceUnsized;
+
+#[repr(C)]
+pub struct BoxWithZstTail<T: ?Sized>(Box<T>, ());
+
+impl<S: ?Sized, T: ?Sized> CoerceUnsized<BoxWithZstTail<T>> for BoxWithZstTail<S> where
+    Box<S>: CoerceUnsized<Box<T>>
+{
+}
+
+pub fn noop_dyn_upcast_with_zst_tail(
+    b: BoxWithZstTail<dyn Send + Sync>,
+) -> BoxWithZstTail<dyn Send> {
+    b
+}
+
+fn main() {}

From f3d93b6c625a0837cd6f2bedc713436e56856b5d Mon Sep 17 00:00:00 2001
From: cole <cole@swift-mail.com>
Date: Sat, 4 Jun 2022 17:05:33 -0500
Subject: [PATCH 03/11] Allow unstable items to be re-exported unstably without
 requiring the feature be enabled

---
 compiler/rustc_middle/src/middle/stability.rs | 77 +++++++++++++++++--
 compiler/rustc_passes/src/stability.rs        | 40 +++++++++-
 compiler/rustc_typeck/src/astconv/mod.rs      |  2 +
 .../allow-unstable-reexport.rs                | 30 ++++++++
 .../allow-unstable-reexport.stderr            | 27 +++++++
 .../auxiliary/lint-stability-reexport.rs      |  9 +++
 6 files changed, 174 insertions(+), 11 deletions(-)
 create mode 100644 src/test/ui/stability-attribute/allow-unstable-reexport.rs
 create mode 100644 src/test/ui/stability-attribute/allow-unstable-reexport.stderr
 create mode 100644 src/test/ui/stability-attribute/auxiliary/lint-stability-reexport.rs

diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs
index 8b11e35a7c3f7..62e0fec06615e 100644
--- a/compiler/rustc_middle/src/middle/stability.rs
+++ b/compiler/rustc_middle/src/middle/stability.rs
@@ -9,10 +9,9 @@ use rustc_attr::{self as attr, ConstStability, Deprecation, Stability};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::{Applicability, Diagnostic};
 use rustc_feature::GateIssue;
-use rustc_hir as hir;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{DefId, LocalDefId};
-use rustc_hir::{self, HirId};
+use rustc_hir::{self as hir, HirId};
 use rustc_middle::ty::print::with_no_trimmed_paths;
 use rustc_session::lint::builtin::{DEPRECATED, DEPRECATED_IN_FUTURE, SOFT_UNSTABLE};
 use rustc_session::lint::{BuiltinLintDiagnostics, Level, Lint, LintBuffer};
@@ -306,6 +305,14 @@ fn suggestion_for_allocator_api(
     None
 }
 
+/// An override option for eval_stability.
+pub enum AllowUnstable {
+    /// Don't emit an unstable error for the item
+    Yes,
+    /// Handle the item normally
+    No,
+}
+
 impl<'tcx> TyCtxt<'tcx> {
     /// Evaluates the stability of an item.
     ///
@@ -322,6 +329,28 @@ impl<'tcx> TyCtxt<'tcx> {
         id: Option<HirId>,
         span: Span,
         method_span: Option<Span>,
+    ) -> EvalResult {
+        self.eval_stability_allow_unstable(def_id, id, span, method_span, AllowUnstable::No)
+    }
+
+    /// Evaluates the stability of an item.
+    ///
+    /// Returns `EvalResult::Allow` if the item is stable, or unstable but the corresponding
+    /// `#![feature]` has been provided. Returns `EvalResult::Deny` which describes the offending
+    /// unstable feature otherwise.
+    ///
+    /// If `id` is `Some(_)`, this function will also check if the item at `def_id` has been
+    /// deprecated. If the item is indeed deprecated, we will emit a deprecation lint attached to
+    /// `id`.
+    ///
+    /// Pass `AllowUnstable::Yes` to `allow_unstable` to force an unstable item to be allowed. Deprecation warnings will be emitted normally.
+    pub fn eval_stability_allow_unstable(
+        self,
+        def_id: DefId,
+        id: Option<HirId>,
+        span: Span,
+        method_span: Option<Span>,
+        allow_unstable: AllowUnstable,
     ) -> EvalResult {
         // Deprecated attributes apply in-crate and cross-crate.
         if let Some(id) = id {
@@ -419,6 +448,10 @@ impl<'tcx> TyCtxt<'tcx> {
                     }
                 }
 
+                if matches!(allow_unstable, AllowUnstable::Yes) {
+                    return EvalResult::Allow;
+                }
+
                 let suggestion = suggestion_for_allocator_api(self, def_id, span, feature);
                 EvalResult::Deny { feature, reason, issue, suggestion, is_soft }
             }
@@ -445,11 +478,38 @@ impl<'tcx> TyCtxt<'tcx> {
         span: Span,
         method_span: Option<Span>,
     ) {
-        self.check_optional_stability(def_id, id, span, method_span, |span, def_id| {
-            // The API could be uncallable for other reasons, for example when a private module
-            // was referenced.
-            self.sess.delay_span_bug(span, &format!("encountered unmarked API: {:?}", def_id));
-        })
+        self.check_stability_allow_unstable(def_id, id, span, method_span, AllowUnstable::No)
+    }
+
+    /// Checks if an item is stable or error out.
+    ///
+    /// If the item defined by `def_id` is unstable and the corresponding `#![feature]` does not
+    /// exist, emits an error.
+    ///
+    /// This function will also check if the item is deprecated.
+    /// If so, and `id` is not `None`, a deprecated lint attached to `id` will be emitted.
+    ///
+    /// Pass `AllowUnstable::Yes` to `allow_unstable` to force an unstable item to be allowed. Deprecation warnings will be emitted normally.
+    pub fn check_stability_allow_unstable(
+        self,
+        def_id: DefId,
+        id: Option<HirId>,
+        span: Span,
+        method_span: Option<Span>,
+        allow_unstable: AllowUnstable,
+    ) {
+        self.check_optional_stability(
+            def_id,
+            id,
+            span,
+            method_span,
+            allow_unstable,
+            |span, def_id| {
+                // The API could be uncallable for other reasons, for example when a private module
+                // was referenced.
+                self.sess.delay_span_bug(span, &format!("encountered unmarked API: {:?}", def_id));
+            },
+        )
     }
 
     /// Like `check_stability`, except that we permit items to have custom behaviour for
@@ -462,6 +522,7 @@ impl<'tcx> TyCtxt<'tcx> {
         id: Option<HirId>,
         span: Span,
         method_span: Option<Span>,
+        allow_unstable: AllowUnstable,
         unmarked: impl FnOnce(Span, DefId),
     ) {
         let soft_handler = |lint, span, msg: &_| {
@@ -469,7 +530,7 @@ impl<'tcx> TyCtxt<'tcx> {
                 lint.build(msg).emit();
             })
         };
-        match self.eval_stability(def_id, id, span, method_span) {
+        match self.eval_stability_allow_unstable(def_id, id, span, method_span, allow_unstable) {
             EvalResult::Allow => {}
             EvalResult::Deny { feature, reason, issue, suggestion, is_soft } => report_unstable(
                 self.sess,
diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs
index 70cb1f2a281a8..144a60faad265 100644
--- a/compiler/rustc_passes/src/stability.rs
+++ b/compiler/rustc_passes/src/stability.rs
@@ -9,10 +9,10 @@ use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID};
 use rustc_hir::hir_id::CRATE_HIR_ID;
 use rustc_hir::intravisit::{self, Visitor};
-use rustc_hir::{FieldDef, Generics, HirId, Item, TraitRef, Ty, TyKind, Variant};
+use rustc_hir::{FieldDef, Generics, HirId, Item, ItemKind, TraitRef, Ty, TyKind, Variant};
 use rustc_middle::hir::nested_filter;
 use rustc_middle::middle::privacy::AccessLevels;
-use rustc_middle::middle::stability::{DeprecationEntry, Index};
+use rustc_middle::middle::stability::{AllowUnstable, DeprecationEntry, Index};
 use rustc_middle::ty::{self, query::Providers, TyCtxt};
 use rustc_session::lint;
 use rustc_session::lint::builtin::{INEFFECTIVE_UNSTABLE_TRAIT_IMPL, USELESS_DEPRECATED};
@@ -807,12 +807,46 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
     fn visit_path(&mut self, path: &'tcx hir::Path<'tcx>, id: hir::HirId) {
         if let Some(def_id) = path.res.opt_def_id() {
             let method_span = path.segments.last().map(|s| s.ident.span);
-            self.tcx.check_stability(def_id, Some(id), path.span, method_span)
+            self.tcx.check_stability_allow_unstable(
+                def_id,
+                Some(id),
+                path.span,
+                method_span,
+                if is_unstable_reexport(self.tcx, id) {
+                    AllowUnstable::Yes
+                } else {
+                    AllowUnstable::No
+                },
+            )
         }
         intravisit::walk_path(self, path)
     }
 }
 
+/// Check whether a path is a `use` item that has been marked as unstable.
+///
+/// See issue #94972 for details on why this is a special case
+fn is_unstable_reexport<'tcx>(tcx: TyCtxt<'tcx>, id: hir::HirId) -> bool {
+    // Get the LocalDefId so we can lookup the item to check the kind.
+    let Some(def_id) = tcx.hir().opt_local_def_id(id) else { return false; };
+
+    let Some(stab) = tcx.stability().local_stability(def_id) else {
+        return false;
+    };
+
+    if stab.level.is_stable() {
+        // The re-export is not marked as unstable, don't override
+        return false;
+    }
+
+    // If this is a path that isn't a use, we don't need to do anything special
+    if !matches!(tcx.hir().item(hir::ItemId { def_id }).kind, ItemKind::Use(..)) {
+        return false;
+    }
+
+    true
+}
+
 struct CheckTraitImplStable<'tcx> {
     tcx: TyCtxt<'tcx>,
     fully_stable: bool,
diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs
index 96d083bb94f3c..18a1cab76d98e 100644
--- a/compiler/rustc_typeck/src/astconv/mod.rs
+++ b/compiler/rustc_typeck/src/astconv/mod.rs
@@ -24,6 +24,7 @@ use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_hir::intravisit::{walk_generics, Visitor as _};
 use rustc_hir::lang_items::LangItem;
 use rustc_hir::{GenericArg, GenericArgs};
+use rustc_middle::middle::stability::AllowUnstable;
 use rustc_middle::ty::subst::{self, GenericArgKind, InternalSubsts, Subst, SubstsRef};
 use rustc_middle::ty::GenericParamDefKind;
 use rustc_middle::ty::{self, Const, DefIdTree, EarlyBinder, Ty, TyCtxt, TypeFoldable};
@@ -426,6 +427,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                             Some(arg.id()),
                             arg.span(),
                             None,
+                            AllowUnstable::No,
                             |_, _| {
                                 // Default generic parameters may not be marked
                                 // with stability attributes, i.e. when the
diff --git a/src/test/ui/stability-attribute/allow-unstable-reexport.rs b/src/test/ui/stability-attribute/allow-unstable-reexport.rs
new file mode 100644
index 0000000000000..937913954a791
--- /dev/null
+++ b/src/test/ui/stability-attribute/allow-unstable-reexport.rs
@@ -0,0 +1,30 @@
+// Allow an unstable re-export without requiring a feature gate.
+// #94972
+
+// aux-build:lint-stability.rs
+// aux-build:lint-stability-reexport.rs
+#![feature(staged_api)]
+#![stable(feature = "lint_stability", since = "1.0.0")]
+
+extern crate lint_stability;
+extern crate lint_stability_reexport;
+
+#[unstable(feature = "unstable_test_feature", issue = "none")]
+pub use lint_stability::unstable;
+
+// We want to confirm that using a re-export through another crate behaves
+// the same way as using an item directly
+#[unstable(feature = "unstable_test_feature", issue = "none")]
+pub use lint_stability_reexport::unstable_text;
+
+// Ensure items which aren't marked as unstable can't re-export unstable items
+#[stable(feature = "lint_stability", since = "1.0.0")]
+pub use lint_stability::unstable as unstable2;
+//~^ ERROR use of unstable library feature 'unstable_test_feature'
+
+fn main() {
+    // Since we didn't enable the feature in this crate, we still can't
+    // use these items, even though they're in scope from the `use`s which are now allowed.
+    unstable(); //~ ERROR use of unstable library feature 'unstable_test_feature'
+    unstable_text(); //~ ERROR use of unstable library feature 'unstable_test_feature'
+}
diff --git a/src/test/ui/stability-attribute/allow-unstable-reexport.stderr b/src/test/ui/stability-attribute/allow-unstable-reexport.stderr
new file mode 100644
index 0000000000000..a11da9dc8a7be
--- /dev/null
+++ b/src/test/ui/stability-attribute/allow-unstable-reexport.stderr
@@ -0,0 +1,27 @@
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+  --> $DIR/allow-unstable-reexport.rs:22:9
+   |
+LL | pub use lint_stability::unstable as unstable2;
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+  --> $DIR/allow-unstable-reexport.rs:28:5
+   |
+LL |     unstable();
+   |     ^^^^^^^^
+   |
+   = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature': text
+  --> $DIR/allow-unstable-reexport.rs:29:5
+   |
+LL |     unstable_text();
+   |     ^^^^^^^^^^^^^
+   |
+   = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/stability-attribute/auxiliary/lint-stability-reexport.rs b/src/test/ui/stability-attribute/auxiliary/lint-stability-reexport.rs
new file mode 100644
index 0000000000000..9884731d562e9
--- /dev/null
+++ b/src/test/ui/stability-attribute/auxiliary/lint-stability-reexport.rs
@@ -0,0 +1,9 @@
+#![crate_type = "lib"]
+#![feature(staged_api)]
+#![stable(feature = "lint_stability", since = "1.0.0")]
+
+extern crate lint_stability;
+
+// Re-exporting without enabling the feature "unstable_test_feature" in this crate
+#[unstable(feature = "unstable_test_feature", issue = "none")]
+pub use lint_stability::unstable_text;

From fac5cbc2f59df4cf881e9117d271750c274cb4c0 Mon Sep 17 00:00:00 2001
From: Ryan Zoeller <rtzoeller@rtzoeller.com>
Date: Sun, 5 Jun 2022 15:14:18 -0500
Subject: [PATCH 04/11] Remove SIGIO reference on Haiku

Haiku doesn't define SIGIO. The nix crate already employs this workaround:
https://github.com/nix-rust/nix/blob/5dedbc7850448ae3922ab0a833f3eb971bf7e25f/src/sys/signal.rs#L92-L94
---
 library/std/src/sys/unix/process/process_unix.rs | 1 +
 1 file changed, 1 insertion(+)

diff --git a/library/std/src/sys/unix/process/process_unix.rs b/library/std/src/sys/unix/process/process_unix.rs
index ef29aa3c89078..75bb92437fd92 100644
--- a/library/std/src/sys/unix/process/process_unix.rs
+++ b/library/std/src/sys/unix/process/process_unix.rs
@@ -730,6 +730,7 @@ fn signal_string(signal: i32) -> &'static str {
         libc::SIGVTALRM => " (SIGVTALRM)",
         libc::SIGPROF => " (SIGPROF)",
         libc::SIGWINCH => " (SIGWINCH)",
+        #[cfg(not(target_os = "haiku"))]
         libc::SIGIO => " (SIGIO)",
         libc::SIGSYS => " (SIGSYS)",
         // For information on Linux signals, run `man 7 signal`

From 85136dbe56dbbd7cdbcb27886a03807ea265ecd1 Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Fri, 13 May 2022 10:29:35 +0000
Subject: [PATCH 05/11] Remove unnecessary cgu name length hash

This is a tiny optimization
---
 compiler/rustc_query_system/src/dep_graph/dep_node.rs | 1 -
 1 file changed, 1 deletion(-)

diff --git a/compiler/rustc_query_system/src/dep_graph/dep_node.rs b/compiler/rustc_query_system/src/dep_graph/dep_node.rs
index c274c2cc26c15..bb2179a24953b 100644
--- a/compiler/rustc_query_system/src/dep_graph/dep_node.rs
+++ b/compiler/rustc_query_system/src/dep_graph/dep_node.rs
@@ -164,7 +164,6 @@ pub struct WorkProductId {
 impl WorkProductId {
     pub fn from_cgu_name(cgu_name: &str) -> WorkProductId {
         let mut hasher = StableHasher::new();
-        cgu_name.len().hash(&mut hasher);
         cgu_name.hash(&mut hasher);
         WorkProductId { hash: hasher.finish() }
     }

From 02162c4163f5d1a0e3dc8b552aafaa92d652b279 Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Fri, 13 May 2022 10:32:03 +0000
Subject: [PATCH 06/11] Rename CodegenUnit::work_product to
 previous_work_product

It returns the previous work product or panics if there is none. This rename
makes the purpose of this method clearer.
---
 compiler/rustc_codegen_cranelift/src/driver/aot.rs | 2 +-
 compiler/rustc_codegen_ssa/src/base.rs             | 4 ++--
 compiler/rustc_middle/src/mir/mono.rs              | 2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/compiler/rustc_codegen_cranelift/src/driver/aot.rs b/compiler/rustc_codegen_cranelift/src/driver/aot.rs
index 5e1e1c81d26ea..0faf1221c8399 100644
--- a/compiler/rustc_codegen_cranelift/src/driver/aot.rs
+++ b/compiler/rustc_codegen_cranelift/src/driver/aot.rs
@@ -85,7 +85,7 @@ fn reuse_workproduct_for_cgu(
     work_products: &mut FxHashMap<WorkProductId, WorkProduct>,
 ) -> CompiledModule {
     let mut object = None;
-    let work_product = cgu.work_product(tcx);
+    let work_product = cgu.previous_work_product(tcx);
     if let Some(saved_file) = &work_product.saved_file {
         let obj_out =
             tcx.output_filenames(()).temp_path(OutputType::Object, Some(cgu.name().as_str()));
diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs
index 420adec456f61..c52a908e90f45 100644
--- a/compiler/rustc_codegen_ssa/src/base.rs
+++ b/compiler/rustc_codegen_ssa/src/base.rs
@@ -716,7 +716,7 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
                     &ongoing_codegen.coordinator_send,
                     CachedModuleCodegen {
                         name: cgu.name().to_string(),
-                        source: cgu.work_product(tcx),
+                        source: cgu.previous_work_product(tcx),
                     },
                 );
                 true
@@ -727,7 +727,7 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
                     &ongoing_codegen.coordinator_send,
                     CachedModuleCodegen {
                         name: cgu.name().to_string(),
-                        source: cgu.work_product(tcx),
+                        source: cgu.previous_work_product(tcx),
                     },
                 );
                 true
diff --git a/compiler/rustc_middle/src/mir/mono.rs b/compiler/rustc_middle/src/mir/mono.rs
index d389fa8c0ebdd..021f278273646 100644
--- a/compiler/rustc_middle/src/mir/mono.rs
+++ b/compiler/rustc_middle/src/mir/mono.rs
@@ -336,7 +336,7 @@ impl<'tcx> CodegenUnit<'tcx> {
         WorkProductId::from_cgu_name(self.name().as_str())
     }
 
-    pub fn work_product(&self, tcx: TyCtxt<'_>) -> WorkProduct {
+    pub fn previous_work_product(&self, tcx: TyCtxt<'_>) -> WorkProduct {
         let work_product_id = self.work_product_id();
         tcx.dep_graph
             .previous_work_product(&work_product_id)

From 065e202b563b7f690b7cc79b8fb5a61150c2976e Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Fri, 13 May 2022 12:18:13 +0000
Subject: [PATCH 07/11] Avoid an unnecessary clone for
 copy_cgu_workproduct_to_incr_comp_cache_dir calls

---
 compiler/rustc_codegen_cranelift/src/driver/aot.rs     | 2 +-
 compiler/rustc_codegen_ssa/src/back/write.rs           | 4 ++--
 compiler/rustc_incremental/src/persist/work_product.rs | 4 ++--
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/compiler/rustc_codegen_cranelift/src/driver/aot.rs b/compiler/rustc_codegen_cranelift/src/driver/aot.rs
index 0faf1221c8399..ef8fc14a5a00b 100644
--- a/compiler/rustc_codegen_cranelift/src/driver/aot.rs
+++ b/compiler/rustc_codegen_cranelift/src/driver/aot.rs
@@ -69,7 +69,7 @@ fn emit_module(
         rustc_incremental::copy_cgu_workproduct_to_incr_comp_cache_dir(
             tcx.sess,
             &name,
-            &Some(tmp_file.clone()),
+            Some(&tmp_file),
         )
     };
 
diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs
index 88293dec01cac..7cd062e5e4bea 100644
--- a/compiler/rustc_codegen_ssa/src/back/write.rs
+++ b/compiler/rustc_codegen_ssa/src/back/write.rs
@@ -494,10 +494,10 @@ fn copy_all_cgu_workproducts_to_incr_comp_cache_dir(
     let _timer = sess.timer("copy_all_cgu_workproducts_to_incr_comp_cache_dir");
 
     for module in compiled_modules.modules.iter().filter(|m| m.kind == ModuleKind::Regular) {
-        let path = module.object.as_ref().cloned();
+        let path = module.object.as_deref();
 
         if let Some((id, product)) =
-            copy_cgu_workproduct_to_incr_comp_cache_dir(sess, &module.name, &path)
+            copy_cgu_workproduct_to_incr_comp_cache_dir(sess, &module.name, path)
         {
             work_products.insert(id, product);
         }
diff --git a/compiler/rustc_incremental/src/persist/work_product.rs b/compiler/rustc_incremental/src/persist/work_product.rs
index 85b44ed753192..54b06e56d2418 100644
--- a/compiler/rustc_incremental/src/persist/work_product.rs
+++ b/compiler/rustc_incremental/src/persist/work_product.rs
@@ -7,13 +7,13 @@ use rustc_fs_util::link_or_copy;
 use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
 use rustc_session::Session;
 use std::fs as std_fs;
-use std::path::PathBuf;
+use std::path::Path;
 
 /// Copies a CGU work product to the incremental compilation directory, so next compilation can find and reuse it.
 pub fn copy_cgu_workproduct_to_incr_comp_cache_dir(
     sess: &Session,
     cgu_name: &str,
-    path: &Option<PathBuf>,
+    path: Option<&Path>,
 ) -> Option<(WorkProductId, WorkProduct)> {
     debug!("copy_cgu_workproduct_to_incr_comp_cache_dir({:?},{:?})", cgu_name, path);
     sess.opts.incremental.as_ref()?;

From 906b85157cc7928d86fd186a255f3fd89543aca8 Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Fri, 13 May 2022 12:20:32 +0000
Subject: [PATCH 08/11] Factor Option out of
 copy_cgu_workproduct_to_incr_comp_cache_dir call

This improves clarity of the code a bit
---
 .../rustc_codegen_cranelift/src/driver/aot.rs |  6 +---
 compiler/rustc_codegen_ssa/src/back/write.rs  | 12 ++++----
 .../src/persist/work_product.rs               | 30 ++++++++-----------
 3 files changed, 20 insertions(+), 28 deletions(-)

diff --git a/compiler/rustc_codegen_cranelift/src/driver/aot.rs b/compiler/rustc_codegen_cranelift/src/driver/aot.rs
index ef8fc14a5a00b..b652b58cb65a8 100644
--- a/compiler/rustc_codegen_cranelift/src/driver/aot.rs
+++ b/compiler/rustc_codegen_cranelift/src/driver/aot.rs
@@ -66,11 +66,7 @@ fn emit_module(
     let work_product = if backend_config.disable_incr_cache {
         None
     } else {
-        rustc_incremental::copy_cgu_workproduct_to_incr_comp_cache_dir(
-            tcx.sess,
-            &name,
-            Some(&tmp_file),
-        )
+        rustc_incremental::copy_cgu_workproduct_to_incr_comp_cache_dir(tcx.sess, &name, &tmp_file)
     };
 
     ModuleCodegenResult(
diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs
index 7cd062e5e4bea..36e5906652412 100644
--- a/compiler/rustc_codegen_ssa/src/back/write.rs
+++ b/compiler/rustc_codegen_ssa/src/back/write.rs
@@ -494,12 +494,12 @@ fn copy_all_cgu_workproducts_to_incr_comp_cache_dir(
     let _timer = sess.timer("copy_all_cgu_workproducts_to_incr_comp_cache_dir");
 
     for module in compiled_modules.modules.iter().filter(|m| m.kind == ModuleKind::Regular) {
-        let path = module.object.as_deref();
-
-        if let Some((id, product)) =
-            copy_cgu_workproduct_to_incr_comp_cache_dir(sess, &module.name, path)
-        {
-            work_products.insert(id, product);
+        if let Some(path) = &module.object {
+            if let Some((id, product)) =
+                copy_cgu_workproduct_to_incr_comp_cache_dir(sess, &module.name, path)
+            {
+                work_products.insert(id, product);
+            }
         }
     }
 
diff --git a/compiler/rustc_incremental/src/persist/work_product.rs b/compiler/rustc_incremental/src/persist/work_product.rs
index 54b06e56d2418..2d5cbc28d6eac 100644
--- a/compiler/rustc_incremental/src/persist/work_product.rs
+++ b/compiler/rustc_incremental/src/persist/work_product.rs
@@ -13,28 +13,24 @@ use std::path::Path;
 pub fn copy_cgu_workproduct_to_incr_comp_cache_dir(
     sess: &Session,
     cgu_name: &str,
-    path: Option<&Path>,
+    path: &Path,
 ) -> Option<(WorkProductId, WorkProduct)> {
     debug!("copy_cgu_workproduct_to_incr_comp_cache_dir({:?},{:?})", cgu_name, path);
     sess.opts.incremental.as_ref()?;
 
-    let saved_file = if let Some(path) = path {
-        let file_name = format!("{}.o", cgu_name);
-        let path_in_incr_dir = in_incr_comp_dir_sess(sess, &file_name);
-        match link_or_copy(path, &path_in_incr_dir) {
-            Ok(_) => Some(file_name),
-            Err(err) => {
-                sess.warn(&format!(
-                    "error copying object file `{}` to incremental directory as `{}`: {}",
-                    path.display(),
-                    path_in_incr_dir.display(),
-                    err
-                ));
-                return None;
-            }
+    let file_name = format!("{}.o", cgu_name);
+    let path_in_incr_dir = in_incr_comp_dir_sess(sess, &file_name);
+    let saved_file = match link_or_copy(path, &path_in_incr_dir) {
+        Ok(_) => Some(file_name),
+        Err(err) => {
+            sess.warn(&format!(
+                "error copying object file `{}` to incremental directory as `{}`: {}",
+                path.display(),
+                path_in_incr_dir.display(),
+                err
+            ));
+            return None;
         }
-    } else {
-        None
     };
 
     let work_product = WorkProduct { cgu_name: cgu_name.to_string(), saved_file };

From e16c3b4a44214add436e9834d2090a7288eba3a3 Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Sun, 15 May 2022 11:31:28 +0000
Subject: [PATCH 09/11] Make saved_file field of WorkProduct non-optional

A WorkProduct without a saved file is useless
---
 .../rustc_codegen_cranelift/src/driver/aot.rs | 25 +++++------
 compiler/rustc_codegen_ssa/src/back/write.rs  | 42 +++++++++----------
 .../rustc_incremental/src/persist/load.rs     | 20 ++++-----
 .../rustc_incremental/src/persist/save.rs     |  9 +---
 .../src/persist/work_product.rs               | 22 +++++-----
 .../rustc_query_system/src/dep_graph/graph.rs |  2 +-
 6 files changed, 51 insertions(+), 69 deletions(-)

diff --git a/compiler/rustc_codegen_cranelift/src/driver/aot.rs b/compiler/rustc_codegen_cranelift/src/driver/aot.rs
index b652b58cb65a8..05457ce15e9a7 100644
--- a/compiler/rustc_codegen_cranelift/src/driver/aot.rs
+++ b/compiler/rustc_codegen_cranelift/src/driver/aot.rs
@@ -80,21 +80,16 @@ fn reuse_workproduct_for_cgu(
     cgu: &CodegenUnit<'_>,
     work_products: &mut FxHashMap<WorkProductId, WorkProduct>,
 ) -> CompiledModule {
-    let mut object = None;
     let work_product = cgu.previous_work_product(tcx);
-    if let Some(saved_file) = &work_product.saved_file {
-        let obj_out =
-            tcx.output_filenames(()).temp_path(OutputType::Object, Some(cgu.name().as_str()));
-        object = Some(obj_out.clone());
-        let source_file = rustc_incremental::in_incr_comp_dir_sess(&tcx.sess, &saved_file);
-        if let Err(err) = rustc_fs_util::link_or_copy(&source_file, &obj_out) {
-            tcx.sess.err(&format!(
-                "unable to copy {} to {}: {}",
-                source_file.display(),
-                obj_out.display(),
-                err
-            ));
-        }
+    let obj_out = tcx.output_filenames(()).temp_path(OutputType::Object, Some(cgu.name().as_str()));
+    let source_file = rustc_incremental::in_incr_comp_dir_sess(&tcx.sess, &work_product.saved_file);
+    if let Err(err) = rustc_fs_util::link_or_copy(&source_file, &obj_out) {
+        tcx.sess.err(&format!(
+            "unable to copy {} to {}: {}",
+            source_file.display(),
+            obj_out.display(),
+            err
+        ));
     }
 
     work_products.insert(cgu.work_product_id(), work_product);
@@ -102,7 +97,7 @@ fn reuse_workproduct_for_cgu(
     CompiledModule {
         name: cgu.name().to_string(),
         kind: ModuleKind::Regular,
-        object,
+        object: Some(obj_out),
         dwarf_object: None,
         bytecode: None,
     }
diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs
index 36e5906652412..02c7c1a435fae 100644
--- a/compiler/rustc_codegen_ssa/src/back/write.rs
+++ b/compiler/rustc_codegen_ssa/src/back/write.rs
@@ -853,35 +853,31 @@ fn execute_copy_from_cache_work_item<B: ExtraBackendMethods>(
     module: CachedModuleCodegen,
     module_config: &ModuleConfig,
 ) -> WorkItemResult<B> {
+    assert!(module_config.emit_obj != EmitObj::None);
+
     let incr_comp_session_dir = cgcx.incr_comp_session_dir.as_ref().unwrap();
-    let mut object = None;
-    if let Some(saved_file) = module.source.saved_file {
-        let obj_out = cgcx.output_filenames.temp_path(OutputType::Object, Some(&module.name));
-        object = Some(obj_out.clone());
-        let source_file = in_incr_comp_dir(&incr_comp_session_dir, &saved_file);
-        debug!(
-            "copying pre-existing module `{}` from {:?} to {}",
-            module.name,
-            source_file,
-            obj_out.display()
-        );
-        if let Err(err) = link_or_copy(&source_file, &obj_out) {
-            let diag_handler = cgcx.create_diag_handler();
-            diag_handler.err(&format!(
-                "unable to copy {} to {}: {}",
-                source_file.display(),
-                obj_out.display(),
-                err
-            ));
-        }
+    let obj_out = cgcx.output_filenames.temp_path(OutputType::Object, Some(&module.name));
+    let source_file = in_incr_comp_dir(&incr_comp_session_dir, &module.source.saved_file);
+    debug!(
+        "copying pre-existing module `{}` from {:?} to {}",
+        module.name,
+        source_file,
+        obj_out.display()
+    );
+    if let Err(err) = link_or_copy(&source_file, &obj_out) {
+        let diag_handler = cgcx.create_diag_handler();
+        diag_handler.err(&format!(
+            "unable to copy {} to {}: {}",
+            source_file.display(),
+            obj_out.display(),
+            err
+        ));
     }
 
-    assert_eq!(object.is_some(), module_config.emit_obj != EmitObj::None);
-
     WorkItemResult::Compiled(CompiledModule {
         name: module.name,
         kind: ModuleKind::Regular,
-        object,
+        object: Some(obj_out),
         dwarf_object: None,
         bytecode: None,
     })
diff --git a/compiler/rustc_incremental/src/persist/load.rs b/compiler/rustc_incremental/src/persist/load.rs
index 908a936142475..9de14950aa8d3 100644
--- a/compiler/rustc_incremental/src/persist/load.rs
+++ b/compiler/rustc_incremental/src/persist/load.rs
@@ -162,18 +162,16 @@ pub fn load_dep_graph(sess: &Session) -> DepGraphFuture {
 
             for swp in work_products {
                 let mut all_files_exist = true;
-                if let Some(ref file_name) = swp.work_product.saved_file {
-                    let path = in_incr_comp_dir_sess(sess, file_name);
-                    if !path.exists() {
-                        all_files_exist = false;
-
-                        if sess.opts.debugging_opts.incremental_info {
-                            eprintln!(
-                                "incremental: could not find file for work \
+                let path = in_incr_comp_dir_sess(sess, &swp.work_product.saved_file);
+                if !path.exists() {
+                    all_files_exist = false;
+
+                    if sess.opts.debugging_opts.incremental_info {
+                        eprintln!(
+                            "incremental: could not find file for work \
                                     product: {}",
-                                path.display()
-                            );
-                        }
+                            path.display()
+                        );
                     }
                 }
 
diff --git a/compiler/rustc_incremental/src/persist/save.rs b/compiler/rustc_incremental/src/persist/save.rs
index 20ffde90064bf..0223976b08a5b 100644
--- a/compiler/rustc_incremental/src/persist/save.rs
+++ b/compiler/rustc_incremental/src/persist/save.rs
@@ -107,11 +107,7 @@ pub fn save_work_product_index(
     for (id, wp) in previous_work_products.iter() {
         if !new_work_products.contains_key(id) {
             work_product::delete_workproduct_files(sess, wp);
-            debug_assert!(
-                wp.saved_file.as_ref().map_or(true, |file_name| {
-                    !in_incr_comp_dir_sess(sess, &file_name).exists()
-                })
-            );
+            debug_assert!(!in_incr_comp_dir_sess(sess, &wp.saved_file).exists());
         }
     }
 
@@ -119,8 +115,7 @@ pub fn save_work_product_index(
     debug_assert!({
         new_work_products
             .iter()
-            .flat_map(|(_, wp)| wp.saved_file.iter())
-            .map(|name| in_incr_comp_dir_sess(sess, name))
+            .map(|(_, wp)| in_incr_comp_dir_sess(sess, &wp.saved_file))
             .all(|path| path.exists())
     });
 }
diff --git a/compiler/rustc_incremental/src/persist/work_product.rs b/compiler/rustc_incremental/src/persist/work_product.rs
index 2d5cbc28d6eac..4789c0f581fdb 100644
--- a/compiler/rustc_incremental/src/persist/work_product.rs
+++ b/compiler/rustc_incremental/src/persist/work_product.rs
@@ -21,7 +21,7 @@ pub fn copy_cgu_workproduct_to_incr_comp_cache_dir(
     let file_name = format!("{}.o", cgu_name);
     let path_in_incr_dir = in_incr_comp_dir_sess(sess, &file_name);
     let saved_file = match link_or_copy(path, &path_in_incr_dir) {
-        Ok(_) => Some(file_name),
+        Ok(_) => file_name,
         Err(err) => {
             sess.warn(&format!(
                 "error copying object file `{}` to incremental directory as `{}`: {}",
@@ -41,17 +41,15 @@ pub fn copy_cgu_workproduct_to_incr_comp_cache_dir(
 
 /// Removes files for a given work product.
 pub fn delete_workproduct_files(sess: &Session, work_product: &WorkProduct) {
-    if let Some(ref file_name) = work_product.saved_file {
-        let path = in_incr_comp_dir_sess(sess, file_name);
-        match std_fs::remove_file(&path) {
-            Ok(()) => {}
-            Err(err) => {
-                sess.warn(&format!(
-                    "file-system error deleting outdated file `{}`: {}",
-                    path.display(),
-                    err
-                ));
-            }
+    let path = in_incr_comp_dir_sess(sess, &work_product.saved_file);
+    match std_fs::remove_file(&path) {
+        Ok(()) => {}
+        Err(err) => {
+            sess.warn(&format!(
+                "file-system error deleting outdated file `{}`: {}",
+                path.display(),
+                err
+            ));
         }
     }
 }
diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs
index f7655e55d3485..f6d06e4362c53 100644
--- a/compiler/rustc_query_system/src/dep_graph/graph.rs
+++ b/compiler/rustc_query_system/src/dep_graph/graph.rs
@@ -887,7 +887,7 @@ impl<K: DepKind> DepGraph<K> {
 pub struct WorkProduct {
     pub cgu_name: String,
     /// Saved file associated with this CGU.
-    pub saved_file: Option<String>,
+    pub saved_file: String,
 }
 
 // Index type for `DepNodeData`'s edges.

From 10336cf1624ada36e8ba64e851d4df3f2976da81 Mon Sep 17 00:00:00 2001
From: Chase Wilson <buckshot1233@gmail.com>
Date: Mon, 6 Jun 2022 10:19:33 -0500
Subject: [PATCH 10/11] Update src/test/ui/unsized/issue-97732.rs

Co-authored-by: Eduard-Mihai Burtescu <edy.burt@gmail.com>
---
 src/test/ui/unsized/issue-97732.rs | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/src/test/ui/unsized/issue-97732.rs b/src/test/ui/unsized/issue-97732.rs
index 172f0724d4263..72f765033969a 100644
--- a/src/test/ui/unsized/issue-97732.rs
+++ b/src/test/ui/unsized/issue-97732.rs
@@ -15,9 +15,14 @@ impl<S: ?Sized, T: ?Sized> CoerceUnsized<BoxWithZstTail<T>> for BoxWithZstTail<S
 }
 
 pub fn noop_dyn_upcast_with_zst_tail(
-    b: BoxWithZstTail<dyn Send + Sync>,
-) -> BoxWithZstTail<dyn Send> {
+    b: BoxWithZstTail<dyn ToString + Send>,
+) -> BoxWithZstTail<dyn ToString> {
     b
 }
 
-fn main() {}
+fn main() {
+    let original = "foo";
+    let boxed = BoxWithZstTail(Box::new(original) as Box<dyn ToString + Send>, ());
+    let noop_upcasted = noop_dyn_upcast_with_zst_tail(boxed);
+    assert_eq!(original, noop_upcasted.0.to_string());
+}

From ff3700171316bb59e571e1b8604efba191bdb1c0 Mon Sep 17 00:00:00 2001
From: Alex Crichton <alex@alexcrichton.com>
Date: Mon, 6 Jun 2022 15:01:17 -0700
Subject: [PATCH 11/11] Add some unstable target features for the wasm target
 codegen

I was experimenting with cross-language LTO for the wasm target recently
between Rust and C and found that C was injecting the `+mutable-globals`
flag on all functions. When specifying the corresponding
`-Ctarget-feature=+mutable-globals` feature to Rust it prints a warning
about an unknown feature. I've added the `mutable-globals` feature plus
another few I know of to the list of known features for wasm targets.
These features all continue to be unstable to source code as they were
before.
---
 compiler/rustc_codegen_ssa/src/target_features.rs | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs
index ba1e1862227a8..bfdef2dc0e80c 100644
--- a/compiler/rustc_codegen_ssa/src/target_features.rs
+++ b/compiler/rustc_codegen_ssa/src/target_features.rs
@@ -246,6 +246,9 @@ const WASM_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
     ("simd128", None),
     ("atomics", Some(sym::wasm_target_feature)),
     ("nontrapping-fptoint", Some(sym::wasm_target_feature)),
+    ("bulk-memory", Some(sym::wasm_target_feature)),
+    ("mutable-globals", Some(sym::wasm_target_feature)),
+    ("reference-types", Some(sym::wasm_target_feature)),
 ];
 
 const BPF_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[("alu32", Some(sym::bpf_target_feature))];