about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock3
-rw-r--r--compiler/rustc_borrowck/src/renumber.rs41
-rw-r--r--compiler/rustc_const_eval/src/transform/validate.rs12
-rw-r--r--compiler/rustc_data_structures/Cargo.toml1
-rw-r--r--compiler/rustc_data_structures/src/sso/either_iter.rs73
-rw-r--r--compiler/rustc_data_structures/src/sso/map.rs70
-rw-r--r--compiler/rustc_data_structures/src/sso/mod.rs1
-rw-r--r--compiler/rustc_infer/messages.ftl1
-rw-r--r--compiler/rustc_infer/src/errors/note_and_explain.rs123
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs74
-rw-r--r--compiler/rustc_mir_build/src/build/custom/parse/instruction.rs5
-rw-r--r--library/core/src/intrinsics/mir.rs2
-rw-r--r--src/doc/rustc/src/platform-support/loongarch-linux.md10
-rw-r--r--src/tools/rust-installer/Cargo.toml4
-rw-r--r--src/tools/rust-installer/src/remove_dir_all.rs860
-rw-r--r--tests/mir-opt/building/custom/references.raw_pointer_offset.built.after.mir10
-rw-r--r--tests/mir-opt/building/custom/references.rs11
-rw-r--r--tests/ui/lint/dead-code/issue-59003.rs18
-rw-r--r--tests/ui/mir/validate/transmute_cast_sized.rs17
19 files changed, 208 insertions, 1128 deletions
diff --git a/Cargo.lock b/Cargo.lock
index b5932607128..f9e8ea7a714 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2769,13 +2769,11 @@ dependencies = [
  "anyhow",
  "clap 3.2.20",
  "flate2",
- "lazy_static",
  "num_cpus",
  "rayon",
  "remove_dir_all",
  "tar",
  "walkdir",
- "winapi",
  "xz2",
 ]
 
@@ -4576,6 +4574,7 @@ dependencies = [
  "elsa",
  "ena",
  "indexmap",
+ "itertools",
  "jobserver",
  "libc",
  "measureme",
diff --git a/compiler/rustc_borrowck/src/renumber.rs b/compiler/rustc_borrowck/src/renumber.rs
index 0fbf01dbe44..2c1d74ef9ca 100644
--- a/compiler/rustc_borrowck/src/renumber.rs
+++ b/compiler/rustc_borrowck/src/renumber.rs
@@ -20,31 +20,13 @@ pub fn renumber_mir<'tcx>(
 ) {
     debug!(?body.arg_count);
 
-    let mut visitor = NllVisitor { infcx };
+    let mut renumberer = RegionRenumberer { infcx };
 
     for body in promoted.iter_mut() {
-        visitor.visit_body(body);
+        renumberer.visit_body(body);
     }
 
-    visitor.visit_body(body);
-}
-
-/// Replaces all regions appearing in `value` with fresh inference
-/// variables.
-#[instrument(skip(infcx, get_ctxt_fn), level = "debug")]
-pub(crate) fn renumber_regions<'tcx, T, F>(
-    infcx: &BorrowckInferCtxt<'_, 'tcx>,
-    value: T,
-    get_ctxt_fn: F,
-) -> T
-where
-    T: TypeFoldable<TyCtxt<'tcx>>,
-    F: Fn() -> RegionCtxt,
-{
-    infcx.tcx.fold_regions(value, |_region, _depth| {
-        let origin = NllRegionVariableOrigin::Existential { from_forall: false };
-        infcx.next_nll_region_var(origin, || get_ctxt_fn())
-    })
+    renumberer.visit_body(body);
 }
 
 #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
@@ -82,21 +64,26 @@ impl RegionCtxt {
     }
 }
 
-struct NllVisitor<'a, 'tcx> {
+struct RegionRenumberer<'a, 'tcx> {
     infcx: &'a BorrowckInferCtxt<'a, 'tcx>,
 }
 
-impl<'a, 'tcx> NllVisitor<'a, 'tcx> {
+impl<'a, 'tcx> RegionRenumberer<'a, 'tcx> {
+    /// Replaces all regions appearing in `value` with fresh inference
+    /// variables.
     fn renumber_regions<T, F>(&mut self, value: T, region_ctxt_fn: F) -> T
     where
         T: TypeFoldable<TyCtxt<'tcx>>,
         F: Fn() -> RegionCtxt,
     {
-        renumber_regions(self.infcx, value, region_ctxt_fn)
+        let origin = NllRegionVariableOrigin::Existential { from_forall: false };
+        self.infcx.tcx.fold_regions(value, |_region, _depth| {
+            self.infcx.next_nll_region_var(origin, || region_ctxt_fn())
+        })
     }
 }
 
-impl<'a, 'tcx> MutVisitor<'tcx> for NllVisitor<'a, 'tcx> {
+impl<'a, 'tcx> MutVisitor<'tcx> for RegionRenumberer<'a, 'tcx> {
     fn tcx(&self) -> TyCtxt<'tcx> {
         self.infcx.tcx
     }
@@ -124,9 +111,9 @@ impl<'a, 'tcx> MutVisitor<'tcx> for NllVisitor<'a, 'tcx> {
     }
 
     #[instrument(skip(self), level = "debug")]
-    fn visit_constant(&mut self, constant: &mut Constant<'tcx>, _location: Location) {
+    fn visit_constant(&mut self, constant: &mut Constant<'tcx>, location: Location) {
         let literal = constant.literal;
-        constant.literal = self.renumber_regions(literal, || RegionCtxt::Location(_location));
+        constant.literal = self.renumber_regions(literal, || RegionCtxt::Location(location));
         debug!("constant: {:#?}", constant);
     }
 }
diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs
index 0f56fda18f5..d4bed97380b 100644
--- a/compiler/rustc_const_eval/src/transform/validate.rs
+++ b/compiler/rustc_const_eval/src/transform/validate.rs
@@ -679,13 +679,21 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
                             // Unlike `mem::transmute`, a MIR `Transmute` is well-formed
                             // for any two `Sized` types, just potentially UB to run.
 
