about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-06-16 21:14:24 +0000
committerbors <bors@rust-lang.org>2023-06-16 21:14:24 +0000
commit670a0edaa9d80683df8db81554890710e79f8024 (patch)
tree4bbbcd5f4ab51712cefa538eeaed165118fc94b9
parent6bba061467f7c2cab04b262b95eb67bf89265587 (diff)
parent56c96d755262be18788191c1f6cddeeae7911379 (diff)
downloadrust-670a0edaa9d80683df8db81554890710e79f8024.tar.gz
rust-670a0edaa9d80683df8db81554890710e79f8024.zip
Auto merge of #112716 - compiler-errors:rollup-h77daia, r=compiler-errors
Rollup of 7 pull requests

Successful merges:

 - #111074 (Relax implicit `T: Sized` bounds on `BufReader<T>`, `BufWriter<T>` and `LineWriter<T>`)
 - #112226 (std: available_parallelism using native netbsd api first)
 - #112474 (Support 128-bit enum variant in debuginfo codegen)
 - #112662 (`#[lang_item]` for `core::ptr::Unique`)
 - #112665 (Make assumption functions in new solver take `Binder<'tcx, Clause<'tcx>>`)
 - #112684 (Disable alignment checks on i686-pc-windows-msvc)
 - #112706 (Add `SyntaxContext::is_root`)

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--compiler/rustc_codegen_gcc/src/common.rs6
-rw-r--r--compiler/rustc_codegen_llvm/src/common.rs4
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs8
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/consts.rs1
-rw-r--r--compiler/rustc_expand/src/mbe/quoted.rs4
-rw-r--r--compiler/rustc_hir/src/lang_items.rs2
-rw-r--r--compiler/rustc_middle/src/mir/spanview.rs4
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs66
-rw-r--r--compiler/rustc_mir_transform/src/check_alignment.rs4
-rw-r--r--compiler/rustc_span/src/hygiene.rs13
-rw-r--r--compiler/rustc_span/src/lib.rs14
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--compiler/rustc_trait_selection/src/solve/assembly/mod.rs40
-rw-r--r--compiler/rustc_trait_selection/src/solve/project_goals.rs8
-rw-r--r--compiler/rustc_trait_selection/src/solve/trait_goals.rs10
-rw-r--r--library/core/src/ptr/unique.rs2
-rw-r--r--library/std/src/io/buffered/bufreader.rs27
-rw-r--r--library/std/src/io/buffered/bufwriter.rs138
-rw-r--r--library/std/src/io/buffered/linewriter.rs50
-rw-r--r--library/std/src/io/buffered/linewritershim.rs6
-rw-r--r--library/std/src/io/copy.rs2
-rw-r--r--library/std/src/io/mod.rs2
-rw-r--r--library/std/src/sys/unix/kernel_copy.rs4
-rw-r--r--library/std/src/sys/unix/thread.rs23
-rw-r--r--tests/codegen/enum-debug-niche-2.rs4
-rw-r--r--tests/codegen/enum-u128.rs27
-rw-r--r--tests/ui/mir/mir_alignment_check.rs1
-rw-r--r--tests/ui/mir/mir_alignment_check_i686-pc-windows-msvc.rs21
29 files changed, 331 insertions, 163 deletions
diff --git a/compiler/rustc_codegen_gcc/src/common.rs b/compiler/rustc_codegen_gcc/src/common.rs
index bad87db4732..b62f4676f70 100644
--- a/compiler/rustc_codegen_gcc/src/common.rs
+++ b/compiler/rustc_codegen_gcc/src/common.rs
@@ -108,6 +108,10 @@ impl<'gcc, 'tcx> ConstMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
         self.const_uint(self.type_u64(), i)
     }
 
+    fn const_u128(&self, i: u128) -> RValue<'gcc> {
+        self.const_uint_big(self.type_u128(), i)
+    }
+
     fn const_usize(&self, i: u64) -> RValue<'gcc> {
         let bit_size = self.data_layout().pointer_size.bits();
         if bit_size < 64 {
@@ -254,7 +258,7 @@ impl<'gcc, 'tcx> ConstMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
         // SIMD builtins require a constant value.
         self.bitcast_if_needed(value, typ)
     }
-    
+
     fn const_ptr_byte_offset(&self, base_addr: Self::Value, offset: abi::Size) -> Self::Value {
         self.context.new_array_access(None, base_addr, self.const_usize(offset.bytes())).get_address(None)
     }
diff --git a/compiler/rustc_codegen_llvm/src/common.rs b/compiler/rustc_codegen_llvm/src/common.rs
index a3910fef954..a2db59bd6c4 100644
--- a/compiler/rustc_codegen_llvm/src/common.rs
+++ b/compiler/rustc_codegen_llvm/src/common.rs
@@ -168,6 +168,10 @@ impl<'ll, 'tcx> ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
         self.const_uint(self.type_i64(), i)
     }
 
+    fn const_u128(&self, i: u128) -> &'ll Value {
+        self.const_uint_big(self.type_i128(), i)
+    }
+
     fn const_usize(&self, i: u64) -> &'ll Value {
         let bit_size = self.data_layout().pointer_size.bits();
         if bit_size < 64 {
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
index fa67a1b3310..1a8618e0c55 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
@@ -429,7 +429,7 @@ pub fn type_di_node<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> &'ll D
         return existing_di_node;
     }
 
