about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_borrowck/src/consumers.rs8
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs20
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/find_use.rs5
-rw-r--r--compiler/rustc_borrowck/src/lib.rs36
-rw-r--r--compiler/rustc_borrowck/src/nll.rs12
-rw-r--r--compiler/rustc_borrowck/src/region_infer/mod.rs12
-rw-r--r--compiler/rustc_borrowck/src/region_infer/values.rs11
-rw-r--r--compiler/rustc_borrowck/src/type_check/free_region_relations.rs4
-rw-r--r--compiler/rustc_borrowck/src/type_check/liveness/mod.rs4
-rw-r--r--compiler/rustc_borrowck/src/type_check/liveness/trace.rs4
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs12
-rw-r--r--compiler/rustc_builtin_macros/messages.ftl2
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs64
-rw-r--r--compiler/rustc_builtin_macros/src/errors.rs7
-rw-r--r--compiler/rustc_driver_impl/src/lib.rs7
-rw-r--r--compiler/rustc_fs_util/src/lib.rs6
-rw-r--r--compiler/rustc_serialize/src/opaque.rs6
-rw-r--r--src/bootstrap/src/core/build_steps/test.rs6
-rw-r--r--src/bootstrap/src/core/build_steps/tool.rs7
-rw-r--r--src/bootstrap/src/core/builder.rs22
-rw-r--r--src/bootstrap/src/utils/shared_helpers.rs2
-rw-r--r--src/tools/compiletest/src/common.rs8
-rw-r--r--src/tools/compiletest/src/lib.rs6
-rw-r--r--src/tools/compiletest/src/main.rs4
-rw-r--r--src/tools/compiletest/src/runtest.rs38
-rw-r--r--src/tools/compiletest/src/runtest/incremental.rs34
-rw-r--r--src/tools/compiletest/src/runtest/valgrind.rs34
-rw-r--r--src/tools/opt-dist/src/tests.rs1
-rw-r--r--tests/run-pass-valgrind/cast-enum-with-dtor.rs34
-rw-r--r--tests/run-pass-valgrind/cleanup-auto-borrow-obj.rs28
-rw-r--r--tests/run-pass-valgrind/cleanup-stdin.rs5
-rw-r--r--tests/run-pass-valgrind/coerce-match-calls.rs21
-rw-r--r--tests/run-pass-valgrind/coerce-match.rs31
-rw-r--r--tests/run-pass-valgrind/down-with-thread-dtors.rs43
-rw-r--r--tests/run-pass-valgrind/dst-dtor-1.rs28
-rw-r--r--tests/run-pass-valgrind/dst-dtor-2.rs23
-rw-r--r--tests/run-pass-valgrind/dst-dtor-3.rs26
-rw-r--r--tests/run-pass-valgrind/dst-dtor-4.rs21
-rw-r--r--tests/run-pass-valgrind/exit-flushes.rs19
-rw-r--r--tests/run-pass-valgrind/issue-44800.rs12
-rw-r--r--tests/run-pass-valgrind/unsized-locals/by-value-trait-objects-rust-call.rs55
-rw-r--r--tests/run-pass-valgrind/unsized-locals/by-value-trait-objects-rust-call2.rs69
-rw-r--r--tests/run-pass-valgrind/unsized-locals/by-value-trait-objects.rs48
-rw-r--r--tests/run-pass-valgrind/unsized-locals/long-live-the-unsized-temporary.rs52
-rw-r--r--tests/ui/deriving/deriving-smart-pointer-neg.rs33
-rw-r--r--tests/ui/deriving/deriving-smart-pointer-neg.stderr26
-rw-r--r--triagebot.toml1
47 files changed, 254 insertions, 703 deletions
diff --git a/compiler/rustc_borrowck/src/consumers.rs b/compiler/rustc_borrowck/src/consumers.rs
index c994c4dc1e4..7ace38c3e85 100644
--- a/compiler/rustc_borrowck/src/consumers.rs
+++ b/compiler/rustc_borrowck/src/consumers.rs
@@ -1,7 +1,5 @@
 //! This file provides API for compiler consumers.
 
-use std::rc::Rc;
-
 use rustc_hir::def_id::LocalDefId;
 use rustc_index::{IndexSlice, IndexVec};
 use rustc_middle::mir::{Body, Promoted};
@@ -65,10 +63,10 @@ pub struct BodyWithBorrowckFacts<'tcx> {
     /// The mir bodies of promoteds.
     pub promoted: IndexVec<Promoted, Body<'tcx>>,
     /// The set of borrows occurring in `body` with data about them.
-    pub borrow_set: Rc<BorrowSet<'tcx>>,
+    pub borrow_set: BorrowSet<'tcx>,
     /// Context generated during borrowck, intended to be passed to
     /// [`calculate_borrows_out_of_scope_at_location`].
-    pub region_inference_context: Rc<RegionInferenceContext<'tcx>>,
+    pub region_inference_context: RegionInferenceContext<'tcx>,
     /// The table that maps Polonius points to locations in the table.
     /// Populated when using [`ConsumerOptions::PoloniusInputFacts`]
     /// or [`ConsumerOptions::PoloniusOutputFacts`].
@@ -79,7 +77,7 @@ pub struct BodyWithBorrowckFacts<'tcx> {
     pub input_facts: Option<Box<PoloniusInput>>,
     /// Polonius output facts. Populated when using
     /// [`ConsumerOptions::PoloniusOutputFacts`].
-    pub output_facts: Option<Rc<PoloniusOutput>>,
+    pub output_facts: Option<Box<PoloniusOutput>>,
 }
 
 /// This function computes borrowck facts for the given body. The [`ConsumerOptions`]
diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index 60ea0d1edbf..c687be69b1a 100644
--- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
@@ -708,9 +708,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
         // for the branching codepaths that aren't covered, to point at them.
         let map = self.infcx.tcx.hir();
         let body = map.body_owned_by(self.mir_def_id());
-        let mut visitor =
-            ConditionVisitor { tcx: self.infcx.tcx, spans: &spans, name: &name, errors: vec![] };
+        let mut visitor = ConditionVisitor { tcx: self.infcx.tcx, spans, name, errors: vec![] };
         visitor.visit_body(&body);
+        let spans = visitor.spans;
 
         let mut show_assign_sugg = false;
         let isnt_initialized = if let InitializationRequiringAction::PartialAssignment
