about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_ast/src/format.rs6
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/region_name.rs1
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/var_name.rs4
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs27
-rw-r--r--compiler/rustc_borrowck/src/universal_regions.rs11
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs14
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs1
-rw-r--r--compiler/rustc_const_eval/src/transform/validate.rs5
-rw-r--r--compiler/rustc_infer/src/infer/opaque_types.rs8
-rw-r--r--compiler/rustc_middle/src/ty/layout.rs2
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs4
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs26
-rw-r--r--compiler/rustc_mir_dataflow/src/elaborate_drops.rs10
-rw-r--r--compiler/rustc_mir_transform/src/generator.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs6
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs5
-rw-r--r--compiler/rustc_ty_utils/src/layout.rs8
-rw-r--r--compiler/rustc_ty_utils/src/needs_drop.rs8
-rw-r--r--src/bootstrap/format.rs31
-rw-r--r--src/librustdoc/clean/utils.rs6
-rw-r--r--tests/ui/consts/ptr_comparisons.rs36
-rw-r--r--tests/ui/consts/ptr_comparisons.stderr40
-rw-r--r--tests/ui/imports/resolve-other-libc.rs14
-rw-r--r--tests/ui/imports/resolve-other-libc.stderr8
24 files changed, 120 insertions, 165 deletions
diff --git a/compiler/rustc_ast/src/format.rs b/compiler/rustc_ast/src/format.rs
index 699946f307b..805596ff00a 100644
--- a/compiler/rustc_ast/src/format.rs
+++ b/compiler/rustc_ast/src/format.rs
@@ -67,12 +67,6 @@ pub struct FormatArguments {
     names: FxHashMap<Symbol, usize>,
 }
 