-                            if !op_ty.is_sized(self.tcx, self.param_env) {
+                            if !self
+                                .tcx
+                                .normalize_erasing_regions(self.param_env, op_ty)
+                                .is_sized(self.tcx, self.param_env)
+                            {
                                 self.fail(
                                     location,
                                     format!("Cannot transmute from non-`Sized` type {op_ty:?}"),
                                 );
                             }
-                            if !target_type.is_sized(self.tcx, self.param_env) {
+                            if !self
+                                .tcx
+                                .normalize_erasing_regions(self.param_env, *target_type)
+                                .is_sized(self.tcx, self.param_env)
+                            {
                                 self.fail(
                                     location,
                                     format!("Cannot transmute to non-`Sized` type {target_type:?}"),
diff --git a/compiler/rustc_data_structures/Cargo.toml b/compiler/rustc_data_structures/Cargo.toml
index 24b6b5cfb1f..2102f09c56a 100644
--- a/compiler/rustc_data_structures/Cargo.toml
+++ b/compiler/rustc_data_structures/Cargo.toml
@@ -33,6 +33,7 @@ tempfile = "3.2"
 thin-vec = "0.2.12"
 tracing = "0.1"
 elsa = "=1.7.1"
+itertools = "0.10.1"
 
 [dependencies.parking_lot]
 version = "0.11"
diff --git a/compiler/rustc_data_structures/src/sso/either_iter.rs b/compiler/rustc_data_structures/src/sso/either_iter.rs
deleted file mode 100644
index bca6c0955b9..00000000000
--- a/compiler/rustc_data_structures/src/sso/either_iter.rs
+++ /dev/null
@@ -1,73 +0,0 @@
-use std::fmt;
-use std::iter::FusedIterator;
-
-/// Iterator which may contain instance of
-/// one of two specific implementations.
-///
-/// Note: For most methods providing custom
-///       implementation may marginally
-///       improve performance by avoiding
-///       doing Left/Right match on every step
-///       and doing it only once instead.
-#[derive(Clone)]
-pub enum EitherIter<L, R> {
-    Left(L),
-    Right(R),
-}
-
-impl<L, R> Iterator for EitherIter<L, R>
-where
-    L: Iterator,
-    R: Iterator<Item = L::Item>,
-{
-    type Item = L::Item;
-
-    fn next(&mut self) -> Option<Self::Item> {
-        match self {
-            EitherIter::Left(l) => l.next(),
-            EitherIter::Right(r) => r.next(),
-        }
-    }
-
-    fn size_hint(&self) -> (usize, Option<usize>) {
-        match self {
-            EitherIter::Left(l) => l.size_hint(),
-            EitherIter::Right(r) => r.size_hint(),
-        }
-    }
-}
-
-impl<L, R> ExactSizeIterator for EitherIter<L, R>
-where
-    L: ExactSizeIterator,
-    R: ExactSizeIterator,
-    EitherIter<L, R>: Iterator,
-{
-    fn len(&self) -> usize {
-        match self {
-            EitherIter::Left(l) => l.len(),
-            EitherIter::Right(r) => r.len(),
-        }
-    }
-}
-
-impl<L, R> FusedIterator for EitherIter<L, R>
-where
-    L: FusedIterator,
-    R: FusedIterator,
-    EitherIter<L, R>: Iterator,
-{
-}
-
-impl<L, R> fmt::Debug for EitherIter<L, R>
-where
-    L: fmt::Debug,
-    R: fmt::Debug,
-{
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        match self {
-            EitherIter::Left(l) => l.fmt(f),
-            EitherIter::Right(r) => r.fmt(f),
-        }
-    }
-}
diff --git a/compiler/rustc_data_structures/src/sso/map.rs b/compiler/rustc_data_structures/src/sso/map.rs
index 7cdac581977..89b8c852649 100644
--- a/compiler/rustc_data_structures/src/sso/map.rs
+++ b/compiler/rustc_data_structures/src/sso/map.rs
@@ -1,24 +1,24 @@
-use super::either_iter::EitherIter;
 use crate::fx::FxHashMap;
 use arrayvec::ArrayVec;
+use itertools::Either;
 use std::fmt;
 use std::hash::Hash;
 use std::ops::Index;
 
-// For pointer-sized arguments arrays
-// are faster than set/map for up to 64
-// arguments.
-//
-// On the other hand such a big array
-// hurts cache performance, makes passing
-// sso structures around very expensive.
-//
-// Biggest performance benefit is gained
-// for reasonably small arrays that stay
-// small in vast majority of cases.
-//
-// '8' is chosen as a sane default, to be
-// reevaluated later.
+/// For pointer-sized arguments arrays
+/// are faster than set/map for up to 64
+/// arguments.
+///
+/// On the other hand such a big array
+/// hurts cache performance, makes passing
+/// sso structures around very expensive.
+///
+/// Biggest performance benefit is gained
+/// for reasonably small arrays that stay
+/// small in vast majority of cases.
+///
+/// '8' is chosen as a sane default, to be
+/// reevaluated later.
 const SSO_ARRAY_SIZE: usize = 8;
 
 /// Small-storage-optimized implementation of a map.
@@ -138,8 +138,8 @@ impl<K, V> SsoHashMap<K, V> {
     /// The iterator element type is `&'a K`.
     pub fn keys(&self) -> impl Iterator<Item = &'_ K> {
         match self {
-            SsoHashMap::Array(array) => EitherIter::Left(array.iter().map(|(k, _v)| k)),
-            SsoHashMap::Map(map) => EitherIter::Right(map.keys()),
+            SsoHashMap::Array(array) => Either::Left(array.iter().map(|(k, _v)| k)),
+            SsoHashMap::Map(map) => Either::Right(map.keys()),
         }
     }
 
@@ -147,8 +147,8 @@ impl<K, V> SsoHashMap<K, V> {
     /// The iterator element type is `&'a V`.
     pub fn values(&self) -> impl Iterator<Item = &'_ V> {
         match self {
-            SsoHashMap::Array(array) => EitherIter::Left(array.iter().map(|(_k, v)| v)),
-            SsoHashMap::Map(map) => EitherIter::Right(map.values()),
+            SsoHashMap::Array(array) => Either::Left(array.iter().map(|(_k, v)| v)),
+            SsoHashMap::Map(map) => Either::Right(map.values()),
         }
     }
 
@@ -156,8 +156,8 @@ impl<K, V> SsoHashMap<K, V> {
     /// The iterator element type is `&'a mut V`.
     pub fn values_mut(&mut self) -> impl Iterator<Item = &'_ mut V> {
         match self {
-            SsoHashMap::Array(array) => EitherIter::Left(array.iter_mut().map(|(_k, v)| v)),
-            SsoHashMap::Map(map) => EitherIter::Right(map.values_mut()),
+            SsoHashMap::Array(array) => Either::Left(array.iter_mut().map(|(_k, v)| v)),
+            SsoHashMap::Map(map) => Either::Right(map.values_mut()),
         }
     }
 
@@ -165,8 +165,8 @@ impl<K, V> SsoHashMap<K, V> {
     /// allocated memory for reuse.
     pub fn drain(&mut self) -> impl Iterator<Item = (K, V)> + '_ {
         match self {
-            SsoHashMap::Array(array) => EitherIter::Left(array.drain(..)),
-            SsoHashMap::Map(map) => EitherIter::Right(map.drain()),
+            SsoHashMap::Array(array) => Either::Left(array.drain(..)),
+            SsoHashMap::Map(map) => Either::Right(map.drain()),
         }
     }
 }
@@ -406,16 +406,16 @@ where
 }
 
 impl<K, V> IntoIterator for SsoHashMap<K, V> {
-    type IntoIter = EitherIter<
-        <ArrayVec<(K, V), 8> as IntoIterator>::IntoIter,
+    type IntoIter = Either<
+        <ArrayVec<(K, V), SSO_ARRAY_SIZE> as IntoIterator>::IntoIter,
         <FxHashMap<K, V> as IntoIterator>::IntoIter,
     >;
     type Item = <Self::IntoIter as Iterator>::Item;
 
     fn into_iter(self) -> Self::IntoIter {
         match self {
-            SsoHashMap::Array(array) => EitherIter::Left(array.into_iter()),
-            SsoHashMap::Map(map) => EitherIter::Right(map.into_iter()),
+            SsoHashMap::Array(array) => Either::Left(array.into_iter()),
+            SsoHashMap::Map(map) => Either::Right(map.into_iter()),
         }
     }
 }
@@ -435,9 +435,9 @@ fn adapt_array_mut_it<K, V>(pair: &mut (K, V)) -> (&K, &mut V) {
 }
 
 impl<'a, K, V> IntoIterator for &'a SsoHashMap<K, V> {
-    type IntoIter = EitherIter<
+    type IntoIter = Either<
         std::iter::Map<
-            <&'a ArrayVec<(K, V), 8> as IntoIterator>::IntoIter,
+            <&'a ArrayVec<(K, V), SSO_ARRAY_SIZE> as IntoIterator>::IntoIter,
             fn(&'a (K, V)) -> (&'a K, &'a V),
         >,
         <&'a FxHashMap<K, V> as IntoIterator>::IntoIter,
@@ -446,16 +446,16 @@ impl<'a, K, V> IntoIterator for &'a SsoHashMap<K, V> {
 
     fn into_iter(self) -> Self::IntoIter {
         match self {
-            SsoHashMap::Array(array) => EitherIter::Left(array.into_iter().map(adapt_array_ref_it)),
-            SsoHashMap::Map(map) => EitherIter::Right(map.iter()),
+            SsoHashMap::Array(array) => Either::Left(array.into_iter().map(adapt_array_ref_it)),
+            SsoHashMap::Map(map) => Either::Right(map.iter()),
         }
     }
 }
 
 impl<'a, K, V> IntoIterator for &'a mut SsoHashMap<K, V> {
-    type IntoIter = EitherIter<
+    type IntoIter = Either<
         std::iter::Map<
-            <&'a mut ArrayVec<(K, V), 8> as IntoIterator>::IntoIter,
+            <&'a mut ArrayVec<(K, V), SSO_ARRAY_SIZE> as IntoIterator>::IntoIter,
             fn(&'a mut (K, V)) -> (&'a K, &'a mut V),
         >,
         <&'a mut FxHashMap<K, V> as IntoIterator>::IntoIter,
@@ -464,8 +464,8 @@ impl<'a, K, V> IntoIterator for &'a mut SsoHashMap<K, V> {
 
     fn into_iter(self) -> Self::IntoIter {
         match self {
-            SsoHashMap::Array(array) => EitherIter::Left(array.into_iter().map(adapt_array_mut_it)),
-            SsoHashMap::Map(map) => EitherIter::Right(map.iter_mut()),
+            SsoHashMap::Array(array) => Either::Left(array.into_iter().map(adapt_array_mut_it)),
+            SsoHashMap::Map(map) => Either::Right(map.iter_mut()),
         }
     }
 }
diff --git a/compiler/rustc_data_structures/src/sso/mod.rs b/compiler/rustc_data_structures/src/sso/mod.rs
index dd21bc8e696..ef634b9adce 100644
--- a/compiler/rustc_data_structures/src/sso/mod.rs
+++ b/compiler/rustc_data_structures/src/sso/mod.rs
@@ -1,4 +1,3 @@
-mod either_iter;
 mod map;
 mod set;
 
diff --git a/compiler/rustc_infer/messages.ftl b/compiler/rustc_infer/messages.ftl
index 4d4a7880b00..1ae53182046 100644
--- a/compiler/rustc_infer/messages.ftl
+++ b/compiler/rustc_infer/messages.ftl
@@ -163,7 +163,6 @@ infer_region_explanation = {$pref_kind ->
     [as_defined] the lifetime `{$desc_arg}` as defined here
     [as_defined_anon] the anonymous lifetime as defined here
     [defined_here] the anonymous lifetime defined here
-    [anon_num_here] the anonymous lifetime #{$desc_num_arg} defined here
     [defined_here_reg] the lifetime `{$desc_arg}` as defined here
 }{$suff_kind ->
     *[should_not_happen] [{$suff_kind}]
diff --git a/compiler/rustc_infer/src/errors/note_and_explain.rs b/compiler/rustc_infer/src/errors/note_and_explain.rs
index 30f6af74b83..7328241dfbc 100644
--- a/compiler/rustc_infer/src/errors/note_and_explain.rs
+++ b/compiler/rustc_infer/src/errors/note_and_explain.rs
@@ -4,12 +4,10 @@ use rustc_errors::{self, AddToDiagnostic, Diagnostic, IntoDiagnosticArg, Subdiag
 use rustc_middle::ty::{self, TyCtxt};
 use rustc_span::{symbol::kw, Span};
 
-#[derive(Default)]
 struct DescriptionCtx<'a> {
     span: Option<Span>,
     kind: &'a str,
     arg: String,
-    num_arg: u32,
 }
 
 impl<'a> DescriptionCtx<'a> {
@@ -18,102 +16,74 @@ impl<'a> DescriptionCtx<'a> {
         region: ty::Region<'tcx>,
         alt_span: Option<Span>,
     ) -> Option<Self> {
-        let mut me = DescriptionCtx::default();
-        me.span = alt_span;
-        match *region {
-            ty::ReEarlyBound(_) | ty::ReFree(_) => {
-                return Self::from_early_bound_and_free_regions(tcx, region);
-            }
-            ty::ReStatic => {
-                me.kind = "restatic";
-            }
-
-            ty::RePlaceholder(_) => return None,
-
-            ty::ReError(_) => return None,
-
-            // FIXME(#13998) RePlaceholder should probably print like
-            // ReFree rather than dumping Debug output on the user.
-            //
-            // We shouldn't really be having unification failures with ReVar
-            // and ReLateBound though.
-            ty::ReVar(_) | ty::ReLateBound(..) | ty::ReErased => {
-                me.kind = "revar";
-                me.arg = format!("{:?}", region);
-            }
-        };
-        Some(me)
-    }
-
-    fn from_early_bound_and_free_regions<'tcx>(
-        tcx: TyCtxt<'tcx>,
-        region: ty::Region<'tcx>,
-    ) -> Option<Self> {
-        let mut me = DescriptionCtx::default();
-        let scope = region.free_region_binding_scope(tcx).expect_local();
-        match *region {
+        let (span, kind, arg) = match *region {
             ty::ReEarlyBound(ref br) => {
-                let mut sp = tcx.def_span(scope);
-                if let Some(param) =
+                let scope = region.free_region_binding_scope(tcx).expect_local();
+                let span = if let Some(param) =
                     tcx.hir().get_generics(scope).and_then(|generics| generics.get_named(br.name))
                 {
-                    sp = param.span;
-                }
-                if br.has_name() {
-                    me.kind = "as_defined";
-                    me.arg = br.name.to_string();
+                    param.span
                 } else {
-                    me.kind = "as_defined_anon";
+                    tcx.def_span(scope)
                 };
-                me.span = Some(sp)
+                if br.has_name() {
+                    (Some(span), "as_defined", br.name.to_string())
+                } else {
+                    (Some(span), "as_defined_anon", String::new())
+                }
             }
             ty::ReFree(ref fr) => {
                 if !fr.bound_region.is_named()
                     && let Some((ty, _)) = find_anon_type(tcx, region, &fr.bound_region)
                 {
-                    me.kind = "defined_here";
-                    me.span = Some(ty.span);
+                    (Some(ty.span), "defined_here", String::new())
                 } else {
+                    let scope = region.free_region_binding_scope(tcx).expect_local();
                     match fr.bound_region {
                         ty::BoundRegionKind::BrNamed(_, name) => {
-                            let mut sp = tcx.def_span(scope);
-                            if let Some(param) =
-                                tcx.hir().get_generics(scope).and_then(|generics| generics.get_named(name))
+                            let span = if let Some(param) = tcx
+                                .hir()
+                                .get_generics(scope)
+                                .and_then(|generics| generics.get_named(name))
                             {
-                                sp = param.span;
-                            }
-                            if name == kw::UnderscoreLifetime {
-                                me.kind = "as_defined_anon";
+                                param.span
                             } else {
-                                me.kind = "as_defined";
-                                me.arg = name.to_string();
+                                tcx.def_span(scope)
                             };
-                            me.span = Some(sp);
+                            if name == kw::UnderscoreLifetime {
+                                (Some(span), "as_defined_anon", String::new())
+                            } else {
+                                (Some(span), "as_defined", name.to_string())
+                            }
                         }
                         ty::BrAnon(span) => {
-                            me.kind = "defined_here";
-                            me.span = match span {
+                            let span = match span {
                                 Some(_) => span,
                                 None => Some(tcx.def_span(scope)),
-                            }
-                        },
+                            };
+                            (span, "defined_here", String::new())
+                        }
                         _ => {
-                            me.kind = "defined_here_reg";
-                            me.arg = region.to_string();
-                            me.span = Some(tcx.def_span(scope));
-                        },
+                            (Some(tcx.def_span(scope)), "defined_here_reg", region.to_string())
+                        }
                     }
                 }
             }
-            _ => bug!(),
-        }
-        Some(me)
-    }
 
-    fn add_to(self, diag: &mut rustc_errors::Diagnostic) {
-        diag.set_arg("desc_kind", self.kind);
-        diag.set_arg("desc_arg", self.arg);
-        diag.set_arg("desc_num_arg", self.num_arg);
+            ty::ReStatic => (alt_span, "restatic", String::new()),
+
+            ty::RePlaceholder(_) | ty::ReError(_) => return None,
+
+            // FIXME(#13998) RePlaceholder should probably print like
+            // ReFree rather than dumping Debug output on the user.
+            //
+            // We shouldn't really be having unification failures with ReVar
+            // and ReLateBound though.
+            ty::ReVar(_) | ty::ReLateBound(..) | ty::ReErased => {
+                (alt_span, "revar", format!("{:?}", region))
+            }
+        };
+        Some(DescriptionCtx { span, kind, arg })
     }
 }
 
@@ -198,10 +168,11 @@ impl AddToDiagnostic for RegionExplanation<'_> {
     {
         diag.set_arg("pref_kind", self.prefix);
         diag.set_arg("suff_kind", self.suffix);
-        let desc_span = self.desc.span;
-        self.desc.add_to(diag);
+        diag.set_arg("desc_kind", self.desc.kind);
+        diag.set_arg("desc_arg", self.desc.arg);
+
         let msg = f(diag, fluent::infer_region_explanation.into());
-        if let Some(span) = desc_span {
+        if let Some(span) = self.desc.span {
             diag.span_note(span, msg);
         } else {
             diag.note(msg);
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index 7901bc94021..b68ffaed69d 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -185,83 +185,73 @@ fn msg_span_from_named_region<'tcx>(
     alt_span: Option<Span>,
 ) -> (String, Option<Span>) {
     match *region {
-        ty::ReEarlyBound(_) | ty::ReFree(_) => {
-            let (msg, span) = msg_span_from_early_bound_and_free_regions(tcx, region);
-            (msg, Some(span))
-        }
-        ty::ReStatic => ("the static lifetime".to_owned(), alt_span),
-        ty::RePlaceholder(ty::PlaceholderRegion {
-            bound: ty::BoundRegion { kind: ty::BoundRegionKind::BrNamed(def_id, name), .. },
-            ..
-        }) => (format!("the lifetime `{name}` as defined here"), Some(tcx.def_span(def_id))),
-        ty::RePlaceholder(ty::PlaceholderRegion {
-            bound: ty::BoundRegion { kind: ty::BoundRegionKind::BrAnon(Some(span)), .. },
-            ..
-        }) => (format!("the anonymous lifetime defined here"), Some(span)),
-        ty::RePlaceholder(ty::PlaceholderRegion {
-            bound: ty::BoundRegion { kind: ty::BoundRegionKind::BrAnon(None), .. },
-            ..
-        }) => (format!("an anonymous lifetime"), None),
-        _ => bug!("{:?}", region),
-    }
-}
-
-fn msg_span_from_early_bound_and_free_regions<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    region: ty::Region<'tcx>,
-) -> (String, Span) {
-    let scope = region.free_region_binding_scope(tcx).expect_local();
-    match *region {
         ty::ReEarlyBound(ref br) => {
-            let mut sp = tcx.def_span(scope);
-            if let Some(param) =
+            let scope = region.free_region_binding_scope(tcx).expect_local();
+            let span = if let Some(param) =
                 tcx.hir().get_generics(scope).and_then(|generics| generics.get_named(br.name))
             {
-                sp = param.span;
-            }
+                param.span
+            } else {
+                tcx.def_span(scope)
+            };
             let text = if br.has_name() {
                 format!("the lifetime `{}` as defined here", br.name)
             } else {
                 "the anonymous lifetime as defined here".to_string()
             };
-            (text, sp)
+            (text, Some(span))
         }
         ty::ReFree(ref fr) => {
             if !fr.bound_region.is_named()
                 && let Some((ty, _)) = find_anon_type(tcx, region, &fr.bound_region)
             {
-                ("the anonymous lifetime defined here".to_string(), ty.span)
+                ("the anonymous lifetime defined here".to_string(), Some(ty.span))
             } else {
+                let scope = region.free_region_binding_scope(tcx).expect_local();
                 match fr.bound_region {
                     ty::BoundRegionKind::BrNamed(_, name) => {
-                        let mut sp = tcx.def_span(scope);
-                        if let Some(param) =
+                        let span = if let Some(param) =
                             tcx.hir().get_generics(scope).and_then(|generics| generics.get_named(name))
                         {
-                            sp = param.span;
-                        }
+                            param.span
+                        } else {
+                            tcx.def_span(scope)
+                        };
                         let text = if name == kw::UnderscoreLifetime {
                             "the anonymous lifetime as defined here".to_string()
                         } else {
                             format!("the lifetime `{}` as defined here", name)
                         };
-                        (text, sp)
+                        (text, Some(span))
                     }
                     ty::BrAnon(span) => (
                         "the anonymous lifetime as defined here".to_string(),
-                        match span {
+                        Some(match span {
                             Some(span) => span,
                             None => tcx.def_span(scope)
-                        }
+                        })
                     ),
                     _ => (
                         format!("the lifetime `{}` as defined here", region),
-                        tcx.def_span(scope),
+                        Some(tcx.def_span(scope)),
                     ),
                 }
             }
         }
-        _ => bug!(),
+        ty::ReStatic => ("the static lifetime".to_owned(), alt_span),
+        ty::RePlaceholder(ty::PlaceholderRegion {
+            bound: ty::BoundRegion { kind: ty::BoundRegionKind::BrNamed(def_id, name), .. },
+            ..
+        }) => (format!("the lifetime `{name}` as defined here"), Some(tcx.def_span(def_id))),
+        ty::RePlaceholder(ty::PlaceholderRegion {
+            bound: ty::BoundRegion { kind: ty::BoundRegionKind::BrAnon(Some(span)), .. },
+            ..
+        }) => (format!("the anonymous lifetime defined here"), Some(span)),
+        ty::RePlaceholder(ty::PlaceholderRegion {
+            bound: ty::BoundRegion { kind: ty::BoundRegionKind::BrAnon(None), .. },
+            ..
+        }) => (format!("an anonymous lifetime"), None),
+        _ => bug!("{:?}", region),
     }
 }
 
diff --git a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs
index 54028dfe87b..931fe1b2433 100644
--- a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs
+++ b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs
@@ -148,6 +148,11 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
                     )),
                 )
             },