@@ -4465,20 +4465,20 @@ impl<'hir> Visitor<'hir> for BreakFinder {
 
 /// Given a set of spans representing statements initializing the relevant binding, visit all the
 /// function expressions looking for branching code paths that *do not* initialize the binding.
-struct ConditionVisitor<'b, 'tcx> {
+struct ConditionVisitor<'tcx> {
     tcx: TyCtxt<'tcx>,
-    spans: &'b [Span],
-    name: &'b str,
+    spans: Vec<Span>,
+    name: String,
     errors: Vec<(Span, String)>,
 }
 
-impl<'b, 'v, 'tcx> Visitor<'v> for ConditionVisitor<'b, 'tcx> {
+impl<'v, 'tcx> Visitor<'v> for ConditionVisitor<'tcx> {
     fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) {
         match ex.kind {
             hir::ExprKind::If(cond, body, None) => {
                 // `if` expressions with no `else` that initialize the binding might be missing an
                 // `else` arm.
-                if ReferencedStatementsVisitor(self.spans).visit_expr(body).is_break() {
+                if ReferencedStatementsVisitor(&self.spans).visit_expr(body).is_break() {
                     self.errors.push((
                         cond.span,
                         format!(
@@ -4495,8 +4495,8 @@ impl<'b, 'v, 'tcx> Visitor<'v> for ConditionVisitor<'b, 'tcx> {
             hir::ExprKind::If(cond, body, Some(other)) => {
                 // `if` expressions where the binding is only initialized in one of the two arms
                 // might be missing a binding initialization.
-                let a = ReferencedStatementsVisitor(self.spans).visit_expr(body).is_break();
-                let b = ReferencedStatementsVisitor(self.spans).visit_expr(other).is_break();
+                let a = ReferencedStatementsVisitor(&self.spans).visit_expr(body).is_break();
+                let b = ReferencedStatementsVisitor(&self.spans).visit_expr(other).is_break();
                 match (a, b) {
                     (true, true) | (false, false) => {}
                     (true, false) => {
@@ -4536,7 +4536,7 @@ impl<'b, 'v, 'tcx> Visitor<'v> for ConditionVisitor<'b, 'tcx> {
                 // arms might be missing an initialization.
                 let results: Vec<bool> = arms
                     .iter()
-                    .map(|arm| ReferencedStatementsVisitor(self.spans).visit_arm(arm).is_break())
+                    .map(|arm| ReferencedStatementsVisitor(&self.spans).visit_arm(arm).is_break())
                     .collect();
                 if results.iter().any(|x| *x) && !results.iter().all(|x| *x) {
                     for (arm, seen) in arms.iter().zip(results) {
diff --git a/compiler/rustc_borrowck/src/diagnostics/find_use.rs b/compiler/rustc_borrowck/src/diagnostics/find_use.rs
index d8fa5506a99..26a090f5579 100644
--- a/compiler/rustc_borrowck/src/diagnostics/find_use.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/find_use.rs
@@ -1,5 +1,4 @@
 use std::collections::VecDeque;
-use std::rc::Rc;
 
 use rustc_data_structures::fx::FxIndexSet;
 use rustc_middle::mir::visit::{MirVisitable, PlaceContext, Visitor};
@@ -11,7 +10,7 @@ use crate::region_infer::{Cause, RegionInferenceContext};
 
 pub(crate) fn find<'tcx>(
     body: &Body<'tcx>,
-    regioncx: &Rc<RegionInferenceContext<'tcx>>,
+    regioncx: &RegionInferenceContext<'tcx>,
     tcx: TyCtxt<'tcx>,
     region_vid: RegionVid,
     start_point: Location,
@@ -23,7 +22,7 @@ pub(crate) fn find<'tcx>(
 
 struct UseFinder<'a, 'tcx> {
     body: &'a Body<'tcx>,
-    regioncx: &'a Rc<RegionInferenceContext<'tcx>>,
+    regioncx: &'a RegionInferenceContext<'tcx>,
     tcx: TyCtxt<'tcx>,
     region_vid: RegionVid,
     start_point: Location,
diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs
index fad4d790be4..cbf8aa313c5 100644
--- a/compiler/rustc_borrowck/src/lib.rs
+++ b/compiler/rustc_borrowck/src/lib.rs
@@ -19,7 +19,6 @@ use std::cell::RefCell;
 use std::collections::BTreeMap;
 use std::marker::PhantomData;
 use std::ops::Deref;
-use std::rc::Rc;
 
 use consumers::{BodyWithBorrowckFacts, ConsumerOptions};
 use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
@@ -200,8 +199,7 @@ fn do_mir_borrowck<'tcx>(
         .into_results_cursor(body);
 
     let locals_are_invalidated_at_exit = tcx.hir().body_owner_kind(def).is_fn_or_closure();
-    let borrow_set =
-        Rc::new(BorrowSet::build(tcx, body, locals_are_invalidated_at_exit, &move_data));
+    let borrow_set = BorrowSet::build(tcx, body, locals_are_invalidated_at_exit, &move_data);
 
     // Compute non-lexical lifetimes.
     let nll::NllOutput {
@@ -245,8 +243,6 @@ fn do_mir_borrowck<'tcx>(
     // usage significantly on some benchmarks.
     drop(flow_inits);
 
-    let regioncx = Rc::new(regioncx);
-
     let flow_borrows = Borrows::new(tcx, body, &regioncx, &borrow_set)
         .into_engine(tcx, body)
         .pass_name("borrowck")
@@ -288,10 +284,10 @@ fn do_mir_borrowck<'tcx>(
             access_place_error_reported: Default::default(),
             reservation_error_reported: Default::default(),
             uninitialized_error_reported: Default::default(),
-            regioncx: regioncx.clone(),
+            regioncx: &regioncx,
             used_mut: Default::default(),
             used_mut_upvars: SmallVec::new(),
-            borrow_set: Rc::clone(&borrow_set),
+            borrow_set: &borrow_set,
             upvars: &[],
             local_names: IndexVec::from_elem(None, &promoted_body.local_decls),
             region_names: RefCell::default(),
@@ -329,10 +325,10 @@ fn do_mir_borrowck<'tcx>(
         access_place_error_reported: Default::default(),
         reservation_error_reported: Default::default(),
         uninitialized_error_reported: Default::default(),
-        regioncx: Rc::clone(&regioncx),
+        regioncx: &regioncx,
         used_mut: Default::default(),
         used_mut_upvars: SmallVec::new(),
-        borrow_set: Rc::clone(&borrow_set),
+        borrow_set: &borrow_set,
         upvars: tcx.closure_captures(def),
         local_names,
         region_names: RefCell::default(),
@@ -569,10 +565,10 @@ struct MirBorrowckCtxt<'a, 'infcx, 'tcx> {
     used_mut_upvars: SmallVec<[FieldIdx; 8]>,
     /// Region inference context. This contains the results from region inference and lets us e.g.
     /// find out which CFG points are contained in each borrow region.
-    regioncx: Rc<RegionInferenceContext<'tcx>>,
+    regioncx: &'a RegionInferenceContext<'tcx>,
 
     /// The set of borrows extracted from the MIR
-    borrow_set: Rc<BorrowSet<'tcx>>,
+    borrow_set: &'a BorrowSet<'tcx>,
 
     /// Information about upvars not necessarily preserved in types or MIR
     upvars: &'tcx [&'tcx ty::CapturedPlace<'tcx>],
@@ -588,7 +584,7 @@ struct MirBorrowckCtxt<'a, 'infcx, 'tcx> {
     next_region_name: RefCell<usize>,
 
     /// Results of Polonius analysis.
-    polonius_output: Option<Rc<PoloniusOutput>>,
+    polonius_output: Option<Box<PoloniusOutput>>,
 
     diags: diags::BorrowckDiags<'infcx, 'tcx>,
     move_errors: Vec<MoveError<'tcx>>,
@@ -800,9 +796,8 @@ impl<'a, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'a, 'tcx, R>
             TerminatorKind::Yield { value: _, resume: _, resume_arg: _, drop: _ } => {
                 if self.movable_coroutine {
                     // Look for any active borrows to locals
-                    let borrow_set = self.borrow_set.clone();
                     for i in state.borrows.iter() {
-                        let borrow = &borrow_set[i];
+                        let borrow = &self.borrow_set[i];
                         self.check_for_local_borrow(borrow, span);
                     }
                 }
@@ -816,9 +811,8 @@ impl<'a, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'a, 'tcx, R>
                 // Often, the storage will already have been killed by an explicit
                 // StorageDead, but we don't always emit those (notably on unwind paths),
                 // so this "extra check" serves as a kind of backup.
-                let borrow_set = self.borrow_set.clone();
                 for i in state.borrows.iter() {
-                    let borrow = &borrow_set[i];
+                    let borrow = &self.borrow_set[i];
                     self.check_for_invalidation_at_exit(loc, borrow, span);
                 }
             }
@@ -1037,13 +1031,12 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
         state: &BorrowckDomain<'a, 'tcx>,
     ) -> bool {
         let mut error_reported = false;
-        let borrow_set = Rc::clone(&self.borrow_set);
 
         // Use polonius output if it has been enabled.
         let mut polonius_output;
         let borrows_in_scope = if let Some(polonius) = &self.polonius_output {
             let location = self.location_table.start_index(location);
-            polonius_output = BitSet::new_empty(borrow_set.len());
+            polonius_output = BitSet::new_empty(self.borrow_set.len());
             for &idx in polonius.errors_at(location) {
                 polonius_output.insert(idx);
             }
@@ -1057,7 +1050,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
             self.infcx.tcx,
             self.body,
             (sd, place_span.0),
-            &borrow_set,
+            self.borrow_set,
             |borrow_index| borrows_in_scope.contains(borrow_index),
             |this, borrow_index, borrow| match (rw, borrow.kind) {
                 // Obviously an activation is compatible with its own
@@ -1580,9 +1573,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
         // Two-phase borrow support: For each activation that is newly
         // generated at this statement, check if it interferes with
         // another borrow.
-        let borrow_set = self.borrow_set.clone();
-        for &borrow_index in borrow_set.activations_at_location(location) {
-            let borrow = &borrow_set[borrow_index];
+        for &borrow_index in self.borrow_set.activations_at_location(location) {
+            let borrow = &self.borrow_set[borrow_index];
 
             // only mutable borrows should be 2-phase
             assert!(match borrow.kind {
diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs
index d85af52b01e..f3207c26bfc 100644
--- a/compiler/rustc_borrowck/src/nll.rs
+++ b/compiler/rustc_borrowck/src/nll.rs
@@ -42,7 +42,7 @@ pub(crate) struct NllOutput<'tcx> {
     pub regioncx: RegionInferenceContext<'tcx>,
     pub opaque_type_values: FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>>,
     pub polonius_input: Option<Box<AllFacts>>,
-    pub polonius_output: Option<Rc<PoloniusOutput>>,
+    pub polonius_output: Option<Box<PoloniusOutput>>,
     pub opt_closure_req: Option<ClosureRegionRequirements<'tcx>>,
     pub nll_errors: RegionErrors<'tcx>,
 }
@@ -98,7 +98,7 @@ pub(crate) fn compute_regions<'a, 'tcx>(
 
     let universal_regions = Rc::new(universal_regions);
 
-    let elements = &Rc::new(DenseLocationMap::new(body));
+    let elements = Rc::new(DenseLocationMap::new(body));
 
     // Run the MIR type-checker.
     let MirTypeckResults { constraints, universal_region_relations, opaque_type_values } =
@@ -107,13 +107,13 @@ pub(crate) fn compute_regions<'a, 'tcx>(
             param_env,
             body,
             promoted,
-            &universal_regions,
+            universal_regions.clone(),
             location_table,
             borrow_set,
             &mut all_facts,
             flow_inits,
             move_data,
-            elements,
+            elements.clone(),
             upvars,
         );
 
@@ -165,7 +165,7 @@ pub(crate) fn compute_regions<'a, 'tcx>(
         universe_causes,
         type_tests,
         liveness_constraints,
-        elements,
+        elements.clone(),
     );
 
     // If requested: dump NLL facts, and run legacy polonius analysis.
@@ -184,7 +184,7 @@ pub(crate) fn compute_regions<'a, 'tcx>(
             let algorithm = Algorithm::from_str(&algorithm).unwrap();
             debug!("compute_regions: using polonius algorithm {:?}", algorithm);
             let _prof_timer = infcx.tcx.prof.generic_activity("polonius_analysis");
-            Some(Rc::new(Output::compute(all_facts, algorithm, false)))
+            Some(Box::new(Output::compute(all_facts, algorithm, false)))
         } else {
             None
         }
diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs
index c62ea870acf..e85f529bf0e 100644
--- a/compiler/rustc_borrowck/src/region_infer/mod.rs
+++ b/compiler/rustc_borrowck/src/region_infer/mod.rs
@@ -407,7 +407,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         universe_causes: FxIndexMap<ty::UniverseIndex, UniverseInfo<'tcx>>,
         type_tests: Vec<TypeTest<'tcx>>,
         liveness_constraints: LivenessValues,
-        elements: &Rc<DenseLocationMap>,
+        elements: Rc<DenseLocationMap>,
     ) -> Self {
         debug!("universal_regions: {:#?}", universal_regions);
         debug!("outlives constraints: {:#?}", outlives_constraints);
@@ -430,7 +430,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         }
 
         let mut scc_values =
-            RegionValues::new(elements, universal_regions.len(), &placeholder_indices);
+            RegionValues::new(elements, universal_regions.len(), placeholder_indices);
 
         for region in liveness_constraints.regions() {
             let scc = constraint_sccs.scc(region);
@@ -637,7 +637,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         &mut self,
         infcx: &InferCtxt<'tcx>,
         body: &Body<'tcx>,
-        polonius_output: Option<Rc<PoloniusOutput>>,
+        polonius_output: Option<Box<PoloniusOutput>>,
     ) -> (Option<ClosureRegionRequirements<'tcx>>, RegionErrors<'tcx>) {
         let mir_def_id = body.source.def_id();
         self.propagate_constraints();
@@ -663,7 +663,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
             self.check_polonius_subset_errors(
                 outlives_requirements.as_mut(),
                 &mut errors_buffer,
-                polonius_output.expect("Polonius output is unavailable despite `-Z polonius`"),
+                polonius_output
+                    .as_ref()
+                    .expect("Polonius output is unavailable despite `-Z polonius`"),
             );
         } else {
             self.check_universal_regions(outlives_requirements.as_mut(), &mut errors_buffer);
@@ -1411,7 +1413,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         &self,
         mut propagated_outlives_requirements: Option<&mut Vec<ClosureOutlivesRequirement<'tcx>>>,
         errors_buffer: &mut RegionErrors<'tcx>,
-        polonius_output: Rc<PoloniusOutput>,
+        polonius_output: &PoloniusOutput,
     ) {
         debug!(
             "check_polonius_subset_errors: {} subset_errors",
diff --git a/compiler/rustc_borrowck/src/region_infer/values.rs b/compiler/rustc_borrowck/src/region_infer/values.rs
index b95fe5b5028..662e6fa46b5 100644
--- a/compiler/rustc_borrowck/src/region_infer/values.rs
+++ b/compiler/rustc_borrowck/src/region_infer/values.rs
@@ -275,15 +275,16 @@ impl<N: Idx> RegionValues<N> {
     /// Each of the regions in num_region_variables will be initialized with an
     /// empty set of points and no causal information.
     pub(crate) fn new(
-        elements: &Rc<DenseLocationMap>,
+        elements: Rc<DenseLocationMap>,
         num_universal_regions: usize,
-        placeholder_indices: &Rc<PlaceholderIndices>,
+        placeholder_indices: Rc<PlaceholderIndices>,
     ) -> Self {
+        let num_points = elements.num_points();
         let num_placeholders = placeholder_indices.len();
         Self {
-            elements: elements.clone(),
-            points: SparseIntervalMatrix::new(elements.num_points()),
-            placeholder_indices: placeholder_indices.clone(),
+            elements,
+            points: SparseIntervalMatrix::new(num_points),
+            placeholder_indices,
             free_regions: SparseBitMatrix::new(num_universal_regions),
             placeholders: SparseBitMatrix::new(num_placeholders),
         }
diff --git a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs
index 6977fed59ed..cded9935f97 100644
--- a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs
+++ b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs
@@ -54,7 +54,7 @@ pub(crate) fn create<'tcx>(
     infcx: &InferCtxt<'tcx>,
     param_env: ty::ParamEnv<'tcx>,
     implicit_region_bound: ty::Region<'tcx>,
-    universal_regions: &Rc<UniversalRegions<'tcx>>,
+    universal_regions: Rc<UniversalRegions<'tcx>>,
     constraints: &mut MirTypeckRegionConstraints<'tcx>,
 ) -> CreateResult<'tcx> {
     UniversalRegionRelationsBuilder {
@@ -62,7 +62,7 @@ pub(crate) fn create<'tcx>(
         param_env,
         implicit_region_bound,
         constraints,
-        universal_regions: universal_regions.clone(),
+        universal_regions,
         region_bound_pairs: Default::default(),
         outlives: Default::default(),
         inverse_outlives: Default::default(),
diff --git a/compiler/rustc_borrowck/src/type_check/liveness/mod.rs b/compiler/rustc_borrowck/src/type_check/liveness/mod.rs
index d4900d21f8f..b8e35f882ec 100644
--- a/compiler/rustc_borrowck/src/type_check/liveness/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/liveness/mod.rs
@@ -1,5 +1,3 @@
-use std::rc::Rc;
-
 use itertools::{Either, Itertools};
 use rustc_data_structures::fx::FxHashSet;
 use rustc_middle::mir::visit::{TyContext, Visitor};
@@ -33,7 +31,7 @@ mod trace;
 pub(super) fn generate<'a, 'tcx>(
     typeck: &mut TypeChecker<'_, 'tcx>,
     body: &Body<'tcx>,
-    elements: &Rc<DenseLocationMap>,
+    elements: &DenseLocationMap,
     flow_inits: &mut ResultsCursor<'a, 'tcx, MaybeInitializedPlaces<'a, 'tcx>>,
     move_data: &MoveData<'tcx>,
 ) {
diff --git a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs
index 8cbe3ac6701..a5175e653d8 100644
--- a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs
+++ b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs
@@ -1,5 +1,3 @@
-use std::rc::Rc;
-
 use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
 use rustc_index::bit_set::BitSet;
 use rustc_index::interval::IntervalSet;
@@ -40,7 +38,7 @@ use crate::type_check::{NormalizeLocation, TypeChecker};
 pub(super) fn trace<'a, 'tcx>(
     typeck: &mut TypeChecker<'_, 'tcx>,
     body: &Body<'tcx>,
-    elements: &Rc<DenseLocationMap>,
+    elements: &DenseLocationMap,
     flow_inits: &mut ResultsCursor<'a, 'tcx, MaybeInitializedPlaces<'a, 'tcx>>,
     move_data: &MoveData<'tcx>,
     relevant_live_locals: Vec<Local>,
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index 6b17879de26..82aeca66693 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -121,13 +121,13 @@ pub(crate) fn type_check<'a, 'tcx>(
     param_env: ty::ParamEnv<'tcx>,
     body: &Body<'tcx>,
     promoted: &IndexSlice<Promoted, Body<'tcx>>,
-    universal_regions: &Rc<UniversalRegions<'tcx>>,
+    universal_regions: Rc<UniversalRegions<'tcx>>,
     location_table: &LocationTable,
     borrow_set: &BorrowSet<'tcx>,
     all_facts: &mut Option<AllFacts>,
     flow_inits: &mut ResultsCursor<'a, 'tcx, MaybeInitializedPlaces<'a, 'tcx>>,
     move_data: &MoveData<'tcx>,
-    elements: &Rc<DenseLocationMap>,
+    elements: Rc<DenseLocationMap>,
     upvars: &[&ty::CapturedPlace<'tcx>],
 ) -> MirTypeckResults<'tcx> {
     let implicit_region_bound = ty::Region::new_var(infcx.tcx, universal_regions.fr_fn_body);
@@ -150,14 +150,14 @@ pub(crate) fn type_check<'a, 'tcx>(
         infcx,
         param_env,
         implicit_region_bound,
-        universal_regions,
+        universal_regions.clone(),
         &mut constraints,
     );
 
     debug!(?normalized_inputs_and_output);
 
     let mut borrowck_context = BorrowCheckContext {
-        universal_regions,
+        universal_regions: &universal_regions,
         location_table,
         borrow_set,
         all_facts,
@@ -181,10 +181,10 @@ pub(crate) fn type_check<'a, 'tcx>(
     verifier.visit_body(body);
 
     checker.typeck_mir(body);
-    checker.equate_inputs_and_outputs(body, universal_regions, &normalized_inputs_and_output);
+    checker.equate_inputs_and_outputs(body, &universal_regions, &normalized_inputs_and_output);
     checker.check_signature_annotation(body);
 
-    liveness::generate(&mut checker, body, elements, flow_inits, move_data);
+    liveness::generate(&mut checker, body, &elements, flow_inits, move_data);
 
     translate_outlives_facts(&mut checker);
     let opaque_type_values = infcx.take_opaque_types();
diff --git a/compiler/rustc_builtin_macros/messages.ftl b/compiler/rustc_builtin_macros/messages.ftl
index b25892242b5..77cb8dc63c4 100644
--- a/compiler/rustc_builtin_macros/messages.ftl
+++ b/compiler/rustc_builtin_macros/messages.ftl
@@ -235,6 +235,8 @@ builtin_macros_non_exhaustive_default = default variant must be exhaustive
     .label = declared `#[non_exhaustive]` here
     .help = consider a manual implementation of `Default`
 
+builtin_macros_non_generic_pointee = the `#[pointee]` attribute may only be used on generic parameters
+
 builtin_macros_non_unit_default = the `#[default]` attribute may only be used on unit enum variants
     .help = consider a manual implementation of `Default`
 
diff --git a/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs b/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs
index 78028df2aa0..fab1906eecd 100644
--- a/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs
@@ -13,6 +13,8 @@ use rustc_span::symbol::{Ident, sym};
 use rustc_span::{Span, Symbol};
 use thin_vec::{ThinVec, thin_vec};
 
+use crate::errors;
+
 macro_rules! path {
     ($span:expr, $($part:ident)::*) => { vec![$(Ident::new(sym::$part, $span),)*] }
 }
@@ -25,6 +27,8 @@ pub(crate) fn expand_deriving_smart_ptr(
     push: &mut dyn FnMut(Annotatable),
     _is_const: bool,
 ) {
+    item.visit_with(&mut DetectNonGenericPointeeAttr { cx });
+
     let (name_ident, generics) = if let Annotatable::Item(aitem) = item
         && let ItemKind::Struct(struct_data, g) = &aitem.kind
     {
@@ -396,3 +400,63 @@ impl<'a> ast::mut_visit::MutVisitor for TypeSubstitution<'a> {
         }
     }
 }
+
+struct DetectNonGenericPointeeAttr<'a, 'b> {
+    cx: &'a ExtCtxt<'b>,
+}
+
+impl<'a, 'b> rustc_ast::visit::Visitor<'a> for DetectNonGenericPointeeAttr<'a, 'b> {
+    fn visit_attribute(&mut self, attr: &'a rustc_ast::Attribute) -> Self::Result {
+        if attr.has_name(sym::pointee) {
+            self.cx.dcx().emit_err(errors::NonGenericPointee { span: attr.span });
+        }
+    }
+
+    fn visit_generic_param(&mut self, param: &'a rustc_ast::GenericParam) -> Self::Result {
+        let mut error_on_pointee = AlwaysErrorOnGenericParam { cx: self.cx };
+
+        match &param.kind {
+            GenericParamKind::Type { default } => {
+                // The `default` may end up containing a block expression.
+                // The problem is block expressions  may define structs with generics.
+                // A user may attach a #[pointee] attribute to one of these generics
+                // We want to catch that. The simple solution is to just
+                // always raise a `NonGenericPointee` error when this happens.
+                //
+                // This solution does reject valid rust programs but,
+                // such a code would have to, in order:
+                // - Define a smart pointer struct.
+                // - Somewhere in this struct definition use a type with a const generic argument.
+                // - Calculate this const generic in a expression block.
+                // - Define a new smart pointer type in this block.
+                // - Have this smart pointer type have more than 1 generic type.
+                // In this case, the inner smart pointer derive would be complaining that it
+                // needs a pointer attribute. Meanwhile, the outer macro would be complaining
+                // that we attached a #[pointee] to a generic type argument while helpfully
+                // informing the user that #[pointee] can only be attached to generic pointer arguments
+                rustc_ast::visit::visit_opt!(error_on_pointee, visit_ty, default);
+            }
+
+            GenericParamKind::Const { .. } | GenericParamKind::Lifetime => {
+                rustc_ast::visit::walk_generic_param(&mut error_on_pointee, param);
+            }
+        }
+    }
+
+    fn visit_ty(&mut self, t: &'a rustc_ast::Ty) -> Self::Result {
+        let mut error_on_pointee = AlwaysErrorOnGenericParam { cx: self.cx };
+        error_on_pointee.visit_ty(t)
+    }
+}
+
+struct AlwaysErrorOnGenericParam<'a, 'b> {
+    cx: &'a ExtCtxt<'b>,
+}
+
+impl<'a, 'b> rustc_ast::visit::Visitor<'a> for AlwaysErrorOnGenericParam<'a, 'b> {
+    fn visit_attribute(&mut self, attr: &'a rustc_ast::Attribute) -> Self::Result {
+        if attr.has_name(sym::pointee) {
+            self.cx.dcx().emit_err(errors::NonGenericPointee { span: attr.span });
+        }
+    }
+}
diff --git a/compiler/rustc_builtin_macros/src/errors.rs b/compiler/rustc_builtin_macros/src/errors.rs
index f13ca224a45..639c2aa231c 100644
--- a/compiler/rustc_builtin_macros/src/errors.rs
+++ b/compiler/rustc_builtin_macros/src/errors.rs
@@ -940,3 +940,10 @@ pub(crate) struct NakedFunctionTestingAttribute {
     #[label]
     pub testing_span: Span,
 }
+
+#[derive(Diagnostic)]
+#[diag(builtin_macros_non_generic_pointee)]
+pub(crate) struct NonGenericPointee {
+    #[primary_span]
+    pub span: Span,
+}
diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs
index 76b7270d4b8..a59dea557bb 100644
--- a/compiler/rustc_driver_impl/src/lib.rs
+++ b/compiler/rustc_driver_impl/src/lib.rs
@@ -29,13 +29,12 @@ use std::path::PathBuf;
 use std::process::{self, Command, Stdio};
 use std::sync::atomic::{AtomicBool, Ordering};
 use std::sync::{Arc, OnceLock};
-use std::time::{Duration, Instant, SystemTime};
+use std::time::{Instant, SystemTime};
 use std::{env, str};
 
 use rustc_ast as ast;
 use rustc_codegen_ssa::traits::CodegenBackend;
 use rustc_codegen_ssa::{CodegenErrors, CodegenResults};
-use rustc_const_eval::CTRL_C_RECEIVED;
 use rustc_data_structures::profiling::{
     TimePassesFormat, get_resident_set_size, print_time_passes_entry,
 };
@@ -1577,8 +1576,8 @@ pub fn install_ctrlc_handler() {
         // time to check CTRL_C_RECEIVED and run its own shutdown logic, but after a short amount
         // of time exit the process. This sleep+exit ensures that even if nobody is checking
         // CTRL_C_RECEIVED, the compiler exits reasonably promptly.
-        CTRL_C_RECEIVED.store(true, Ordering::Relaxed);
-        std::thread::sleep(Duration::from_millis(100));
+        rustc_const_eval::CTRL_C_RECEIVED.store(true, Ordering::Relaxed);
+        std::thread::sleep(std::time::Duration::from_millis(100));
         std::process::exit(1);
     })
     .expect("Unable to install ctrlc handler");
diff --git a/compiler/rustc_fs_util/src/lib.rs b/compiler/rustc_fs_util/src/lib.rs
index 80813af3864..4e9d21c900d 100644
--- a/compiler/rustc_fs_util/src/lib.rs
+++ b/compiler/rustc_fs_util/src/lib.rs
@@ -76,10 +76,14 @@ pub fn link_or_copy<P: AsRef<Path>, Q: AsRef<Path>>(p: P, q: Q) -> io::Result<Li
     }
 }
 
-#[cfg(unix)]
+#[cfg(any(unix, all(target_os = "wasi", target_env = "p1")))]
 pub fn path_to_c_string(p: &Path) -> CString {
     use std::ffi::OsStr;
+    #[cfg(unix)]
     use std::os::unix::ffi::OsStrExt;
+    #[cfg(all(target_os = "wasi", target_env = "p1"))]
+    use std::os::wasi::ffi::OsStrExt;
+
     let p: &OsStr = p.as_ref();
     CString::new(p.as_bytes()).unwrap()
 }
diff --git a/compiler/rustc_serialize/src/opaque.rs b/compiler/rustc_serialize/src/opaque.rs
index c7c561156e3..27e9f817894 100644
--- a/compiler/rustc_serialize/src/opaque.rs
+++ b/compiler/rustc_serialize/src/opaque.rs
@@ -437,10 +437,10 @@ impl IntEncodedWithFixedSize {
 impl Encodable<FileEncoder> for IntEncodedWithFixedSize {
     #[inline]
     fn encode(&self, e: &mut FileEncoder) {
-        let _start_pos = e.position();
+        let start_pos = e.position();
         e.write_array(self.0.to_le_bytes());
-        let _end_pos = e.position();
-        debug_assert_eq!((_end_pos - _start_pos), IntEncodedWithFixedSize::ENCODED_SIZE);
+        let end_pos = e.position();
+        debug_assert_eq!((end_pos - start_pos), IntEncodedWithFixedSize::ENCODED_SIZE);
     }
 }
 
diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs
index 7283b0e9574..7a49b68b91e 100644
--- a/src/bootstrap/src/core/build_steps/test.rs
+++ b/src/bootstrap/src/core/build_steps/test.rs
@@ -1394,12 +1394,6 @@ default_test!(Ui { path: "tests/ui", mode: "ui", suite: "ui" });
 
 default_test!(Crashes { path: "tests/crashes", mode: "crashes", suite: "crashes" });
 
-default_test!(RunPassValgrind {
-    path: "tests/run-pass-valgrind",
-    mode: "run-pass-valgrind",
-    suite: "run-pass-valgrind"
-});
-
 default_test!(Codegen { path: "tests/codegen", mode: "codegen", suite: "codegen" });
 
 default_test!(CodegenUnits {
diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs
index 64dfe054d9c..e2fcd13efe3 100644
--- a/src/bootstrap/src/core/build_steps/tool.rs
+++ b/src/bootstrap/src/core/build_steps/tool.rs
@@ -872,8 +872,11 @@ impl Step for LlvmBitcodeLinker {
     fn run(self, builder: &Builder<'_>) -> PathBuf {
         let bin_name = "llvm-bitcode-linker";
 
-        builder.ensure(compile::Std::new(self.compiler, self.compiler.host));
-        builder.ensure(compile::Rustc::new(self.compiler, self.target));
+        // If enabled, use ci-rustc and skip building the in-tree compiler.
+        if !builder.download_rustc() {
+            builder.ensure(compile::Std::new(self.compiler, self.compiler.host));
+            builder.ensure(compile::Rustc::new(self.compiler, self.target));
+        }
 
         let cargo = prepare_tool_cargo(
             builder,
diff --git a/src/bootstrap/src/core/builder.rs b/src/bootstrap/src/core/builder.rs
index e7a19d0bcc0..155c6515db8 100644
--- a/src/bootstrap/src/core/builder.rs
+++ b/src/bootstrap/src/core/builder.rs
@@ -327,7 +327,6 @@ const PATH_REMAP: &[(&str, &[&str])] = &[
         "tests/mir-opt",
         "tests/pretty",
         "tests/run-make",
-        "tests/run-pass-valgrind",
         "tests/rustdoc",
         "tests/rustdoc-gui",
         "tests/rustdoc-js",
@@ -852,7 +851,6 @@ impl<'a> Builder<'a> {
                 test::Tidy,
                 test::Ui,
                 test::Crashes,
-                test::RunPassValgrind,
                 test::Coverage,
                 test::CoverageMap,
                 test::CoverageRun,
@@ -1687,10 +1685,24 @@ impl<'a> Builder<'a> {
         match mode {
             Mode::Std | Mode::ToolBootstrap | Mode::ToolStd => {}
             Mode::Rustc | Mode::Codegen | Mode::ToolRustc => {
-                // Build proc macros both for the host and the target
+                // Build proc macros both for the host and the target unless proc-macros are not
+                // supported by the target.
                 if target != compiler.host && cmd_kind != Kind::Check {
-                    cargo.arg("-Zdual-proc-macros");
-                    rustflags.arg("-Zdual-proc-macros");
+                    let error = command(self.rustc(compiler))
+                        .arg("--target")
+                        .arg(target.rustc_target_arg())
+                        .arg("--print=file-names")
+                        .arg("--crate-type=proc-macro")
+                        .arg("-")
+                        .run_capture(self)
+                        .stderr();
+                    let not_supported = error
+                        .lines()
+                        .any(|line| line.contains("unsupported crate type `proc-macro`"));
+                    if !not_supported {
+                        cargo.arg("-Zdual-proc-macros");
+                        rustflags.arg("-Zdual-proc-macros");
+                    }
                 }
             }
         }
diff --git a/src/bootstrap/src/utils/shared_helpers.rs b/src/bootstrap/src/utils/shared_helpers.rs
index 7150c84313c..6d3c276cc05 100644
--- a/src/bootstrap/src/utils/shared_helpers.rs
+++ b/src/bootstrap/src/utils/shared_helpers.rs
@@ -49,6 +49,8 @@ pub fn exe(name: &str, target: &str) -> String {
         format!("{name}.exe")
     } else if target.contains("uefi") {
         format!("{name}.efi")
+    } else if target.contains("wasm") {
+        format!("{name}.wasm")
     } else {
         name.to_string()
     }
diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs
index adc89cad72f..17ec6ea4301 100644
--- a/src/tools/compiletest/src/common.rs
+++ b/src/tools/compiletest/src/common.rs
@@ -53,7 +53,6 @@ macro_rules! string_enum {
 string_enum! {
     #[derive(Clone, Copy, PartialEq, Debug)]
     pub enum Mode {
-        RunPassValgrind => "run-pass-valgrind",
         Pretty => "pretty",
         DebugInfo => "debuginfo",
         Codegen => "codegen",
@@ -207,13 +206,6 @@ pub struct Config {
     /// Path to LLVM's bin directory.
     pub llvm_bin_dir: Option<PathBuf>,
 
-    /// The valgrind path.
-    pub valgrind_path: Option<String>,
-
-    /// Whether to fail if we can't run run-pass-valgrind tests under valgrind
-    /// (or, alternatively, to silently run them like regular run-pass tests).
-    pub force_valgrind: bool,
-
     /// The path to the Clang executable to run Clang-based tests with. If
     /// `None` then these tests will be ignored.
     pub run_clang_based_tests_with: Option<String>,
diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs
index a8355ee9590..d9f64cddf5d 100644
--- a/src/tools/compiletest/src/lib.rs
+++ b/src/tools/compiletest/src/lib.rs
@@ -53,8 +53,6 @@ pub fn parse_config(args: Vec<String>) -> Config {
         .reqopt("", "python", "path to python to use for doc tests", "PATH")
         .optopt("", "jsondocck-path", "path to jsondocck to use for doc tests", "PATH")
         .optopt("", "jsondoclint-path", "path to jsondoclint to use for doc tests", "PATH")
-        .optopt("", "valgrind-path", "path to Valgrind executable for Valgrind tests", "PROGRAM")
-        .optflag("", "force-valgrind", "fail if Valgrind tests cannot be run under Valgrind")
         .optopt("", "run-clang-based-tests-with", "path to Clang executable", "PATH")
         .optopt("", "llvm-filecheck", "path to LLVM's FileCheck binary", "DIR")
         .reqopt("", "src-base", "directory to scan for test files", "PATH")
@@ -65,7 +63,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
             "",
             "mode",
             "which sort of compile tests to run",
-            "run-pass-valgrind | pretty | debug-info | codegen | rustdoc \
+            "pretty | debug-info | codegen | rustdoc \
             | rustdoc-json | codegen-units | incremental | run-make | ui \
             | js-doc-test | mir-opt | assembly | crashes",
         )
@@ -269,8 +267,6 @@ pub fn parse_config(args: Vec<String>) -> Config {
         python: matches.opt_str("python").unwrap(),
         jsondocck_path: matches.opt_str("jsondocck-path"),
         jsondoclint_path: matches.opt_str("jsondoclint-path"),
-        valgrind_path: matches.opt_str("valgrind-path"),
-        force_valgrind: matches.opt_present("force-valgrind"),
         run_clang_based_tests_with: matches.opt_str("run-clang-based-tests-with"),
         llvm_filecheck: matches.opt_str("llvm-filecheck").map(PathBuf::from),
         llvm_bin_dir: matches.opt_str("llvm-bin-dir").map(PathBuf::from),
diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs
index 7b85e6f80b3..9f3eef3776d 100644
--- a/src/tools/compiletest/src/main.rs
+++ b/src/tools/compiletest/src/main.rs
@@ -18,10 +18,6 @@ fn main() {
 
     let config = Arc::new(parse_config(env::args().collect()));
 
-    if config.valgrind_path.is_none() && config.force_valgrind {
-        panic!("Can't find Valgrind to run Valgrind tests");
-    }
-
     if !config.has_tidy && config.mode == Mode::Rustdoc {
         eprintln!("warning: `tidy` is not installed; diffs will not be generated");
     }
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index e26c178ccb0..256b88758f0 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -20,9 +20,9 @@ use tracing::*;
 use crate::common::{
     Assembly, Codegen, CodegenUnits, CompareMode, Config, CoverageMap, CoverageRun, Crashes,
     DebugInfo, Debugger, FailMode, Incremental, JsDocTest, MirOpt, PassMode, Pretty, RunMake,
-    RunPassValgrind, Rustdoc, RustdocJson, TestPaths, UI_EXTENSIONS, UI_FIXED, UI_RUN_STDERR,
-    UI_RUN_STDOUT, UI_STDERR, UI_STDOUT, UI_SVG, UI_WINDOWS_SVG, Ui, expected_output_path,
-    incremental_dir, output_base_dir, output_base_name, output_testname_unique,
+    Rustdoc, RustdocJson, TestPaths, UI_EXTENSIONS, UI_FIXED, UI_RUN_STDERR, UI_RUN_STDOUT,
+    UI_STDERR, UI_STDOUT, UI_SVG, UI_WINDOWS_SVG, Ui, expected_output_path, incremental_dir,
+    output_base_dir, output_base_name, output_testname_unique,
 };
 use crate::compute_diff::{write_diff, write_filtered_diff};
 use crate::errors::{self, Error, ErrorKind};
@@ -49,7 +49,6 @@ mod run_make;
 mod rustdoc;
 mod rustdoc_json;
 mod ui;
-mod valgrind;
 // tidy-alphabet-end
 
 #[cfg(test)]
@@ -253,7 +252,6 @@ impl<'test> TestCx<'test> {
             self.fatal("cannot use should-ice in a test that is not cfail");
         }
         match self.config.mode {
-            RunPassValgrind => self.run_valgrind_test(),
             Pretty => self.run_pretty_test(),
             DebugInfo => self.run_debuginfo_test(),
             Codegen => self.run_codegen_test(),
@@ -1500,8 +1498,7 @@ impl<'test> TestCx<'test> {
             Crashes => {
                 set_mir_dump_dir(&mut rustc);
             }
-            RunPassValgrind | Pretty | DebugInfo | Rustdoc | RustdocJson | RunMake
-            | CodegenUnits | JsDocTest => {
+            Pretty | DebugInfo | Rustdoc | RustdocJson | RunMake | CodegenUnits | JsDocTest => {
                 // do not use JSON output
             }
         }
@@ -2655,33 +2652,6 @@ impl<'test> TestCx<'test> {
         }
     }
 
-    // FIXME(jieyouxu): `run_rpass_test` is hoisted out here and not in incremental because
-    // apparently valgrind test falls back to `run_rpass_test` if valgrind isn't available, which
-    // seems highly questionable to me.
-    fn run_rpass_test(&self) {
-        let emit_metadata = self.should_emit_metadata(self.pass_mode());
-        let should_run = self.run_if_enabled();
-        let proc_res = self.compile_test(should_run, emit_metadata);
-
-        if !proc_res.status.success() {
-            self.fatal_proc_rec("compilation failed!", &proc_res);
-        }
-
-        // FIXME(#41968): Move this check to tidy?
-        if !errors::load_errors(&self.testpaths.file, self.revision).is_empty() {
-            self.fatal("run-pass tests with expected warnings should be moved to ui/");
-        }
-
-        if let WillExecute::Disabled = should_run {
-            return;
-        }
-
-        let proc_res = self.exec_compiled_test();
-        if !proc_res.status.success() {
-            self.fatal_proc_rec("test run failed!", &proc_res);
-        }
-    }
-
     fn aggressive_rm_rf(&self, path: &Path) -> io::Result<()> {
         for e in path.read_dir()? {
             let entry = e?;
diff --git a/src/tools/compiletest/src/runtest/incremental.rs b/src/tools/compiletest/src/runtest/incremental.rs
index 81b006292e4..bf2b71fef43 100644
--- a/src/tools/compiletest/src/runtest/incremental.rs
+++ b/src/tools/compiletest/src/runtest/incremental.rs
@@ -1,10 +1,6 @@
 use super::{TestCx, WillExecute};
 use crate::errors;
 
-// FIXME(jieyouxu): `run_rpass_test` got hoisted out of this because apparently valgrind falls back
-// to `run_rpass_test` if valgrind isn't available, which is questionable, but keeping it for
-// refactoring changes to preserve current behavior.
-
 impl TestCx<'_> {
     pub(super) fn run_incremental_test(&self) {
         // Basic plan for a test incremental/foo/bar.rs:
@@ -73,6 +69,30 @@ impl TestCx<'_> {
         }
     }
 
+    fn run_rpass_test(&self) {
+        let emit_metadata = self.should_emit_metadata(self.pass_mode());
+        let should_run = self.run_if_enabled();
+        let proc_res = self.compile_test(should_run, emit_metadata);
+
+        if !proc_res.status.success() {
+            self.fatal_proc_rec("compilation failed!", &proc_res);
+        }
+
+        // FIXME(#41968): Move this check to tidy?
+        if !errors::load_errors(&self.testpaths.file, self.revision).is_empty() {
+            self.fatal("run-pass tests with expected warnings should be moved to ui/");
+        }
+
+        if let WillExecute::Disabled = should_run {
+            return;
+        }
+
+        let proc_res = self.exec_compiled_test();
+        if !proc_res.status.success() {
+            self.fatal_proc_rec("test run failed!", &proc_res);
+        }
+    }
+
     fn run_cfail_test(&self) {
         let pm = self.pass_mode();
         let proc_res = self.compile_test(WillExecute::No, self.should_emit_metadata(pm));
@@ -115,12 +135,6 @@ impl TestCx<'_> {
 
         let proc_res = self.exec_compiled_test();
 
-        // The value our Makefile configures valgrind to return on failure
-        const VALGRIND_ERR: i32 = 100;
-        if proc_res.status.code() == Some(VALGRIND_ERR) {
-            self.fatal_proc_rec("run-fail test isn't valgrind-clean!", &proc_res);
-        }
-
         let output_to_check = self.get_output(&proc_res);
         self.check_correct_failure_status(&proc_res);
         self.check_all_error_patterns(&output_to_check, &proc_res, pm);
diff --git a/src/tools/compiletest/src/runtest/valgrind.rs b/src/tools/compiletest/src/runtest/valgrind.rs
deleted file mode 100644
index 8d72c4be9ff..00000000000
--- a/src/tools/compiletest/src/runtest/valgrind.rs
+++ /dev/null
@@ -1,34 +0,0 @@
-use super::{Emit, TestCx, WillExecute};
-
-impl TestCx<'_> {
-    pub(super) fn run_valgrind_test(&self) {
-        assert!(self.revision.is_none(), "revisions not relevant here");
-
-        // FIXME(jieyouxu): does this really make any sense? If a valgrind test isn't testing
-        // valgrind, what is it even testing?
-        if self.config.valgrind_path.is_none() {
-            assert!(!self.config.force_valgrind);
-            return self.run_rpass_test();
-        }
-
-        let should_run = self.run_if_enabled();
-        let mut proc_res = self.compile_test(should_run, Emit::None);
-
-        if !proc_res.status.success() {
-            self.fatal_proc_rec("compilation failed!", &proc_res);
-        }
-
-        if let WillExecute::Disabled = should_run {
-            return;
-        }
-
-        let mut new_config = self.config.clone();
-        new_config.runner = new_config.valgrind_path.clone();
-        let new_cx = TestCx { config: &new_config, ..*self };
-        proc_res = new_cx.exec_compiled_test();
-
-        if !proc_res.status.success() {
-            self.fatal_proc_rec("test run failed!", &proc_res);
-        }
-    }
-}
diff --git a/src/tools/opt-dist/src/tests.rs b/src/tools/opt-dist/src/tests.rs
index 82c393d34a6..e401554640c 100644
--- a/src/tools/opt-dist/src/tests.rs
+++ b/src/tools/opt-dist/src/tests.rs
@@ -96,7 +96,6 @@ llvm-config = "{llvm_config}"
         "tests/incremental",
         "tests/mir-opt",
         "tests/pretty",
-        "tests/run-pass-valgrind",
         "tests/ui",
         "tests/crashes",
     ];
diff --git a/tests/run-pass-valgrind/cast-enum-with-dtor.rs b/tests/run-pass-valgrind/cast-enum-with-dtor.rs
deleted file mode 100644
index a57dc373478..00000000000
--- a/tests/run-pass-valgrind/cast-enum-with-dtor.rs
+++ /dev/null
@@ -1,34 +0,0 @@
-#![allow(dead_code, cenum_impl_drop_cast)]
-
-// check dtor calling order when casting enums.
-
-use std::mem;
-use std::sync::atomic;
-use std::sync::atomic::Ordering;
-
-enum E {
-    A = 0,
-    B = 1,
-    C = 2,
-}
-
-static FLAG: atomic::AtomicUsize = atomic::AtomicUsize::new(0);
-
-impl Drop for E {
-    fn drop(&mut self) {
-        // avoid dtor loop
-        unsafe { mem::forget(mem::replace(self, E::B)) };
-
-        FLAG.store(FLAG.load(Ordering::SeqCst) + 1, Ordering::SeqCst);
-    }
-}
-
-fn main() {
-    assert_eq!(FLAG.load(Ordering::SeqCst), 0);
-    {
-        let e = E::C;
-        assert_eq!(e as u32, 2);
-        assert_eq!(FLAG.load(Ordering::SeqCst), 1);
-    }
-    assert_eq!(FLAG.load(Ordering::SeqCst), 1);
-}
diff --git a/tests/run-pass-valgrind/cleanup-auto-borrow-obj.rs b/tests/run-pass-valgrind/cleanup-auto-borrow-obj.rs
deleted file mode 100644
index e4ce80b3305..00000000000
--- a/tests/run-pass-valgrind/cleanup-auto-borrow-obj.rs
+++ /dev/null
@@ -1,28 +0,0 @@
-// This would previously leak the Box<Trait> because we wouldn't
-// schedule cleanups when auto borrowing trait objects.
-// This program should be valgrind clean.
-
-static mut DROP_RAN: bool = false;
-
-struct Foo;
-impl Drop for Foo {
-    fn drop(&mut self) {
-        unsafe {
-            DROP_RAN = true;
-        }
-    }
-}
-
-trait Trait {
-    fn dummy(&self) {}
-}
-impl Trait for Foo {}
-
-pub fn main() {
-    {
-        let _x: &Trait = &*(Box::new(Foo) as Box<Trait>);
-    }
-    unsafe {
-        assert!(DROP_RAN);
-    }
-}
diff --git a/tests/run-pass-valgrind/cleanup-stdin.rs b/tests/run-pass-valgrind/cleanup-stdin.rs
deleted file mode 100644
index cf8f81cf5aa..00000000000
--- a/tests/run-pass-valgrind/cleanup-stdin.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-fn main() {
-    let _ = std::io::stdin();
-    let _ = std::io::stdout();
-    let _ = std::io::stderr();
-}
diff --git a/tests/run-pass-valgrind/coerce-match-calls.rs b/tests/run-pass-valgrind/coerce-match-calls.rs
deleted file mode 100644
index 8c7375610dd..00000000000
--- a/tests/run-pass-valgrind/coerce-match-calls.rs
+++ /dev/null
@@ -1,21 +0,0 @@
-// Check that coercions are propagated through match and if expressions.
-
-//@ pretty-expanded FIXME #23616
-
-use std::boxed::Box;
-
-pub fn main() {
-    let _: Box<[isize]> = if true { Box::new([1, 2, 3]) } else { Box::new([1]) };
-
-    let _: Box<[isize]> = match true {
-        true => Box::new([1, 2, 3]),
-        false => Box::new([1]),
-    };
-
-    // Check we don't get over-keen at propagating coercions in the case of casts.
-    let x = if true { 42 } else { 42u8 } as u16;
-    let x = match true {
-        true => 42,
-        false => 42u8,
-    } as u16;
-}
diff --git a/tests/run-pass-valgrind/coerce-match.rs b/tests/run-pass-valgrind/coerce-match.rs
deleted file mode 100644
index 95f16a8cc89..00000000000
--- a/tests/run-pass-valgrind/coerce-match.rs
+++ /dev/null
@@ -1,31 +0,0 @@
-// Check that coercions are propagated through match and if expressions.
-
-//@ pretty-expanded FIXME #23616
-
-pub fn main() {
-    let _: Box<[isize]> = if true {
-        let b: Box<_> = Box::new([1, 2, 3]);
-        b
-    } else {
-        let b: Box<_> = Box::new([1]);
-        b
-    };
-
-    let _: Box<[isize]> = match true {
-        true => {
-            let b: Box<_> = Box::new([1, 2, 3]);
-            b
-        }
-        false => {
-            let b: Box<_> = Box::new([1]);
-            b
-        }
-    };
-
-    // Check we don't get over-keen at propagating coercions in the case of casts.
-    let x = if true { 42 } else { 42u8 } as u16;
-    let x = match true {
-        true => 42,
-        false => 42u8,
-    } as u16;
-}
diff --git a/tests/run-pass-valgrind/down-with-thread-dtors.rs b/tests/run-pass-valgrind/down-with-thread-dtors.rs
deleted file mode 100644
index 0d3745bba5b..00000000000
--- a/tests/run-pass-valgrind/down-with-thread-dtors.rs
+++ /dev/null
@@ -1,43 +0,0 @@
-//@ ignore-emscripten
-
-thread_local!(static FOO: Foo = Foo);
-thread_local!(static BAR: Bar = Bar(1));
-thread_local!(static BAZ: Baz = Baz);
-
-static mut HIT: bool = false;
-
-struct Foo;
-struct Bar(i32);
-struct Baz;
-
-impl Drop for Foo {
-    fn drop(&mut self) {
-        BAR.with(|_| {});
-    }
-}
-
-impl Drop for Bar {
-    fn drop(&mut self) {
-        assert_eq!(self.0, 1);
-        self.0 = 2;
-        BAZ.with(|_| {});
-        assert_eq!(self.0, 2);
-    }
-}
-
-impl Drop for Baz {
-    fn drop(&mut self) {
-        unsafe {
-            HIT = true;
-        }
-    }
-}
-
-fn main() {
-    std::thread::spawn(|| {
-        FOO.with(|_| {});
-    })
-    .join()
-    .unwrap();
-    assert!(unsafe { HIT });
-}
diff --git a/tests/run-pass-valgrind/dst-dtor-1.rs b/tests/run-pass-valgrind/dst-dtor-1.rs
deleted file mode 100644
index 47065151a03..00000000000
--- a/tests/run-pass-valgrind/dst-dtor-1.rs
+++ /dev/null
@@ -1,28 +0,0 @@
-static mut DROP_RAN: bool = false;
-
-struct Foo;
-impl Drop for Foo {
-    fn drop(&mut self) {
-        unsafe {
-            DROP_RAN = true;
-        }
-    }
-}
-
-trait Trait {
-    fn dummy(&self) {}
-}
-impl Trait for Foo {}
-
-struct Fat<T: ?Sized> {
-    f: T,
-}
-
-pub fn main() {
-    {
-        let _x: Box<Fat<Trait>> = Box::<Fat<Foo>>::new(Fat { f: Foo });
-    }
-    unsafe {
-        assert!(DROP_RAN);
-    }
-}
diff --git a/tests/run-pass-valgrind/dst-dtor-2.rs b/tests/run-pass-valgrind/dst-dtor-2.rs
deleted file mode 100644
index d8abebfb447..00000000000
--- a/tests/run-pass-valgrind/dst-dtor-2.rs
+++ /dev/null
@@ -1,23 +0,0 @@
-static mut DROP_RAN: isize = 0;
-
-struct Foo;
-impl Drop for Foo {
-    fn drop(&mut self) {
-        unsafe {
-            DROP_RAN += 1;
-        }
-    }
-}
-
-struct Fat<T: ?Sized> {
-    f: T,
-}
-
-pub fn main() {
-    {
-        let _x: Box<Fat<[Foo]>> = Box::<Fat<[Foo; 3]>>::new(Fat { f: [Foo, Foo, Foo] });
-    }
-    unsafe {
-        assert_eq!(DROP_RAN, 3);
-    }
-}
diff --git a/tests/run-pass-valgrind/dst-dtor-3.rs b/tests/run-pass-valgrind/dst-dtor-3.rs
deleted file mode 100644
index 09adaca21c7..00000000000
--- a/tests/run-pass-valgrind/dst-dtor-3.rs
+++ /dev/null
@@ -1,26 +0,0 @@
-#![feature(unsized_tuple_coercion)]
-
-static mut DROP_RAN: bool = false;
-
-struct Foo;
-impl Drop for Foo {
-    fn drop(&mut self) {
-        unsafe {
-            DROP_RAN = true;
-        }
-    }
-}
-
-trait Trait {
-    fn dummy(&self) {}
-}
-impl Trait for Foo {}
-
-pub fn main() {
-    {
-        let _x: Box<(i32, Trait)> = Box::<(i32, Foo)>::new((42, Foo));
-    }
-    unsafe {
-        assert!(DROP_RAN);
-    }
-}
diff --git a/tests/run-pass-valgrind/dst-dtor-4.rs b/tests/run-pass-valgrind/dst-dtor-4.rs
deleted file mode 100644
index a66ac8e3cfc..00000000000
--- a/tests/run-pass-valgrind/dst-dtor-4.rs
+++ /dev/null
@@ -1,21 +0,0 @@
-#![feature(unsized_tuple_coercion)]
-
-static mut DROP_RAN: isize = 0;
-
-struct Foo;
-impl Drop for Foo {
-    fn drop(&mut self) {
-        unsafe {
-            DROP_RAN += 1;
-        }
-    }
-}
-
-pub fn main() {
-    {
-        let _x: Box<(i32, [Foo])> = Box::<(i32, [Foo; 3])>::new((42, [Foo, Foo, Foo]));
-    }
-    unsafe {
-        assert_eq!(DROP_RAN, 3);
-    }
-}
diff --git a/tests/run-pass-valgrind/exit-flushes.rs b/tests/run-pass-valgrind/exit-flushes.rs
deleted file mode 100644
index 4e25ef76d39..00000000000
--- a/tests/run-pass-valgrind/exit-flushes.rs
+++ /dev/null
@@ -1,19 +0,0 @@
-//@ ignore-wasm32 no subprocess support
-//@ ignore-sgx no processes
-//@ ignore-apple this needs valgrind 3.11 or higher; see
-// https://github.com/rust-lang/rust/pull/30365#issuecomment-165763679
-
-use std::env;
-use std::process::{Command, exit};
-
-fn main() {
-    if env::args().len() > 1 {
-        print!("hello!");
-        exit(0);
-    } else {
-        let out = Command::new(env::args().next().unwrap()).arg("foo").output().unwrap();
-        assert!(out.status.success());
-        assert_eq!(String::from_utf8(out.stdout).unwrap(), "hello!");
-        assert_eq!(String::from_utf8(out.stderr).unwrap(), "");
-    }
-}
diff --git a/tests/run-pass-valgrind/issue-44800.rs b/tests/run-pass-valgrind/issue-44800.rs
deleted file mode 100644
index f76657ca752..00000000000
--- a/tests/run-pass-valgrind/issue-44800.rs
+++ /dev/null
@@ -1,12 +0,0 @@
-use std::alloc::System;
-use std::collections::VecDeque;
-
-#[global_allocator]
-static ALLOCATOR: System = System;
-
-fn main() {
-    let mut deque = VecDeque::with_capacity(32);
-    deque.push_front(0);
-    deque.reserve(31);
-    deque.push_back(0);
-}
diff --git a/tests/run-pass-valgrind/unsized-locals/by-value-trait-objects-rust-call.rs b/tests/run-pass-valgrind/unsized-locals/by-value-trait-objects-rust-call.rs
deleted file mode 100644
index 5d3f558a63a..00000000000
--- a/tests/run-pass-valgrind/unsized-locals/by-value-trait-objects-rust-call.rs
+++ /dev/null
@@ -1,55 +0,0 @@
-#![feature(unsized_locals)]
-#![feature(unboxed_closures)]
-#![feature(tuple_trait)]
-
-pub trait FnOnce<Args: std::marker::Tuple> {
-    type Output;
-    extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
-}
-
-struct A;
-
-impl FnOnce<()> for A {
-    type Output = String;
-    extern "rust-call" fn call_once(self, (): ()) -> Self::Output {
-        format!("hello")
-    }
-}
-
-struct B(i32);
-
-impl FnOnce<()> for B {
-    type Output = String;
-    extern "rust-call" fn call_once(self, (): ()) -> Self::Output {
-        format!("{}", self.0)
-    }
-}
-
-struct C(String);
-
-impl FnOnce<()> for C {
-    type Output = String;
-    extern "rust-call" fn call_once(self, (): ()) -> Self::Output {
-        self.0
-    }
-}
-
-struct D(Box<String>);
-
-impl FnOnce<()> for D {
-    type Output = String;
-    extern "rust-call" fn call_once(self, (): ()) -> Self::Output {
-        *self.0
-    }
-}
-
-fn main() {
-    let x = *(Box::new(A) as Box<dyn FnOnce<(), Output = String>>);
-    assert_eq!(x.call_once(()), format!("hello"));
-    let x = *(Box::new(B(42)) as Box<dyn FnOnce<(), Output = String>>);
-    assert_eq!(x.call_once(()), format!("42"));
-    let x = *(Box::new(C(format!("jumping fox"))) as Box<dyn FnOnce<(), Output = String>>);
-    assert_eq!(x.call_once(()), format!("jumping fox"));
-    let x = *(Box::new(D(Box::new(format!("lazy dog")))) as Box<dyn FnOnce<(), Output = String>>);
-    assert_eq!(x.call_once(()), format!("lazy dog"));
-}
diff --git a/tests/run-pass-valgrind/unsized-locals/by-value-trait-objects-rust-call2.rs b/tests/run-pass-valgrind/unsized-locals/by-value-trait-objects-rust-call2.rs
deleted file mode 100644
index 9b6648f2e27..00000000000
--- a/tests/run-pass-valgrind/unsized-locals/by-value-trait-objects-rust-call2.rs
+++ /dev/null
@@ -1,69 +0,0 @@
-#![feature(unsized_locals)]
-#![feature(unboxed_closures)]
-#![feature(tuple_trait)]
-
-pub trait FnOnce<Args: std::marker::Tuple> {
-    type Output;
-    extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
-}
-
-struct A;
-
-impl FnOnce<(String, Box<str>)> for A {
-    type Output = String;
-    extern "rust-call" fn call_once(self, (s1, s2): (String, Box<str>)) -> Self::Output {
-        assert_eq!(&s1 as &str, "s1");
-        assert_eq!(&s2 as &str, "s2");
-        format!("hello")
-    }
-}
-
-struct B(i32);
-
-impl FnOnce<(String, Box<str>)> for B {
-    type Output = String;
-    extern "rust-call" fn call_once(self, (s1, s2): (String, Box<str>)) -> Self::Output {
-        assert_eq!(&s1 as &str, "s1");
-        assert_eq!(&s2 as &str, "s2");
-        format!("{}", self.0)
-    }
-}
-
-struct C(String);
-
-impl FnOnce<(String, Box<str>)> for C {
-    type Output = String;
-    extern "rust-call" fn call_once(self, (s1, s2): (String, Box<str>)) -> Self::Output {
-        assert_eq!(&s1 as &str, "s1");
-        assert_eq!(&s2 as &str, "s2");
-        self.0
-    }
-}
-
-struct D(Box<String>);
-
-impl FnOnce<(String, Box<str>)> for D {
-    type Output = String;
-    extern "rust-call" fn call_once(self, (s1, s2): (String, Box<str>)) -> Self::Output {
-        assert_eq!(&s1 as &str, "s1");
-        assert_eq!(&s2 as &str, "s2");
-        *self.0
-    }
-}
-
-fn main() {
-    let (s1, s2) = (format!("s1"), format!("s2").into_boxed_str());
-    let x = *(Box::new(A) as Box<dyn FnOnce<(String, Box<str>), Output = String>>);
-    assert_eq!(x.call_once((s1, s2)), format!("hello"));
-    let (s1, s2) = (format!("s1"), format!("s2").into_boxed_str());
-    let x = *(Box::new(B(42)) as Box<dyn FnOnce<(String, Box<str>), Output = String>>);
-    assert_eq!(x.call_once((s1, s2)), format!("42"));
-    let (s1, s2) = (format!("s1"), format!("s2").into_boxed_str());
-    let x = *(Box::new(C(format!("jumping fox")))
-        as Box<dyn FnOnce<(String, Box<str>), Output = String>>);
-    assert_eq!(x.call_once((s1, s2)), format!("jumping fox"));
-    let (s1, s2) = (format!("s1"), format!("s2").into_boxed_str());
-    let x = *(Box::new(D(Box::new(format!("lazy dog"))))
-        as Box<dyn FnOnce<(String, Box<str>), Output = String>>);
-    assert_eq!(x.call_once((s1, s2)), format!("lazy dog"));
-}
diff --git a/tests/run-pass-valgrind/unsized-locals/by-value-trait-objects.rs b/tests/run-pass-valgrind/unsized-locals/by-value-trait-objects.rs
deleted file mode 100644
index 3f6b6d262b5..00000000000
--- a/tests/run-pass-valgrind/unsized-locals/by-value-trait-objects.rs
+++ /dev/null
@@ -1,48 +0,0 @@
-#![feature(unsized_locals)]
-
-pub trait Foo {
-    fn foo(self) -> String;
-}
-
-struct A;
-
-impl Foo for A {
-    fn foo(self) -> String {
-        format!("hello")
-    }
-}
-
-struct B(i32);
-
-impl Foo for B {
-    fn foo(self) -> String {
-        format!("{}", self.0)
-    }
-}
-
-struct C(String);
-
-impl Foo for C {
-    fn foo(self) -> String {
-        self.0
-    }
-}
-
-struct D(Box<String>);
-
-impl Foo for D {
-    fn foo(self) -> String {
-        *self.0
-    }
-}
-
-fn main() {
-    let x = *(Box::new(A) as Box<dyn Foo>);
-    assert_eq!(x.foo(), format!("hello"));
-    let x = *(Box::new(B(42)) as Box<dyn Foo>);
-    assert_eq!(x.foo(), format!("42"));
-    let x = *(Box::new(C(format!("jumping fox"))) as Box<dyn Foo>);
-    assert_eq!(x.foo(), format!("jumping fox"));
-    let x = *(Box::new(D(Box::new(format!("lazy dog")))) as Box<dyn Foo>);
-    assert_eq!(x.foo(), format!("lazy dog"));
-}
diff --git a/tests/run-pass-valgrind/unsized-locals/long-live-the-unsized-temporary.rs b/tests/run-pass-valgrind/unsized-locals/long-live-the-unsized-temporary.rs
deleted file mode 100644
index a7b9052617f..00000000000
--- a/tests/run-pass-valgrind/unsized-locals/long-live-the-unsized-temporary.rs
+++ /dev/null
@@ -1,52 +0,0 @@
-#![allow(incomplete_features)]
-#![feature(unsized_locals, unsized_fn_params)]
-
-use std::fmt;
-
-fn gen_foo() -> Box<fmt::Display> {
-    Box::new(Box::new("foo"))
-}
-
-fn foo(x: fmt::Display) {
-    assert_eq!(x.to_string(), "foo");
-}
-
-fn foo_indirect(x: fmt::Display) {
-    foo(x);
-}
-
-fn main() {
-    foo(*gen_foo());
-    foo_indirect(*gen_foo());
-
-    {
-        let x: fmt::Display = *gen_foo();
-        foo(x);
-    }
-
-    {
-        let x: fmt::Display = *gen_foo();
-        let y: fmt::Display = *gen_foo();
-        foo(x);
-        foo(y);
-    }
-
-    {
-        let mut cnt: usize = 3;
-        let x = loop {
-            let x: fmt::Display = *gen_foo();
-            if cnt == 0 {
-                break x;
-            } else {
-                cnt -= 1;
-            }
-        };
-        foo(x);
-    }
-
-    {
-        let x: fmt::Display = *gen_foo();
-        let x = if true { x } else { *gen_foo() };
-        foo(x);
-    }
-}
diff --git a/tests/ui/deriving/deriving-smart-pointer-neg.rs b/tests/ui/deriving/deriving-smart-pointer-neg.rs
index f02fb56130f..41d3039236f 100644
--- a/tests/ui/deriving/deriving-smart-pointer-neg.rs
+++ b/tests/ui/deriving/deriving-smart-pointer-neg.rs
@@ -53,6 +53,39 @@ struct NoMaybeSized<'a, #[pointee] T> {
     ptr: &'a T,
 }
 
+#[derive(SmartPointer)]
+#[repr(transparent)]
+struct PointeeOnField<'a, #[pointee] T: ?Sized> {
+    #[pointee]
+    //~^ ERROR: the `#[pointee]` attribute may only be used on generic parameters
+    ptr: &'a T
+}
+
+#[derive(SmartPointer)]
+#[repr(transparent)]
+struct PointeeInTypeConstBlock<'a, T: ?Sized = [u32; const { struct UhOh<#[pointee] T>(T); 10 }]> {
+    //~^ ERROR: the `#[pointee]` attribute may only be used on generic parameters
+    ptr: &'a T,
+}
+
+#[derive(SmartPointer)]
+#[repr(transparent)]
+struct PointeeInConstConstBlock<
+    'a,
+    T: ?Sized,
+    const V: u32 = { struct UhOh<#[pointee] T>(T); 10 }>
+    //~^ ERROR: the `#[pointee]` attribute may only be used on generic parameters
+{
+    ptr: &'a T,
+}
+
+#[derive(SmartPointer)]
+#[repr(transparent)]
+struct PointeeInAnotherTypeConstBlock<'a, #[pointee] T: ?Sized> {
+    ptr: PointeeInConstConstBlock<'a, T, { struct UhOh<#[pointee] T>(T); 0 }>
+    //~^ ERROR: the `#[pointee]` attribute may only be used on generic parameters
+}
+
 // However, reordering attributes should work nevertheless.
 #[repr(transparent)]
 #[derive(SmartPointer)]
diff --git a/tests/ui/deriving/deriving-smart-pointer-neg.stderr b/tests/ui/deriving/deriving-smart-pointer-neg.stderr
index e7c2afc8b00..9ab117698c7 100644
--- a/tests/ui/deriving/deriving-smart-pointer-neg.stderr
+++ b/tests/ui/deriving/deriving-smart-pointer-neg.stderr
@@ -58,6 +58,30 @@ error: `derive(SmartPointer)` requires T to be marked `?Sized`
 LL | struct NoMaybeSized<'a, #[pointee] T> {
    |                                    ^
 
+error: the `#[pointee]` attribute may only be used on generic parameters
+  --> $DIR/deriving-smart-pointer-neg.rs:59:5
+   |
+LL |     #[pointee]
+   |     ^^^^^^^^^^
+
+error: the `#[pointee]` attribute may only be used on generic parameters
+  --> $DIR/deriving-smart-pointer-neg.rs:66:74
+   |
+LL | struct PointeeInTypeConstBlock<'a, T: ?Sized = [u32; const { struct UhOh<#[pointee] T>(T); 10 }]> {
+   |                                                                          ^^^^^^^^^^
+
+error: the `#[pointee]` attribute may only be used on generic parameters
+  --> $DIR/deriving-smart-pointer-neg.rs:76:34
+   |
+LL |     const V: u32 = { struct UhOh<#[pointee] T>(T); 10 }>
+   |                                  ^^^^^^^^^^
+
+error: the `#[pointee]` attribute may only be used on generic parameters
+  --> $DIR/deriving-smart-pointer-neg.rs:85:56
+   |
+LL |     ptr: PointeeInConstConstBlock<'a, T, { struct UhOh<#[pointee] T>(T); 0 }>
+   |                                                        ^^^^^^^^^^
+
 error[E0392]: lifetime parameter `'a` is never used
   --> $DIR/deriving-smart-pointer-neg.rs:15:16
    |
@@ -90,6 +114,6 @@ LL | struct NoFieldUnit<'a, #[pointee] T: ?Sized>();
    |
    = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
 
-error: aborting due to 12 previous errors
+error: aborting due to 16 previous errors
 
 For more information about this error, try `rustc --explain E0392`.
diff --git a/triagebot.toml b/triagebot.toml
index 737be4cc457..0172a80b3a5 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -921,6 +921,7 @@ cc = ["@kobzol"]
 warn_non_default_branch = true
 contributing_url = "https://rustc-dev-guide.rust-lang.org/getting-started.html"
 users_on_vacation = [
+    "BoxyUwU",
     "fmease",
     "jhpratt",
     "jyn514",