-    debug!("type_di_node: {:?}", t);
+    debug!("type_di_node: {:?} kind: {:?}", t, t.kind());
 
     let DINodeCreationResult { di_node, already_stored_in_typemap } = match *t.kind() {
         ty::Never | ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_) => {
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs
index 978141917c6..666b9762f5a 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs
@@ -412,13 +412,7 @@ fn build_enum_variant_member_di_node<'ll, 'tcx>(
             enum_type_and_layout.size.bits(),
             enum_type_and_layout.align.abi.bits() as u32,
             Size::ZERO.bits(),
-            discr_value.opt_single_val().map(|value| {
-                // NOTE(eddyb) do *NOT* remove this assert, until
-                // we pass the full 128-bit value to LLVM, otherwise
-                // truncation will be silent and remain undetected.
-                assert_eq!(value as u64 as u128, value);
-                cx.const_u64(value as u64)
-            }),
+            discr_value.opt_single_val().map(|value| cx.const_u128(value)),
             DIFlags::FlagZero,
             variant_member_info.variant_struct_type_di_node,
         )
diff --git a/compiler/rustc_codegen_ssa/src/traits/consts.rs b/compiler/rustc_codegen_ssa/src/traits/consts.rs
index dc2fc396480..d6e9bfce1a4 100644
--- a/compiler/rustc_codegen_ssa/src/traits/consts.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/consts.rs
@@ -15,6 +15,7 @@ pub trait ConstMethods<'tcx>: BackendTypes {
     fn const_i32(&self, i: i32) -> Self::Value;
     fn const_u32(&self, i: u32) -> Self::Value;
     fn const_u64(&self, i: u64) -> Self::Value;
+    fn const_u128(&self, i: u128) -> Self::Value;
     fn const_usize(&self, i: u64) -> Self::Value;
     fn const_u8(&self, i: u8) -> Self::Value;
     fn const_real(&self, t: Self::Type, val: f64) -> Self::Value;
diff --git a/compiler/rustc_expand/src/mbe/quoted.rs b/compiler/rustc_expand/src/mbe/quoted.rs
index b2bdf9c7e6d..40bfa3715be 100644
--- a/compiler/rustc_expand/src/mbe/quoted.rs
+++ b/compiler/rustc_expand/src/mbe/quoted.rs
@@ -9,7 +9,7 @@ use rustc_session::parse::{feature_err, ParseSess};
 use rustc_span::symbol::{kw, sym, Ident};
 
 use rustc_span::edition::Edition;
-use rustc_span::{Span, SyntaxContext};
+use rustc_span::Span;
 
 const VALID_FRAGMENT_NAMES_MSG: &str = "valid fragment specifiers are \
                                         `ident`, `block`, `stmt`, `expr`, `pat`, `ty`, `lifetime`, \
@@ -72,7 +72,7 @@ pub(super) fn parse(
                                             // `SyntaxContext::root()` from a foreign crate will
                                             // have the edition of that crate (which we manually
                                             // retrieve via the `edition` parameter).
-                                            if span.ctxt() == SyntaxContext::root() {
+                                            if span.ctxt().is_root() {
                                                 edition
                                             } else {
                                                 span.edition()
diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs
index 4b3bc816b95..4e23a28b371 100644
--- a/compiler/rustc_hir/src/lang_items.rs
+++ b/compiler/rustc_hir/src/lang_items.rs
@@ -260,6 +260,8 @@ language_item_table! {
     EhCatchTypeinfo,         sym::eh_catch_typeinfo,   eh_catch_typeinfo,          Target::Static,         GenericRequirement::None;
 
     OwnedBox,                sym::owned_box,           owned_box,                  Target::Struct,         GenericRequirement::Minimum(1);
+    // Experimental language item for Miri
+    PtrUnique,               sym::ptr_unique,          ptr_unique,                 Target::Struct,         GenericRequirement::Exact(1);
 
     PhantomData,             sym::phantom_data,        phantom_data,               Target::Struct,         GenericRequirement::Exact(1);
 
diff --git a/compiler/rustc_middle/src/mir/spanview.rs b/compiler/rustc_middle/src/mir/spanview.rs
index 2165403da26..6b036194381 100644
--- a/compiler/rustc_middle/src/mir/spanview.rs
+++ b/compiler/rustc_middle/src/mir/spanview.rs
@@ -3,7 +3,7 @@ use rustc_middle::hir;
 use rustc_middle::mir::*;
 use rustc_middle::ty::TyCtxt;
 use rustc_session::config::MirSpanview;
-use rustc_span::{BytePos, Pos, Span, SyntaxContext};
+use rustc_span::{BytePos, Pos, Span};
 
 use std::cmp;
 use std::io::{self, Write};
@@ -327,7 +327,7 @@ fn compute_block_span(data: &BasicBlockData<'_>, body_span: Span) -> Span {
     let mut span = data.terminator().source_info.span;
     for statement_span in data.statements.iter().map(|statement| statement.source_info.span) {
         // Only combine Spans from the root context, and within the function's body_span.
-        if statement_span.ctxt() == SyntaxContext::root() && body_span.contains(statement_span) {
+        if statement_span.ctxt().is_root() && body_span.contains(statement_span) {
             span = span.to(statement_span);
         }
     }
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 72341e656e2..ff5d99794f1 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -586,6 +586,24 @@ pub enum Clause<'tcx> {
     ConstArgHasType(Const<'tcx>, Ty<'tcx>),
 }
 
+impl<'tcx> Binder<'tcx, Clause<'tcx>> {
+    pub fn as_trait_clause(self) -> Option<Binder<'tcx, TraitPredicate<'tcx>>> {
+        if let ty::Clause::Trait(trait_clause) = self.skip_binder() {
+            Some(self.rebind(trait_clause))
+        } else {
+            None
+        }
+    }
+
+    pub fn as_projection_clause(self) -> Option<Binder<'tcx, ProjectionPredicate<'tcx>>> {
+        if let ty::Clause::Projection(projection_clause) = self.skip_binder() {
+            Some(self.rebind(projection_clause))
+        } else {
+            None
+        }
+    }
+}
+
 #[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
 #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
 pub enum PredicateKind<'tcx> {
@@ -1203,6 +1221,17 @@ impl<'tcx> ToPredicate<'tcx> for TraitRef<'tcx> {
     }
 }
 
+impl<'tcx> ToPredicate<'tcx, Binder<'tcx, Clause<'tcx>>> for TraitRef<'tcx> {
+    #[inline(always)]
+    fn to_predicate(self, _tcx: TyCtxt<'tcx>) -> Binder<'tcx, Clause<'tcx>> {
+        Binder::dummy(Clause::Trait(TraitPredicate {
+            trait_ref: self,
+            constness: ty::BoundConstness::NotConst,
+            polarity: ty::ImplPolarity::Positive,
+        }))
+    }
+}
+
 impl<'tcx> ToPredicate<'tcx> for Binder<'tcx, TraitRef<'tcx>> {
     #[inline(always)]
     fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
@@ -1211,6 +1240,14 @@ impl<'tcx> ToPredicate<'tcx> for Binder<'tcx, TraitRef<'tcx>> {
     }
 }
 
+impl<'tcx> ToPredicate<'tcx, Binder<'tcx, Clause<'tcx>>> for Binder<'tcx, TraitRef<'tcx>> {
+    #[inline(always)]
+    fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Binder<'tcx, Clause<'tcx>> {
+        let pred: PolyTraitPredicate<'tcx> = self.to_predicate(tcx);
+        pred.to_predicate(tcx)
+    }
+}
+
 impl<'tcx> ToPredicate<'tcx, PolyTraitPredicate<'tcx>> for Binder<'tcx, TraitRef<'tcx>> {
     #[inline(always)]
     fn to_predicate(self, _: TyCtxt<'tcx>) -> PolyTraitPredicate<'tcx> {
@@ -1240,6 +1277,12 @@ impl<'tcx> ToPredicate<'tcx> for PolyTraitPredicate<'tcx> {
     }
 }
 
+impl<'tcx> ToPredicate<'tcx, Binder<'tcx, Clause<'tcx>>> for PolyTraitPredicate<'tcx> {
+    fn to_predicate(self, _tcx: TyCtxt<'tcx>) -> Binder<'tcx, Clause<'tcx>> {
+        self.map_bound(|p| Clause::Trait(p))
+    }
+}
+
 impl<'tcx> ToPredicate<'tcx> for PolyRegionOutlivesPredicate<'tcx> {
     fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
         self.map_bound(|p| PredicateKind::Clause(Clause::RegionOutlives(p))).to_predicate(tcx)
