Auto merge of #146023 - tgross35:rollup-gbec538, r=tgross35

Rollup of 9 pull requests

Successful merges:

 - rust-lang/rust#145242 (std: use a TAIT to define `SplitPaths` on UNIX)
 - rust-lang/rust#145467 (Stabilize `strict_provenance_atomic_ptr` feature)
 - rust-lang/rust#145756 (str: Stabilize `round_char_boundary` feature)
 - rust-lang/rust#145967 (compiler: Include span of too huge enum with `-Cdebuginfo=2`)
 - rust-lang/rust#145990 (`AutoDeref::final_ty` is already resolved)
 - rust-lang/rust#145991 (std: haiku: fix `B_FIND_PATH_IMAGE_PATH`)
 - rust-lang/rust#146000 (Improve librustdoc error when a file creation/modification failed)
 - rust-lang/rust#146017 (Mark pipe2 supported in Android)
 - rust-lang/rust#146022 (compiler-builtins subtree update)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2025-08-30 01:06:25 +00:00
commit e004014d1b
43 changed files with 201 additions and 138 deletions

View file

@ -19,7 +19,9 @@ use rustc_middle::ty::{
self, AdtKind, CoroutineArgsExt, ExistentialTraitRef, Instance, Ty, TyCtxt, Visibility,
};
use rustc_session::config::{self, DebugInfo, Lto};
use rustc_span::{DUMMY_SP, FileName, FileNameDisplayPreference, SourceFile, Symbol, hygiene};
use rustc_span::{
DUMMY_SP, FileName, FileNameDisplayPreference, SourceFile, Span, Symbol, hygiene,
};
use rustc_symbol_mangling::typeid_for_trait_ref;
use rustc_target::spec::DebuginfoKind;
use smallvec::smallvec;
@ -423,6 +425,14 @@ fn build_slice_type_di_node<'ll, 'tcx>(
/// This function will look up the debuginfo node in the TypeMap. If it can't find it, it
/// will create the node by dispatching to the corresponding `build_*_di_node()` function.
pub(crate) fn type_di_node<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> &'ll DIType {
spanned_type_di_node(cx, t, DUMMY_SP)
}
pub(crate) fn spanned_type_di_node<'ll, 'tcx>(
cx: &CodegenCx<'ll, 'tcx>,
t: Ty<'tcx>,
span: Span,
) -> &'ll DIType {
let unique_type_id = UniqueTypeId::for_ty(cx.tcx, t);
if let Some(existing_di_node) = debug_context(cx).type_map.di_node_for_unique_id(unique_type_id)
@ -460,7 +470,7 @@ pub(crate) fn type_di_node<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) ->
ty::Adt(def, ..) => match def.adt_kind() {
AdtKind::Struct => build_struct_type_di_node(cx, unique_type_id),
AdtKind::Union => build_union_type_di_node(cx, unique_type_id),
AdtKind::Enum => enums::build_enum_type_di_node(cx, unique_type_id),
AdtKind::Enum => enums::build_enum_type_di_node(cx, unique_type_id, span),
},
ty::Tuple(_) => build_tuple_type_di_node(cx, unique_type_id),
_ => bug!("debuginfo: unexpected type in type_di_node(): {:?}", t),

View file

