about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-01-23 20:43:38 +0000
committerbors <bors@rust-lang.org>2024-01-23 20:43:38 +0000
commit5d3d3479d774754856db2db3e439dfb88ef3c52f (patch)
treec1fb20b5e72855a5a638b349d6c69ba76ae1a0fd /compiler
parentdfe53afaebd817f334d8ef9dc75a5cd2562cf6e6 (diff)
parent08bac31f8f95a9cf2bdcbecfb65ca8de5b644699 (diff)
downloadrust-5d3d3479d774754856db2db3e439dfb88ef3c52f.tar.gz
rust-5d3d3479d774754856db2db3e439dfb88ef3c52f.zip
Auto merge of #120281 - fmease:rollup-9nxail8, r=fmease
Rollup of 10 pull requests

Successful merges:

 - #119028 (Add more weirdness to weird-exprs.rs)
 - #119805 (Suggest array::from_fn for array initialization)
 - #120188 (compiler: update freebsd and netbsd base specs.)
 - #120215 (Update some deps with `bitflags` v1 dependencies)
 - #120244 (Use `Self` in `NonZero*` implementations.)
 - #120246 (Re-add estebank to review rotation)
 - #120252 (rename `RawTy` to `LoweredTy`)
 - #120255 (correct my mailmap entry)
 - #120270 (A bunch of random modifications)
 - #120280 (Move condition enabling the pass to `is_enabled`)

r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_hir_analysis/src/autoderef.rs3
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs25
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs10
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs12
-rw-r--r--compiler/rustc_hir_typeck/src/lib.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/method/probe.rs4
-rw-r--r--compiler/rustc_hir_typeck/src/pat.rs4
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs38
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs45
-rw-r--r--compiler/rustc_mir_transform/src/remove_storage_markers.rs8
-rw-r--r--compiler/rustc_target/src/spec/base/dragonfly.rs1
-rw-r--r--compiler/rustc_target/src/spec/base/freebsd.rs1
-rw-r--r--compiler/rustc_target/src/spec/base/netbsd.rs1
-rw-r--r--compiler/rustc_trait_selection/src/solve/normalizes_to/weak_types.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs39
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs7
18 files changed, 92 insertions, 116 deletions
diff --git a/compiler/rustc_hir_analysis/src/autoderef.rs b/compiler/rustc_hir_analysis/src/autoderef.rs
index 556560945e9..5bc904e5930 100644
--- a/compiler/rustc_hir_analysis/src/autoderef.rs
+++ b/compiler/rustc_hir_analysis/src/autoderef.rs
@@ -12,7 +12,9 @@ use rustc_trait_selection::traits::StructurallyNormalizeExt;
 
 #[derive(Copy, Clone, Debug)]
 pub enum AutoderefKind {
+    /// A true pointer type, such as `&T` and `*mut T`.
     Builtin,
+    /// A type which must dispatch to a `Deref` implementation.
     Overloaded,
 }
 