@@ -1258,6 +1301,12 @@ impl<'tcx> ToPredicate<'tcx> for PolyProjectionPredicate<'tcx> {
     }
 }
 
+impl<'tcx> ToPredicate<'tcx, Binder<'tcx, Clause<'tcx>>> for PolyProjectionPredicate<'tcx> {
+    fn to_predicate(self, _tcx: TyCtxt<'tcx>) -> Binder<'tcx, Clause<'tcx>> {
+        self.map_bound(|p| Clause::Projection(p))
+    }
+}
+
 impl<'tcx> ToPredicate<'tcx> for TraitPredicate<'tcx> {
     fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
         PredicateKind::Clause(Clause::Trait(self)).to_predicate(tcx)
@@ -1327,6 +1376,23 @@ impl<'tcx> Predicate<'tcx> {
             | PredicateKind::TypeWellFormedFromEnv(..) => None,
         }
     }
+
+    pub fn as_clause(self) -> Option<Binder<'tcx, Clause<'tcx>>> {
+        let predicate = self.kind();
+        match predicate.skip_binder() {
+            PredicateKind::Clause(clause) => Some(predicate.rebind(clause)),
+            PredicateKind::AliasRelate(..)
+            | PredicateKind::Subtype(..)
+            | PredicateKind::Coerce(..)
+            | PredicateKind::WellFormed(..)
+            | PredicateKind::ObjectSafe(..)
+            | PredicateKind::ClosureKind(..)
+            | PredicateKind::ConstEvaluatable(..)
+            | PredicateKind::ConstEquate(..)
+            | PredicateKind::Ambiguous
+            | PredicateKind::TypeWellFormedFromEnv(..) => None,
+        }
+    }
 }
 
 /// Represents the bounds declared on a particular set of type
