diff --git a/compiler/rustc_codegen_gcc/patches/libgccjit12/0001-core-Disable-portable-simd-test.patch b/compiler/rustc_codegen_gcc/patches/libgccjit12/0001-core-Disable-portable-simd-test.patch
index 914ae986b50..36d0789d2a2 100644
--- a/compiler/rustc_codegen_gcc/patches/libgccjit12/0001-core-Disable-portable-simd-test.patch
+++ b/compiler/rustc_codegen_gcc/patches/libgccjit12/0001-core-Disable-portable-simd-test.patch
@@ -14,7 +14,7 @@ index d0a119c..76fdece 100644
@@ -89,7 +89,6 @@
#![feature(never_type)]
#![feature(unwrap_infallible)]
- #![feature(pointer_is_aligned)]
+ #![feature(pointer_is_aligned_to)]
-#![feature(portable_simd)]
#![feature(ptr_metadata)]
#![feature(lazy_cell)]
@@ -27,6 +27,6 @@ index d0a119c..76fdece 100644
mod slice;
mod str;
mod str_lossy;
---
+--
2.42.1
diff --git a/compiler/rustc_data_structures/src/tagged_ptr/copy.rs b/compiler/rustc_data_structures/src/tagged_ptr/copy.rs
index ff4208def31..8b9e834b60b 100644
--- a/compiler/rustc_data_structures/src/tagged_ptr/copy.rs
+++ b/compiler/rustc_data_structures/src/tagged_ptr/copy.rs
@@ -243,6 +243,7 @@ where
T: Tag,
{
#[inline]
+ #[allow(ambiguous_wide_pointer_comparisons)]
fn eq(&self, other: &Self) -> bool {
self.packed == other.packed
}
diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl
index 9bf4d63267a..d8a90d62dac 100644
--- a/compiler/rustc_hir_analysis/messages.ftl
+++ b/compiler/rustc_hir_analysis/messages.ftl
@@ -295,6 +295,8 @@ hir_analysis_not_supported_delegation =
{$descr} is not supported yet
.label = callee defined here
+hir_analysis_only_current_traits_adt = `{$name}` is not defined in the current crate
+
hir_analysis_only_current_traits_arbitrary = only traits defined in the current crate can be implemented for arbitrary types
hir_analysis_only_current_traits_foreign = this is not defined in the current crate because this is a foreign trait
diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs
index ca8a635ab5e..1770f7b4e91 100644
--- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs
@@ -4,7 +4,7 @@
use crate::errors;
use rustc_errors::ErrorGuaranteed;
use rustc_hir as hir;
-use rustc_middle::ty::{self, AliasKind, Ty, TyCtxt, TypeVisitableExt};
+use rustc_middle::ty::{self, AliasKind, TyCtxt, TypeVisitableExt};
use rustc_span::def_id::LocalDefId;
use rustc_span::Span;
use rustc_trait_selection::traits::{self, IsFirstInputType};
@@ -283,9 +283,14 @@ fn emit_orphan_check_error<'tcx>(
let self_ty = trait_ref.self_ty();
Err(match err {
traits::OrphanCheckErr::NonLocalInputType(tys) => {
- let (mut opaque, mut foreign, mut name, mut pointer, mut ty_diag) =
- (Vec::new(), Vec::new(), Vec::new(), Vec::new(), Vec::new());
- let mut sugg = None;
+ let mut diag = tcx.dcx().create_err(match self_ty.kind() {
+ ty::Adt(..) => errors::OnlyCurrentTraits::Outside { span: sp, note: () },
+ _ if self_ty.is_primitive() => {
+ errors::OnlyCurrentTraits::Primitive { span: sp, note: () }
+ }
+ _ => errors::OnlyCurrentTraits::Arbitrary { span: sp, note: () },
+ });
+
for &(mut ty, is_target_ty) in &tys {
let span = if matches!(is_target_ty, IsFirstInputType::Yes) {
// Point at `D` in `impl for C in D`
@@ -296,113 +301,86 @@ fn emit_orphan_check_error<'tcx>(
};
ty = tcx.erase_regions(ty);
- ty = match ty.kind() {
- // Remove the type arguments from the output, as they are not relevant.
- // You can think of this as the reverse of `resolve_vars_if_possible`.
- // That way if we had `Vec`, we will properly attribute the
- // problem to `Vec` and avoid confusing the user if they were to see
- // `MyType` in the error.
- ty::Adt(def, _) => Ty::new_adt(tcx, *def, ty::List::empty()),
- _ => ty,
- };
-
- fn push_to_foreign_or_name<'tcx>(
- is_foreign: bool,
- foreign: &mut Vec,
- name: &mut Vec>,
- span: Span,
- sname: &'tcx str,
- ) {
- if is_foreign {
- foreign.push(errors::OnlyCurrentTraitsForeign { span })
- } else {
- name.push(errors::OnlyCurrentTraitsName { span, name: sname });
- }
- }
let is_foreign =
!trait_ref.def_id.is_local() && matches!(is_target_ty, IsFirstInputType::No);
match *ty.kind() {
ty::Slice(_) => {
- push_to_foreign_or_name(
- is_foreign,
- &mut foreign,
- &mut name,
- span,
- "slices",
- );
+ if is_foreign {
+ diag.subdiagnostic(
+ tcx.dcx(),
+ errors::OnlyCurrentTraitsForeign { span },
+ );
+ } else {
+ diag.subdiagnostic(
+ tcx.dcx(),
+ errors::OnlyCurrentTraitsName { span, name: "slices" },
+ );
+ }
}
ty::Array(..) => {
- push_to_foreign_or_name(
- is_foreign,
- &mut foreign,
- &mut name,
- span,
- "arrays",
- );
+ if is_foreign {
+ diag.subdiagnostic(
+ tcx.dcx(),
+ errors::OnlyCurrentTraitsForeign { span },
+ );
+ } else {
+ diag.subdiagnostic(
+ tcx.dcx(),
+ errors::OnlyCurrentTraitsName { span, name: "arrays" },
+ );
+ }
}
ty::Tuple(..) => {
- push_to_foreign_or_name(
- is_foreign,
- &mut foreign,
- &mut name,
- span,
- "tuples",
- );
+ if is_foreign {
+ diag.subdiagnostic(
+ tcx.dcx(),
+ errors::OnlyCurrentTraitsForeign { span },
+ );
+ } else {
+ diag.subdiagnostic(
+ tcx.dcx(),
+ errors::OnlyCurrentTraitsName { span, name: "tuples" },
+ );
+ }
}
ty::Alias(ty::Opaque, ..) => {
- opaque.push(errors::OnlyCurrentTraitsOpaque { span })
+ diag.subdiagnostic(tcx.dcx(), errors::OnlyCurrentTraitsOpaque { span });
}
ty::RawPtr(ptr_ty, mutbl) => {
if !self_ty.has_param() {
- let mut_key = mutbl.prefix_str();
- sugg = Some(errors::OnlyCurrentTraitsPointerSugg {
- wrapper_span: self_ty_span,
- struct_span: full_impl_span.shrink_to_lo(),
- mut_key,
- ptr_ty,
- });
+ diag.subdiagnostic(
+ tcx.dcx(),
+ errors::OnlyCurrentTraitsPointerSugg {
+ wrapper_span: self_ty_span,
+ struct_span: full_impl_span.shrink_to_lo(),
+ mut_key: mutbl.prefix_str(),
+ ptr_ty,
+ },
+ );
}
- pointer.push(errors::OnlyCurrentTraitsPointer { span, pointer: ty });
+ diag.subdiagnostic(
+ tcx.dcx(),
+ errors::OnlyCurrentTraitsPointer { span, pointer: ty },
+ );
+ }
+ ty::Adt(adt_def, _) => {
+ diag.subdiagnostic(
+ tcx.dcx(),
+ errors::OnlyCurrentTraitsAdt {
+ span,
+ name: tcx.def_path_str(adt_def.did()),
+ },
+ );
+ }
+ _ => {
+ diag.subdiagnostic(tcx.dcx(), errors::OnlyCurrentTraitsTy { span, ty });
}
- _ => ty_diag.push(errors::OnlyCurrentTraitsTy { span, ty }),
}
}
- let err_struct = match self_ty.kind() {
- ty::Adt(..) => errors::OnlyCurrentTraits::Outside {
- span: sp,
- note: (),
- opaque,
- foreign,
- name,
- pointer,
- ty: ty_diag,
- sugg,
- },
- _ if self_ty.is_primitive() => errors::OnlyCurrentTraits::Primitive {
- span: sp,
- note: (),
- opaque,
- foreign,
- name,
- pointer,
- ty: ty_diag,
- sugg,
- },
- _ => errors::OnlyCurrentTraits::Arbitrary {
- span: sp,
- note: (),
- opaque,
- foreign,
- name,
- pointer,
- ty: ty_diag,
- sugg,
- },
- };
- tcx.dcx().emit_err(err_struct)
+ diag.emit()
}
traits::OrphanCheckErr::UncoveredTy(param_ty, local_type) => {
let mut sp = sp;
diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs
index fb919714afd..2d4742fa1dc 100644
--- a/compiler/rustc_hir_analysis/src/errors.rs
+++ b/compiler/rustc_hir_analysis/src/errors.rs
@@ -1376,7 +1376,7 @@ pub struct TyParamSome<'a> {
}
#[derive(Diagnostic)]
-pub enum OnlyCurrentTraits<'a> {
+pub enum OnlyCurrentTraits {
#[diag(hir_analysis_only_current_traits_outside, code = E0117)]
Outside {
#[primary_span]
@@ -1384,18 +1384,6 @@ pub enum OnlyCurrentTraits<'a> {
span: Span,
#[note(hir_analysis_only_current_traits_note)]
note: (),
- #[subdiagnostic]
- opaque: Vec,
- #[subdiagnostic]
- foreign: Vec,
- #[subdiagnostic]
- name: Vec>,
- #[subdiagnostic]
- pointer: Vec>,
- #[subdiagnostic]
- ty: Vec>,
- #[subdiagnostic]
- sugg: Option>,
},
#[diag(hir_analysis_only_current_traits_primitive, code = E0117)]
Primitive {
@@ -1404,18 +1392,6 @@ pub enum OnlyCurrentTraits<'a> {
span: Span,
#[note(hir_analysis_only_current_traits_note)]
note: (),
- #[subdiagnostic]
- opaque: Vec,
- #[subdiagnostic]
- foreign: Vec,
- #[subdiagnostic]
- name: Vec>,
- #[subdiagnostic]
- pointer: Vec>,
- #[subdiagnostic]
- ty: Vec>,
- #[subdiagnostic]
- sugg: Option>,
},
#[diag(hir_analysis_only_current_traits_arbitrary, code = E0117)]
Arbitrary {
@@ -1424,18 +1400,6 @@ pub enum OnlyCurrentTraits<'a> {
span: Span,
#[note(hir_analysis_only_current_traits_note)]
note: (),
- #[subdiagnostic]
- opaque: Vec,
- #[subdiagnostic]
- foreign: Vec,
- #[subdiagnostic]
- name: Vec>,
- #[subdiagnostic]
- pointer: Vec>,
- #[subdiagnostic]
- ty: Vec>,
- #[subdiagnostic]
- sugg: Option>,
},
}
@@ -1445,7 +1409,6 @@ pub struct OnlyCurrentTraitsOpaque {
#[primary_span]
pub span: Span,
}
-
#[derive(Subdiagnostic)]
#[label(hir_analysis_only_current_traits_foreign)]
pub struct OnlyCurrentTraitsForeign {
@@ -1477,6 +1440,14 @@ pub struct OnlyCurrentTraitsTy<'a> {
pub ty: Ty<'a>,
}
+#[derive(Subdiagnostic)]
+#[label(hir_analysis_only_current_traits_adt)]
+pub struct OnlyCurrentTraitsAdt {
+ #[primary_span]
+ pub span: Span,
+ pub name: String,
+}
+
#[derive(Subdiagnostic)]
#[multipart_suggestion(
hir_analysis_only_current_traits_pointer_sugg,
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index ebc5e11a561..8ea1a88be5d 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -1916,18 +1916,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pat: &'tcx hir::Pat<'tcx>,
ty: Ty<'tcx>,
) {
- struct V<'tcx> {
- tcx: TyCtxt<'tcx>,
+ struct V {
pat_hir_ids: Vec,
}
- impl<'tcx> Visitor<'tcx> for V<'tcx> {
- type NestedFilter = rustc_middle::hir::nested_filter::All;
-
- fn nested_visit_map(&mut self) -> Self::Map {
- self.tcx.hir()
- }
-
+ impl<'tcx> Visitor<'tcx> for V {
fn visit_pat(&mut self, p: &'tcx hir::Pat<'tcx>) {
self.pat_hir_ids.push(p.hir_id);
hir::intravisit::walk_pat(self, p);
@@ -1938,7 +1931,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let err = Ty::new_error(self.tcx, guar);
self.write_ty(hir_id, err);
self.write_ty(pat.hir_id, err);
- let mut visitor = V { tcx: self.tcx, pat_hir_ids: vec![] };
+ let mut visitor = V { pat_hir_ids: vec![] };
hir::intravisit::walk_pat(&mut visitor, pat);
// Mark all the subpatterns as `{type error}` as well. This allows errors for specific
// subpatterns to be silenced.
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index cf3890dc61c..a034bebc85e 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -1632,11 +1632,13 @@ pub struct AmbiguousWidePointerComparisonsAddrMetadataSuggestion<'a> {
pub ne: &'a str,
pub deref_left: &'a str,
pub deref_right: &'a str,
+ pub l_modifiers: &'a str,
+ pub r_modifiers: &'a str,
#[suggestion_part(code = "{ne}std::ptr::eq({deref_left}")]
pub left: Span,
- #[suggestion_part(code = ", {deref_right}")]
+ #[suggestion_part(code = "{l_modifiers}, {deref_right}")]
pub middle: Span,
- #[suggestion_part(code = ")")]
+ #[suggestion_part(code = "{r_modifiers})")]
pub right: Span,
}
@@ -1652,11 +1654,13 @@ pub enum AmbiguousWidePointerComparisonsAddrSuggestion<'a> {
ne: &'a str,
deref_left: &'a str,
deref_right: &'a str,
+ l_modifiers: &'a str,
+ r_modifiers: &'a str,
#[suggestion_part(code = "{ne}std::ptr::addr_eq({deref_left}")]
left: Span,
- #[suggestion_part(code = ", {deref_right}")]
+ #[suggestion_part(code = "{l_modifiers}, {deref_right}")]
middle: Span,
- #[suggestion_part(code = ")")]
+ #[suggestion_part(code = "{r_modifiers})")]
right: Span,
},
#[multipart_suggestion(
@@ -1670,13 +1674,15 @@ pub enum AmbiguousWidePointerComparisonsAddrSuggestion<'a> {
deref_right: &'a str,
paren_left: &'a str,
paren_right: &'a str,
+ l_modifiers: &'a str,
+ r_modifiers: &'a str,
#[suggestion_part(code = "({deref_left}")]
left_before: Option,
- #[suggestion_part(code = "{paren_left}.cast::<()>()")]
+ #[suggestion_part(code = "{l_modifiers}{paren_left}.cast::<()>()")]
left_after: Span,
#[suggestion_part(code = "({deref_right}")]
right_before: Option,
- #[suggestion_part(code = "{paren_right}.cast::<()>()")]
+ #[suggestion_part(code = "{r_modifiers}{paren_right}.cast::<()>()")]
right_after: Span,
},
}
diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs
index 68cc024d9c7..534eb60eeb0 100644
--- a/compiler/rustc_lint/src/types.rs
+++ b/compiler/rustc_lint/src/types.rs
@@ -670,7 +670,11 @@ fn lint_wide_pointer<'tcx>(
l: &'tcx hir::Expr<'tcx>,
r: &'tcx hir::Expr<'tcx>,
) {
- let ptr_unsized = |mut ty: Ty<'tcx>| -> Option<(usize, bool)> {
+ let ptr_unsized = |mut ty: Ty<'tcx>| -> Option<(
+ /* number of refs */ usize,
+ /* modifiers */ String,
+ /* is dyn */ bool,
+ )> {
let mut refs = 0;
// here we remove any "implicit" references and count the number
// of them to correctly suggest the right number of deref
@@ -678,11 +682,20 @@ fn lint_wide_pointer<'tcx>(
ty = *inner_ty;
refs += 1;
}
- match ty.kind() {
- ty::RawPtr(ty, _) => (!ty.is_sized(cx.tcx, cx.param_env))
- .then(|| (refs, matches!(ty.kind(), ty::Dynamic(_, _, ty::Dyn)))),
- _ => None,
- }
+
+ // get the inner type of a pointer (or akin)
+ let mut modifiers = String::new();
+ ty = match ty.kind() {
+ ty::RawPtr(ty, _) => *ty,
+ ty::Adt(def, args) if cx.tcx.is_diagnostic_item(sym::NonNull, def.did()) => {
+ modifiers.push_str(".as_ptr()");
+ args.type_at(0)
+ }
+ _ => return None,
+ };
+
+ (!ty.is_sized(cx.tcx, cx.param_env))
+ .then(|| (refs, modifiers, matches!(ty.kind(), ty::Dynamic(_, _, ty::Dyn))))
};
// the left and right operands can have references, remove any explicit references
@@ -696,10 +709,10 @@ fn lint_wide_pointer<'tcx>(
return;
};
- let Some((l_ty_refs, l_inner_ty_is_dyn)) = ptr_unsized(l_ty) else {
+ let Some((l_ty_refs, l_modifiers, l_inner_ty_is_dyn)) = ptr_unsized(l_ty) else {
return;
};
- let Some((r_ty_refs, r_inner_ty_is_dyn)) = ptr_unsized(r_ty) else {
+ let Some((r_ty_refs, r_modifiers, r_inner_ty_is_dyn)) = ptr_unsized(r_ty) else {
return;
};
@@ -724,6 +737,9 @@ fn lint_wide_pointer<'tcx>(
let deref_left = &*"*".repeat(l_ty_refs);
let deref_right = &*"*".repeat(r_ty_refs);
+ let l_modifiers = &*l_modifiers;
+ let r_modifiers = &*r_modifiers;
+
cx.emit_span_lint(
AMBIGUOUS_WIDE_POINTER_COMPARISONS,
e.span,
@@ -733,6 +749,8 @@ fn lint_wide_pointer<'tcx>(
ne,
deref_left,
deref_right,
+ l_modifiers,
+ r_modifiers,
left,
middle,
right,
@@ -743,6 +761,8 @@ fn lint_wide_pointer<'tcx>(
ne,
deref_left,
deref_right,
+ l_modifiers,
+ r_modifiers,
left,
middle,
right,
@@ -751,6 +771,8 @@ fn lint_wide_pointer<'tcx>(
AmbiguousWidePointerComparisonsAddrSuggestion::Cast {
deref_left,
deref_right,
+ l_modifiers,
+ r_modifiers,
paren_left: if l_ty_refs != 0 { ")" } else { "" },
paren_right: if r_ty_refs != 0 { ")" } else { "" },
left_before: (l_ty_refs != 0).then_some(l_span.shrink_to_lo()),
diff --git a/compiler/rustc_middle/src/ty/region.rs b/compiler/rustc_middle/src/ty/region.rs
index 867faf63261..b92800a1728 100644
--- a/compiler/rustc_middle/src/ty/region.rs
+++ b/compiler/rustc_middle/src/ty/region.rs
@@ -140,6 +140,10 @@ impl<'tcx> rustc_type_ir::new::Region> for Region<'tcx> {
fn new_anon_bound(tcx: TyCtxt<'tcx>, debruijn: ty::DebruijnIndex, var: ty::BoundVar) -> Self {
Region::new_bound(tcx, debruijn, ty::BoundRegion { var, kind: ty::BoundRegionKind::BrAnon })
}
+
+ fn new_static(tcx: TyCtxt<'tcx>) -> Self {
+ tcx.lifetimes.re_static
+ }
}
/// Region utilities
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index 57a675e4453..b5e619f1e2a 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -1624,6 +1624,13 @@ impl<'tcx> Ty<'tcx> {
#[inline]
pub fn new_adt(tcx: TyCtxt<'tcx>, def: AdtDef<'tcx>, args: GenericArgsRef<'tcx>) -> Ty<'tcx> {
+ debug_assert_eq!(
+ tcx.generics_of(def.did()).count(),
+ args.len(),
+ "wrong number of args for ADT: {:#?} vs {:#?}",
+ tcx.generics_of(def.did()).params,
+ args
+ );
Ty::new(tcx, Adt(def, args))
}
diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs
index b66dd83b7ec..690879b9488 100644
--- a/compiler/rustc_mir_build/src/build/matches/test.rs
+++ b/compiler/rustc_mir_build/src/build/matches/test.rs
@@ -650,12 +650,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}
}
- // FIXME(#29623): return `Some(1)` when the values are different.
- (TestKind::Eq { value: test_val, .. }, TestCase::Constant { value: case_val })
- if test_val == case_val =>
- {
- fully_matched = true;
- Some(TestBranch::Success)
+ (TestKind::Eq { value: test_val, .. }, TestCase::Constant { value: case_val }) => {
+ if test_val == case_val {
+ fully_matched = true;
+ Some(TestBranch::Success)
+ } else {
+ fully_matched = false;
+ Some(TestBranch::Failure)
+ }
}
(
diff --git a/compiler/rustc_next_trait_solver/src/canonicalizer.rs b/compiler/rustc_next_trait_solver/src/canonicalizer.rs
index 16d8453ea24..1899517c0e2 100644
--- a/compiler/rustc_next_trait_solver/src/canonicalizer.rs
+++ b/compiler/rustc_next_trait_solver/src/canonicalizer.rs
@@ -296,10 +296,7 @@ impl, I: Interner> TypeFolder
Region::new_anon_bound(self.interner(), self.binder_index, var)
}
- fn fold_ty(&mut self, t: I::Ty) -> I::Ty
- where
- I::Ty: TypeSuperFoldable,
- {
+ fn fold_ty(&mut self, t: I::Ty) -> I::Ty {
let kind = match t.kind() {
ty::Infer(i) => match i {
ty::TyVar(vid) => {
@@ -378,47 +375,48 @@ impl, I: Interner> TypeFolder
Ty::new_anon_bound(self.interner(), self.binder_index, var)
}
- fn fold_const(&mut self, c: I::Const) -> I::Const
- where
- I::Const: TypeSuperFoldable,
- {
+ fn fold_const(&mut self, c: I::Const) -> I::Const {
+ // We could canonicalize all consts with static types, but the only ones we
+ // *really* need to worry about are the ones that we end up putting into `CanonicalVarKind`
+ // since canonical vars can't reference other canonical vars.
+ let ty = c
+ .ty()
+ .fold_with(&mut RegionsToStatic { interner: self.interner(), binder: ty::INNERMOST });
let kind = match c.kind() {
- ty::ConstKind::Infer(i) => {
- // FIXME: we should fold the ty too eventually
- match i {
- ty::InferConst::Var(vid) => {
- assert_eq!(
- self.infcx.root_ct_var(vid),
- vid,
- "region vid should have been resolved fully before canonicalization"
- );
- assert_eq!(
- self.infcx.probe_ct_var(vid),
- None,
- "region vid should have been resolved fully before canonicalization"
- );
- CanonicalVarKind::Const(self.infcx.universe_of_ct(vid).unwrap(), c.ty())
- }
- ty::InferConst::EffectVar(_) => CanonicalVarKind::Effect,
- ty::InferConst::Fresh(_) => todo!(),
+ ty::ConstKind::Infer(i) => match i {
+ ty::InferConst::Var(vid) => {
+ assert_eq!(
+ self.infcx.root_ct_var(vid),
+ vid,
+ "region vid should have been resolved fully before canonicalization"
+ );
+ assert_eq!(
+ self.infcx.probe_ct_var(vid),
+ None,
+ "region vid should have been resolved fully before canonicalization"
+ );
+ CanonicalVarKind::Const(self.infcx.universe_of_ct(vid).unwrap(), ty)
}
- }
+ ty::InferConst::EffectVar(_) => CanonicalVarKind::Effect,
+ ty::InferConst::Fresh(_) => todo!(),
+ },
ty::ConstKind::Placeholder(placeholder) => match self.canonicalize_mode {
CanonicalizeMode::Input => CanonicalVarKind::PlaceholderConst(
PlaceholderLike::new(placeholder.universe(), self.variables.len().into()),
- c.ty(),
+ ty,
),
CanonicalizeMode::Response { .. } => {
- CanonicalVarKind::PlaceholderConst(placeholder, c.ty())
+ CanonicalVarKind::PlaceholderConst(placeholder, ty)
}
},
ty::ConstKind::Param(_) => match self.canonicalize_mode {
CanonicalizeMode::Input => CanonicalVarKind::PlaceholderConst(
PlaceholderLike::new(ty::UniverseIndex::ROOT, self.variables.len().into()),
- c.ty(),
+ ty,
),
CanonicalizeMode::Response { .. } => panic!("param ty in response: {c:?}"),
},
+ // FIXME: See comment above -- we could fold the region separately or something.
ty::ConstKind::Bound(_, _)
| ty::ConstKind::Unevaluated(_)
| ty::ConstKind::Value(_)
@@ -435,6 +433,35 @@ impl, I: Interner> TypeFolder
}),
);
- Const::new_anon_bound(self.interner(), self.binder_index, var, c.ty())
+ Const::new_anon_bound(self.interner(), self.binder_index, var, ty)
+ }
+}
+
+struct RegionsToStatic {
+ interner: I,
+ binder: ty::DebruijnIndex,
+}
+
+impl TypeFolder for RegionsToStatic {
+ fn interner(&self) -> I {
+ self.interner
+ }
+
+ fn fold_binder(&mut self, t: I::Binder) -> I::Binder
+ where
+ T: TypeFoldable,
+ I::Binder: TypeSuperFoldable,
+ {
+ self.binder.shift_in(1);
+ let t = t.fold_with(self);
+ self.binder.shift_out(1);
+ t
+ }
+
+ fn fold_region(&mut self, r: I::Region) -> I::Region {
+ match r.kind() {
+ ty::ReBound(db, _) if self.binder > db => r,
+ _ => Region::new_static(self.interner()),
+ }
}
}
diff --git a/compiler/rustc_session/messages.ftl b/compiler/rustc_session/messages.ftl
index 179fd79bef7..b8dacc6968d 100644
--- a/compiler/rustc_session/messages.ftl
+++ b/compiler/rustc_session/messages.ftl
@@ -96,6 +96,8 @@ session_sanitizer_cfi_requires_lto = `-Zsanitizer=cfi` requires `-Clto` or `-Cli
session_sanitizer_cfi_requires_single_codegen_unit = `-Zsanitizer=cfi` with `-Clto` requires `-Ccodegen-units=1`
+session_sanitizer_kcfi_requires_panic_abort = `-Z sanitizer=kcfi` requires `-C panic=abort`
+
session_sanitizer_not_supported = {$us} sanitizer is not supported for this target
session_sanitizers_not_supported = {$us} sanitizers are not supported for this target
diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs
index 0a855f87586..2e4c7d14ecd 100644
--- a/compiler/rustc_session/src/errors.rs
+++ b/compiler/rustc_session/src/errors.rs
@@ -145,6 +145,10 @@ pub(crate) struct SanitizerCfiGeneralizePointersRequiresCfi;
#[diag(session_sanitizer_cfi_normalize_integers_requires_cfi)]
pub(crate) struct SanitizerCfiNormalizeIntegersRequiresCfi;
+#[derive(Diagnostic)]
+#[diag(session_sanitizer_kcfi_requires_panic_abort)]
+pub(crate) struct SanitizerKcfiRequiresPanicAbort;
+
#[derive(Diagnostic)]
#[diag(session_split_lto_unit_requires_lto)]
pub(crate) struct SplitLtoUnitRequiresLto;
diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs
index 85428303382..55fff4421ae 100644
--- a/compiler/rustc_session/src/session.rs
+++ b/compiler/rustc_session/src/session.rs
@@ -1211,6 +1211,11 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
sess.dcx().emit_err(errors::SanitizerCfiRequiresLto);
}
+ // KCFI requires panic=abort
+ if sess.is_sanitizer_kcfi_enabled() && sess.panic_strategy() != PanicStrategy::Abort {
+ sess.dcx().emit_err(errors::SanitizerKcfiRequiresPanicAbort);
+ }
+
// LLVM CFI using rustc LTO requires a single codegen unit.
if sess.is_sanitizer_cfi_enabled()
&& sess.lto() == config::Lto::Fat
diff --git a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs
index 7fd5cfeb48b..5963bd7c5f1 100644
--- a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs
+++ b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs
@@ -10,6 +10,7 @@
use rustc_data_structures::base_n;
use rustc_data_structures::fx::FxHashMap;
use rustc_hir as hir;
+use rustc_hir::lang_items::LangItem;
use rustc_middle::ty::layout::IntegerExt;
use rustc_middle::ty::TypeVisitableExt;
use rustc_middle::ty::{
@@ -641,9 +642,7 @@ fn encode_ty<'tcx>(
}
// Function types
- ty::FnDef(def_id, args)
- | ty::Closure(def_id, args)
- | ty::CoroutineClosure(def_id, args) => {
+ ty::FnDef(def_id, args) | ty::Closure(def_id, args) => {
// u[IE], where is ,
// as vendor extended type.
let mut s = String::new();
@@ -654,6 +653,18 @@ fn encode_ty<'tcx>(
typeid.push_str(&s);
}
+ ty::CoroutineClosure(def_id, args) => {
+ // u[IE], where is ,
+ // as vendor extended type.
+ let mut s = String::new();
+ let name = encode_ty_name(tcx, *def_id);
+ let _ = write!(s, "u{}{}", name.len(), &name);
+ let parent_args = tcx.mk_args(args.as_coroutine_closure().parent_args());
+ s.push_str(&encode_args(tcx, parent_args, dict, options));
+ compress(dict, DictKey::Ty(ty, TyQ::None), &mut s);
+ typeid.push_str(&s);
+ }
+
ty::Coroutine(def_id, args, ..) => {
// u[IE], where is ,
// as vendor extended type.
@@ -1140,45 +1151,102 @@ pub fn typeid_for_instance<'tcx>(
let predicates = tcx.mk_poly_existential_predicates(&[ty::Binder::dummy(predicate)]);
let self_ty = Ty::new_dynamic(tcx, predicates, tcx.lifetimes.re_erased, ty::Dyn);
instance.args = tcx.mk_args_trait(self_ty, List::empty());
- } else if matches!(instance.def, ty::InstanceDef::Virtual(..)) {
- instance.args = strip_receiver_auto(tcx, instance.args);
+ } else if let ty::InstanceDef::Virtual(def_id, _) = instance.def {
+ let upcast_ty = match tcx.trait_of_item(def_id) {
+ Some(trait_id) => trait_object_ty(
+ tcx,
+ ty::Binder::dummy(ty::TraitRef::from_method(tcx, trait_id, instance.args)),
+ ),
+ // drop_in_place won't have a defining trait, skip the upcast
+ None => instance.args.type_at(0),
+ };
+ let stripped_ty = strip_receiver_auto(tcx, upcast_ty);
+ instance.args = tcx.mk_args_trait(stripped_ty, instance.args.into_iter().skip(1));
+ } else if let ty::InstanceDef::VTableShim(def_id) = instance.def
+ && let Some(trait_id) = tcx.trait_of_item(def_id)
+ {
+ // VTableShims may have a trait method, but a concrete Self. This is not suitable for a vtable,
+ // as the caller will not know the concrete Self.
+ let trait_ref = ty::TraitRef::new(tcx, trait_id, instance.args);
+ let invoke_ty = trait_object_ty(tcx, ty::Binder::dummy(trait_ref));
+ instance.args = tcx.mk_args_trait(invoke_ty, trait_ref.args.into_iter().skip(1));
}
- if !options.contains(EncodeTyOptions::NO_SELF_TYPE_ERASURE)
- && let Some(impl_id) = tcx.impl_of_method(instance.def_id())
- && let Some(trait_ref) = tcx.impl_trait_ref(impl_id)
- {
- let impl_method = tcx.associated_item(instance.def_id());
- let method_id = impl_method
- .trait_item_def_id
- .expect("Part of a trait implementation, but not linked to the def_id?");
- let trait_method = tcx.associated_item(method_id);
- let trait_id = trait_ref.skip_binder().def_id;
- if traits::is_vtable_safe_method(tcx, trait_id, trait_method)
- && tcx.object_safety_violations(trait_id).is_empty()
+ if !options.contains(EncodeTyOptions::NO_SELF_TYPE_ERASURE) {
+ if let Some(impl_id) = tcx.impl_of_method(instance.def_id())
+ && let Some(trait_ref) = tcx.impl_trait_ref(impl_id)
{
- // Trait methods will have a Self polymorphic parameter, where the concreteized
- // implementatation will not. We need to walk back to the more general trait method
- let trait_ref = tcx.instantiate_and_normalize_erasing_regions(
- instance.args,
- ty::ParamEnv::reveal_all(),
- trait_ref,
- );
- let invoke_ty = trait_object_ty(tcx, ty::Binder::dummy(trait_ref));
+ let impl_method = tcx.associated_item(instance.def_id());
+ let method_id = impl_method
+ .trait_item_def_id
+ .expect("Part of a trait implementation, but not linked to the def_id?");
+ let trait_method = tcx.associated_item(method_id);
+ let trait_id = trait_ref.skip_binder().def_id;
+ if traits::is_vtable_safe_method(tcx, trait_id, trait_method)
+ && tcx.object_safety_violations(trait_id).is_empty()
+ {
+ // Trait methods will have a Self polymorphic parameter, where the concreteized
+ // implementatation will not. We need to walk back to the more general trait method
+ let trait_ref = tcx.instantiate_and_normalize_erasing_regions(
+ instance.args,
+ ty::ParamEnv::reveal_all(),
+ trait_ref,
+ );
+ let invoke_ty = trait_object_ty(tcx, ty::Binder::dummy(trait_ref));
- // At the call site, any call to this concrete function through a vtable will be
- // `Virtual(method_id, idx)` with appropriate arguments for the method. Since we have the
- // original method id, and we've recovered the trait arguments, we can make the callee
- // instance we're computing the alias set for match the caller instance.
- //
- // Right now, our code ignores the vtable index everywhere, so we use 0 as a placeholder.
- // If we ever *do* start encoding the vtable index, we will need to generate an alias set
- // based on which vtables we are putting this method into, as there will be more than one
- // index value when supertraits are involved.
- instance.def = ty::InstanceDef::Virtual(method_id, 0);
- let abstract_trait_args =
- tcx.mk_args_trait(invoke_ty, trait_ref.args.into_iter().skip(1));
- instance.args = instance.args.rebase_onto(tcx, impl_id, abstract_trait_args);
+ // At the call site, any call to this concrete function through a vtable will be
+ // `Virtual(method_id, idx)` with appropriate arguments for the method. Since we have the
+ // original method id, and we've recovered the trait arguments, we can make the callee
+ // instance we're computing the alias set for match the caller instance.
+ //
+ // Right now, our code ignores the vtable index everywhere, so we use 0 as a placeholder.
+ // If we ever *do* start encoding the vtable index, we will need to generate an alias set
+ // based on which vtables we are putting this method into, as there will be more than one
+ // index value when supertraits are involved.
+ instance.def = ty::InstanceDef::Virtual(method_id, 0);
+ let abstract_trait_args =
+ tcx.mk_args_trait(invoke_ty, trait_ref.args.into_iter().skip(1));
+ instance.args = instance.args.rebase_onto(tcx, impl_id, abstract_trait_args);
+ }
+ } else if tcx.is_closure_like(instance.def_id()) {
+ // We're either a closure or a coroutine. Our goal is to find the trait we're defined on,
+ // instantiate it, and take the type of its only method as our own.
+ let closure_ty = instance.ty(tcx, ty::ParamEnv::reveal_all());
+ let (trait_id, inputs) = match closure_ty.kind() {
+ ty::Closure(..) => {
+ let closure_args = instance.args.as_closure();
+ let trait_id = tcx.fn_trait_kind_to_def_id(closure_args.kind()).unwrap();
+ let tuple_args =
+ tcx.instantiate_bound_regions_with_erased(closure_args.sig()).inputs()[0];
+ (trait_id, tuple_args)
+ }
+ ty::Coroutine(..) => (
+ tcx.require_lang_item(LangItem::Coroutine, None),
+ instance.args.as_coroutine().resume_ty(),
+ ),
+ ty::CoroutineClosure(..) => (
+ tcx.require_lang_item(LangItem::FnOnce, None),
+ tcx.instantiate_bound_regions_with_erased(
+ instance.args.as_coroutine_closure().coroutine_closure_sig(),
+ )
+ .tupled_inputs_ty,
+ ),
+ x => bug!("Unexpected type kind for closure-like: {x:?}"),
+ };
+ let trait_ref = ty::TraitRef::new(tcx, trait_id, [closure_ty, inputs]);
+ let invoke_ty = trait_object_ty(tcx, ty::Binder::dummy(trait_ref));
+ let abstract_args = tcx.mk_args_trait(invoke_ty, trait_ref.args.into_iter().skip(1));
+ // There should be exactly one method on this trait, and it should be the one we're
+ // defining.
+ let call = tcx
+ .associated_items(trait_id)
+ .in_definition_order()
+ .find(|it| it.kind == ty::AssocKind::Fn)
+ .expect("No call-family function on closure-like Fn trait?")
+ .def_id;
+
+ instance.def = ty::InstanceDef::Virtual(call, 0);
+ instance.args = abstract_args;
}
}
@@ -1191,15 +1259,11 @@ pub fn typeid_for_instance<'tcx>(
typeid_for_fnabi(tcx, fn_abi, options)
}
-fn strip_receiver_auto<'tcx>(
- tcx: TyCtxt<'tcx>,
- args: ty::GenericArgsRef<'tcx>,
-) -> ty::GenericArgsRef<'tcx> {
- let ty = args.type_at(0);
+fn strip_receiver_auto<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
let ty::Dynamic(preds, lifetime, kind) = ty.kind() else {
bug!("Tried to strip auto traits from non-dynamic type {ty}");
};
- let new_rcvr = if preds.principal().is_some() {
+ if preds.principal().is_some() {
let filtered_preds =
tcx.mk_poly_existential_predicates_from_iter(preds.into_iter().filter(|pred| {
!matches!(pred.skip_binder(), ty::ExistentialPredicate::AutoTrait(..))
@@ -1210,8 +1274,7 @@ fn strip_receiver_auto<'tcx>(
// about it. This technically discards the knowledge that it was a type that was made
// into a trait object at some point, but that's not a lot.
tcx.types.unit
- };
- tcx.mk_args_trait(new_rcvr, args.into_iter().skip(1))
+ }
}
#[instrument(skip(tcx), ret)]
diff --git a/compiler/rustc_type_ir/src/fold.rs b/compiler/rustc_type_ir/src/fold.rs
index 8d402588398..01bb3d73dbd 100644
--- a/compiler/rustc_type_ir/src/fold.rs
+++ b/compiler/rustc_type_ir/src/fold.rs
@@ -136,31 +136,21 @@ pub trait TypeFolder: FallibleTypeFolder {
t.super_fold_with(self)
}
- fn fold_ty(&mut self, t: I::Ty) -> I::Ty
- where
- I::Ty: TypeSuperFoldable,
- {
+ fn fold_ty(&mut self, t: I::Ty) -> I::Ty {
t.super_fold_with(self)
}
// The default region folder is a no-op because `Region` is non-recursive
- // and has no `super_fold_with` method to call. That also explains the
- // lack of `I::Region: TypeSuperFoldable` bound on this method.
+ // and has no `super_fold_with` method to call.
fn fold_region(&mut self, r: I::Region) -> I::Region {
r
}
- fn fold_const(&mut self, c: I::Const) -> I::Const
- where
- I::Const: TypeSuperFoldable,
- {
+ fn fold_const(&mut self, c: I::Const) -> I::Const {
c.super_fold_with(self)
}
- fn fold_predicate(&mut self, p: I::Predicate) -> I::Predicate
- where
- I::Predicate: TypeSuperFoldable,
- {
+ fn fold_predicate(&mut self, p: I::Predicate) -> I::Predicate {
p.super_fold_with(self)
}
}
@@ -185,31 +175,21 @@ pub trait FallibleTypeFolder: Sized {
t.try_super_fold_with(self)
}
- fn try_fold_ty(&mut self, t: I::Ty) -> Result
- where
- I::Ty: TypeSuperFoldable,
- {
+ fn try_fold_ty(&mut self, t: I::Ty) -> Result {
t.try_super_fold_with(self)
}
// The default region folder is a no-op because `Region` is non-recursive
- // and has no `super_fold_with` method to call. That also explains the
- // lack of `I::Region: TypeSuperFoldable` bound on this method.
+ // and has no `super_fold_with` method to call.
fn try_fold_region(&mut self, r: I::Region) -> Result {
Ok(r)
}
- fn try_fold_const(&mut self, c: I::Const) -> Result
- where
- I::Const: TypeSuperFoldable,
- {
+ fn try_fold_const(&mut self, c: I::Const) -> Result {
c.try_super_fold_with(self)
}
- fn try_fold_predicate(&mut self, p: I::Predicate) -> Result
- where
- I::Predicate: TypeSuperFoldable,
- {
+ fn try_fold_predicate(&mut self, p: I::Predicate) -> Result {
p.try_super_fold_with(self)
}
}
@@ -234,10 +214,7 @@ where
Ok(self.fold_binder(t))
}
- fn try_fold_ty(&mut self, t: I::Ty) -> Result
- where
- I::Ty: TypeSuperFoldable,
- {
+ fn try_fold_ty(&mut self, t: I::Ty) -> Result {
Ok(self.fold_ty(t))
}
@@ -245,17 +222,11 @@ where
Ok(self.fold_region(r))
}
- fn try_fold_const(&mut self, c: I::Const) -> Result
- where
- I::Const: TypeSuperFoldable,
- {
+ fn try_fold_const(&mut self, c: I::Const) -> Result {
Ok(self.fold_const(c))
}
- fn try_fold_predicate(&mut self, p: I::Predicate) -> Result
- where
- I::Predicate: TypeSuperFoldable,
- {
+ fn try_fold_predicate(&mut self, p: I::Predicate) -> Result {
Ok(self.fold_predicate(p))
}
}
diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs
index ae1e1902f14..7a2885dd3bb 100644
--- a/compiler/rustc_type_ir/src/interner.rs
+++ b/compiler/rustc_type_ir/src/interner.rs
@@ -2,13 +2,14 @@ use smallvec::SmallVec;
use std::fmt::Debug;
use std::hash::Hash;
+use crate::fold::TypeSuperFoldable;
use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable};
use crate::{
new, BoundVar, BoundVars, CanonicalVarInfo, ConstKind, DebugWithInfcx, RegionKind, TyKind,
UniverseIndex,
};
-pub trait Interner: Sized {
+pub trait Interner: Sized + Copy {
type DefId: Copy + Debug + Hash + Eq;
type AdtDef: Copy + Debug + Hash + Eq;
@@ -34,6 +35,7 @@ pub trait Interner: Sized {
+ Into
+ IntoKind>
+ TypeSuperVisitable
+ + TypeSuperFoldable
+ Flags
+ new::Ty;
type Tys: Copy + Debug + Hash + Eq + IntoIterator- ;
@@ -57,6 +59,7 @@ pub trait Interner: Sized {
+ IntoKind>
+ ConstTy
+ TypeSuperVisitable
+ + TypeSuperFoldable
+ Flags
+ new::Const;
type AliasConst: Copy + DebugWithInfcx + Hash + Eq;
@@ -82,7 +85,13 @@ pub trait Interner: Sized {
type PlaceholderRegion: Copy + Debug + Hash + Eq + PlaceholderLike;
// Predicates
- type Predicate: Copy + Debug + Hash + Eq + TypeSuperVisitable + Flags;
+ type Predicate: Copy
+ + Debug
+ + Hash
+ + Eq
+ + TypeSuperVisitable
+ + TypeSuperFoldable
+ + Flags;
type TraitPredicate: Copy + Debug + Hash + Eq;
type RegionOutlivesPredicate: Copy + Debug + Hash + Eq;
type TypeOutlivesPredicate: Copy + Debug + Hash + Eq;
diff --git a/compiler/rustc_type_ir/src/new.rs b/compiler/rustc_type_ir/src/new.rs
index e7e695e5908..1572a641d06 100644
--- a/compiler/rustc_type_ir/src/new.rs
+++ b/compiler/rustc_type_ir/src/new.rs
@@ -6,6 +6,8 @@ pub trait Ty> {
pub trait Region> {
fn new_anon_bound(interner: I, debruijn: DebruijnIndex, var: BoundVar) -> Self;
+
+ fn new_static(interner: I) -> Self;
}
pub trait Const> {
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index b6a9d6005d4..cafd59cb0d9 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -198,7 +198,6 @@
#![feature(multiple_supertrait_upcastable)]
#![feature(negative_impls)]
#![feature(never_type)]
-#![feature(pointer_is_aligned)]
#![feature(rustc_allow_const_fn_unstable)]
#![feature(rustc_attrs)]
#![feature(slice_internals)]
diff --git a/library/alloc/tests/lib.rs b/library/alloc/tests/lib.rs
index 04709af5c0a..a34bce66496 100644
--- a/library/alloc/tests/lib.rs
+++ b/library/alloc/tests/lib.rs
@@ -37,7 +37,7 @@
#![feature(const_trait_impl)]
#![feature(const_str_from_utf8)]
#![feature(panic_update_hook)]
-#![feature(pointer_is_aligned)]
+#![feature(pointer_is_aligned_to)]
#![feature(slice_flatten)]
#![feature(thin_box)]
#![feature(strict_provenance)]
diff --git a/library/core/src/any.rs b/library/core/src/any.rs
index a4252d0c9e0..37cb8e7d303 100644
--- a/library/core/src/any.rs
+++ b/library/core/src/any.rs
@@ -40,10 +40,10 @@
//!
//! ## Examples
//!
-//! Consider a situation where we want to log out a value passed to a function.
-//! We know the value we're working on implements Debug, but we don't know its
+//! Consider a situation where we want to log a value passed to a function.
+//! We know the value we're working on implements `Debug`, but we don't know its
//! concrete type. We want to give special treatment to certain types: in this
-//! case printing out the length of String values prior to their value.
+//! case printing out the length of `String` values prior to their value.
//! We don't know the concrete type of our value at compile time, so we need to
//! use runtime reflection instead.
//!
@@ -51,7 +51,7 @@
//! use std::fmt::Debug;
//! use std::any::Any;
//!
-//! // Logger function for any type that implements Debug.
+//! // Logger function for any type that implements `Debug`.
//! fn log(value: &T) {
//! let value_any = value as &dyn Any;
//!
diff --git a/library/core/src/clone.rs b/library/core/src/clone.rs
index ba86334f950..d448c5338fc 100644
--- a/library/core/src/clone.rs
+++ b/library/core/src/clone.rs
@@ -227,7 +227,7 @@ mod impls {
impl_clone! {
usize u8 u16 u32 u64 u128
isize i8 i16 i32 i64 i128
- f32 f64
+ f16 f32 f64 f128
bool char
}
diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs
index cc9ef673da7..b0c5021022f 100644
--- a/library/core/src/cmp.rs
+++ b/library/core/src/cmp.rs
@@ -1493,7 +1493,7 @@ mod impls {
}
partial_eq_impl! {
- bool char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64
+ bool char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128
}
macro_rules! eq_impl {
@@ -1546,7 +1546,7 @@ mod impls {
}
}
- partial_ord_impl! { f32 f64 }
+ partial_ord_impl! { f16 f32 f64 f128 }
macro_rules! ord_impl {
($($t:ty)*) => ($(
diff --git a/library/core/src/default.rs b/library/core/src/default.rs
index a5075554682..e717a8d022f 100644
--- a/library/core/src/default.rs
+++ b/library/core/src/default.rs
@@ -178,5 +178,9 @@ default_impl! { i32, 0, "Returns the default value of `0`" }
default_impl! { i64, 0, "Returns the default value of `0`" }
default_impl! { i128, 0, "Returns the default value of `0`" }
+#[cfg(not(bootstrap))]
+default_impl! { f16, 0.0f16, "Returns the default value of `0.0`" }
default_impl! { f32, 0.0f32, "Returns the default value of `0.0`" }
default_impl! { f64, 0.0f64, "Returns the default value of `0.0`" }
+#[cfg(not(bootstrap))]
+default_impl! { f128, 0.0f128, "Returns the default value of `0.0`" }
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 18dd3440b6e..0cc3ad1ead7 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -137,6 +137,7 @@
#![feature(const_heap)]
#![feature(const_hint_assert_unchecked)]
#![feature(const_index_range_slice_index)]
+#![feature(const_int_from_str)]
#![feature(const_intrinsic_copy)]
#![feature(const_intrinsic_forget)]
#![feature(const_ipv4)]
@@ -228,6 +229,8 @@
#![feature(doc_notable_trait)]
#![feature(effects)]
#![feature(extern_types)]
+#![feature(f128)]
+#![feature(f16)]
#![feature(freeze_impls)]
#![feature(fundamental)]
#![feature(generic_arg_infer)]
diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs
index a56a2578c22..385c288db12 100644
--- a/library/core/src/marker.rs
+++ b/library/core/src/marker.rs
@@ -422,7 +422,7 @@ marker_impls! {
Copy for
usize, u8, u16, u32, u64, u128,
isize, i8, i16, i32, i64, i128,
- f32, f64,
+ f16, f32, f64, f128,
bool, char,
{T: ?Sized} *const T,
{T: ?Sized} *mut T,
diff --git a/library/core/src/num/error.rs b/library/core/src/num/error.rs
index 14e99578a7c..a2d7e6f7b07 100644
--- a/library/core/src/num/error.rs
+++ b/library/core/src/num/error.rs
@@ -113,8 +113,9 @@ pub enum IntErrorKind {
impl ParseIntError {
/// Outputs the detailed cause of parsing an integer failing.
#[must_use]
+ #[rustc_const_unstable(feature = "const_int_from_str", issue = "59133")]
#[stable(feature = "int_error_matching", since = "1.55.0")]
- pub fn kind(&self) -> &IntErrorKind {
+ pub const fn kind(&self) -> &IntErrorKind {
&self.kind
}
}
diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs
index 2fec8ef2381..2f5184da885 100644
--- a/library/core/src/num/int_macros.rs
+++ b/library/core/src/num/int_macros.rs
@@ -60,32 +60,6 @@ macro_rules! int_impl {
#[stable(feature = "int_bits_const", since = "1.53.0")]
pub const BITS: u32 = <$UnsignedT>::BITS;
- /// Converts a string slice in a given base to an integer.
- ///
- /// The string is expected to be an optional `+` or `-` sign followed by digits.
- /// Leading and trailing whitespace represent an error. Digits are a subset of these characters,
- /// depending on `radix`:
- ///
- /// * `0-9`
- /// * `a-z`
- /// * `A-Z`
- ///
- /// # Panics
- ///
- /// This function panics if `radix` is not in the range from 2 to 36.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- #[doc = concat!("assert_eq!(", stringify!($SelfT), "::from_str_radix(\"A\", 16), Ok(10));")]
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn from_str_radix(src: &str, radix: u32) -> Result {
- from_str_radix(src, radix)
- }
-
/// Returns the number of ones in the binary representation of `self`.
///
/// # Examples
diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs
index 03c977abbbb..9e519dad432 100644
--- a/library/core/src/num/mod.rs
+++ b/library/core/src/num/mod.rs
@@ -6,7 +6,6 @@ use crate::ascii;
use crate::hint;
use crate::intrinsics;
use crate::mem;
-use crate::ops::{Add, Mul, Sub};
use crate::str::FromStr;
// Used because the `?` operator is not allowed in a const context.
@@ -1386,51 +1385,19 @@ pub enum FpCategory {
Normal,
}
-#[doc(hidden)]
-trait FromStrRadixHelper:
- PartialOrd + Copy + Add