-// FIXME: Rustdoc has trouble proving Send/Sync for this. See #106930.
-#[cfg(parallel_compiler)]
-unsafe impl Sync for FormatArguments {}
-#[cfg(parallel_compiler)]
-unsafe impl Send for FormatArguments {}
-
 impl FormatArguments {
     pub fn new() -> Self {
         Self {
diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs
index 9cad8fa5318..be6eb2d1d12 100644
--- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs
@@ -886,6 +886,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
             .universal_regions()
             .defining_ty
             .upvar_tys()
+            .iter()
             .position(|ty| self.any_param_predicate_mentions(&predicates, ty, region))
         {
             let (upvar_name, upvar_span) = self.regioncx.get_upvar_name_and_span_for_region(
diff --git a/compiler/rustc_borrowck/src/diagnostics/var_name.rs b/compiler/rustc_borrowck/src/diagnostics/var_name.rs
index 98418e2372f..8832d345df2 100644
--- a/compiler/rustc_borrowck/src/diagnostics/var_name.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/var_name.rs
@@ -43,7 +43,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         fr: RegionVid,
     ) -> Option<usize> {
         let upvar_index =
-            self.universal_regions().defining_ty.upvar_tys().position(|upvar_ty| {
+            self.universal_regions().defining_ty.upvar_tys().iter().position(|upvar_ty| {
                 debug!("get_upvar_index_for_region: upvar_ty={upvar_ty:?}");
                 tcx.any_free_region_meets(&upvar_ty, |r| {
                     let r = r.as_var();
@@ -52,7 +52,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
                 })
             })?;
 
-        let upvar_ty = self.universal_regions().defining_ty.upvar_tys().nth(upvar_index);
+        let upvar_ty = self.universal_regions().defining_ty.upvar_tys().get(upvar_index);
 
         debug!(
             "get_upvar_index_for_region: found {fr:?} in upvar {upvar_index} which has type {upvar_ty:?}",
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index fd4a3ec1a5e..abb11ce7396 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -791,25 +791,20 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
                     (adt_def.variant(FIRST_VARIANT), args)
                 }
                 ty::Closure(_, args) => {
-                    return match args
-                        .as_closure()
-                        .tupled_upvars_ty()
-                        .tuple_fields()
-                        .get(field.index())
-                    {
+                    return match args.as_closure().upvar_tys().get(field.index()) {
                         Some(&ty) => Ok(ty),
                         None => Err(FieldAccessError::OutOfRange {
-                            field_count: args.as_closure().upvar_tys().count(),
+                            field_count: args.as_closure().upvar_tys().len(),
                         }),
                     };
                 }
                 ty::Generator(_, args, _) => {
                     // Only prefix fields (upvars and current state) are
                     // accessible without a variant index.
-                    return match args.as_generator().prefix_tys().nth(field.index()) {
-                        Some(ty) => Ok(ty),
+                    return match args.as_generator().prefix_tys().get(field.index()) {
+                        Some(ty) => Ok(*ty),
                         None => Err(FieldAccessError::OutOfRange {
-                            field_count: args.as_generator().prefix_tys().count(),
+                            field_count: args.as_generator().prefix_tys().len(),
                         }),
                     };
                 }
@@ -1772,10 +1767,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                 }
             }
             AggregateKind::Closure(_, args) => {
-                match args.as_closure().upvar_tys().nth(field_index.as_usize()) {
-                    Some(ty) => Ok(ty),
+                match args.as_closure().upvar_tys().get(field_index.as_usize()) {
+                    Some(ty) => Ok(*ty),
                     None => Err(FieldAccessError::OutOfRange {
-                        field_count: args.as_closure().upvar_tys().count(),
+                        field_count: args.as_closure().upvar_tys().len(),
                     }),
                 }
             }
@@ -1783,10 +1778,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                 // It doesn't make sense to look at a field beyond the prefix;
                 // these require a variant index, and are not initialized in
                 // aggregate rvalues.
-                match args.as_generator().prefix_tys().nth(field_index.as_usize()) {
-                    Some(ty) => Ok(ty),
+                match args.as_generator().prefix_tys().get(field_index.as_usize()) {
+                    Some(ty) => Ok(*ty),
                     None => Err(FieldAccessError::OutOfRange {
-                        field_count: args.as_generator().prefix_tys().count(),
+                        field_count: args.as_generator().prefix_tys().len(),
                     }),
                 }
             }
diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs
index a751a9732f0..56945f43fcd 100644
--- a/compiler/rustc_borrowck/src/universal_regions.rs
+++ b/compiler/rustc_borrowck/src/universal_regions.rs
@@ -12,7 +12,6 @@
 //! The code in this file doesn't *do anything* with those results; it
 //! just returns them for other code to use.
 
-use either::Either;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::Diagnostic;
 use rustc_hir as hir;
@@ -115,14 +114,12 @@ impl<'tcx> DefiningTy<'tcx> {
     /// not a closure or generator, there are no upvars, and hence it
     /// will be an empty list. The order of types in this list will
     /// match up with the upvar order in the HIR, typesystem, and MIR.
-    pub fn upvar_tys(self) -> impl Iterator<Item = Ty<'tcx>> + 'tcx {
+    pub fn upvar_tys(self) -> &'tcx ty::List<Ty<'tcx>> {
         match self {
-            DefiningTy::Closure(_, args) => Either::Left(args.as_closure().upvar_tys()),
-            DefiningTy::Generator(_, args, _) => {
-                Either::Right(Either::Left(args.as_generator().upvar_tys()))
-            }
+            DefiningTy::Closure(_, args) => args.as_closure().upvar_tys(),
+            DefiningTy::Generator(_, args, _) => args.as_generator().upvar_tys(),
             DefiningTy::FnDef(..) | DefiningTy::Const(..) | DefiningTy::InlineConst(..) => {
-                Either::Right(Either::Right(iter::empty()))
+                ty::List::empty()
             }
         }
     }
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
index 40f0bcfdf58..f8cbcbd5ec8 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
@@ -990,14 +990,8 @@ fn build_upvar_field_di_nodes<'ll, 'tcx>(
     closure_or_generator_di_node: &'ll DIType,
 ) -> SmallVec<&'ll DIType> {
     let (&def_id, up_var_tys) = match closure_or_generator_ty.kind() {
-        ty::Generator(def_id, args, _) => {
-            let upvar_tys: SmallVec<_> = args.as_generator().prefix_tys().collect();
-            (def_id, upvar_tys)
-        }
-        ty::Closure(def_id, args) => {
-            let upvar_tys: SmallVec<_> = args.as_closure().upvar_tys().collect();
-            (def_id, upvar_tys)
-        }
+        ty::Generator(def_id, args, _) => (def_id, args.as_generator().prefix_tys()),
+        ty::Closure(def_id, args) => (def_id, args.as_closure().upvar_tys()),
         _ => {
             bug!(
                 "build_upvar_field_di_nodes() called with non-closure-or-generator-type: {:?}",
@@ -1007,9 +1001,7 @@ fn build_upvar_field_di_nodes<'ll, 'tcx>(
     };
 
     debug_assert!(
-        up_var_tys
-            .iter()
-            .all(|&t| t == cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), t))
+        up_var_tys.iter().all(|t| t == cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), t))
     );
 
     let capture_names = cx.tcx.closure_saved_names_of_captured_variables(def_id);
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs
index b4beb80ca8b..d3239d5c358 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs
@@ -379,6 +379,7 @@ pub fn build_generator_variant_struct_type_di_node<'ll, 'tcx>(
             // Fields that are common to all states
             let common_fields: SmallVec<_> = generator_args
                 .prefix_tys()
+                .iter()
                 .zip(common_upvar_names)
                 .enumerate()
                 .map(|(index, (upvar_ty, upvar_name))| {
diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs
index 31effadd2c2..83004492c8b 100644
--- a/compiler/rustc_const_eval/src/transform/validate.rs
+++ b/compiler/rustc_const_eval/src/transform/validate.rs
@@ -630,7 +630,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
                     }
                     ty::Closure(_, args) => {
                         let args = args.as_closure();
-                        let Some(f_ty) = args.upvar_tys().nth(f.as_usize()) else {
+                        let Some(&f_ty) = args.upvar_tys().get(f.as_usize()) else {
                             fail_out_of_bounds(self, location);
                             return;
                         };
@@ -667,7 +667,8 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
 
                             f_ty.ty
                         } else {
-                            let Some(f_ty) = args.as_generator().prefix_tys().nth(f.index()) else {
+                            let Some(&f_ty) = args.as_generator().prefix_tys().get(f.index())
+                            else {
                                 fail_out_of_bounds(self, location);
                                 return;
                             };
diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs
index 9c90b704586..a6052f52917 100644
--- a/compiler/rustc_infer/src/infer/opaque_types.rs
+++ b/compiler/rustc_infer/src/infer/opaque_types.rs
@@ -448,7 +448,9 @@ where
             ty::Closure(_, ref args) => {
                 // Skip lifetime parameters of the enclosing item(s)
 
-                args.as_closure().tupled_upvars_ty().visit_with(self);
+                for upvar in args.as_closure().upvar_tys() {
+                    upvar.visit_with(self);
+                }
                 args.as_closure().sig_as_fn_ptr_ty().visit_with(self);
             }
 
@@ -456,7 +458,9 @@ where
                 // Skip lifetime parameters of the enclosing item(s)
                 // Also skip the witness type, because that has no free regions.
 
-                args.as_generator().tupled_upvars_ty().visit_with(self);
+                for upvar in args.as_generator().upvar_tys() {
+                    upvar.visit_with(self);
+                }
                 args.as_generator().return_ty().visit_with(self);
                 args.as_generator().yield_ty().visit_with(self);
                 args.as_generator().resume_ty().visit_with(self);
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index 0f7bed0845c..df39103bc19 100644
--- a/compiler/rustc_middle/src/ty/layout.rs
+++ b/compiler/rustc_middle/src/ty/layout.rs
@@ -911,7 +911,7 @@ where
                         if i == tag_field {
                             return TyMaybeWithLayout::TyAndLayout(tag_layout(tag));
                         }
-                        TyMaybeWithLayout::Ty(args.as_generator().prefix_tys().nth(i).unwrap())
+                        TyMaybeWithLayout::Ty(args.as_generator().prefix_tys()[i])
                     }
                 },
 
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index f146f8aa8b4..290c4a48ab0 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -827,7 +827,7 @@ pub trait PrettyPrinter<'tcx>:
                     if !args.as_generator().is_valid() {
                         p!("unavailable");
                     } else {
-                        self = self.comma_sep(args.as_generator().upvar_tys())?;
+                        self = self.comma_sep(args.as_generator().upvar_tys().iter())?;
                     }
                     p!(")");
 
@@ -900,7 +900,7 @@ pub trait PrettyPrinter<'tcx>:
                             print(args.as_closure().sig_as_fn_ptr_ty())
                         );
                         p!(" upvar_tys=(");
-                        self = self.comma_sep(args.as_closure().upvar_tys())?;
+                        self = self.comma_sep(args.as_closure().upvar_tys().iter())?;
                         p!(")");
                     }
                 }
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index 3e023ccdead..1e5f64df9a5 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -296,15 +296,13 @@ impl<'tcx> ClosureArgs<'tcx> {
     /// In case there was a type error in figuring out the types of the captured path, an
     /// empty iterator is returned.
     #[inline]
-    pub fn upvar_tys(self) -> impl Iterator<Item = Ty<'tcx>> + 'tcx {
+    pub fn upvar_tys(self) -> &'tcx List<Ty<'tcx>> {
         match self.tupled_upvars_ty().kind() {
-            TyKind::Error(_) => None,
-            TyKind::Tuple(..) => Some(self.tupled_upvars_ty().tuple_fields()),
+            TyKind::Error(_) => ty::List::empty(),
+            TyKind::Tuple(..) => self.tupled_upvars_ty().tuple_fields(),
             TyKind::Infer(_) => bug!("upvar_tys called before capture types are inferred"),
             ty => bug!("Unexpected representation of upvar types tuple {:?}", ty),
         }
-        .into_iter()
-        .flatten()
     }
 
     /// Returns the tuple type representing the upvars for this closure.
@@ -436,15 +434,13 @@ impl<'tcx> GeneratorArgs<'tcx> {
     /// In case there was a type error in figuring out the types of the captured path, an
     /// empty iterator is returned.
     #[inline]
-    pub fn upvar_tys(self) -> impl Iterator<Item = Ty<'tcx>> + 'tcx {
+    pub fn upvar_tys(self) -> &'tcx List<Ty<'tcx>> {
         match self.tupled_upvars_ty().kind() {
-            TyKind::Error(_) => None,
-            TyKind::Tuple(..) => Some(self.tupled_upvars_ty().tuple_fields()),
+            TyKind::Error(_) => ty::List::empty(),
+            TyKind::Tuple(..) => self.tupled_upvars_ty().tuple_fields(),
             TyKind::Infer(_) => bug!("upvar_tys called before capture types are inferred"),
             ty => bug!("Unexpected representation of upvar types tuple {:?}", ty),
         }
-        .into_iter()
-        .flatten()
     }
 
     /// Returns the tuple type representing the upvars for this generator.
@@ -576,7 +572,7 @@ impl<'tcx> GeneratorArgs<'tcx> {
     /// This is the types of the fields of a generator which are not stored in a
     /// variant.
     #[inline]
-    pub fn prefix_tys(self) -> impl Iterator<Item = Ty<'tcx>> {
+    pub fn prefix_tys(self) -> &'tcx List<Ty<'tcx>> {
         self.upvar_tys()
     }
 }
@@ -592,20 +588,18 @@ impl<'tcx> UpvarArgs<'tcx> {
     /// In case there was a type error in figuring out the types of the captured path, an
     /// empty iterator is returned.
     #[inline]
-    pub fn upvar_tys(self) -> impl Iterator<Item = Ty<'tcx>> + 'tcx {
+    pub fn upvar_tys(self) -> &'tcx List<Ty<'tcx>> {
         let tupled_tys = match self {
             UpvarArgs::Closure(args) => args.as_closure().tupled_upvars_ty(),
             UpvarArgs::Generator(args) => args.as_generator().tupled_upvars_ty(),
         };
 
         match tupled_tys.kind() {
-            TyKind::Error(_) => None,
-            TyKind::Tuple(..) => Some(self.tupled_upvars_ty().tuple_fields()),
+            TyKind::Error(_) => ty::List::empty(),
+            TyKind::Tuple(..) => self.tupled_upvars_ty().tuple_fields(),
             TyKind::Infer(_) => bug!("upvar_tys called before capture types are inferred"),
             ty => bug!("Unexpected representation of upvar types tuple {:?}", ty),
         }
-        .into_iter()
-        .flatten()
     }
 
     #[inline]
diff --git a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs
index 1d7d905c937..9e02b027182 100644
--- a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs
+++ b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs
@@ -860,20 +860,14 @@ where
     fn open_drop(&mut self) -> BasicBlock {
         let ty = self.place_ty(self.place);
         match ty.kind() {
-            ty::Closure(_, args) => {
-                let tys: Vec<_> = args.as_closure().upvar_tys().collect();
-                self.open_drop_for_tuple(&tys)
-            }
+            ty::Closure(_, args) => self.open_drop_for_tuple(&args.as_closure().upvar_tys()),
             // Note that `elaborate_drops` only drops the upvars of a generator,
             // and this is ok because `open_drop` here can only be reached
             // within that own generator's resume function.
             // This should only happen for the self argument on the resume function.
             // It effectively only contains upvars until the generator transformation runs.
             // See librustc_body/transform/generator.rs for more details.
-            ty::Generator(_, args, _) => {
-                let tys: Vec<_> = args.as_generator().upvar_tys().collect();
-                self.open_drop_for_tuple(&tys)
-            }
+            ty::Generator(_, args, _) => self.open_drop_for_tuple(&args.as_generator().upvar_tys()),
             ty::Tuple(fields) => self.open_drop_for_tuple(fields),
             ty::Adt(def, args) => self.open_drop_for_adt(*def, args),
             ty::Dynamic(..) => self.complete_drop(self.succ, self.unwind),
diff --git a/compiler/rustc_mir_transform/src/generator.rs b/compiler/rustc_mir_transform/src/generator.rs
index 669135f80bc..797a1a86846 100644
--- a/compiler/rustc_mir_transform/src/generator.rs
+++ b/compiler/rustc_mir_transform/src/generator.rs
@@ -856,7 +856,7 @@ fn sanitize_witness<'tcx>(
     tcx: TyCtxt<'tcx>,
     body: &Body<'tcx>,
     witness: Ty<'tcx>,
-    upvars: Vec<Ty<'tcx>>,
+    upvars: &'tcx ty::List<Ty<'tcx>>,
     layout: &GeneratorLayout<'tcx>,
 ) {
     let did = body.source.def_id();
@@ -1471,7 +1471,7 @@ impl<'tcx> MirPass<'tcx> for StateTransform {
                 let args = args.as_generator();
                 (
                     args.discr_ty(tcx),
-                    args.upvar_tys().collect::<Vec<_>>(),
+                    args.upvar_tys(),
                     args.witness(),
                     movability == hir::Movability::Movable,
                 )
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 ef989d8c9d6..9484a50e3a9 100644
--- a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs
@@ -291,9 +291,9 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>(
                 return Err(NoSolution);
             }
 
-            constraints.outlives.extend(
-                args.as_generator().upvar_tys().map(|t| -> ty::GenericArg<'tcx> { t.into() }),
-            );
+            constraints
+                .outlives
+                .extend(args.as_generator().upvar_tys().iter().map(ty::GenericArg::from));
             constraints.outlives.push(args.as_generator().resume_ty().into());
         }
 
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 6080a440de6..367a196dcb8 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -2169,7 +2169,8 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
                         let all = args
                             .as_generator()
                             .upvar_tys()
-                            .chain(iter::once(args.as_generator().witness()))
+                            .iter()
+                            .chain([args.as_generator().witness()])
                             .collect::<Vec<_>>();
                         Where(obligation.predicate.rebind(all))
                     }
@@ -2210,7 +2211,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
                     // Not yet resolved.
                     Ambiguous
                 } else {
-                    Where(obligation.predicate.rebind(args.as_closure().upvar_tys().collect()))
+                    Where(obligation.predicate.rebind(args.as_closure().upvar_tys().to_vec()))
                 }
             }
 
diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs
index 3500c2cc370..6b4273c03e4 100644
--- a/compiler/rustc_ty_utils/src/layout.rs
+++ b/compiler/rustc_ty_utils/src/layout.rs
@@ -317,7 +317,9 @@ fn layout_of_uncached<'tcx>(
         ty::Closure(_, ref args) => {
             let tys = args.as_closure().upvar_tys();
             univariant(
-                &tys.map(|ty| Ok(cx.layout_of(ty)?.layout)).try_collect::<IndexVec<_, _>>()?,
+                &tys.iter()
+                    .map(|ty| Ok(cx.layout_of(ty)?.layout))
+                    .try_collect::<IndexVec<_, _>>()?,
                 &ReprOptions::default(),
                 StructKind::AlwaysSized,
             )?
@@ -729,7 +731,7 @@ fn generator_layout<'tcx>(
     // Build a prefix layout, including "promoting" all ineligible
     // locals as part of the prefix. We compute the layout of all of
     // these fields at once to get optimal packing.
-    let tag_index = args.as_generator().prefix_tys().count();
+    let tag_index = args.as_generator().prefix_tys().len();
 
     // `info.variant_fields` already accounts for the reserved variants, so no need to add them.
     let max_discr = (info.variant_fields.len() - 1) as u128;
@@ -748,6 +750,7 @@ fn generator_layout<'tcx>(
     let prefix_layouts = args
         .as_generator()
         .prefix_tys()
+        .iter()
         .map(|ty| Ok(cx.layout_of(ty)?.layout))
         .chain(iter::once(Ok(tag_layout)))
         .chain(promoted_layouts)
@@ -1062,6 +1065,7 @@ fn variant_info_for_generator<'tcx>(
     let upvar_fields: Vec<_> = args
         .as_generator()
         .upvar_tys()
+        .iter()
         .zip(upvar_names)
         .enumerate()
         .map(|(field_idx, (_, name))| {
diff --git a/compiler/rustc_ty_utils/src/needs_drop.rs b/compiler/rustc_ty_utils/src/needs_drop.rs
index f89558a4599..34fd31e49e1 100644
--- a/compiler/rustc_ty_utils/src/needs_drop.rs
+++ b/compiler/rustc_ty_utils/src/needs_drop.rs
@@ -120,12 +120,16 @@ where
                     _ if component.is_copy_modulo_regions(tcx, self.param_env) => (),
 
                     ty::Closure(_, args) => {
-                        queue_type(self, args.as_closure().tupled_upvars_ty());
+                        for upvar in args.as_closure().upvar_tys() {
+                            queue_type(self, upvar);
+                        }
                     }
 
                     ty::Generator(def_id, args, _) => {
                         let args = args.as_generator();
-                        queue_type(self, args.tupled_upvars_ty());
+                        for upvar in args.upvar_tys() {
+                            queue_type(self, upvar);
+                        }
 
                         let witness = args.witness();
                         let interior_tys = match witness.kind() {
diff --git a/src/bootstrap/format.rs b/src/bootstrap/format.rs
index 3f9230aa5d5..d658be0b8eb 100644
--- a/src/bootstrap/format.rs
+++ b/src/bootstrap/format.rs
@@ -113,9 +113,9 @@ pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) {
     }
     let rustfmt_config = t!(std::fs::read_to_string(&rustfmt_config));
     let rustfmt_config: RustfmtConfig = t!(toml::from_str(&rustfmt_config));
-    let mut ignore_fmt = ignore::overrides::OverrideBuilder::new(&build.src);
+    let mut fmt_override = ignore::overrides::OverrideBuilder::new(&build.src);
     for ignore in rustfmt_config.ignore {
-        ignore_fmt.add(&format!("!{ignore}")).expect(&ignore);
+        fmt_override.add(&format!("!{ignore}")).expect(&ignore);
     }
     let git_available = match Command::new("git")
         .arg("--version")
@@ -152,6 +152,7 @@ pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) {
                 .map(|entry| {
                     entry.split(' ').nth(1).expect("every git status entry should list a path")
                 });
+            let mut untracked_count = 0;
             for untracked_path in untracked_paths {
                 println!("skip untracked path {untracked_path} during rustfmt invocations");
                 // The leading `/` makes it an exact match against the
@@ -159,7 +160,8 @@ pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) {
                 // have `foo.rs` in the repository root it will also match
                 // against anything like `compiler/rustc_foo/src/foo.rs`,
                 // preventing the latter from being formatted.
-                ignore_fmt.add(&format!("!/{untracked_path}")).expect(&untracked_path);
+                untracked_count += 1;
+                fmt_override.add(&format!("!/{untracked_path}")).expect(&untracked_path);
             }
             // Only check modified files locally to speed up runtime.
             // We still check all files in CI to avoid bugs in `get_modified_rs_files` letting regressions slip through;
@@ -172,10 +174,25 @@ pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) {
                                 println!("formatting modified file {file}");
                             }
                         } else {
-                            println!("formatting {} modified files", files.len());
+                            let pluralized = |count| if count > 1 { "files" } else { "file" };
+                            let untracked_msg = if untracked_count == 0 {
+                                "".to_string()
+                            } else {
+                                format!(
+                                    ", skipped {} untracked {}",
+                                    untracked_count,
+                                    pluralized(untracked_count),
+                                )
+                            };
+                            println!(
+                                "formatting {} modified {}{}",
+                                files.len(),
+                                pluralized(files.len()),
+                                untracked_msg
+                            );
                         }
                         for file in files {
-                            ignore_fmt.add(&format!("/{file}")).expect(&file);
+                            fmt_override.add(&format!("/{file}")).expect(&file);
                         }
                     }
                     Ok(None) => {}
@@ -196,7 +213,7 @@ pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) {
         println!("Could not find usable git. Skipping git-aware format checks");
     }
 
-    let ignore_fmt = ignore_fmt.build().unwrap();
+    let fmt_override = fmt_override.build().unwrap();
 
     let rustfmt_path = build.initial_rustfmt().unwrap_or_else(|| {
         eprintln!("./x.py fmt is not supported on this channel");
@@ -252,7 +269,7 @@ pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) {
         None => WalkBuilder::new(src.clone()),
     }
     .types(matcher)
-    .overrides(ignore_fmt)
+    .overrides(fmt_override)
     .build_parallel();
 
     // there is a lot of blocking involved in spawning a child process and reading files to format.
diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs
index baf90b6d73e..944d0145de2 100644
--- a/src/librustdoc/clean/utils.rs
+++ b/src/librustdoc/clean/utils.rs
@@ -480,12 +480,6 @@ pub(crate) fn get_auto_trait_and_blanket_impls(
     cx: &mut DocContext<'_>,
     item_def_id: DefId,
 ) -> impl Iterator<Item = Item> {
-    // FIXME: To be removed once `parallel_compiler` bugs are fixed!
-    // More information in <https://github.com/rust-lang/rust/pull/106930>.
-    if cfg!(parallel_compiler) {
-        return vec![].into_iter().chain(vec![].into_iter());
-    }
-
     let auto_impls = cx
         .sess()
         .prof
diff --git a/tests/ui/consts/ptr_comparisons.rs b/tests/ui/consts/ptr_comparisons.rs
index f442e613839..a5b6cd9d2d4 100644
--- a/tests/ui/consts/ptr_comparisons.rs
+++ b/tests/ui/consts/ptr_comparisons.rs
@@ -1,8 +1,5 @@
 // compile-flags: --crate-type=lib
-// normalize-stderr-32bit: "8 bytes" -> "$$TWO_WORDS bytes"
-// normalize-stderr-64bit: "16 bytes" -> "$$TWO_WORDS bytes"
-// normalize-stderr-32bit: "size 4" -> "size $$WORD"
-// normalize-stderr-64bit: "size 8" -> "size $$WORD"
+// check-pass
 
 #![feature(
     core_intrinsics,
@@ -34,30 +31,13 @@ check!(ne, unsafe { (FOO as *const usize as *const u8).offset(3) }, 0);
 
 // We want pointers to be equal to themselves, but aren't checking this yet because
 // there are some open questions (e.g. whether function pointers to the same function
-// compare equal, they don't necessarily at runtime).
-// The case tested here should work eventually, but does not work yet.
+// compare equal: they don't necessarily do at runtime).
 check!(!, FOO as *const _, FOO as *const _);
 
+// aside from 0, these pointers might end up pretty much anywhere.
+check!(!, FOO as *const _, 1); // this one could be `ne` by taking into account alignment
+check!(!, FOO as *const _, 1024);
 
-///////////////////////////////////////////////////////////////////////////////
-// If any of the below start compiling, make sure to add a `check` test for it.
-// These invocations exist as canaries so we don't forget to check that the
-// behaviour of `guaranteed_eq` and `guaranteed_ne` is still correct.
-// All of these try to obtain an out of bounds pointer in some manner. If we
-// can create out of bounds pointers, we can offset a pointer far enough that
-// at runtime it would be zero and at compile-time it would not be zero.
-
-const _: *const usize = unsafe { (FOO as *const usize).offset(2) };
-
-const _: *const u8 =
-    unsafe { std::ptr::addr_of!((*(FOO as *const usize as *const [u8; 1000]))[999]) };
-//~^ ERROR evaluation of constant value failed
-//~| out-of-bounds
-
-const _: usize = unsafe { std::mem::transmute::<*const usize, usize>(FOO) + 4 };
-//~^ ERROR evaluation of constant value failed
-//~| unable to turn pointer into raw bytes
-
-const _: usize = unsafe { *std::mem::transmute::<&&usize, &usize>(&FOO) + 4 };
-//~^ ERROR evaluation of constant value failed
-//~| unable to turn pointer into raw bytes
+// When pointers go out-of-bounds, they *might* become null, so these comparions cannot work.
+check!(!, unsafe { (FOO as *const usize).wrapping_add(2) }, 0);
+check!(!, unsafe { (FOO as *const usize).wrapping_sub(1) }, 0);
diff --git a/tests/ui/consts/ptr_comparisons.stderr b/tests/ui/consts/ptr_comparisons.stderr
deleted file mode 100644
index fea924d12e5..00000000000
--- a/tests/ui/consts/ptr_comparisons.stderr
+++ /dev/null
@@ -1,40 +0,0 @@
-error[E0080]: evaluation of constant value failed
-  --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
-   |
-   = note: out-of-bounds pointer arithmetic: alloc3 has size $WORD, so pointer to $TWO_WORDS bytes starting at offset 0 is out-of-bounds
-   |
-note: inside `ptr::const_ptr::<impl *const usize>::offset`
-  --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
-note: inside `_`
-  --> $DIR/ptr_comparisons.rs:50:34
-   |
-LL | const _: *const usize = unsafe { (FOO as *const usize).offset(2) };
-   |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0080]: evaluation of constant value failed
-  --> $DIR/ptr_comparisons.rs:53:33
-   |
-LL |     unsafe { std::ptr::addr_of!((*(FOO as *const usize as *const [u8; 1000]))[999]) };
-   |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: alloc3 has size $WORD, so pointer to 1000 bytes starting at offset 0 is out-of-bounds
-
-error[E0080]: evaluation of constant value failed
-  --> $DIR/ptr_comparisons.rs:57:27
-   |
-LL | const _: usize = unsafe { std::mem::transmute::<*const usize, usize>(FOO) + 4 };
-   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
-   |
-   = help: this code performed an operation that depends on the underlying bytes representing a pointer
-   = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
-
-error[E0080]: evaluation of constant value failed
-  --> $DIR/ptr_comparisons.rs:61:27
-   |
-LL | const _: usize = unsafe { *std::mem::transmute::<&&usize, &usize>(&FOO) + 4 };
-   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
-   |
-   = help: this code performed an operation that depends on the underlying bytes representing a pointer
-   = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
-
-error: aborting due to 4 previous errors
-
-For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/imports/resolve-other-libc.rs b/tests/ui/imports/resolve-other-libc.rs
new file mode 100644
index 00000000000..806d854ec89
--- /dev/null
+++ b/tests/ui/imports/resolve-other-libc.rs
@@ -0,0 +1,14 @@
+// Regression test for https://github.com/rust-lang/rust/issues/26043
+
+// compile-flags: --extern libc=test.rlib
+
+// The error shall NOT be something similar to the following, because it
+// indicates that `libc` was wrongly resolved to `libc` shipped with the
+// compiler:
+//
+//   error[E0658]: use of unstable library feature 'rustc_private': \
+//           this crate is being loaded from the sysroot
+//
+extern crate libc; //~ ERROR: extern location for libc does not exist: test.rlib
+
+fn main() {}
diff --git a/tests/ui/imports/resolve-other-libc.stderr b/tests/ui/imports/resolve-other-libc.stderr
new file mode 100644
index 00000000000..e57b88e50c6
--- /dev/null
+++ b/tests/ui/imports/resolve-other-libc.stderr
@@ -0,0 +1,8 @@
+error: extern location for libc does not exist: test.rlib
+  --> $DIR/resolve-other-libc.rs:12:1
+   |
+LL | extern crate libc;
+   | ^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+