diff --git a/compiler/rustc_mir_transform/src/check_alignment.rs b/compiler/rustc_mir_transform/src/check_alignment.rs
index ef64f70fdf3..fd349c07040 100644
--- a/compiler/rustc_mir_transform/src/check_alignment.rs
+++ b/compiler/rustc_mir_transform/src/check_alignment.rs
@@ -15,6 +15,10 @@ pub struct CheckAlignment;
 
 impl<'tcx> MirPass<'tcx> for CheckAlignment {
     fn is_enabled(&self, sess: &Session) -> bool {
+        // FIXME(#112480) MSVC and rustc disagree on minimum stack alignment on x86 Windows
+        if sess.target.llvm_target == "i686-pc-windows-msvc" {
+            return false;
+        }
         sess.opts.debug_assertions
     }
 
diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs
index 0c7e36b3bef..9f2ff437842 100644
--- a/compiler/rustc_span/src/hygiene.rs
+++ b/compiler/rustc_span/src/hygiene.rs
@@ -507,7 +507,7 @@ impl HygieneData {
             self.normalize_to_macro_rules(call_site_ctxt)
         };
 
-        if call_site_ctxt == SyntaxContext::root() {
+        if call_site_ctxt.is_root() {
             return self.apply_mark_internal(ctxt, expn_id, transparency);
         }
 
@@ -671,12 +671,17 @@ impl SyntaxContext {
     }
 
     #[inline]
-    pub(crate) fn as_u32(self) -> u32 {
+    pub const fn is_root(self) -> bool {
+        self.0 == SyntaxContext::root().as_u32()
+    }
+
+    #[inline]
+    pub(crate) const fn as_u32(self) -> u32 {
         self.0
     }
 
     #[inline]
-    pub(crate) fn from_u32(raw: u32) -> SyntaxContext {
+    pub(crate) const fn from_u32(raw: u32) -> SyntaxContext {
         SyntaxContext(raw)
     }
 
@@ -1500,7 +1505,7 @@ impl<CTX: HashStableContext> HashStable<CTX> for SyntaxContext {
         const TAG_EXPANSION: u8 = 0;
         const TAG_NO_EXPANSION: u8 = 1;
 
-        if *self == SyntaxContext::root() {
+        if self.is_root() {
             TAG_NO_EXPANSION.hash_stable(ctx, hasher);
         } else {
             TAG_EXPANSION.hash_stable(ctx, hasher);
diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs
index eae3f0fa041..e7a53c63e83 100644
--- a/compiler/rustc_span/src/lib.rs
+++ b/compiler/rustc_span/src/lib.rs
@@ -826,9 +826,9 @@ impl Span {
         // Return the macro span on its own to avoid weird diagnostic output. It is preferable to
         // have an incomplete span than a completely nonsensical one.
         if span_data.ctxt != end_data.ctxt {
-            if span_data.ctxt == SyntaxContext::root() {
+            if span_data.ctxt.is_root() {
                 return end;
-            } else if end_data.ctxt == SyntaxContext::root() {
+            } else if end_data.ctxt.is_root() {
                 return self;
             }
             // Both spans fall within a macro.
@@ -837,7 +837,7 @@ impl Span {
         Span::new(
             cmp::min(span_data.lo, end_data.lo),
             cmp::max(span_data.hi, end_data.hi),
-            if span_data.ctxt == SyntaxContext::root() { end_data.ctxt } else { span_data.ctxt },
+            if span_data.ctxt.is_root() { end_data.ctxt } else { span_data.ctxt },
             if span_data.parent == end_data.parent { span_data.parent } else { None },
         )
     }
@@ -855,7 +855,7 @@ impl Span {
         Span::new(
             span.hi,
             end.lo,
-            if end.ctxt == SyntaxContext::root() { end.ctxt } else { span.ctxt },
+            if end.ctxt.is_root() { end.ctxt } else { span.ctxt },
             if span.parent == end.parent { span.parent } else { None },
         )
     }
@@ -879,9 +879,9 @@ impl Span {
         // Return the macro span on its own to avoid weird diagnostic output. It is preferable to
         // have an incomplete span than a completely nonsensical one.
         if span_data.ctxt != end_data.ctxt {
-            if span_data.ctxt == SyntaxContext::root() {
+            if span_data.ctxt.is_root() {
                 return end;
-            } else if end_data.ctxt == SyntaxContext::root() {
+            } else if end_data.ctxt.is_root() {
                 return self;
             }
             // Both spans fall within a macro.
@@ -890,7 +890,7 @@ impl Span {
         Span::new(
             span_data.lo,
             end_data.lo,
-            if end_data.ctxt == SyntaxContext::root() { end_data.ctxt } else { span_data.ctxt },
+            if end_data.ctxt.is_root() { end_data.ctxt } else { span_data.ctxt },
             if span_data.parent == end_data.parent { span_data.parent } else { None },
         )
     }
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index c5ce2575fff..19d986a3152 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -1156,6 +1156,7 @@ symbols! {
         ptr_null_mut,
         ptr_offset_from,
         ptr_offset_from_unsigned,
+        ptr_unique,
         pub_macro_rules,
         pub_restricted,
         public,
diff --git a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
index 1b749b9c854..e6eddf24844 100644
--- a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
@@ -105,7 +105,7 @@ pub(super) trait GoalKind<'tcx>:
     fn probe_and_match_goal_against_assumption(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-        assumption: ty::Predicate<'tcx>,
+        assumption: ty::Binder<'tcx, ty::Clause<'tcx>>,
         then: impl FnOnce(&mut EvalCtxt<'_, 'tcx>) -> QueryResult<'tcx>,
     ) -> QueryResult<'tcx>;
 
@@ -115,7 +115,7 @@ pub(super) trait GoalKind<'tcx>:
     fn consider_implied_clause(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-        assumption: ty::Predicate<'tcx>,
+        assumption: ty::Binder<'tcx, ty::Clause<'tcx>>,
         requirements: impl IntoIterator<Item = Goal<'tcx, ty::Predicate<'tcx>>>,
     ) -> QueryResult<'tcx> {
         Self::probe_and_match_goal_against_assumption(ecx, goal, assumption, |ecx| {
@@ -131,7 +131,7 @@ pub(super) trait GoalKind<'tcx>:
     fn consider_alias_bound_candidate(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-        assumption: ty::Predicate<'tcx>,
+        assumption: ty::Binder<'tcx, ty::Clause<'tcx>>,
     ) -> QueryResult<'tcx> {
         Self::probe_and_match_goal_against_assumption(ecx, goal, assumption, |ecx| {
             ecx.validate_alias_bound_self_from_param_env(goal)
@@ -144,7 +144,7 @@ pub(super) trait GoalKind<'tcx>:
     fn consider_object_bound_candidate(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-        assumption: ty::Predicate<'tcx>,
+        assumption: ty::Binder<'tcx, ty::Clause<'tcx>>,
     ) -> QueryResult<'tcx> {
         Self::probe_and_match_goal_against_assumption(ecx, goal, assumption, |ecx| {
             let tcx = ecx.tcx();
@@ -467,11 +467,13 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         candidates: &mut Vec<Candidate<'tcx>>,
     ) {
         for (i, assumption) in goal.param_env.caller_bounds().iter().enumerate() {
-            match G::consider_implied_clause(self, goal, assumption, []) {
-                Ok(result) => {
-                    candidates.push(Candidate { source: CandidateSource::ParamEnv(i), result })
+            if let Some(clause) = assumption.as_clause() {
+                match G::consider_implied_clause(self, goal, clause, []) {
+                    Ok(result) => {
+                        candidates.push(Candidate { source: CandidateSource::ParamEnv(i), result })
+                    }
+                    Err(NoSolution) => (),
                 }
-                Err(NoSolution) => (),
             }
         }
     }
@@ -517,11 +519,13 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
 
         for assumption in self.tcx().item_bounds(alias_ty.def_id).subst(self.tcx(), alias_ty.substs)
         {
-            match G::consider_alias_bound_candidate(self, goal, assumption) {
-                Ok(result) => {
-                    candidates.push(Candidate { source: CandidateSource::AliasBound, result })
+            if let Some(clause) = assumption.as_clause() {
+                match G::consider_alias_bound_candidate(self, goal, clause) {
+                    Ok(result) => {
+                        candidates.push(Candidate { source: CandidateSource::AliasBound, result })
+                    }
+                    Err(NoSolution) => (),
                 }
-                Err(NoSolution) => (),
             }
         }
     }
@@ -675,18 +679,20 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
             // projection predicates that we reach by elaborating the principal trait ref,
             // since that'll cause ambiguity.
             //
-            // We can remove this when we have implemented intersections in responses.
+            // We can remove this when we have implemented lifetime intersections in responses.
             if assumption.to_opt_poly_projection_pred().is_some()
                 && !own_bounds.contains(&assumption)
             {
                 continue;
             }
 
-            match G::consider_object_bound_candidate(self, goal, assumption) {
-                Ok(result) => {
-                    candidates.push(Candidate { source: CandidateSource::BuiltinImpl, result })
+            if let Some(clause) = assumption.as_clause() {
+                match G::consider_object_bound_candidate(self, goal, clause) {
+                    Ok(result) => {
+                        candidates.push(Candidate { source: CandidateSource::BuiltinImpl, result })
+                    }
+                    Err(NoSolution) => (),
                 }
-                Err(NoSolution) => (),
             }
         }
     }
diff --git a/compiler/rustc_trait_selection/src/solve/project_goals.rs b/compiler/rustc_trait_selection/src/solve/project_goals.rs
index 242f9ba8747..8303bab4c36 100644
--- a/compiler/rustc_trait_selection/src/solve/project_goals.rs
+++ b/compiler/rustc_trait_selection/src/solve/project_goals.rs
@@ -105,15 +105,15 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
     fn probe_and_match_goal_against_assumption(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-        assumption: ty::Predicate<'tcx>,
+        assumption: ty::Binder<'tcx, ty::Clause<'tcx>>,
         then: impl FnOnce(&mut EvalCtxt<'_, 'tcx>) -> QueryResult<'tcx>,
     ) -> QueryResult<'tcx> {
-        if let Some(poly_projection_pred) = assumption.to_opt_poly_projection_pred()
-            && poly_projection_pred.projection_def_id() == goal.predicate.def_id()
+        if let Some(projection_pred) = assumption.as_projection_clause()
+            && projection_pred.projection_def_id() == goal.predicate.def_id()
         {
             ecx.probe(|ecx| {
                 let assumption_projection_pred =
-                    ecx.instantiate_binder_with_infer(poly_projection_pred);
+                    ecx.instantiate_binder_with_infer(projection_pred);
                 ecx.eq(
                     goal.param_env,
                     goal.predicate.projection_ty,
diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs
index f722f281314..60cf386a289 100644
--- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs
+++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs
@@ -81,17 +81,17 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
     fn probe_and_match_goal_against_assumption(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-        assumption: ty::Predicate<'tcx>,
+        assumption: ty::Binder<'tcx, ty::Clause<'tcx>>,
         then: impl FnOnce(&mut EvalCtxt<'_, 'tcx>) -> QueryResult<'tcx>,
     ) -> QueryResult<'tcx> {
-        if let Some(poly_trait_pred) = assumption.to_opt_poly_trait_pred()
-            && poly_trait_pred.def_id() == goal.predicate.def_id()
-            && poly_trait_pred.polarity() == goal.predicate.polarity
+        if let Some(trait_clause) = assumption.as_trait_clause()
+            && trait_clause.def_id() == goal.predicate.def_id()
+            && trait_clause.polarity() == goal.predicate.polarity
         {
             // FIXME: Constness
             ecx.probe(|ecx| {
                 let assumption_trait_pred =
-                    ecx.instantiate_binder_with_infer(poly_trait_pred);
+                    ecx.instantiate_binder_with_infer(trait_clause);
                 ecx.eq(
                     goal.param_env,
                     goal.predicate.trait_ref,
diff --git a/library/core/src/ptr/unique.rs b/library/core/src/ptr/unique.rs
index a853f15edb7..ff7e91d3ec3 100644
--- a/library/core/src/ptr/unique.rs
+++ b/library/core/src/ptr/unique.rs
@@ -32,6 +32,8 @@ use crate::ptr::NonNull;
 )]
 #[doc(hidden)]
 #[repr(transparent)]
+// Lang item used experimentally by Miri to define the semantics of `Unique`.
+#[cfg_attr(not(bootstrap), lang = "ptr_unique")]
 pub struct Unique<T: ?Sized> {
     pointer: NonNull<T>,
     // NOTE: this marker has no consequences for variance, but is necessary
diff --git a/library/std/src/io/buffered/bufreader.rs b/library/std/src/io/buffered/bufreader.rs
index 4f339a18a48..3edf9d747ce 100644
--- a/library/std/src/io/buffered/bufreader.rs
+++ b/library/std/src/io/buffered/bufreader.rs
@@ -47,9 +47,9 @@ use buffer::Buffer;
 /// }
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
-pub struct BufReader<R> {
-    inner: R,
+pub struct BufReader<R: ?Sized> {
     buf: Buffer,
+    inner: R,
 }
 
 impl<R: Read> BufReader<R> {
@@ -95,7 +95,7 @@ impl<R: Read> BufReader<R> {
     }
 }
 
-impl<R> BufReader<R> {
+impl<R: ?Sized> BufReader<R> {
     /// Gets a reference to the underlying reader.
     ///
     /// It is inadvisable to directly read from the underlying reader.
@@ -213,7 +213,10 @@ impl<R> BufReader<R> {
     /// }
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn into_inner(self) -> R {
+    pub fn into_inner(self) -> R
+    where
+        R: Sized,
+    {
         self.inner
     }
 
@@ -226,13 +229,13 @@ impl<R> BufReader<R> {
 
 // This is only used by a test which asserts that the initialization-tracking is correct.
 #[cfg(test)]
-impl<R> BufReader<R> {
+impl<R: ?Sized> BufReader<R> {
     pub fn initialized(&self) -> usize {
         self.buf.initialized()
     }
 }
 
-impl<R: Seek> BufReader<R> {
+impl<R: ?Sized + Seek> BufReader<R> {
     /// Seeks relative to the current position. If the new position lies within the buffer,
     /// the buffer will not be flushed, allowing for more efficient seeks.
     /// This method does not return the location of the underlying reader, so the caller
@@ -257,7 +260,7 @@ impl<R: Seek> BufReader<R> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<R: Read> Read for BufReader<R> {
+impl<R: ?Sized + Read> Read for BufReader<R> {
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
         // If we don't have any buffered data and we're doing a massive read
         // (larger than our internal buffer), bypass our internal buffer
@@ -371,7 +374,7 @@ impl<R: Read> Read for BufReader<R> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<R: Read> BufRead for BufReader<R> {
+impl<R: ?Sized + Read> BufRead for BufReader<R> {
     fn fill_buf(&mut self) -> io::Result<&[u8]> {
         self.buf.fill_buf(&mut self.inner)
     }
@@ -384,11 +387,11 @@ impl<R: Read> BufRead for BufReader<R> {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<R> fmt::Debug for BufReader<R>
 where
-    R: fmt::Debug,
+    R: ?Sized + fmt::Debug,
 {
     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
         fmt.debug_struct("BufReader")
-            .field("reader", &self.inner)
+            .field("reader", &&self.inner)
             .field(
                 "buffer",
                 &format_args!("{}/{}", self.buf.filled() - self.buf.pos(), self.capacity()),
@@ -398,7 +401,7 @@ where
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<R: Seek> Seek for BufReader<R> {
+impl<R: ?Sized + Seek> Seek for BufReader<R> {
     /// Seek to an offset, in bytes, in the underlying reader.
     ///
     /// The position used for seeking with <code>[SeekFrom::Current]\(_)</code> is the
@@ -491,7 +494,7 @@ impl<R: Seek> Seek for BufReader<R> {
     }
 }
 
-impl<T> SizeHint for BufReader<T> {
+impl<T: ?Sized> SizeHint for BufReader<T> {
     #[inline]
     fn lower_bound(&self) -> usize {
         SizeHint::lower_bound(self.get_ref()) + self.buffer().len()
diff --git a/library/std/src/io/buffered/bufwriter.rs b/library/std/src/io/buffered/bufwriter.rs
index 14c455d4fa3..0e2450655e5 100644
--- a/library/std/src/io/buffered/bufwriter.rs
+++ b/library/std/src/io/buffered/bufwriter.rs
@@ -67,8 +67,7 @@ use crate::ptr;
 /// [`TcpStream`]: crate::net::TcpStream
 /// [`flush`]: BufWriter::flush
 #[stable(feature = "rust1", since = "1.0.0")]
-pub struct BufWriter<W: Write> {
-    inner: W,
+pub struct BufWriter<W: ?Sized + Write> {
     // The buffer. Avoid using this like a normal `Vec` in common code paths.
     // That is, don't use `buf.push`, `buf.extend_from_slice`, or any other
     // methods that require bounds checking or the like. This makes an enormous
@@ -78,6 +77,7 @@ pub struct BufWriter<W: Write> {
     // write the buffered data a second time in BufWriter's destructor. This
     // flag tells the Drop impl if it should skip the flush.
     panicked: bool,
+    inner: W,
 }
 
 impl<W: Write> BufWriter<W> {
@@ -115,6 +115,69 @@ impl<W: Write> BufWriter<W> {
         BufWriter { inner, buf: Vec::with_capacity(capacity), panicked: false }
     }
 
+    /// Unwraps this `BufWriter<W>`, returning the underlying writer.
+    ///
+    /// The buffer is written out before returning the writer.
+    ///
+    /// # Errors
+    ///
+    /// An [`Err`] will be returned if an error occurs while flushing the buffer.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::io::BufWriter;
+    /// use std::net::TcpStream;
+    ///
+    /// let mut buffer = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap());
+    ///
+    /// // unwrap the TcpStream and flush the buffer
+    /// let stream = buffer.into_inner().unwrap();
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn into_inner(mut self) -> Result<W, IntoInnerError<BufWriter<W>>> {
+        match self.flush_buf() {
+            Err(e) => Err(IntoInnerError::new(self, e)),
+            Ok(()) => Ok(self.into_parts().0),
+        }
+    }
+
+    /// Disassembles this `BufWriter<W>`, returning the underlying writer, and any buffered but
+    /// unwritten data.
+    ///
+    /// If the underlying writer panicked, it is not known what portion of the data was written.
+    /// In this case, we return `WriterPanicked` for the buffered data (from which the buffer
+    /// contents can still be recovered).
+    ///
+    /// `into_parts` makes no attempt to flush data and cannot fail.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::io::{BufWriter, Write};
+    ///
+    /// let mut buffer = [0u8; 10];
+    /// let mut stream = BufWriter::new(buffer.as_mut());
+    /// write!(stream, "too much data").unwrap();
+    /// stream.flush().expect_err("it doesn't fit");
+    /// let (recovered_writer, buffered_data) = stream.into_parts();
+    /// assert_eq!(recovered_writer.len(), 0);
+    /// assert_eq!(&buffered_data.unwrap(), b"ata");
+    /// ```
+    #[stable(feature = "bufwriter_into_parts", since = "1.56.0")]
+    pub fn into_parts(mut self) -> (W, Result<Vec<u8>, WriterPanicked>) {
+        let buf = mem::take(&mut self.buf);
+        let buf = if !self.panicked { Ok(buf) } else { Err(WriterPanicked { buf }) };
+
+        // SAFETY: forget(self) prevents double dropping inner
+        let inner = unsafe { ptr::read(&self.inner) };
+        mem::forget(self);
+
+        (inner, buf)
+    }
+}
+
+impl<W: ?Sized + Write> BufWriter<W> {
     /// Send data in our local buffer into the inner writer, looping as
     /// necessary until either it's all been sent or an error occurs.
     ///
@@ -284,67 +347,6 @@ impl<W: Write> BufWriter<W> {
         self.buf.capacity()
     }
 
-    /// Unwraps this `BufWriter<W>`, returning the underlying writer.
-    ///
-    /// The buffer is written out before returning the writer.
-    ///
-    /// # Errors
-    ///
-    /// An [`Err`] will be returned if an error occurs while flushing the buffer.
-    ///
-    /// # Examples
-    ///
-    /// ```no_run
-    /// use std::io::BufWriter;
-    /// use std::net::TcpStream;
-    ///
-    /// let mut buffer = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap());
-    ///
-    /// // unwrap the TcpStream and flush the buffer
-    /// let stream = buffer.into_inner().unwrap();
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn into_inner(mut self) -> Result<W, IntoInnerError<BufWriter<W>>> {
-        match self.flush_buf() {
-            Err(e) => Err(IntoInnerError::new(self, e)),
-            Ok(()) => Ok(self.into_parts().0),
-        }
-    }
-
-    /// Disassembles this `BufWriter<W>`, returning the underlying writer, and any buffered but
-    /// unwritten data.
-    ///
-    /// If the underlying writer panicked, it is not known what portion of the data was written.
-    /// In this case, we return `WriterPanicked` for the buffered data (from which the buffer
-    /// contents can still be recovered).
-    ///
-    /// `into_parts` makes no attempt to flush data and cannot fail.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::io::{BufWriter, Write};
-    ///
-    /// let mut buffer = [0u8; 10];
-    /// let mut stream = BufWriter::new(buffer.as_mut());
-    /// write!(stream, "too much data").unwrap();
-    /// stream.flush().expect_err("it doesn't fit");
-    /// let (recovered_writer, buffered_data) = stream.into_parts();
-    /// assert_eq!(recovered_writer.len(), 0);
-    /// assert_eq!(&buffered_data.unwrap(), b"ata");
-    /// ```
-    #[stable(feature = "bufwriter_into_parts", since = "1.56.0")]
-    pub fn into_parts(mut self) -> (W, Result<Vec<u8>, WriterPanicked>) {
-        let buf = mem::take(&mut self.buf);
-        let buf = if !self.panicked { Ok(buf) } else { Err(WriterPanicked { buf }) };
-
-        // SAFETY: forget(self) prevents double dropping inner
-        let inner = unsafe { ptr::read(&self.inner) };
-        mem::forget(self);
-
-        (inner, buf)
-    }
-
     // Ensure this function does not get inlined into `write`, so that it
     // remains inlineable and its common path remains as short as possible.
     // If this function ends up being called frequently relative to `write`,
@@ -511,7 +513,7 @@ impl fmt::Debug for WriterPanicked {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<W: Write> Write for BufWriter<W> {
+impl<W: ?Sized + Write> Write for BufWriter<W> {
     #[inline]
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
         // Use < instead of <= to avoid a needless trip through the buffer in some cases.
@@ -640,20 +642,20 @@ impl<W: Write> Write for BufWriter<W> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<W: Write> fmt::Debug for BufWriter<W>
+impl<W: ?Sized + Write> fmt::Debug for BufWriter<W>
 where
     W: fmt::Debug,
 {
     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
         fmt.debug_struct("BufWriter")
-            .field("writer", &self.inner)
+            .field("writer", &&self.inner)
             .field("buffer", &format_args!("{}/{}", self.buf.len(), self.buf.capacity()))
             .finish()
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<W: Write + Seek> Seek for BufWriter<W> {
+impl<W: ?Sized + Write + Seek> Seek for BufWriter<W> {
     /// Seek to the offset, in bytes, in the underlying writer.
     ///
     /// Seeking always writes out the internal buffer before seeking.
@@ -664,7 +666,7 @@ impl<W: Write + Seek> Seek for BufWriter<W> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<W: Write> Drop for BufWriter<W> {
+impl<W: ?Sized + Write> Drop for BufWriter<W> {
     fn drop(&mut self) {
         if !self.panicked {
             // dtors should not panic, so we ignore a failed flush
diff --git a/library/std/src/io/buffered/linewriter.rs b/library/std/src/io/buffered/linewriter.rs
index a26a4ab330e..3d4ae704193 100644
--- a/library/std/src/io/buffered/linewriter.rs
+++ b/library/std/src/io/buffered/linewriter.rs
@@ -64,7 +64,7 @@ use crate::io::{self, buffered::LineWriterShim, BufWriter, IntoInnerError, IoSli
 /// }
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
-pub struct LineWriter<W: Write> {
+pub struct LineWriter<W: ?Sized + Write> {
     inner: BufWriter<W>,
 }
 
@@ -109,27 +109,6 @@ impl<W: Write> LineWriter<W> {
         LineWriter { inner: BufWriter::with_capacity(capacity, inner) }
     }
 
-    /// Gets a reference to the underlying writer.
-    ///
-    /// # Examples
-    ///
-    /// ```no_run
-    /// use std::fs::File;
-    /// use std::io::LineWriter;
-    ///
-    /// fn main() -> std::io::Result<()> {
-    ///     let file = File::create("poem.txt")?;
-    ///     let file = LineWriter::new(file);
-    ///
-    ///     let reference = file.get_ref();
-    ///     Ok(())
-    /// }
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn get_ref(&self) -> &W {
-        self.inner.get_ref()
-    }
-
     /// Gets a mutable reference to the underlying writer.
     ///
     /// Caution must be taken when calling methods on the mutable reference
@@ -184,8 +163,31 @@ impl<W: Write> LineWriter<W> {
     }
 }
 
+impl<W: ?Sized + Write> LineWriter<W> {
+    /// Gets a reference to the underlying writer.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs::File;
+    /// use std::io::LineWriter;
+    ///
+    /// fn main() -> std::io::Result<()> {
+    ///     let file = File::create("poem.txt")?;
+    ///     let file = LineWriter::new(file);
+    ///
+    ///     let reference = file.get_ref();
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn get_ref(&self) -> &W {
+        self.inner.get_ref()
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<W: Write> Write for LineWriter<W> {
+impl<W: ?Sized + Write> Write for LineWriter<W> {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
         LineWriterShim::new(&mut self.inner).write(buf)
     }
@@ -216,7 +218,7 @@ impl<W: Write> Write for LineWriter<W> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<W: Write> fmt::Debug for LineWriter<W>
+impl<W: ?Sized + Write> fmt::Debug for LineWriter<W>
 where
     W: fmt::Debug,
 {
diff --git a/library/std/src/io/buffered/linewritershim.rs b/library/std/src/io/buffered/linewritershim.rs
index 0175d2693e8..f2a55da05b2 100644
--- a/library/std/src/io/buffered/linewritershim.rs
+++ b/library/std/src/io/buffered/linewritershim.rs
@@ -11,11 +11,11 @@ use crate::sys_common::memchr;
 /// `BufWriters` to be temporarily given line-buffering logic; this is what
 /// enables Stdout to be alternately in line-buffered or block-buffered mode.
 #[derive(Debug)]
-pub struct LineWriterShim<'a, W: Write> {
+pub struct LineWriterShim<'a, W: ?Sized + Write> {
     buffer: &'a mut BufWriter<W>,
 }
 
-impl<'a, W: Write> LineWriterShim<'a, W> {
+impl<'a, W: ?Sized + Write> LineWriterShim<'a, W> {
     pub fn new(buffer: &'a mut BufWriter<W>) -> Self {
         Self { buffer }
     }
@@ -49,7 +49,7 @@ impl<'a, W: Write> LineWriterShim<'a, W> {
     }
 }
 
-impl<'a, W: Write> Write for LineWriterShim<'a, W> {
+impl<'a, W: ?Sized + Write> Write for LineWriterShim<'a, W> {
     /// Write some data into this BufReader with line buffering. This means
     /// that, if any newlines are present in the data, the data up to the last
     /// newline is sent directly to the underlying writer, and data after it
diff --git a/library/std/src/io/copy.rs b/library/std/src/io/copy.rs
index 1d9d93f5b64..420fc400705 100644
--- a/library/std/src/io/copy.rs
+++ b/library/std/src/io/copy.rs
@@ -86,7 +86,7 @@ impl<W: Write + ?Sized> BufferedCopySpec for W {
     }
 }
 
-impl<I: Write> BufferedCopySpec for BufWriter<I> {
+impl<I: ?Sized + Write> BufferedCopySpec for BufWriter<I> {
     fn copy_to<R: Read + ?Sized>(reader: &mut R, writer: &mut Self) -> Result<u64> {
         if writer.capacity() < DEFAULT_BUF_SIZE {
             return stack_buffer_copy(reader, writer);
diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs
index 8a007d095d5..173233d7150 100644
--- a/library/std/src/io/mod.rs
+++ b/library/std/src/io/mod.rs
@@ -2754,7 +2754,7 @@ trait SizeHint {
     }
 }
 
-impl<T> SizeHint for T {
+impl<T: ?Sized> SizeHint for T {
     #[inline]
     default fn lower_bound(&self) -> usize {
         0
diff --git a/library/std/src/sys/unix/kernel_copy.rs b/library/std/src/sys/unix/kernel_copy.rs
index 16c8e0c0ebf..7d49bbdcbe0 100644
--- a/library/std/src/sys/unix/kernel_copy.rs
+++ b/library/std/src/sys/unix/kernel_copy.rs
@@ -466,7 +466,7 @@ impl<T: CopyRead> CopyRead for Take<T> {
     }
 }
 
-impl<T: CopyRead> CopyRead for BufReader<T> {
+impl<T: ?Sized + CopyRead> CopyRead for BufReader<T> {
     fn drain_to<W: Write>(&mut self, writer: &mut W, outer_limit: u64) -> Result<u64> {
         let buf = self.buffer();
         let buf = &buf[0..min(buf.len(), outer_limit.try_into().unwrap_or(usize::MAX))];
@@ -495,7 +495,7 @@ impl<T: CopyRead> CopyRead for BufReader<T> {
     }
 }
 
-impl<T: CopyWrite> CopyWrite for BufWriter<T> {
+impl<T: ?Sized + CopyWrite> CopyWrite for BufWriter<T> {
     fn properties(&self) -> CopyParams {
         self.get_ref().properties()
     }
diff --git a/library/std/src/sys/unix/thread.rs b/library/std/src/sys/unix/thread.rs
index 878af5088d9..010015667f7 100644
--- a/library/std/src/sys/unix/thread.rs
+++ b/library/std/src/sys/unix/thread.rs
@@ -344,6 +344,29 @@ pub fn available_parallelism() -> io::Result<NonZeroUsize> {
                 }
             }
 
+            #[cfg(target_os = "netbsd")]
+            {
+                unsafe {
+                    let set = libc::_cpuset_create();
+                    if !set.is_null() {
+                        let mut count: usize = 0;
+                        if libc::pthread_getaffinity_np(libc::pthread_self(), libc::_cpuset_size(set), set) == 0 {
+                            for i in 0..u64::MAX {
+                                match libc::_cpuset_isset(i, set) {
+                                    -1 => break,
+                                    0 => continue,
+                                    _ => count = count + 1,
+                                }
+                            }
+                        }
+                        libc::_cpuset_destroy(set);
+                        if let Some(count) = NonZeroUsize::new(count) {
+                            return Ok(count);
+                        }
+                    }
+                }
+            }
+
             let mut cpus: libc::c_uint = 0;
             let mut cpus_size = crate::mem::size_of_val(&cpus);
 
diff --git a/tests/codegen/enum-debug-niche-2.rs b/tests/codegen/enum-debug-niche-2.rs
index 9c72ad9d248..4b607d50574 100644
--- a/tests/codegen/enum-debug-niche-2.rs
+++ b/tests/codegen/enum-debug-niche-2.rs
@@ -7,8 +7,8 @@
 // compile-flags: -g -C no-prepopulate-passes
 
 // CHECK: {{.*}}DICompositeType{{.*}}tag: DW_TAG_variant_part,{{.*}}size: 32,{{.*}}
-// CHECK: {{.*}}DIDerivedType{{.*}}tag: DW_TAG_member,{{.*}}name: "Placeholder",{{.*}}extraData: i64 4294967295{{[,)].*}}
-// CHECK: {{.*}}DIDerivedType{{.*}}tag: DW_TAG_member,{{.*}}name: "Error",{{.*}}extraData: i64 0{{[,)].*}}
+// CHECK: {{.*}}DIDerivedType{{.*}}tag: DW_TAG_member,{{.*}}name: "Placeholder",{{.*}}extraData: i128 4294967295{{[,)].*}}
+// CHECK: {{.*}}DIDerivedType{{.*}}tag: DW_TAG_member,{{.*}}name: "Error",{{.*}}extraData: i128 0{{[,)].*}}
 
 #![feature(never_type)]
 
diff --git a/tests/codegen/enum-u128.rs b/tests/codegen/enum-u128.rs
new file mode 100644
index 00000000000..f50d360ac9f
--- /dev/null
+++ b/tests/codegen/enum-u128.rs
@@ -0,0 +1,27 @@
+// This tests that debug info for "c-like" 128bit enums is properly emitted.
+// This is ignored for the fallback mode on MSVC due to problems with PDB.
+
+//
+// ignore-msvc
+
+// compile-flags: -g -C no-prepopulate-passes
+
+// CHECK-LABEL: @main
+// CHECK: {{.*}}DICompositeType{{.*}}tag: DW_TAG_enumeration_type,{{.*}}name: "Foo",{{.*}}flags: DIFlagEnumClass,{{.*}}
+// CHECK: {{.*}}DIEnumerator{{.*}}name: "Lo",{{.*}}value: 0,{{.*}}
+// CHECK: {{.*}}DIEnumerator{{.*}}name: "Hi",{{.*}}value: 18446744073709551616,{{.*}}
+// CHECK: {{.*}}DIEnumerator{{.*}}name: "Bar",{{.*}}value: 18446745000000000123,{{.*}}
+
+#![allow(incomplete_features)]
+#![feature(repr128)]
+
+#[repr(u128)]
+pub enum Foo {
+    Lo,
+    Hi = 1 << 64,
+    Bar = 18_446_745_000_000_000_123,
+}
+
+pub fn main() {
+    let foo = Foo::Bar;
+}
diff --git a/tests/ui/mir/mir_alignment_check.rs b/tests/ui/mir/mir_alignment_check.rs
index 68a5384b30d..d1bf3d46a7c 100644
--- a/tests/ui/mir/mir_alignment_check.rs
+++ b/tests/ui/mir/mir_alignment_check.rs
@@ -1,5 +1,6 @@
 // run-fail
 // ignore-wasm32-bare: No panic messages
+// ignore-i686-pc-windows-msvc: #112480
 // compile-flags: -C debug-assertions
 // error-pattern: misaligned pointer dereference: address must be a multiple of 0x4 but is
 
diff --git a/tests/ui/mir/mir_alignment_check_i686-pc-windows-msvc.rs b/tests/ui/mir/mir_alignment_check_i686-pc-windows-msvc.rs
new file mode 100644
index 00000000000..56388c1047e
--- /dev/null
+++ b/tests/ui/mir/mir_alignment_check_i686-pc-windows-msvc.rs
@@ -0,0 +1,21 @@
+// run-pass
+// only-i686-pc-windows-msvc
+// compile-flags: -Copt-level=0 -Cdebug-assertions=yes
+
+// MSVC isn't sure if on 32-bit Windows its u64 type is 8-byte-aligned or 4-byte-aligned.
+// So this test ensures that on i686-pc-windows-msvc, we do not insert a runtime check
+// that will fail on dereferencing of a pointer to u64 which is not 8-byte-aligned but is
+// 4-byte-aligned.
+
+#![feature(strict_provenance)]
+
+fn main() {
+    let mut x = [0u64; 2];
+    let ptr: *mut u8 = x.as_mut_ptr().cast::<u8>();
+    unsafe {
+        let misaligned = ptr.add(4).cast::<u64>();
+        assert!(misaligned.addr() % 8 != 0);
+        assert!(misaligned.addr() % 4 == 0);
+        *misaligned = 42;
+    }
+}