+            @call("mir_offset", args) => {
+                let ptr = self.parse_operand(args[0])?;
+                let offset = self.parse_operand(args[1])?;
+                Ok(Rvalue::BinaryOp(BinOp::Offset, Box::new((ptr, offset))))
+            },
             @call("mir_len", args) => Ok(Rvalue::Len(self.parse_place(args[0])?)),
             ExprKind::Borrow { borrow_kind, arg } => Ok(
                 Rvalue::Ref(self.tcx.lifetimes.re_erased, *borrow_kind, self.parse_place(*arg)?)
diff --git a/library/core/src/intrinsics/mir.rs b/library/core/src/intrinsics/mir.rs
index 6690c1a76d5..d9d62eb759e 100644
--- a/library/core/src/intrinsics/mir.rs
+++ b/library/core/src/intrinsics/mir.rs
@@ -232,6 +232,7 @@
 //!  - `&`, `&mut`, `addr_of!`, and `addr_of_mut!` all work to create their associated rvalue.
 //!  - [`Discriminant`] and [`Len`] have associated functions.
 //!  - Unary and binary operations use their normal Rust syntax - `a * b`, `!c`, etc.
+//!  - The binary operation `Offset` can be created via [`Offset`].
 //!  - Checked binary operations are represented by wrapping the associated binop in [`Checked`].
 //!  - Array repetition syntax (`[foo; 10]`) creates the associated rvalue.
 //!
@@ -289,6 +290,7 @@ define!(
     fn Discriminant<T>(place: T) -> <T as ::core::marker::DiscriminantKind>::Discriminant
 );
 define!("mir_set_discriminant", fn SetDiscriminant<T>(place: T, index: u32));
+define!("mir_offset", fn Offset<T, U>(ptr: T, count: U) -> T);
 define!(
     "mir_field",
     /// Access the field with the given index of some place.
diff --git a/src/doc/rustc/src/platform-support/loongarch-linux.md b/src/doc/rustc/src/platform-support/loongarch-linux.md
index e046ec244ec..d7d31d8724c 100644
--- a/src/doc/rustc/src/platform-support/loongarch-linux.md
+++ b/src/doc/rustc/src/platform-support/loongarch-linux.md
@@ -6,12 +6,12 @@
 
 [LoongArch]: https://loongson.github.io/LoongArch-Documentation/README-EN.html
 
-The target name follow this format: `<machine>-<vendor>-<os><fabi_suffix>, where `<machine>` specifies the CPU family/model, `<vendor>` specifies the vendor and `<os>` the operating system name.
+The target name follow this format: `<machine>-<vendor>-<os><fabi_suffix>`, where `<machine>` specifies the CPU family/model, `<vendor>` specifies the vendor and `<os>` the operating system name.
 While the integer base ABI is implied by the machine field, the floating point base ABI type is encoded into the os field of the specifier using the string suffix `<fabi-suffix>`.
 
 |    `<fabi-suffix>`     |                           `Description`                            |
 |------------------------|--------------------------------------------------------------------|
-|          f64           | The base ABI use 64-bits FPRs for parameter passing.(lp64d)|
+|          f64           | The base ABI use 64-bits FPRs for parameter passing. (lp64d)|
 |          f32           | The base ABI uses 32-bit FPRs for parameter passing. (lp64f)|
 |          sf            | The base ABI uses no FPR for parameter passing. (lp64s)     |
 
@@ -26,9 +26,9 @@ While the integer base ABI is implied by the machine field, the floating po
 
 ## Target maintainers
 
-- [ZHAI xiaojuan](https://github.com/zhaixiaojuan) `zhaixiaojuan@loongson.cn`
-- [WANG rui](https://github.com/heiher) `wangrui@loongson.cn`
-- [ZHAI xiang](https://github.com/xiangzhai) `zhaixiang@loongson.cn`
+- [ZHAI Xiaojuan](https://github.com/zhaixiaojuan) `zhaixiaojuan@loongson.cn`
+- [WANG Rui](https://github.com/heiher) `wangrui@loongson.cn`
+- [ZHAI Xiang](https://github.com/xiangzhai) `zhaixiang@loongson.cn`
 - [WANG Xuerui](https://github.com/xen0n) `git@xen0n.name`
 
 ## Requirements
diff --git a/src/tools/rust-installer/Cargo.toml b/src/tools/rust-installer/Cargo.toml
index 788e556b0c6..97734f048ab 100644
--- a/src/tools/rust-installer/Cargo.toml
+++ b/src/tools/rust-installer/Cargo.toml
@@ -22,7 +22,3 @@ remove_dir_all = "0.5"
 [dependencies.clap]
 features = ["derive"]
 version = "3.1"
-
-[target."cfg(windows)".dependencies]
-lazy_static = "1"
-winapi = { version = "0.3", features = ["errhandlingapi", "handleapi", "ioapiset", "winerror", "winioctl", "winnt"] }
diff --git a/src/tools/rust-installer/src/remove_dir_all.rs b/src/tools/rust-installer/src/remove_dir_all.rs
deleted file mode 100644
index 11097652865..00000000000
--- a/src/tools/rust-installer/src/remove_dir_all.rs
+++ /dev/null
@@ -1,860 +0,0 @@
-#![allow(non_snake_case)]
-
-use std::io;
-use std::path::Path;
-
-#[cfg(not(windows))]
-pub fn remove_dir_all(path: &Path) -> io::Result<()> {
-    ::std::fs::remove_dir_all(path)
-}
-
-#[cfg(windows)]
-pub fn remove_dir_all(path: &Path) -> io::Result<()> {
-    win::remove_dir_all(path)
-}
-
-#[cfg(windows)]
-mod win {
-    use winapi::ctypes::{c_uint, c_ushort};
-    use winapi::shared::minwindef::{BOOL, DWORD, FALSE, FILETIME, LPVOID};
-    use winapi::shared::winerror::{
-        ERROR_CALL_NOT_IMPLEMENTED, ERROR_INSUFFICIENT_BUFFER, ERROR_NO_MORE_FILES,
-    };
-    use winapi::um::errhandlingapi::{GetLastError, SetLastError};
-    use winapi::um::fileapi::{
-        CreateFileW, FindFirstFileW, FindNextFileW, GetFileInformationByHandle,
-    };
-    use winapi::um::fileapi::{BY_HANDLE_FILE_INFORMATION, CREATE_ALWAYS, CREATE_NEW};
-    use winapi::um::fileapi::{FILE_BASIC_INFO, FILE_RENAME_INFO, TRUNCATE_EXISTING};
-    use winapi::um::fileapi::{OPEN_ALWAYS, OPEN_EXISTING};
-    use winapi::um::handleapi::{CloseHandle, INVALID_HANDLE_VALUE};
-    use winapi::um::ioapiset::DeviceIoControl;
-    use winapi::um::libloaderapi::{GetModuleHandleW, GetProcAddress};
-    use winapi::um::minwinbase::{
-        FileBasicInfo, FileRenameInfo, FILE_INFO_BY_HANDLE_CLASS, WIN32_FIND_DATAW,
-    };
-    use winapi::um::winbase::SECURITY_SQOS_PRESENT;
-    use winapi::um::winbase::{
-        FILE_FLAG_BACKUP_SEMANTICS, FILE_FLAG_DELETE_ON_CLOSE, FILE_FLAG_OPEN_REPARSE_POINT,
-    };
-    use winapi::um::winioctl::FSCTL_GET_REPARSE_POINT;
-    use winapi::um::winnt::{DELETE, FILE_ATTRIBUTE_DIRECTORY, HANDLE, LPCWSTR};
-    use winapi::um::winnt::{FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_REPARSE_POINT};
-    use winapi::um::winnt::{FILE_GENERIC_WRITE, FILE_WRITE_DATA, GENERIC_READ, GENERIC_WRITE};
-    use winapi::um::winnt::{FILE_READ_ATTRIBUTES, FILE_WRITE_ATTRIBUTES};
-    use winapi::um::winnt::{FILE_SHARE_DELETE, FILE_SHARE_READ, FILE_SHARE_WRITE};
-    use winapi::um::winnt::{IO_REPARSE_TAG_MOUNT_POINT, IO_REPARSE_TAG_SYMLINK, LARGE_INTEGER};
-
-    use std::ffi::{OsStr, OsString};
-    use std::io;
-    use std::mem;
-    use std::os::windows::ffi::{OsStrExt, OsStringExt};
-    use std::path::{Path, PathBuf};
-    use std::ptr;
-    use std::sync::Arc;
-
-    pub fn remove_dir_all(path: &Path) -> io::Result<()> {
-        // On Windows it is not enough to just recursively remove the contents of a
-        // directory and then the directory itself. Deleting does not happen
-        // instantaneously, but is scheduled.
-        // To work around this, we move the file or directory to some `base_dir`
-        // right before deletion to avoid races.
-        //
-        // As `base_dir` we choose the parent dir of the directory we want to
-        // remove. We very probably have permission to create files here, as we
-        // already need write permission in this dir to delete the directory. And it
-        // should be on the same volume.
-        //
-        // To handle files with names like `CON` and `morse .. .`, and when a
-        // directory structure is so deep it needs long path names the path is first
-        // converted to a `//?/`-path with `get_path()`.
-        //
-        // To make sure we don't leave a moved file laying around if the process
-        // crashes before we can delete the file, we do all operations on an file
-        // handle. By opening a file with `FILE_FLAG_DELETE_ON_CLOSE` Windows will
-        // always delete the file when the handle closes.
-        //
-        // All files are renamed to be in the `base_dir`, and have their name
-        // changed to "rm-<counter>". After every rename the counter is increased.
-        // Rename should not overwrite possibly existing files in the base dir. So
-        // if it fails with `AlreadyExists`, we just increase the counter and try
-        // again.
-        //
-        // For read-only files and directories we first have to remove the read-only
-        // attribute before we can move or delete them. This also removes the
-        // attribute from possible hardlinks to the file, so just before closing we
-        // restore the read-only attribute.
-        //
-        // If 'path' points to a directory symlink or junction we should not
-        // recursively remove the target of the link, but only the link itself.
-        //
-        // Moving and deleting is guaranteed to succeed if we are able to open the
-        // file with `DELETE` permission. If others have the file open we only have
-        // `DELETE` permission if they have specified `FILE_SHARE_DELETE`. We can
-        // also delete the file now, but it will not disappear until all others have
-        // closed the file. But no-one can open the file after we have flagged it
-        // for deletion.
-
-        // Open the path once to get the canonical path, file type and attributes.
-        let (path, metadata) = {
-            let mut opts = OpenOptions::new();
-            opts.access_mode(FILE_READ_ATTRIBUTES);
-            opts.custom_flags(FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT);
-            let file = File::open(path, &opts)?;
-            (get_path(&file)?, file.file_attr()?)
-        };
-
-        let mut ctx = RmdirContext {
-            base_dir: match path.parent() {
-                Some(dir) => dir,
-                None => {
-                    return Err(io::Error::new(
-                        io::ErrorKind::PermissionDenied,
-                        "can't delete root directory",
-                    ))
-                }
-            },
-            readonly: metadata.perm().readonly(),
-            counter: 0,
-        };
-
-        let filetype = metadata.file_type();
-        if filetype.is_dir() {
-            remove_dir_all_recursive(path.as_ref(), &mut ctx)
-        } else if filetype.is_symlink_dir() {
-            remove_item(path.as_ref(), &mut ctx)
-        } else {
-            Err(io::Error::new(
-                io::ErrorKind::PermissionDenied,
-                "Not a directory",
-            ))
-        }
-    }
-
-    fn readdir(p: &Path) -> io::Result<ReadDir> {
-        let root = p.to_path_buf();
-        let star = p.join("*");
-        let path = to_u16s(&star)?;
-
-        unsafe {
-            let mut wfd = mem::zeroed();
-            let find_handle = FindFirstFileW(path.as_ptr(), &mut wfd);
-            if find_handle != INVALID_HANDLE_VALUE {
-                Ok(ReadDir {
-                    handle: FindNextFileHandle(find_handle),
-                    root: Arc::new(root),
-                    first: Some(wfd),
-                })
-            } else {
-                Err(io::Error::last_os_error())
-            }
-        }
-    }
-
-    struct RmdirContext<'a> {
-        base_dir: &'a Path,
-        readonly: bool,
-        counter: u64,
-    }
-
-    fn remove_dir_all_recursive(path: &Path, ctx: &mut RmdirContext) -> io::Result<()> {
-        let dir_readonly = ctx.readonly;
-        for child in readdir(path)? {
-            let child = child?;
-            let child_type = child.file_type()?;
-            ctx.readonly = child.metadata()?.perm().readonly();
-            if child_type.is_dir() {
-                remove_dir_all_recursive(&child.path(), ctx)?;
-            } else {
-                remove_item(&child.path().as_ref(), ctx)?;
-            }
-        }
-        ctx.readonly = dir_readonly;
-        remove_item(path, ctx)
-    }
-
-    fn remove_item(path: &Path, ctx: &mut RmdirContext) -> io::Result<()> {
-        if !ctx.readonly {
-            let mut opts = OpenOptions::new();
-            opts.access_mode(DELETE);
-            opts.custom_flags(
-                FILE_FLAG_BACKUP_SEMANTICS | // delete directory
-                              FILE_FLAG_OPEN_REPARSE_POINT | // delete symlink
-                              FILE_FLAG_DELETE_ON_CLOSE,
-            );
-            let file = File::open(path, &opts)?;
-            move_item(&file, ctx)
-        } else {
-            // remove read-only permision
-            set_perm(&path, FilePermissions::new())?;
-            // move and delete file, similar to !readonly.
-            // only the access mode is different.
-            let mut opts = OpenOptions::new();
-            opts.access_mode(DELETE | FILE_WRITE_ATTRIBUTES);
-            opts.custom_flags(
-                FILE_FLAG_BACKUP_SEMANTICS
-                    | FILE_FLAG_OPEN_REPARSE_POINT
-                    | FILE_FLAG_DELETE_ON_CLOSE,
-            );
-            let file = File::open(path, &opts)?;
-            move_item(&file, ctx)?;
-            // restore read-only flag just in case there are other hard links
-            let mut perm = FilePermissions::new();
-            perm.set_readonly(true);
-            let _ = file.set_perm(perm); // ignore if this fails
-            Ok(())
-        }
-    }
-
-    macro_rules! compat_fn {
-        ($module:ident: $(
-            fn $symbol:ident($($argname:ident: $argtype:ty),*)
-                             -> $rettype:ty {
-                $($body:expr);*
-            }
-        )*) => ($(
-            #[allow(unused_variables)]
-            unsafe fn $symbol($($argname: $argtype),*) -> $rettype {
-                use std::sync::atomic::{AtomicUsize, Ordering};
-                use std::mem;
-                use std::ffi::CString;
-                type F = unsafe extern "system" fn($($argtype),*) -> $rettype;
-
-                lazy_static! { static ref PTR: AtomicUsize = AtomicUsize::new(0);}
-
-                fn lookup(module: &str, symbol: &str) -> Option<usize> {
-                    let mut module: Vec<u16> = module.encode_utf16().collect();
-                    module.push(0);
-                    let symbol = CString::new(symbol).unwrap();
-                    unsafe {
-                        let handle = GetModuleHandleW(module.as_ptr());
-                        match GetProcAddress(handle, symbol.as_ptr()) as usize {
-                            0 => None,
-                            n => Some(n),
-                        }
-                    }
-                }
-
-                fn store_func(ptr: &AtomicUsize, module: &str, symbol: &str,
-                              fallback: usize) -> usize {
-                    let value = lookup(module, symbol).unwrap_or(fallback);
-                    ptr.store(value, Ordering::SeqCst);
-                    value
-                }
-
-                fn load() -> usize {
-                    store_func(&PTR, stringify!($module), stringify!($symbol), fallback as usize)
-                }
-                unsafe extern "system" fn fallback($($argname: $argtype),*)
-                                                   -> $rettype {
-                    $($body);*
-                }
-
-                let addr = match PTR.load(Ordering::SeqCst) {
-                    0 => load(),
-                    n => n,
-                };
-                mem::transmute::<usize, F>(addr)($($argname),*)
-            }
-        )*)
-    }
-
-    compat_fn! {
-        kernel32:
-        fn GetFinalPathNameByHandleW(_hFile: HANDLE,
-                                     _lpszFilePath: LPCWSTR,
-                                     _cchFilePath: DWORD,
-                                     _dwFlags: DWORD) -> DWORD {
-            SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0
-        }
-        fn SetFileInformationByHandle(_hFile: HANDLE,
-                                      _FileInformationClass: FILE_INFO_BY_HANDLE_CLASS,
-                                      _lpFileInformation: LPVOID,
-                                      _dwBufferSize: DWORD) -> BOOL {
-            SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0
-        }
-    }
-
-    fn cvt(i: i32) -> io::Result<i32> {
-        if i == 0 {
-            Err(io::Error::last_os_error())
-        } else {
-            Ok(i)
-        }
-    }
-
-    fn to_u16s<S: AsRef<OsStr>>(s: S) -> io::Result<Vec<u16>> {
-        fn inner(s: &OsStr) -> io::Result<Vec<u16>> {
-            let mut maybe_result: Vec<u16> = s.encode_wide().collect();
-            if maybe_result.iter().any(|&u| u == 0) {
-                return Err(io::Error::new(
-                    io::ErrorKind::InvalidInput,
-                    "strings passed to WinAPI cannot contain NULs",
-                ));
-            }
-            maybe_result.push(0);
-            Ok(maybe_result)
-        }
-        inner(s.as_ref())
-    }
-
-    fn truncate_utf16_at_nul<'a>(v: &'a [u16]) -> &'a [u16] {
-        match v.iter().position(|c| *c == 0) {
-            // don't include the 0
-            Some(i) => &v[..i],
-            None => v,
-        }
-    }
-
-    fn fill_utf16_buf<F1, F2, T>(mut f1: F1, f2: F2) -> io::Result<T>
-    where
-        F1: FnMut(*mut u16, DWORD) -> DWORD,
-        F2: FnOnce(&[u16]) -> T,
-    {
-        // Start off with a stack buf but then spill over to the heap if we end up
-        // needing more space.
-        let mut stack_buf = [0u16; 512];
-        let mut heap_buf = Vec::new();
-        unsafe {
-            let mut n = stack_buf.len();
-            loop {
-                let buf = if n <= stack_buf.len() {
-                    &mut stack_buf[..]
-                } else {
-                    let extra = n - heap_buf.len();
-                    heap_buf.reserve(extra);
-                    heap_buf.set_len(n);
-                    &mut heap_buf[..]
-                };
-
-                // This function is typically called on windows API functions which
-                // will return the correct length of the string, but these functions
-                // also return the `0` on error. In some cases, however, the
-                // returned "correct length" may actually be 0!
-                //
-                // To handle this case we call `SetLastError` to reset it to 0 and
-                // then check it again if we get the "0 error value". If the "last
-                // error" is still 0 then we interpret it as a 0 length buffer and
-                // not an actual error.
-                SetLastError(0);
-                let k = match f1(buf.as_mut_ptr(), n as DWORD) {
-                    0 if GetLastError() == 0 => 0,
-                    0 => return Err(io::Error::last_os_error()),
-                    n => n,
-                } as usize;
-                if k == n && GetLastError() == ERROR_INSUFFICIENT_BUFFER {
-                    n *= 2;
-                } else if k >= n {
-                    n = k;
-                } else {
-                    return Ok(f2(&buf[..k]));
-                }
-            }
-        }
-    }
-
-    #[derive(Clone, PartialEq, Eq, Debug, Default)]
-    struct FilePermissions {
-        readonly: bool,
-    }
-
-    impl FilePermissions {
-        fn new() -> FilePermissions {
-            Default::default()
-        }
-        fn readonly(&self) -> bool {
-            self.readonly
-        }
-        fn set_readonly(&mut self, readonly: bool) {
-            self.readonly = readonly
-        }
-    }
-
-    #[derive(Clone)]
-    struct OpenOptions {
-        // generic
-        read: bool,
-        write: bool,
-        append: bool,
-        truncate: bool,
-        create: bool,
-        create_new: bool,
-        // system-specific
-        custom_flags: u32,
-        access_mode: Option<DWORD>,
-        attributes: DWORD,
-        share_mode: DWORD,
-        security_qos_flags: DWORD,
-        security_attributes: usize, // FIXME: should be a reference
-    }
-
-    impl OpenOptions {
-        fn new() -> OpenOptions {
-            OpenOptions {
-                // generic
-                read: false,
-                write: false,
-                append: false,
-                truncate: false,
-                create: false,
-                create_new: false,
-                // system-specific
-                custom_flags: 0,
-                access_mode: None,
-                share_mode: FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
-                attributes: 0,
-                security_qos_flags: 0,
-                security_attributes: 0,
-            }
-        }
-        fn custom_flags(&mut self, flags: u32) {
-            self.custom_flags = flags;
-        }
-        fn access_mode(&mut self, access_mode: u32) {
-            self.access_mode = Some(access_mode);
-        }
-
-        fn get_access_mode(&self) -> io::Result<DWORD> {
-            const ERROR_INVALID_PARAMETER: i32 = 87;
-
-            match (self.read, self.write, self.append, self.access_mode) {
-                (_, _, _, Some(mode)) => Ok(mode),
-                (true, false, false, None) => Ok(GENERIC_READ),
-                (false, true, false, None) => Ok(GENERIC_WRITE),
-                (true, true, false, None) => Ok(GENERIC_READ | GENERIC_WRITE),
-                (false, _, true, None) => Ok(FILE_GENERIC_WRITE & !FILE_WRITE_DATA),
-                (true, _, true, None) => Ok(GENERIC_READ | (FILE_GENERIC_WRITE & !FILE_WRITE_DATA)),
-                (false, false, false, None) => {
-                    Err(io::Error::from_raw_os_error(ERROR_INVALID_PARAMETER))
-                }
-            }
-        }
-
-        fn get_creation_mode(&self) -> io::Result<DWORD> {
-            const ERROR_INVALID_PARAMETER: i32 = 87;
-
-            match (self.write, self.append) {
-                (true, false) => {}
-                (false, false) => {
-                    if self.truncate || self.create || self.create_new {
-                        return Err(io::Error::from_raw_os_error(ERROR_INVALID_PARAMETER));
-                    }
-                }
-                (_, true) => {
-                    if self.truncate && !self.create_new {
-                        return Err(io::Error::from_raw_os_error(ERROR_INVALID_PARAMETER));
-                    }
-                }
-            }
-
-            Ok(match (self.create, self.truncate, self.create_new) {
-                (false, false, false) => OPEN_EXISTING,
-                (true, false, false) => OPEN_ALWAYS,
-                (false, true, false) => TRUNCATE_EXISTING,
-                (true, true, false) => CREATE_ALWAYS,
-                (_, _, true) => CREATE_NEW,
-            })
-        }
-
-        fn get_flags_and_attributes(&self) -> DWORD {
-            self.custom_flags
-                | self.attributes
-                | self.security_qos_flags
-                | if self.security_qos_flags != 0 {
-                    SECURITY_SQOS_PRESENT
-                } else {
-                    0
-                }
-                | if self.create_new {
-                    FILE_FLAG_OPEN_REPARSE_POINT
-                } else {
-                    0
-                }
-        }
-    }
-
-    struct File {
-        handle: Handle,
-    }
-
-    impl File {
-        fn open(path: &Path, opts: &OpenOptions) -> io::Result<File> {
-            let path = to_u16s(path)?;
-            let handle = unsafe {
-                CreateFileW(
-                    path.as_ptr(),
-                    opts.get_access_mode()?,
-                    opts.share_mode,
-                    opts.security_attributes as *mut _,
-                    opts.get_creation_mode()?,
-                    opts.get_flags_and_attributes(),
-                    ptr::null_mut(),
-                )
-            };
-            if handle == INVALID_HANDLE_VALUE {
-                Err(io::Error::last_os_error())
-            } else {
-                Ok(File {
-                    handle: Handle::new(handle),
-                })
-            }
-        }
-
-        fn file_attr(&self) -> io::Result<FileAttr> {
-            unsafe {
-                let mut info: BY_HANDLE_FILE_INFORMATION = mem::zeroed();
-                cvt(GetFileInformationByHandle(self.handle.raw(), &mut info))?;
-                let mut attr = FileAttr {
-                    attributes: info.dwFileAttributes,
-                    creation_time: info.ftCreationTime,
-                    last_access_time: info.ftLastAccessTime,
-                    last_write_time: info.ftLastWriteTime,
-                    file_size: ((info.nFileSizeHigh as u64) << 32) | (info.nFileSizeLow as u64),
-                    reparse_tag: 0,
-                };
-                if attr.is_reparse_point() {
-                    let mut b = [0; MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
-                    if let Ok((_, buf)) = self.reparse_point(&mut b) {
-                        attr.reparse_tag = buf.ReparseTag;
-                    }
-                }
-                Ok(attr)
-            }
-        }
-
-        fn set_attributes(&self, attr: DWORD) -> io::Result<()> {
-            let zero: LARGE_INTEGER = unsafe { mem::zeroed() };
-
-            let mut info = FILE_BASIC_INFO {
-                CreationTime: zero,   // do not change
-                LastAccessTime: zero, // do not change
-                LastWriteTime: zero,  // do not change
-                ChangeTime: zero,     // do not change
-                FileAttributes: attr,
-            };
-            let size = mem::size_of_val(&info);
-            cvt(unsafe {
-                SetFileInformationByHandle(
-                    self.handle.raw(),
-                    FileBasicInfo,
-                    &mut info as *mut _ as *mut _,
-                    size as DWORD,
-                )
-            })?;
-            Ok(())
-        }
-
-        fn rename(&self, new: &Path, replace: bool) -> io::Result<()> {
-            // &self must be opened with DELETE permission
-            use std::iter;
-            #[cfg(target_arch = "x86")]
-            const STRUCT_SIZE: usize = 12;
-            #[cfg(target_arch = "x86_64")]
-            const STRUCT_SIZE: usize = 20;
-
-            // FIXME: check for internal NULs in 'new'
-            let mut data: Vec<u16> = iter::repeat(0u16)
-                .take(STRUCT_SIZE / 2)
-                .chain(new.as_os_str().encode_wide())
-                .collect();
-            data.push(0);
-            let size = data.len() * 2;
-
-            unsafe {
-                // Thanks to alignment guarantees on Windows this works
-                // (8 for 32-bit and 16 for 64-bit)
-                let info = data.as_mut_ptr() as *mut FILE_RENAME_INFO;
-                // The type of ReplaceIfExists is BOOL, but it actually expects a
-                // BOOLEAN. This means true is -1, not c::TRUE.
-                (*info).ReplaceIfExists = if replace { -1 } else { FALSE };
-                (*info).RootDirectory = ptr::null_mut();
-                (*info).FileNameLength = (size - STRUCT_SIZE) as DWORD;
-                cvt(SetFileInformationByHandle(
-                    self.handle().raw(),
-                    FileRenameInfo,
-                    data.as_mut_ptr() as *mut _ as *mut _,
-                    size as DWORD,
-                ))?;
-                Ok(())
-            }
-        }
-        fn set_perm(&self, perm: FilePermissions) -> io::Result<()> {
-            let attr = self.file_attr()?.attributes;
-            if perm.readonly == (attr & FILE_ATTRIBUTE_READONLY != 0) {
-                Ok(())
-            } else if perm.readonly {
-                self.set_attributes(attr | FILE_ATTRIBUTE_READONLY)
-            } else {
-                self.set_attributes(attr & !FILE_ATTRIBUTE_READONLY)
-            }
-        }
-
-        fn handle(&self) -> &Handle {
-            &self.handle
-        }
-
-        fn reparse_point<'a>(
-            &self,
-            space: &'a mut [u8; MAXIMUM_REPARSE_DATA_BUFFER_SIZE],
-        ) -> io::Result<(DWORD, &'a REPARSE_DATA_BUFFER)> {
-            unsafe {
-                let mut bytes = 0;
-                cvt({
-                    DeviceIoControl(
-                        self.handle.raw(),
-                        FSCTL_GET_REPARSE_POINT,
-                        ptr::null_mut(),
-                        0,
-                        space.as_mut_ptr() as *mut _,
-                        space.len() as DWORD,
-                        &mut bytes,
-                        ptr::null_mut(),
-                    )
-                })?;
-                Ok((bytes, &*(space.as_ptr() as *const REPARSE_DATA_BUFFER)))
-            }
-        }
-    }
-
-    #[derive(Copy, Clone, PartialEq, Eq, Hash)]
-    enum FileType {
-        Dir,
-        File,
-        SymlinkFile,
-        SymlinkDir,
-        ReparsePoint,
-        MountPoint,
-    }
-
-    impl FileType {
-        fn new(attrs: DWORD, reparse_tag: DWORD) -> FileType {
-            match (
-                attrs & FILE_ATTRIBUTE_DIRECTORY != 0,
-                attrs & FILE_ATTRIBUTE_REPARSE_POINT != 0,
-                reparse_tag,
-            ) {
-                (false, false, _) => FileType::File,
-                (true, false, _) => FileType::Dir,
-                (false, true, IO_REPARSE_TAG_SYMLINK) => FileType::SymlinkFile,
-                (true, true, IO_REPARSE_TAG_SYMLINK) => FileType::SymlinkDir,
-                (true, true, IO_REPARSE_TAG_MOUNT_POINT) => FileType::MountPoint,
-                (_, true, _) => FileType::ReparsePoint,
-                // Note: if a _file_ has a reparse tag of the type IO_REPARSE_TAG_MOUNT_POINT it is
-                // invalid, as junctions always have to be dirs. We set the filetype to ReparsePoint
-                // to indicate it is something symlink-like, but not something you can follow.
-            }
-        }
-
-        fn is_dir(&self) -> bool {
-            *self == FileType::Dir
-        }
-        fn is_symlink_dir(&self) -> bool {
-            *self == FileType::SymlinkDir || *self == FileType::MountPoint
-        }
-    }
-
-    impl DirEntry {
-        fn new(root: &Arc<PathBuf>, wfd: &WIN32_FIND_DATAW) -> Option<DirEntry> {
-            let first_bytes = &wfd.cFileName[0..3];
-            if first_bytes.starts_with(&[46, 0]) || first_bytes.starts_with(&[46, 46, 0]) {
-                None
-            } else {
-                Some(DirEntry {
-                    root: root.clone(),
-                    data: *wfd,
-                })
-            }
-        }
-
-        fn path(&self) -> PathBuf {
-            self.root.join(&self.file_name())
-        }
-
-        fn file_name(&self) -> OsString {
-            let filename = truncate_utf16_at_nul(&self.data.cFileName);
-            OsString::from_wide(filename)
-        }
-
-        fn file_type(&self) -> io::Result<FileType> {
-            Ok(FileType::new(
-                self.data.dwFileAttributes,
-                /* reparse_tag = */ self.data.dwReserved0,
-            ))
-        }
-
-        fn metadata(&self) -> io::Result<FileAttr> {
-            Ok(FileAttr {
-                attributes: self.data.dwFileAttributes,
-                creation_time: self.data.ftCreationTime,
-                last_access_time: self.data.ftLastAccessTime,
-                last_write_time: self.data.ftLastWriteTime,
-                file_size: ((self.data.nFileSizeHigh as u64) << 32)
-                    | (self.data.nFileSizeLow as u64),
-                reparse_tag: if self.data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT != 0 {
-                    // reserved unless this is a reparse point
-                    self.data.dwReserved0
-                } else {
-                    0
-                },
-            })
-        }
-    }
-
-    struct DirEntry {
-        root: Arc<PathBuf>,
-        data: WIN32_FIND_DATAW,
-    }
-
-    struct ReadDir {
-        handle: FindNextFileHandle,
-        root: Arc<PathBuf>,
-        first: Option<WIN32_FIND_DATAW>,
-    }
-
-    impl Iterator for ReadDir {
-        type Item = io::Result<DirEntry>;
-        fn next(&mut self) -> Option<io::Result<DirEntry>> {
-            if let Some(first) = self.first.take() {
-                if let Some(e) = DirEntry::new(&self.root, &first) {
-                    return Some(Ok(e));
-                }
-            }
-            unsafe {
-                let mut wfd = mem::zeroed();
-                loop {
-                    if FindNextFileW(self.handle.0, &mut wfd) == 0 {
-                        if GetLastError() == ERROR_NO_MORE_FILES {
-                            return None;
-                        } else {
-                            return Some(Err(io::Error::last_os_error()));
-                        }
-                    }
-                    if let Some(e) = DirEntry::new(&self.root, &wfd) {
-                        return Some(Ok(e));
-                    }
-                }
-            }
-        }
-    }
-
-    #[derive(Clone)]
-    struct FileAttr {
-        attributes: DWORD,
-        creation_time: FILETIME,
-        last_access_time: FILETIME,
-        last_write_time: FILETIME,
-        file_size: u64,
-        reparse_tag: DWORD,
-    }
-
-    impl FileAttr {
-        fn perm(&self) -> FilePermissions {
-            FilePermissions {
-                readonly: self.attributes & FILE_ATTRIBUTE_READONLY != 0,
-            }
-        }
-
-        fn file_type(&self) -> FileType {
-            FileType::new(self.attributes, self.reparse_tag)
-        }
-
-        fn is_reparse_point(&self) -> bool {
-            self.attributes & FILE_ATTRIBUTE_REPARSE_POINT != 0
-        }
-    }
-
-    #[repr(C)]
-    struct REPARSE_DATA_BUFFER {
-        ReparseTag: c_uint,
-        ReparseDataLength: c_ushort,
-        Reserved: c_ushort,
-        rest: (),
-    }
-
-    const MAXIMUM_REPARSE_DATA_BUFFER_SIZE: usize = 16 * 1024;
-
-    /// An owned container for `HANDLE` object, closing them on Drop.
-    ///
-    /// All methods are inherited through a `Deref` impl to `RawHandle`
-    struct Handle(RawHandle);
-
-    use std::ops::Deref;
-
-    /// A wrapper type for `HANDLE` objects to give them proper Send/Sync inference
-    /// as well as Rust-y methods.
-    ///
-    /// This does **not** drop the handle when it goes out of scope, use `Handle`
-    /// instead for that.
-    #[derive(Copy, Clone)]
-    struct RawHandle(HANDLE);
-
-    unsafe impl Send for RawHandle {}
-    unsafe impl Sync for RawHandle {}
-
-    impl Handle {
-        fn new(handle: HANDLE) -> Handle {
-            Handle(RawHandle::new(handle))
-        }
-    }
-
-    impl Deref for Handle {
-        type Target = RawHandle;
-        fn deref(&self) -> &RawHandle {
-            &self.0
-        }
-    }
-
-    impl Drop for Handle {
-        fn drop(&mut self) {
-            unsafe {
-                let _ = CloseHandle(self.raw());
-            }
-        }
-    }
-
-    impl RawHandle {
-        fn new(handle: HANDLE) -> RawHandle {
-            RawHandle(handle)
-        }
-
-        fn raw(&self) -> HANDLE {
-            self.0
-        }
-    }
-
-    struct FindNextFileHandle(HANDLE);
-
-    fn get_path(f: &File) -> io::Result<PathBuf> {
-        fill_utf16_buf(
-            |buf, sz| unsafe {
-                GetFinalPathNameByHandleW(f.handle.raw(), buf, sz, VOLUME_NAME_DOS)
-            },
-            |buf| PathBuf::from(OsString::from_wide(buf)),
-        )
-    }
-
-    fn move_item(file: &File, ctx: &mut RmdirContext) -> io::Result<()> {
-        let mut tmpname = ctx.base_dir.join(format! {"rm-{}", ctx.counter});
-        ctx.counter += 1;
-        // Try to rename the file. If it already exists, just retry with an other
-        // filename.
-        while let Err(err) = file.rename(tmpname.as_ref(), false) {
-            if err.kind() != io::ErrorKind::AlreadyExists {
-                return Err(err);
-            };
-            tmpname = ctx.base_dir.join(format!("rm-{}", ctx.counter));
-            ctx.counter += 1;
-        }
-        Ok(())
-    }
-
-    fn set_perm(path: &Path, perm: FilePermissions) -> io::Result<()> {
-        let mut opts = OpenOptions::new();
-        opts.access_mode(FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES);
-        opts.custom_flags(FILE_FLAG_BACKUP_SEMANTICS);
-        let file = File::open(path, &opts)?;
-        file.set_perm(perm)
-    }
-
-    const VOLUME_NAME_DOS: DWORD = 0x0;
-}
diff --git a/tests/mir-opt/building/custom/references.raw_pointer_offset.built.after.mir b/tests/mir-opt/building/custom/references.raw_pointer_offset.built.after.mir
new file mode 100644
index 00000000000..f614aef4029
--- /dev/null
+++ b/tests/mir-opt/building/custom/references.raw_pointer_offset.built.after.mir
@@ -0,0 +1,10 @@
+// MIR for `raw_pointer_offset` after built
+
+fn raw_pointer_offset(_1: *const i32) -> *const i32 {
+    let mut _0: *const i32;              // return place in scope 0 at $DIR/references.rs:+0:45: +0:55
+
+    bb0: {
+        _0 = Offset(_1, const 1_isize);  // scope 0 at $DIR/references.rs:+2:9: +2:33
+        return;                          // scope 0 at $DIR/references.rs:+3:9: +3:17
+    }
+}
diff --git a/tests/mir-opt/building/custom/references.rs b/tests/mir-opt/building/custom/references.rs
index a1c896de04c..f87f6664c7a 100644
--- a/tests/mir-opt/building/custom/references.rs
+++ b/tests/mir-opt/building/custom/references.rs
@@ -45,11 +45,22 @@ pub fn raw_pointer(x: *const i32) -> *const i32 {
     })
 }
 