@@ -83,6 +85,7 @@ impl<'a, 'tcx> Iterator for Autoderef<'a, 'tcx> {
                 (AutoderefKind::Builtin, ty)
             }
         } else if let Some(ty) = self.overloaded_deref_ty(self.state.cur_ty) {
+            // The overloaded deref check already normalizes the pointee type.
             (AutoderefKind::Overloaded, ty)
         } else {
             return None;
diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
index 5b264f6f034..57829d9d418 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
@@ -254,7 +254,7 @@ fn compare_method_predicate_entailment<'tcx>(
     // checks. For the comparison to be valid, we need to
     // normalize the associated types in the impl/trait methods
     // first. However, because function types bind regions, just
-    // calling `normalize_associated_types_in` would have no effect on
+    // calling `FnCtxt::normalize` would have no effect on
     // any associated types appearing in the fn arguments or return
     // type.
 
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
index 09dbfaa57d2..c6b9197d0e9 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -2,7 +2,7 @@ use crate::callee::{self, DeferredCallResolution};
 use crate::errors::CtorIsPrivate;
 use crate::method::{self, MethodCallee, SelfSource};
 use crate::rvalue_scopes;
-use crate::{BreakableCtxt, Diverges, Expectation, FnCtxt, RawTy};
+use crate::{BreakableCtxt, Diverges, Expectation, FnCtxt, LoweredTy};
 use rustc_data_structures::captures::Captures;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::{Applicability, Diagnostic, ErrorGuaranteed, MultiSpan, StashKey};
@@ -373,14 +373,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
-    pub fn handle_raw_ty(&self, span: Span, ty: Ty<'tcx>) -> RawTy<'tcx> {
-        RawTy { raw: ty, normalized: self.normalize(span, ty) }
-    }
-
-    pub fn to_ty(&self, ast_t: &hir::Ty<'tcx>) -> RawTy<'tcx> {
+    pub fn to_ty(&self, ast_t: &hir::Ty<'tcx>) -> LoweredTy<'tcx> {
         let t = self.astconv().ast_ty_to_ty(ast_t);
         self.register_wf_obligation(t.into(), ast_t.span, traits::WellFormed(None));
-        self.handle_raw_ty(ast_t.span, t)
+        LoweredTy::from_raw(self, ast_t.span, t)
     }
 
     pub fn to_ty_saving_user_provided_ty(&self, ast_ty: &hir::Ty<'tcx>) -> Ty<'tcx> {
@@ -396,7 +392,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         ty.normalized
     }
 
-    pub(super) fn user_args_for_adt(ty: RawTy<'tcx>) -> UserArgs<'tcx> {
+    pub(super) fn user_args_for_adt(ty: LoweredTy<'tcx>) -> UserArgs<'tcx> {
         match (ty.raw.kind(), ty.normalized.kind()) {
             (ty::Adt(_, args), _) => UserArgs { args, user_self_ty: None },
             (_, ty::Adt(adt, args)) => UserArgs {
@@ -801,7 +797,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         hir_id: hir::HirId,
         span: Span,
         args: Option<&'tcx [hir::Expr<'tcx>]>,
-    ) -> (Res, Option<RawTy<'tcx>>, &'tcx [hir::PathSegment<'tcx>]) {
+    ) -> (Res, Option<LoweredTy<'tcx>>, &'tcx [hir::PathSegment<'tcx>]) {
         debug!(
             "resolve_ty_and_res_fully_qualified_call: qpath={:?} hir_id={:?} span={:?}",
             qpath, hir_id, span
@@ -825,7 +821,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 // We manually call `register_wf_obligation` in the success path
                 // below.
                 let ty = self.astconv().ast_ty_to_ty_in_path(qself);
-                (self.handle_raw_ty(span, ty), qself, segment)
+                (LoweredTy::from_raw(self, span, ty), qself, segment)
             }
             QPath::LangItem(..) => {
                 bug!("`resolve_ty_and_res_fully_qualified_call` called on `LangItem`")
@@ -1074,7 +1070,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     pub fn instantiate_value_path(
         &self,
         segments: &'tcx [hir::PathSegment<'tcx>],
-        self_ty: Option<RawTy<'tcx>>,
+        self_ty: Option<LoweredTy<'tcx>>,
         res: Res,
         span: Span,
         hir_id: hir::HirId,
@@ -1201,8 +1197,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             path_segs.last().is_some_and(|PathSeg(def_id, _)| tcx.generics_of(*def_id).has_self);
 
         let (res, self_ctor_args) = if let Res::SelfCtor(impl_def_id) = res {
-            let ty =
-                self.handle_raw_ty(span, tcx.at(span).type_of(impl_def_id).instantiate_identity());
+            let ty = LoweredTy::from_raw(
+                self,
+                span,
+                tcx.at(span).type_of(impl_def_id).instantiate_identity(),
+            );
             match ty.normalized.ty_adt_def() {
                 Some(adt_def) if adt_def.has_ctor() => {
                     let (ctor_kind, ctor_def_id) = adt_def.non_enum_variant().ctor.unwrap();
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index 136ed1a709e..6a77450f075 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -6,7 +6,7 @@ use crate::method::MethodCallee;
 use crate::TupleArgumentsFlag::*;
 use crate::{errors, Expectation::*};
 use crate::{
-    struct_span_code_err, BreakableCtxt, Diverges, Expectation, FnCtxt, Needs, RawTy,
+    struct_span_code_err, BreakableCtxt, Diverges, Expectation, FnCtxt, LoweredTy, Needs,
     TupleArgumentsFlag,
 };
 use itertools::Itertools;
@@ -1792,12 +1792,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         qpath: &QPath<'tcx>,
         path_span: Span,
         hir_id: hir::HirId,
-    ) -> (Res, RawTy<'tcx>) {
+    ) -> (Res, LoweredTy<'tcx>) {
         match *qpath {
             QPath::Resolved(ref maybe_qself, path) => {
                 let self_ty = maybe_qself.as_ref().map(|qself| self.to_ty(qself).raw);
                 let ty = self.astconv().res_to_ty(self_ty, path, hir_id, true);
-                (path.res, self.handle_raw_ty(path_span, ty))
+                (path.res, LoweredTy::from_raw(self, path_span, ty))
             }
             QPath::TypeRelative(qself, segment) => {
                 let ty = self.to_ty(qself);
@@ -1808,7 +1808,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 let ty = result
                     .map(|(ty, _, _)| ty)
                     .unwrap_or_else(|guar| Ty::new_error(self.tcx(), guar));
-                let ty = self.handle_raw_ty(path_span, ty);
+                let ty = LoweredTy::from_raw(self, path_span, ty);
                 let result = result.map(|(_, kind, def_id)| (kind, def_id));
 
                 // Write back the new resolution.
@@ -1818,7 +1818,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
             QPath::LangItem(lang_item, span) => {
                 let (res, ty) = self.resolve_lang_item_path(lang_item, span, hir_id);
-                (res, self.handle_raw_ty(path_span, ty))
+                (res, LoweredTy::from_raw(self, path_span, ty))
             }
         }
     }
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
index f65e9b698ab..18f547be2a7 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
@@ -353,14 +353,22 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
     }
 }
 
-/// Represents a user-provided type in the raw form (never normalized).
+/// The `ty` representation of a user-provided type. Depending on the use-site
+/// we want to either use the unnormalized or the normalized form of this type.
 ///
 /// This is a bridge between the interface of `AstConv`, which outputs a raw `Ty`,
 /// and the API in this module, which expect `Ty` to be fully normalized.
 #[derive(Clone, Copy, Debug)]
-pub struct RawTy<'tcx> {
+pub struct LoweredTy<'tcx> {
+    /// The unnormalized type provided by the user.
     pub raw: Ty<'tcx>,
 
     /// The normalized form of `raw`, stored here for efficiency.
     pub normalized: Ty<'tcx>,
 }
+
+impl<'tcx> LoweredTy<'tcx> {
+    pub fn from_raw(fcx: &FnCtxt<'_, 'tcx>, span: Span, raw: Ty<'tcx>) -> LoweredTy<'tcx> {
+        LoweredTy { raw, normalized: fcx.normalize(span, raw) }
+    }
+}
diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs
index 80467ca9381..bdd7c382903 100644
--- a/compiler/rustc_hir_typeck/src/lib.rs
+++ b/compiler/rustc_hir_typeck/src/lib.rs
@@ -49,7 +49,7 @@ use crate::check::check_fn;
 use crate::coercion::DynamicCoerceMany;
 use crate::diverges::Diverges;
 use crate::expectation::Expectation;
-use crate::fn_ctxt::RawTy;
+use crate::fn_ctxt::LoweredTy;
 use crate::gather_locals::GatherLocalsVisitor;
 use rustc_data_structures::unord::UnordSet;
 use rustc_errors::{struct_span_code_err, ErrorGuaranteed};
diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs
index 17eff54f7ae..a446c7aa42b 100644
--- a/compiler/rustc_hir_typeck/src/method/probe.rs
+++ b/compiler/rustc_hir_typeck/src/method/probe.rs
@@ -746,11 +746,13 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
             let (xform_self_ty, xform_ret_ty) = self.xform_self_ty(item, impl_ty, impl_args);
             debug!("xform_self_ty: {:?}, xform_ret_ty: {:?}", xform_self_ty, xform_ret_ty);
 
-            // We can't use normalize_associated_types_in as it will pollute the
+            // We can't use `FnCtxt::normalize` as it will pollute the
             // fcx's fulfillment context after this probe is over.
+            //
             // Note: we only normalize `xform_self_ty` here since the normalization
             // of the return type can lead to inference results that prohibit
             // valid candidates from being found, see issue #85671
+            //
             // FIXME Postponing the normalization of the return type likely only hides a deeper bug,
             // which might be caused by the `param_env` itself. The clauses of the `param_env`
             // maybe shouldn't include `Param`s, but rather fresh variables or be canonicalized,
diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs
index 73fc0ee499e..e31eeab4c4a 100644
--- a/compiler/rustc_hir_typeck/src/pat.rs
+++ b/compiler/rustc_hir_typeck/src/pat.rs
@@ -1,5 +1,5 @@
 use crate::gather_locals::DeclOrigin;
-use crate::{errors, FnCtxt, RawTy};
+use crate::{errors, FnCtxt, LoweredTy};
 use rustc_ast as ast;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::{
@@ -891,7 +891,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         &self,
         pat: &Pat<'tcx>,
         qpath: &hir::QPath<'_>,
-        path_resolution: (Res, Option<RawTy<'tcx>>, &'tcx [hir::PathSegment<'tcx>]),
+        path_resolution: (Res, Option<LoweredTy<'tcx>>, &'tcx [hir::PathSegment<'tcx>]),
         expected: Ty<'tcx>,
         ti: TopInfo<'tcx>,
     ) -> Ty<'tcx> {
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index a06f4c6ba12..73052be30ae 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -804,17 +804,12 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
                     }
                 } else {
                     p!(print_def_path(did, args));
-                    p!(" upvar_tys=(");
-                    if !args.as_coroutine().is_valid() {
-                        p!("unavailable");
-                    } else {
-                        self.comma_sep(args.as_coroutine().upvar_tys().iter())?;
-                    }
-                    p!(")");
-
-                    if args.as_coroutine().is_valid() {
-                        p!(" ", print(args.as_coroutine().witness()));
-                    }
+                    p!(
+                        " upvar_tys=",
+                        print(args.as_coroutine().tupled_upvars_ty()),
+                        " witness=",
+                        print(args.as_coroutine().witness())
+                    );
                 }
 
                 p!("}}")
@@ -868,19 +863,14 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
                     }
                 } else {
                     p!(print_def_path(did, args));
-                    if !args.as_closure().is_valid() {
-                        p!(" closure_args=(unavailable)");
-                        p!(write(" args={}", args.print_as_list()));
-                    } else {
-                        p!(" closure_kind_ty=", print(args.as_closure().kind_ty()));
-                        p!(
-                            " closure_sig_as_fn_ptr_ty=",
-                            print(args.as_closure().sig_as_fn_ptr_ty())
-                        );
-                        p!(" upvar_tys=(");
-                        self.comma_sep(args.as_closure().upvar_tys().iter())?;
-                        p!(")");
-                    }
+                    p!(
+                        " closure_kind_ty=",
+                        print(args.as_closure().kind_ty()),
+                        " closure_sig_as_fn_ptr_ty=",
+                        print(args.as_closure().sig_as_fn_ptr_ty()),
+                        " upvar_tys=",
+                        print(args.as_closure().tupled_upvars_ty())
+                    );
                 }
                 p!("}}");
             }
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index 8cf5fc8013f..b089f4a9e78 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -242,9 +242,15 @@ pub struct ClosureArgs<'tcx> {
 
 /// Struct returned by `split()`.
 pub struct ClosureArgsParts<'tcx> {
+    /// This is the args of the typeck root.
     pub parent_args: &'tcx [GenericArg<'tcx>],
+    /// Represents the maximum calling capability of the closure.
     pub closure_kind_ty: Ty<'tcx>,
+    /// Captures the closure's signature. This closure signature is "tupled", and
+    /// thus has a peculiar signature of `extern "rust-call" fn((Args, ...)) -> Ty`.
     pub closure_sig_as_fn_ptr_ty: Ty<'tcx>,
+    /// The upvars captured by the closure. Remains an inference variable
+    /// until the upvar analysis, which happens late in HIR typeck.
     pub tupled_upvars_ty: Ty<'tcx>,
 }
 
@@ -277,15 +283,6 @@ impl<'tcx> ClosureArgs<'tcx> {
         }
     }
 
-    /// Returns `true` only if enough of the synthetic types are known to
-    /// allow using all of the methods on `ClosureArgs` without panicking.
-    ///
-    /// Used primarily by `ty::print::pretty` to be able to handle closure
-    /// types that haven't had their synthetic types substituted in.
-    pub fn is_valid(self) -> bool {
-        self.args.len() >= 3 && matches!(self.split().tupled_upvars_ty.kind(), Tuple(_))
-    }
-
     /// Returns the substitutions of the closure's parent.
     pub fn parent_args(self) -> &'tcx [GenericArg<'tcx>] {
         self.split().parent_args
@@ -296,9 +293,9 @@ impl<'tcx> ClosureArgs<'tcx> {
     /// empty iterator is returned.
     #[inline]
     pub fn upvar_tys(self) -> &'tcx List<Ty<'tcx>> {
-        match self.tupled_upvars_ty().kind() {
+        match *self.tupled_upvars_ty().kind() {
             TyKind::Error(_) => ty::List::empty(),
-            TyKind::Tuple(..) => self.tupled_upvars_ty().tuple_fields(),
+            TyKind::Tuple(tys) => tys,
             TyKind::Infer(_) => bug!("upvar_tys called before capture types are inferred"),
             ty => bug!("Unexpected representation of upvar types tuple {:?}", ty),
         }
@@ -337,10 +334,9 @@ impl<'tcx> ClosureArgs<'tcx> {
 
     /// Extracts the signature from the closure.
     pub fn sig(self) -> ty::PolyFnSig<'tcx> {
-        let ty = self.sig_as_fn_ptr_ty();
-        match ty.kind() {
-            ty::FnPtr(sig) => *sig,
-            _ => bug!("closure_sig_as_fn_ptr_ty is not a fn-ptr: {:?}", ty.kind()),
+        match *self.sig_as_fn_ptr_ty().kind() {
+            ty::FnPtr(sig) => sig,
+            ty => bug!("closure_sig_as_fn_ptr_ty is not a fn-ptr: {ty:?}"),
         }
     }
 
@@ -356,11 +352,17 @@ pub struct CoroutineArgs<'tcx> {
 }
 
 pub struct CoroutineArgsParts<'tcx> {
+    /// This is the args of the typeck root.
     pub parent_args: &'tcx [GenericArg<'tcx>],
     pub resume_ty: Ty<'tcx>,
     pub yield_ty: Ty<'tcx>,
     pub return_ty: Ty<'tcx>,
+    /// The interior type of the coroutine.
+    /// Represents all types that are stored in locals
+    /// in the coroutine's body.
     pub witness: Ty<'tcx>,
+    /// The upvars captured by the closure. Remains an inference variable
+    /// until the upvar analysis, which happens late in HIR typeck.
     pub tupled_upvars_ty: Ty<'tcx>,
 }
 
@@ -397,15 +399,6 @@ impl<'tcx> CoroutineArgs<'tcx> {
         }
     }
 
-    /// Returns `true` only if enough of the synthetic types are known to
-    /// allow using all of the methods on `CoroutineArgs` without panicking.
-    ///
-    /// Used primarily by `ty::print::pretty` to be able to handle coroutine
-    /// types that haven't had their synthetic types substituted in.
-    pub fn is_valid(self) -> bool {
-        self.args.len() >= 5 && matches!(self.split().tupled_upvars_ty.kind(), Tuple(_))
-    }
-
     /// Returns the substitutions of the coroutine's parent.
     pub fn parent_args(self) -> &'tcx [GenericArg<'tcx>] {
         self.split().parent_args
@@ -425,9 +418,9 @@ impl<'tcx> CoroutineArgs<'tcx> {
     /// empty iterator is returned.
     #[inline]
     pub fn upvar_tys(self) -> &'tcx List<Ty<'tcx>> {
-        match self.tupled_upvars_ty().kind() {
+        match *self.tupled_upvars_ty().kind() {
             TyKind::Error(_) => ty::List::empty(),
-            TyKind::Tuple(..) => self.tupled_upvars_ty().tuple_fields(),
+            TyKind::Tuple(tys) => tys,
             TyKind::Infer(_) => bug!("upvar_tys called before capture types are inferred"),
             ty => bug!("Unexpected representation of upvar types tuple {:?}", ty),
         }
diff --git a/compiler/rustc_mir_transform/src/remove_storage_markers.rs b/compiler/rustc_mir_transform/src/remove_storage_markers.rs
index 795f5232ee3..f68e592db15 100644
--- a/compiler/rustc_mir_transform/src/remove_storage_markers.rs
+++ b/compiler/rustc_mir_transform/src/remove_storage_markers.rs
@@ -7,14 +7,10 @@ pub struct RemoveStorageMarkers;
 
 impl<'tcx> MirPass<'tcx> for RemoveStorageMarkers {
     fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
-        sess.mir_opt_level() > 0
+        sess.mir_opt_level() > 0 && !sess.emit_lifetime_markers()
     }
 
-    fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
-        if tcx.sess.emit_lifetime_markers() {
-            return;
-        }
-
+    fn run_pass(&self, _tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
         trace!("Running RemoveStorageMarkers on {:?}", body.source);
         for data in body.basic_blocks.as_mut_preserves_cfg() {
             data.statements.retain(|statement| match statement.kind {
diff --git a/compiler/rustc_target/src/spec/base/dragonfly.rs b/compiler/rustc_target/src/spec/base/dragonfly.rs
index de2be781796..3c1846696f7 100644
--- a/compiler/rustc_target/src/spec/base/dragonfly.rs
+++ b/compiler/rustc_target/src/spec/base/dragonfly.rs
@@ -8,6 +8,7 @@ pub fn opts() -> TargetOptions {
         has_rpath: true,
         position_independent_executables: true,
         relro_level: RelroLevel::Full,
+        has_thread_local: true,
         default_dwarf_version: 2,
         ..Default::default()
     }
diff --git a/compiler/rustc_target/src/spec/base/freebsd.rs b/compiler/rustc_target/src/spec/base/freebsd.rs
index 80b3da8a752..c772754aa8d 100644
--- a/compiler/rustc_target/src/spec/base/freebsd.rs
+++ b/compiler/rustc_target/src/spec/base/freebsd.rs
@@ -9,6 +9,7 @@ pub fn opts() -> TargetOptions {
         crt_static_respected: true,
         position_independent_executables: true,
         relro_level: RelroLevel::Full,
+        has_thread_local: true,
         abi_return_struct_as_int: true,
         default_dwarf_version: 2,
         ..Default::default()
diff --git a/compiler/rustc_target/src/spec/base/netbsd.rs b/compiler/rustc_target/src/spec/base/netbsd.rs
index be94ea23465..495e3d10fbc 100644
--- a/compiler/rustc_target/src/spec/base/netbsd.rs
+++ b/compiler/rustc_target/src/spec/base/netbsd.rs
@@ -9,6 +9,7 @@ pub fn opts() -> TargetOptions {
         has_rpath: true,
         position_independent_executables: true,
         relro_level: RelroLevel::Full,
+        has_thread_local: true,
         use_ctors_section: true,
         default_dwarf_version: 2,
         ..Default::default()
diff --git a/compiler/rustc_trait_selection/src/solve/normalizes_to/weak_types.rs b/compiler/rustc_trait_selection/src/solve/normalizes_to/weak_types.rs
index 6d5728797d1..9f91c02c1ab 100644
--- a/compiler/rustc_trait_selection/src/solve/normalizes_to/weak_types.rs
+++ b/compiler/rustc_trait_selection/src/solve/normalizes_to/weak_types.rs
@@ -1,7 +1,7 @@
 //! Computes a normalizes-to (projection) goal for inherent associated types,
 //! `#![feature(lazy_type_alias)]` and `#![feature(type_alias_impl_trait)]`.
 //!
-//! Since a weak alias is not ambiguous, this just computes the `type_of` of
+//! Since a weak alias is never ambiguous, this just computes the `type_of` of
 //! the alias and registers the where-clauses of the type alias.
 use rustc_middle::traits::solve::{Certainty, Goal, GoalSource, QueryResult};
 use rustc_middle::ty;
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index 0e33e9cd790..e31aaaa1969 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -3152,6 +3152,10 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                         ],
                         Applicability::MachineApplicable,
                     );
+                } else {
+                    // FIXME: we may suggest array::repeat instead
+                    err.help("consider using `core::array::from_fn` to initialize the array");
+                    err.help("see https://doc.rust-lang.org/stable/std/array/fn.from_fn.html# for more information");
                 }
 
                 if self.tcx.sess.is_nightly_build()
diff --git a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs
index 138bc6129f7..79f03242c58 100644
--- a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs
@@ -232,32 +232,12 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>(
             Ok::<_, NoSolution>(())
         })?,
 
-        ty::Closure(_, args) => {
-            if !args.as_closure().is_valid() {
-                // By the time this code runs, all type variables ought to
-                // be fully resolved.
-
-                tcx.dcx().span_delayed_bug(
-                    span,
-                    format!("upvar_tys for closure not found. Expected capture information for closure {ty}",),
-                );
-                return Err(NoSolution);
+        ty::Closure(_, args) => rustc_data_structures::stack::ensure_sufficient_stack(|| {
+            for ty in args.as_closure().upvar_tys() {
+                dtorck_constraint_for_ty_inner(tcx, param_env, span, depth + 1, ty, constraints)?;
             }
-
-            rustc_data_structures::stack::ensure_sufficient_stack(|| {
-                for ty in args.as_closure().upvar_tys() {
-                    dtorck_constraint_for_ty_inner(
-                        tcx,
-                        param_env,
-                        span,
-                        depth + 1,
-                        ty,
-                        constraints,
-                    )?;
-                }
-                Ok::<_, NoSolution>(())
-            })?
-        }
+            Ok::<_, NoSolution>(())
+        })?,
 
         ty::Coroutine(_, args) => {
             // rust-lang/rust#49918: types can be constructed, stored
@@ -283,15 +263,6 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>(
             // derived from lifetimes attached to the upvars and resume
             // argument, and we *do* incorporate those here.
             let args = args.as_coroutine();
-            if !args.is_valid() {
-                // By the time this code runs, all type variables ought to
-                // be fully resolved.
-                tcx.dcx().span_delayed_bug(
-                    span,
-                    format!("upvar_tys for coroutine not found. Expected capture information for coroutine {ty}",),
-                );
-                return Err(NoSolution);
-            }
 
             // While we conservatively assume that all coroutines require drop
             // to avoid query cycles during MIR building, we can check the actual
diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs
index 957de925dd3..fb09f094d37 100644
--- a/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs
@@ -141,6 +141,13 @@ where
         infcx: &InferCtxt<'tcx>,
         span: Span,
     ) -> Result<TypeOpOutput<'tcx, Self>, ErrorGuaranteed> {
+        // In the new trait solver, query type ops are performed locally. This
+        // is because query type ops currently use the old canonicalizer, and
+        // that doesn't preserve things like opaques which have been registered
+        // during MIR typeck. Even after the old canonicalizer is gone, it's
+        // probably worthwhile just keeping this run-locally logic, since we
+        // probably don't gain much from caching here given the new solver does
+        // caching internally.
         if infcx.next_trait_solver() {
             return Ok(scrape_region_constraints(
                 infcx,