about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-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
17 files changed, 142 insertions, 78 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);
     }
 }