+// EMIT_MIR references.raw_pointer_offset.built.after.mir
+#[custom_mir(dialect = "built")]
+pub fn raw_pointer_offset(x: *const i32) -> *const i32 {
+    mir!({
+        RET = Offset(x, 1_isize);
+        Return()
+    })
+}
+
 fn main() {
     let mut x = 5;
+    let arr = [1, 2];
     assert_eq!(*mut_ref(&mut x), 5);
     assert_eq!(*immut_ref(&x), 5);
     unsafe {
         assert_eq!(*raw_pointer(addr_of!(x)), 5);
+        assert_eq!(*raw_pointer_offset(addr_of!(arr[0])), 2);
     }
 }
diff --git a/tests/ui/lint/dead-code/issue-59003.rs b/tests/ui/lint/dead-code/issue-59003.rs
new file mode 100644
index 00000000000..966d6412870
--- /dev/null
+++ b/tests/ui/lint/dead-code/issue-59003.rs
@@ -0,0 +1,18 @@
+// check-pass
+
+// Make sure we don't have any false positives about the "struct is never constructed" lint.
+
+#![deny(dead_code)]
+
+struct Foo {
+    #[allow(dead_code)]
+    inner: u32,
+}
+
+impl From<u32> for Foo {
+    fn from(inner: u32) -> Self {
+        Self { inner }
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/mir/validate/transmute_cast_sized.rs b/tests/ui/mir/validate/transmute_cast_sized.rs
new file mode 100644
index 00000000000..eaaf7eb3ecd
--- /dev/null
+++ b/tests/ui/mir/validate/transmute_cast_sized.rs
@@ -0,0 +1,17 @@
+// build-pass
+// compile-flags: -Zvalidate-mir
+// edition: 2021
+
+#![crate_type = "lib"]
+
+// Use `PhantomData` to get target-independent size
+async fn get(_r: std::marker::PhantomData<&i32>) {
+    loop {}
+}
+
+pub fn check() {
+    let mut v = get(loop {});
+    let _ = || unsafe {
+        v = std::mem::transmute([0_u8; 1]);
+    };
+}