@ -10,7 +10,7 @@ use rustc_middle::bug;
use rustc_middle::mir::CoroutineLayout;
use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
use rustc_middle::ty::{self, AdtDef, CoroutineArgs, CoroutineArgsExt, Ty, VariantDef};
use rustc_span::Symbol;
use rustc_span::{Span, Symbol};
use super::type_map::{DINodeCreationResult, UniqueTypeId};
use super::{SmallVec, size_and_align_of};
@ -30,13 +30,14 @@ mod native;
pub(super) fn build_enum_type_di_node<'ll, 'tcx>(
cx: &CodegenCx<'ll, 'tcx>,
unique_type_id: UniqueTypeId<'tcx>,
span: Span,
) -> DINodeCreationResult<'ll> {
let enum_type = unique_type_id.expect_ty();
let &ty::Adt(enum_adt_def, _) = enum_type.kind() else {
bug!("build_enum_type_di_node() called with non-enum type: `{:?}`", enum_type)
};
let enum_type_and_layout = cx.layout_of(enum_type);
let enum_type_and_layout = cx.spanned_layout_of(enum_type, span);
if wants_c_like_enum_debuginfo(cx.tcx, enum_type_and_layout) {
return build_c_style_enum_di_node(cx, enum_adt_def, enum_type_and_layout);

View file

@ -28,7 +28,9 @@ use rustc_target::spec::DebuginfoKind;
use smallvec::SmallVec;
use tracing::debug;
use self::metadata::{UNKNOWN_COLUMN_NUMBER, UNKNOWN_LINE_NUMBER, file_metadata, type_di_node};
use self::metadata::{
UNKNOWN_COLUMN_NUMBER, UNKNOWN_LINE_NUMBER, file_metadata, spanned_type_di_node, type_di_node,
};
use self::namespace::mangled_name_of_instance;
use self::utils::{DIB, create_DIArray, is_node_local_to_unit};
use crate::builder::Builder;
@ -626,7 +628,7 @@ impl<'ll, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
let loc = self.lookup_debug_loc(span.lo());
let file_metadata = file_metadata(self, &loc.file);
let type_metadata = type_di_node(self, variable_type);
let type_metadata = spanned_type_di_node(self, variable_type, span);
let (argument_index, dwarf_tag) = match variable_kind {
ArgumentVariable(index) => (index as c_uint, DW_TAG_arg_variable),

View file

@ -202,14 +202,10 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> {
Some((normalized_ty, ocx.into_pending_obligations()))
}
/// Returns the final type we ended up with, which may be an inference
/// variable (we will resolve it first, if we want).
pub fn final_ty(&self, resolve: bool) -> Ty<'tcx> {
if resolve {
self.infcx.resolve_vars_if_possible(self.state.cur_ty)
} else {
self.state.cur_ty
}
/// Returns the final type we ended up with, which may be an unresolved
/// inference variable.
pub fn final_ty(&self) -> Ty<'tcx> {
self.state.cur_ty
}
pub fn step_count(&self) -> usize {

View file

@ -42,7 +42,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let mut obligations = PredicateObligations::new();
let targets =
steps.iter().skip(1).map(|&(ty, _)| ty).chain(iter::once(autoderef.final_ty(false)));
steps.iter().skip(1).map(|&(ty, _)| ty).chain(iter::once(autoderef.final_ty()));
let steps: Vec<_> = steps
.iter()
.map(|&(source, kind)| {

View file

@ -86,7 +86,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
result = self.try_overloaded_call_step(call_expr, callee_expr, arg_exprs, &autoderef);
}
match autoderef.final_ty(false).kind() {
match autoderef.final_ty().kind() {
ty::FnDef(def_id, _) => {
let abi = self.tcx.fn_sig(def_id).skip_binder().skip_binder().abi;
self.check_call_abi(abi, call_expr.span);
@ -200,8 +200,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
arg_exprs: &'tcx [hir::Expr<'tcx>],
autoderef: &Autoderef<'a, 'tcx>,
) -> Option<CallStep<'tcx>> {
let adjusted_ty =
self.structurally_resolve_type(autoderef.span(), autoderef.final_ty(false));
let adjusted_ty = self.structurally_resolve_type(autoderef.span(), autoderef.final_ty());
// If the callee is a function pointer or a closure, then we're all set.
match *adjusted_ty.kind() {

View file

@ -2918,7 +2918,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Emits an error if we deref an infer variable, like calling `.field` on a base type
// of `&_`. We can also use this to suppress unnecessary "missing field" errors that
// will follow ambiguity errors.
let final_ty = self.structurally_resolve_type(autoderef.span(), autoderef.final_ty(false));
let final_ty = self.structurally_resolve_type(autoderef.span(), autoderef.final_ty());
if let ty::Error(_) = final_ty.kind() {
return final_ty;
}

View file

@ -629,7 +629,7 @@ pub(crate) fn method_autoderef_steps<'tcx>(
.collect();
(steps, autoderef_via_deref.reached_recursion_limit())
};
let final_ty = autoderef_via_deref.final_ty(true);
let final_ty = autoderef_via_deref.final_ty();
let opt_bad_ty = match final_ty.kind() {
ty::Infer(ty::TyVar(_)) | ty::Error(_) => Some(MethodAutoderefBadTy {
reached_raw_pointer,

View file

@ -109,8 +109,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
index_ty: Ty<'tcx>,
index_expr: &hir::Expr<'_>,
) -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)> {
let adjusted_ty =
self.structurally_resolve_type(autoderef.span(), autoderef.final_ty(false));
let adjusted_ty = self.structurally_resolve_type(autoderef.span(), autoderef.final_ty());
debug!(
"try_index_step(expr={:?}, base_expr={:?}, adjusted_ty={:?}, \
index_ty={:?})",

View file

@ -29,6 +29,7 @@
#![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::direct_use_of_rustc_type_ir)]
#![allow(rustc::untranslatable_diagnostic)]
#![cfg_attr(bootstrap, feature(round_char_boundary))]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(allocator_api)]
@ -51,7 +52,6 @@
#![feature(negative_impls)]
#![feature(never_type)]
#![feature(ptr_alignment_type)]
#![feature(round_char_boundary)]
#![feature(rustc_attrs)]
#![feature(rustdoc_internals)]
#![feature(sized_hierarchy)]

View file

@ -17,6 +17,7 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![cfg_attr(bootstrap, feature(round_char_boundary))]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(array_windows)]
@ -26,7 +27,6 @@
#![feature(map_try_insert)]
#![feature(negative_impls)]
#![feature(read_buf)]
#![feature(round_char_boundary)]
#![feature(rustc_attrs)]
#![feature(rustdoc_internals)]
// tidy-alphabetical-end

View file

@ -24,7 +24,6 @@
#![feature(inplace_iteration)]
#![feature(iter_advance_by)]
#![feature(iter_next_chunk)]
#![feature(round_char_boundary)]
#![feature(slice_partition_dedup)]
#![feature(string_from_utf8_lossy_owned)]
#![feature(string_remove_matches)]

View file

@ -51,8 +51,7 @@ jobs:
- target: aarch64-unknown-linux-gnu
os: ubuntu-24.04-arm
- target: aarch64-pc-windows-msvc
os: windows-2025
build_only: 1
os: windows-11-arm
- target: arm-unknown-linux-gnueabi
os: ubuntu-24.04
- target: arm-unknown-linux-gnueabihf

View file

@ -1,4 +1,3 @@
#![allow(improper_ctypes)]
#![cfg_attr(f128_enabled, feature(f128))]
use builtins_test::float_bench;

View file

@ -1,4 +1,5 @@
#![allow(unused_macros)]
#![cfg_attr(f16_enabled, feature(f16))]
#![cfg_attr(f128_enabled, feature(f128))]
use builtins_test::*;
@ -115,28 +116,25 @@ macro_rules! float_sum {
mod float_addsub {
use super::*;
#[cfg(f16_enabled)]
float_sum! {
f16, __addhf3, __subhf3, Half, all();
}
float_sum! {
f32, __addsf3, __subsf3, Single, all();
f64, __adddf3, __subdf3, Double, all();
}
}
#[cfg(f128_enabled)]
#[cfg(not(x86_no_sse))]
#[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))]
mod float_addsub_f128 {
use super::*;
#[cfg(f128_enabled)]
#[cfg(not(x86_no_sse))]
#[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))]
float_sum! {
f128, __addtf3, __subtf3, Quad, not(feature = "no-sys-f128");
}
}
#[cfg(f128_enabled)]
#[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))]
mod float_addsub_f128_ppc {
use super::*;
#[cfg(f128_enabled)]
#[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))]
float_sum! {
f128, __addkf3, __subkf3, Quad, not(feature = "no-sys-f128");
}

View file

@ -1,5 +1,6 @@
#![allow(unused_macros)]
#![allow(unreachable_code)]
#![cfg_attr(f16_enabled, feature(f16))]
#![cfg_attr(f128_enabled, feature(f128))]
use builtins_test::*;
@ -51,6 +52,26 @@ mod float_comparisons {
};
}
#[test]
#[cfg(f16_enabled)]
fn cmp_f16() {
use compiler_builtins::float::cmp::{
__eqhf2, __gehf2, __gthf2, __lehf2, __lthf2, __nehf2, __unordhf2,
};
fuzz_float_2(N, |x: f16, y: f16| {
assert_eq!(__unordhf2(x, y) != 0, x.is_nan() || y.is_nan());
cmp!(f16, x, y, Half, all(),
1, __lthf2;
1, __lehf2;
1, __eqhf2;
-1, __gehf2;
-1, __gthf2;
1, __nehf2;
);
});
}
#[test]
fn cmp_f32() {
use compiler_builtins::float::cmp::{

View file

@ -1,5 +1,6 @@
#![allow(unused_macros)]
#![cfg_attr(f16_enabled, feature(f16))]
#![cfg_attr(f128_enabled, feature(f128))]
#![allow(unused_macros)]
use builtins_test::*;
@ -117,6 +118,11 @@ macro_rules! float_mul {
mod float_mul {
use super::*;
#[cfg(f16_enabled)]
float_mul! {
f16, __mulhf3, Half, all();
}
// FIXME(#616): Stop ignoring arches that don't have native support once fix for builtins is in
// nightly.
float_mul! {

View file

@ -130,7 +130,7 @@ where
return F::from_bits(MinInt::ZERO);
}
// If partial cancellation occured, we need to left-shift the result
// If partial cancellation occurred, we need to left-shift the result
// and adjust the exponent:
if a_significand < implicit_bit << 3 {
let shift = a_significand.leading_zeros() as i32
@ -191,6 +191,11 @@ where
}
intrinsics! {
#[cfg(f16_enabled)]
pub extern "C" fn __addhf3(a: f16, b: f16) -> f16 {
add(a, b)
}
#[aapcs_on_arm]
#[arm_aeabi_alias = __aeabi_fadd]
pub extern "C" fn __addsf3(a: f32, b: f32) -> f32 {

View file

@ -115,6 +115,37 @@ fn unord<F: Float>(a: F, b: F) -> bool {
a_abs > inf_rep || b_abs > inf_rep
}
#[cfg(f16_enabled)]
intrinsics! {
pub extern "C" fn __lehf2(a: f16, b: f16) -> crate::float::cmp::CmpResult {
cmp(a, b).to_le_abi()
}
pub extern "C" fn __gehf2(a: f16, b: f16) -> crate::float::cmp::CmpResult {
cmp(a, b).to_ge_abi()
}
pub extern "C" fn __unordhf2(a: f16, b: f16) -> crate::float::cmp::CmpResult {
unord(a, b) as crate::float::cmp::CmpResult
}
pub extern "C" fn __eqhf2(a: f16, b: f16) -> crate::float::cmp::CmpResult {
cmp(a, b).to_le_abi()
}
pub extern "C" fn __lthf2(a: f16, b: f16) -> crate::float::cmp::CmpResult {
cmp(a, b).to_le_abi()
}
pub extern "C" fn __nehf2(a: f16, b: f16) -> crate::float::cmp::CmpResult {
cmp(a, b).to_le_abi()
}
pub extern "C" fn __gthf2(a: f16, b: f16) -> crate::float::cmp::CmpResult {
cmp(a, b).to_ge_abi()
}
}
intrinsics! {
pub extern "C" fn __lesf2(a: f32, b: f32) -> crate::float::cmp::CmpResult {
cmp(a, b).to_le_abi()

View file

@ -180,6 +180,11 @@ where
}
intrinsics! {
#[cfg(f16_enabled)]
pub extern "C" fn __mulhf3(a: f16, b: f16) -> f16 {
mul(a, b)
}
#[aapcs_on_arm]
#[arm_aeabi_alias = __aeabi_fmul]
pub extern "C" fn __mulsf3(a: f32, b: f32) -> f32 {

View file

@ -1,6 +1,11 @@
use crate::float::Float;
intrinsics! {
#[cfg(f16_enabled)]
pub extern "C" fn __subhf3(a: f16, b: f16) -> f16 {
crate::float::add::__addhf3(a, f16::from_bits(b.to_bits() ^ f16::SIGN_MASK))
}
#[arm_aeabi_alias = __aeabi_fsub]
pub extern "C" fn __subsf3(a: f32, b: f32) -> f32 {
crate::float::add::__addsf3(a, f32::from_bits(b.to_bits() ^ f32::SIGN_MASK))

View file

@ -18,10 +18,6 @@
#![no_std]
#![allow(unused_features)]
#![allow(internal_features)]
// We use `u128` in a whole bunch of places which we currently agree with the
// compiler on ABIs and such, so we should be "good enough" for now and changes
// to the `u128` ABI will be reflected here.
#![allow(improper_ctypes, improper_ctypes_definitions)]
// `mem::swap` cannot be used because it may generate references to memcpy in unoptimized code.
#![allow(clippy::manual_swap)]
// Support compiling on both stage0 and stage1 which may differ in supported stable features.

View file

@ -73,7 +73,7 @@ pub unsafe extern "custom" fn __rust_probestack() {
// page needed.
//
// Note that we're also testing against `8(%rsp)` to account for the 8
// bytes pushed on the stack orginally with our return address. Using
// bytes pushed on the stack originally with our return address. Using
// `8(%rsp)` simulates us testing the stack pointer in the caller's
// context.

View file

@ -9,7 +9,7 @@ use std::process::{Command, Stdio};
use object::read::archive::{ArchiveFile, ArchiveMember};
use object::{
File as ObjFile, Object, ObjectSymbol, Symbol, SymbolKind, SymbolScope, SymbolSection,
File as ObjFile, Object, ObjectSection, ObjectSymbol, Symbol, SymbolKind, SymbolScope,
};
use serde_json::Value;
@ -154,7 +154,7 @@ struct SymInfo {
name: String,
kind: SymbolKind,
scope: SymbolScope,
section: SymbolSection,
section: String,
is_undefined: bool,
is_global: bool,
is_local: bool,
@ -165,12 +165,22 @@ struct SymInfo {
}
impl SymInfo {
fn new(sym: &Symbol, member: &ArchiveMember) -> Self {
fn new(sym: &Symbol, obj: &ObjFile, member: &ArchiveMember) -> Self {
// Include the section name if possible. Fall back to the `Section` debug impl if not.
let section = sym.section();
let section_name = sym
.section()
.index()
.and_then(|idx| obj.section_by_index(idx).ok())
.and_then(|sec| sec.name().ok())
.map(ToString::to_string)
.unwrap_or_else(|| format!("{section:?}"));
Self {
name: sym.name().expect("missing name").to_owned(),
kind: sym.kind(),
scope: sym.scope(),
section: sym.section(),
section: section_name,
is_undefined: sym.is_undefined(),
is_global: sym.is_global(),
is_local: sym.is_local(),
@ -192,22 +202,27 @@ fn verify_no_duplicates(archive: &Archive) {
let mut dups = Vec::new();
let mut found_any = false;
archive.for_each_symbol(|symbol, member| {
archive.for_each_symbol(|symbol, obj, member| {
// Only check defined globals
if !symbol.is_global() || symbol.is_undefined() {
return;
}
let sym = SymInfo::new(&symbol, member);
let sym = SymInfo::new(&symbol, obj, member);
// x86-32 includes multiple copies of thunk symbols
if sym.name.starts_with("__x86.get_pc_thunk") {
return;
}
// GDB pretty printing symbols may show up more than once but are weak.
if sym.section == ".debug_gdb_scripts" && sym.is_weak {
return;
}
// Windows has symbols for literal numeric constants, string literals, and MinGW pseudo-
// relocations. These are allowed to have repeated definitions.
let win_allowed_dup_pfx = ["__real@", "__xmm@", "??_C@_", ".refptr"];
let win_allowed_dup_pfx = ["__real@", "__xmm@", "__ymm@", "??_C@_", ".refptr"];
if win_allowed_dup_pfx
.iter()
.any(|pfx| sym.name.starts_with(pfx))
@ -244,7 +259,7 @@ fn verify_core_symbols(archive: &Archive) {
let mut undefined = Vec::new();
let mut has_symbols = false;
archive.for_each_symbol(|symbol, member| {
archive.for_each_symbol(|symbol, obj, member| {
has_symbols = true;
// Find only symbols from `core`
@ -252,7 +267,7 @@ fn verify_core_symbols(archive: &Archive) {
return;
}
let sym = SymInfo::new(&symbol, member);
let sym = SymInfo::new(&symbol, obj, member);
if sym.is_undefined {
undefined.push(sym);
} else {
@ -304,9 +319,9 @@ impl Archive {
}
/// For a given archive, do something with each symbol.
fn for_each_symbol(&self, mut f: impl FnMut(Symbol, &ArchiveMember)) {
fn for_each_symbol(&self, mut f: impl FnMut(Symbol, &ObjFile, &ArchiveMember)) {
self.for_each_object(|obj, member| {
obj.symbols().for_each(|sym| f(sym, member));
obj.symbols().for_each(|sym| f(sym, &obj, member));
});
}
}

View file

@ -34,7 +34,7 @@ def eprint(*args, **kwargs):
@dataclass
class Crate:
"""Representation of public interfaces and function defintion locations in
"""Representation of public interfaces and function definition locations in
`libm`.
"""

View file

@ -146,7 +146,7 @@ const PIO2: [f64; 8] = [
// x[i] = floor(z)
// z = (z-x[i])*2**24
//
// y[] ouput result in an array of double precision numbers.
// y[] output result in an array of double precision numbers.
// The dimension of y[] is:
// 24-bit precision 1
// 53-bit precision 2

View file

@ -1 +1 @@
82310651b93a594a3fd69015e1562186a080d94c
d36f964125163c2e698de5559efefb8217b8b7f0

View file

@ -396,7 +396,6 @@ impl str {
/// # Examples
///
/// ```
/// #![feature(round_char_boundary)]
/// let s = "❤️🧡💛💚💙💜";
/// assert_eq!(s.len(), 26);
/// assert!(!s.is_char_boundary(13));
@ -405,7 +404,8 @@ impl str {
/// assert_eq!(closest, 10);
/// assert_eq!(&s[..closest], "❤️🧡");
/// ```
#[unstable(feature = "round_char_boundary", issue = "93743")]
#[stable(feature = "round_char_boundary", since = "CURRENT_RUSTC_VERSION")]
#[rustc_const_stable(feature = "round_char_boundary", since = "CURRENT_RUSTC_VERSION")]
#[inline]
pub const fn floor_char_boundary(&self, index: usize) -> usize {
if index >= self.len() {
@ -439,7 +439,6 @@ impl str {
/// # Examples
///
/// ```
/// #![feature(round_char_boundary)]
/// let s = "❤️🧡💛💚💙💜";
/// assert_eq!(s.len(), 26);
/// assert!(!s.is_char_boundary(13));
@ -448,7 +447,8 @@ impl str {
/// assert_eq!(closest, 14);
/// assert_eq!(&s[..closest], "❤️🧡💛");
/// ```
#[unstable(feature = "round_char_boundary", issue = "93743")]
#[stable(feature = "round_char_boundary", since = "CURRENT_RUSTC_VERSION")]
#[rustc_const_stable(feature = "round_char_boundary", since = "CURRENT_RUSTC_VERSION")]
#[inline]
pub const fn ceil_char_boundary(&self, index: usize) -> usize {
if index >= self.len() {

View file

@ -2199,7 +2199,6 @@ impl<T> AtomicPtr<T> {
/// # Examples
///
/// ```
/// #![feature(strict_provenance_atomic_ptr)]
/// use core::sync::atomic::{AtomicPtr, Ordering};
///
/// let atom = AtomicPtr::<i64>::new(core::ptr::null_mut());
@ -2209,7 +2208,7 @@ impl<T> AtomicPtr<T> {
/// ```
#[inline]
#[cfg(target_has_atomic = "ptr")]
#[unstable(feature = "strict_provenance_atomic_ptr", issue = "99108")]
#[stable(feature = "strict_provenance_atomic_ptr", since = "CURRENT_RUSTC_VERSION")]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
pub fn fetch_ptr_add(&self, val: usize, order: Ordering) -> *mut T {
self.fetch_byte_add(val.wrapping_mul(size_of::<T>()), order)
@ -2240,7 +2239,6 @@ impl<T> AtomicPtr<T> {
/// # Examples
///
/// ```
/// #![feature(strict_provenance_atomic_ptr)]
/// use core::sync::atomic::{AtomicPtr, Ordering};
///
/// let array = [1i32, 2i32];
@ -2254,7 +2252,7 @@ impl<T> AtomicPtr<T> {
/// ```
#[inline]
#[cfg(target_has_atomic = "ptr")]
#[unstable(feature = "strict_provenance_atomic_ptr", issue = "99108")]
#[stable(feature = "strict_provenance_atomic_ptr", since = "CURRENT_RUSTC_VERSION")]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
pub fn fetch_ptr_sub(&self, val: usize, order: Ordering) -> *mut T {
self.fetch_byte_sub(val.wrapping_mul(size_of::<T>()), order)
@ -2279,7 +2277,6 @@ impl<T> AtomicPtr<T> {
/// # Examples
///
/// ```
/// #![feature(strict_provenance_atomic_ptr)]
/// use core::sync::atomic::{AtomicPtr, Ordering};
///
/// let atom = AtomicPtr::<i64>::new(core::ptr::null_mut());
@ -2289,7 +2286,7 @@ impl<T> AtomicPtr<T> {
/// ```
#[inline]
#[cfg(target_has_atomic = "ptr")]
#[unstable(feature = "strict_provenance_atomic_ptr", issue = "99108")]
#[stable(feature = "strict_provenance_atomic_ptr", since = "CURRENT_RUSTC_VERSION")]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
pub fn fetch_byte_add(&self, val: usize, order: Ordering) -> *mut T {
// SAFETY: data races are prevented by atomic intrinsics.
@ -2315,7 +2312,6 @@ impl<T> AtomicPtr<T> {
/// # Examples
///
/// ```
/// #![feature(strict_provenance_atomic_ptr)]
/// use core::sync::atomic::{AtomicPtr, Ordering};
///
/// let mut arr = [0i64, 1];
@ -2325,7 +2321,7 @@ impl<T> AtomicPtr<T> {
/// ```
#[inline]
#[cfg(target_has_atomic = "ptr")]
#[unstable(feature = "strict_provenance_atomic_ptr", issue = "99108")]
#[stable(feature = "strict_provenance_atomic_ptr", since = "CURRENT_RUSTC_VERSION")]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
pub fn fetch_byte_sub(&self, val: usize, order: Ordering) -> *mut T {
// SAFETY: data races are prevented by atomic intrinsics.
@ -2361,7 +2357,6 @@ impl<T> AtomicPtr<T> {
/// # Examples
///
/// ```
/// #![feature(strict_provenance_atomic_ptr)]
/// use core::sync::atomic::{AtomicPtr, Ordering};
///
/// let pointer = &mut 3i64 as *mut i64;
@ -2376,7 +2371,7 @@ impl<T> AtomicPtr<T> {
/// ```
#[inline]
#[cfg(target_has_atomic = "ptr")]
#[unstable(feature = "strict_provenance_atomic_ptr", issue = "99108")]
#[stable(feature = "strict_provenance_atomic_ptr", since = "CURRENT_RUSTC_VERSION")]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
pub fn fetch_or(&self, val: usize, order: Ordering) -> *mut T {
// SAFETY: data races are prevented by atomic intrinsics.
@ -2412,7 +2407,6 @@ impl<T> AtomicPtr<T> {
/// # Examples
///
/// ```
/// #![feature(strict_provenance_atomic_ptr)]
/// use core::sync::atomic::{AtomicPtr, Ordering};
///
/// let pointer = &mut 3i64 as *mut i64;
@ -2426,7 +2420,7 @@ impl<T> AtomicPtr<T> {
/// ```
#[inline]
#[cfg(target_has_atomic = "ptr")]
#[unstable(feature = "strict_provenance_atomic_ptr", issue = "99108")]
#[stable(feature = "strict_provenance_atomic_ptr", since = "CURRENT_RUSTC_VERSION")]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
pub fn fetch_and(&self, val: usize, order: Ordering) -> *mut T {
// SAFETY: data races are prevented by atomic intrinsics.
@ -2462,7 +2456,6 @@ impl<T> AtomicPtr<T> {
/// # Examples
///
/// ```
/// #![feature(strict_provenance_atomic_ptr)]
/// use core::sync::atomic::{AtomicPtr, Ordering};
///
/// let pointer = &mut 3i64 as *mut i64;
@ -2474,7 +2467,7 @@ impl<T> AtomicPtr<T> {
/// ```
#[inline]
#[cfg(target_has_atomic = "ptr")]
#[unstable(feature = "strict_provenance_atomic_ptr", issue = "99108")]
#[stable(feature = "strict_provenance_atomic_ptr", since = "CURRENT_RUSTC_VERSION")]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
pub fn fetch_xor(&self, val: usize, order: Ordering) -> *mut T {
// SAFETY: data races are prevented by atomic intrinsics.

View file

@ -95,7 +95,6 @@
#![feature(std_internals)]
#![feature(step_trait)]
#![feature(str_internals)]
#![feature(strict_provenance_atomic_ptr)]
#![feature(strict_provenance_lints)]
#![feature(test)]
#![feature(trusted_len)]

View file

@ -263,7 +263,6 @@
all(target_vendor = "fortanix", target_env = "sgx"),
feature(slice_index_methods, coerce_unsized, sgx_platform)
)]
#![cfg_attr(any(windows, target_os = "uefi"), feature(round_char_boundary))]
#![cfg_attr(target_family = "wasm", feature(stdarch_wasm_atomic_wait))]
#![cfg_attr(target_arch = "wasm64", feature(simd_wasm64))]
//
@ -371,7 +370,6 @@
#![feature(slice_range)]
#![feature(std_internals)]
#![feature(str_internals)]
#![feature(strict_provenance_atomic_ptr)]
#![feature(sync_unsafe_cell)]
#![feature(temporary_niche_types)]
#![feature(ub_checks)]

View file

@ -16,10 +16,7 @@ use crate::{fmt, io, iter, mem, ptr, slice, str};
const TMPBUF_SZ: usize = 128;
const PATH_SEPARATOR: u8 = cfg_select! {
target_os = "redox" => b';',
_ => b':',
};
const PATH_SEPARATOR: u8 = if cfg!(target_os = "redox") { b';' } else { b':' };
unsafe extern "C" {
#[cfg(not(any(target_os = "dragonfly", target_os = "vxworks", target_os = "rtems")))]
@ -189,33 +186,14 @@ pub fn chdir(p: &path::Path) -> io::Result<()> {
if result == 0 { Ok(()) } else { Err(io::Error::last_os_error()) }
}
pub struct SplitPaths<'a> {
iter: iter::Map<slice::Split<'a, u8, fn(&u8) -> bool>, fn(&'a [u8]) -> PathBuf>,
}
pub type SplitPaths<'a> = impl Iterator<Item = PathBuf>;
#[define_opaque(SplitPaths)]
pub fn split_paths(unparsed: &OsStr) -> SplitPaths<'_> {
fn bytes_to_path(b: &[u8]) -> PathBuf {
PathBuf::from(<OsStr as OsStrExt>::from_bytes(b))
}
fn is_separator(b: &u8) -> bool {
*b == PATH_SEPARATOR
}
let unparsed = unparsed.as_bytes();
SplitPaths {
iter: unparsed
.split(is_separator as fn(&u8) -> bool)
.map(bytes_to_path as fn(&[u8]) -> PathBuf),
}
}
impl<'a> Iterator for SplitPaths<'a> {
type Item = PathBuf;
fn next(&mut self) -> Option<PathBuf> {
self.iter.next()
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
unparsed
.as_bytes()
.split(|&b| b == PATH_SEPARATOR)
.map(|part| PathBuf::from(OsStr::from_bytes(part)))
}
#[derive(Debug)]
@ -469,7 +447,7 @@ pub fn current_exe() -> io::Result<PathBuf> {
unsafe {
let result = libc::find_path(
crate::ptr::null_mut(),
libc::path_base_directory::B_FIND_PATH_IMAGE_PATH,
libc::B_FIND_PATH_IMAGE_PATH,
crate::ptr::null_mut(),
name.as_mut_ptr(),
name.len(),

View file

@ -20,6 +20,7 @@ pub fn anon_pipe() -> io::Result<(AnonPipe, AnonPipe)> {
// and musl 0.9.3, and some other targets also have it.
cfg_select! {
any(
target_os = "android",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "hurd",

View file

@ -1,4 +1,5 @@
// tidy-alphabetical-start
#![cfg_attr(bootstrap, feature(round_char_boundary))]
#![doc(
html_root_url = "https://doc.rust-lang.org/nightly/",
html_playground_url = "https://play.rust-lang.org/"
@ -13,7 +14,6 @@
#![feature(if_let_guard)]
#![feature(iter_advance_by)]
#![feature(iter_intersperse)]
#![feature(round_char_boundary)]
#![feature(rustc_private)]
#![feature(test)]
#![warn(rustc::internal)]
@ -760,7 +760,9 @@ fn run_renderer<
tcx.dcx().struct_fatal(format!("couldn't generate documentation: {}", e.error));
let file = e.file.display().to_string();
if !file.is_empty() {
msg.note(format!("failed to create or modify \"{file}\""));
msg.note(format!("failed to create or modify {e}"));
} else {
msg.note(format!("failed to create or modify file: {e}"));
}
msg.emit();
}

View file

@ -7,7 +7,7 @@
#![feature(iter_intersperse)]
#![feature(iter_partition_in_place)]
#![feature(never_type)]
#![feature(round_char_boundary)]
#![cfg_attr(bootstrap, feature(round_char_boundary))]
#![feature(rustc_private)]
#![feature(stmt_expr_attributes)]
#![feature(unwrap_infallible)]

View file

@ -1,4 +1,3 @@
#![feature(round_char_boundary)]
#![warn(clippy::char_indices_as_byte_indices)]
trait StrExt {

View file

@ -1,4 +1,3 @@
#![feature(round_char_boundary)]
#![warn(clippy::char_indices_as_byte_indices)]
trait StrExt {

View file

@ -1,12 +1,12 @@
error: indexing into a string with a character position where a byte index is expected
--> tests/ui/char_indices_as_byte_indices.rs:13:24
--> tests/ui/char_indices_as_byte_indices.rs:12:24
|
LL | let _ = prim[..idx];
| ^^^
|
= note: a character can take up more than one byte, so they are not interchangeable
note: position comes from the enumerate iterator
--> tests/ui/char_indices_as_byte_indices.rs:12:10
--> tests/ui/char_indices_as_byte_indices.rs:11:10
|
LL | for (idx, _) in prim.chars().enumerate() {
| ^^^ ^^^^^^^^^^^
@ -19,14 +19,14 @@ LL + for (idx, _) in prim.char_indices() {
|
error: passing a character position to a method that expects a byte index
--> tests/ui/char_indices_as_byte_indices.rs:15:23
--> tests/ui/char_indices_as_byte_indices.rs:14:23
|
LL | prim.split_at(idx);
| ^^^
|
= note: a character can take up more than one byte, so they are not interchangeable
note: position comes from the enumerate iterator
--> tests/ui/char_indices_as_byte_indices.rs:12:10
--> tests/ui/char_indices_as_byte_indices.rs:11:10
|
LL | for (idx, _) in prim.chars().enumerate() {
| ^^^ ^^^^^^^^^^^
@ -37,14 +37,14 @@ LL + for (idx, _) in prim.char_indices() {
|
error: passing a character position to a method that expects a byte index
--> tests/ui/char_indices_as_byte_indices.rs:19:49
--> tests/ui/char_indices_as_byte_indices.rs:18:49
|
LL | let _ = prim[..prim.floor_char_boundary(idx)];
| ^^^
|
= note: a character can take up more than one byte, so they are not interchangeable
note: position comes from the enumerate iterator
--> tests/ui/char_indices_as_byte_indices.rs:12:10
--> tests/ui/char_indices_as_byte_indices.rs:11:10
|
LL | for (idx, _) in prim.chars().enumerate() {
| ^^^ ^^^^^^^^^^^
@ -55,14 +55,14 @@ LL + for (idx, _) in prim.char_indices() {
|
error: indexing into a string with a character position where a byte index is expected
--> tests/ui/char_indices_as_byte_indices.rs:29:24
--> tests/ui/char_indices_as_byte_indices.rs:28:24
|
LL | let _ = prim[..c.0];
| ^^^
|
= note: a character can take up more than one byte, so they are not interchangeable
note: position comes from the enumerate iterator
--> tests/ui/char_indices_as_byte_indices.rs:28:9
--> tests/ui/char_indices_as_byte_indices.rs:27:9
|
LL | for c in prim.chars().enumerate() {
| ^ ^^^^^^^^^^^
@ -73,14 +73,14 @@ LL + for c in prim.char_indices() {
|
error: passing a character position to a method that expects a byte index
--> tests/ui/char_indices_as_byte_indices.rs:31:23
--> tests/ui/char_indices_as_byte_indices.rs:30:23
|
LL | prim.split_at(c.0);
| ^^^
|
= note: a character can take up more than one byte, so they are not interchangeable
note: position comes from the enumerate iterator
--> tests/ui/char_indices_as_byte_indices.rs:28:9
--> tests/ui/char_indices_as_byte_indices.rs:27:9
|
LL | for c in prim.chars().enumerate() {
| ^ ^^^^^^^^^^^
@ -91,14 +91,14 @@ LL + for c in prim.char_indices() {
|
error: indexing into a string with a character position where a byte index is expected
--> tests/ui/char_indices_as_byte_indices.rs:36:26
--> tests/ui/char_indices_as_byte_indices.rs:35:26
|
LL | let _ = string[..idx];
| ^^^
|
= note: a character can take up more than one byte, so they are not interchangeable
note: position comes from the enumerate iterator
--> tests/ui/char_indices_as_byte_indices.rs:35:10
--> tests/ui/char_indices_as_byte_indices.rs:34:10
|
LL | for (idx, _) in string.chars().enumerate() {
| ^^^ ^^^^^^^^^^^
@ -109,14 +109,14 @@ LL + for (idx, _) in string.char_indices() {
|
error: passing a character position to a method that expects a byte index
--> tests/ui/char_indices_as_byte_indices.rs:38:25
--> tests/ui/char_indices_as_byte_indices.rs:37:25
|
LL | string.split_at(idx);
| ^^^
|
= note: a character can take up more than one byte, so they are not interchangeable
note: position comes from the enumerate iterator
--> tests/ui/char_indices_as_byte_indices.rs:35:10
--> tests/ui/char_indices_as_byte_indices.rs:34:10
|
LL | for (idx, _) in string.chars().enumerate() {
| ^^^ ^^^^^^^^^^^

View file

@ -2,7 +2,6 @@
//@[tree]compile-flags: -Zmiri-tree-borrows
//@compile-flags: -Zmiri-strict-provenance
#![feature(strict_provenance_atomic_ptr)]
// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
#![allow(static_mut_refs)]

View file

@ -6,7 +6,6 @@
//@ compile-flags: -Copt-level=3 -Cno-prepopulate-passes
#![crate_type = "lib"]
#![feature(strict_provenance_atomic_ptr)]
use std::ptr::without_provenance_mut;
use std::sync::atomic::AtomicPtr;

View file

@ -1,5 +1,5 @@
error: values of the type `Option<TYPE>` are too big for the target architecture
--> $DIR/huge-enum.rs:15:9
--> $DIR/huge-enum.rs:17:9
|
LL | let big: BIG = None;
| ^^^

View file

@ -0,0 +1,8 @@
error: values of the type `Option<TYPE>` are too big for the target architecture
--> $DIR/huge-enum.rs:17:9
|
LL | let big: BIG = None;
| ^^^
error: aborting due to 1 previous error

View file

@ -1,9 +1,11 @@
// FIXME(#61117): Remove revisions once x86_64-gnu-debug CI job sets rust.debuginfo-level-tests=2
// NOTE: The .stderr for both revisions shall be identical.
//@ revisions: no-debuginfo full-debuginfo
//@ build-fail
//@ normalize-stderr: "std::option::Option<\[u32; \d+\]>" -> "TYPE"
//@ normalize-stderr: "\[u32; \d+\]" -> "TYPE"
// FIXME(#61117): Respect debuginfo-level-tests, do not force debuginfo-level=0
//@ compile-flags: -Cdebuginfo=0
//@[no-debuginfo] compile-flags: -Cdebuginfo=0
//@[full-debuginfo] compile-flags: -Cdebuginfo=2
#[cfg(target_pointer_width = "32")]
type BIG = Option<[u32; (1<<29)-1]>;