Auto merge of #146052 - matthiaskrgr:rollup-cfxx9m6, r=matthiaskrgr

Rollup of 4 pull requests

Successful merges:

 - rust-lang/rust#144443 (Make target pointer width in target json an integer)
 - rust-lang/rust#145174 (Ensure consistent drop for panicking drop in hint::select_unpredictable)
 - rust-lang/rust#145592 (Fix format string grammar in docs and improve alignment error message for rust-lang/rust#144023)
 - rust-lang/rust#145931 (Clarify that align_offset overaligns)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors
2025-08-31 11:53:54 +00:00
27 changed files with 123 additions and 55 deletions
+1 -1
View File
@@ -315,7 +315,7 @@ pub enum TargetDataLayoutErrors<'a> {
MissingAlignment { cause: &'a str },
InvalidAlignment { cause: &'a str, err: AlignFromBytesError },
InconsistentTargetArchitecture { dl: &'a str, target: &'a str },
InconsistentTargetPointerWidth { pointer_size: u64, target: u32 },
InconsistentTargetPointerWidth { pointer_size: u64, target: u16 },
InvalidBitsSize { err: String },
UnknownPointerSpecification { err: String },
}
+2 -2
View File
@@ -69,7 +69,7 @@ pub fn bit_width(&self) -> Option<u64> {
})
}
pub fn normalize(&self, target_width: u32) -> Self {
pub fn normalize(&self, target_width: u16) -> Self {
match self {
IntTy::Isize => match target_width {
16 => IntTy::I16,
@@ -148,7 +148,7 @@ pub fn bit_width(&self) -> Option<u64> {
})
}
pub fn normalize(&self, target_width: u32) -> Self {
pub fn normalize(&self, target_width: u16) -> Self {
match self {
UintTy::Usize => match target_width {
16 => UintTy::U16,
@@ -22,5 +22,5 @@
"unix"
],
"target-mcount": "_mcount",
"target-pointer-width": "32"
"target-pointer-width": 32
}
+3 -1
View File
@@ -858,7 +858,9 @@ fn suggest_format_align(&mut self, alignment: char) {
self.errors.insert(
0,
ParseError {
description: "expected format parameter to occur after `:`".to_owned(),
description:
"expected alignment specifier after `:` in format string; example: `{:>?}`"
.to_owned(),
note: None,
label: format!("expected `{}` to occur after `:`", alignment),
span: range,
+10 -15
View File
@@ -25,10 +25,7 @@ pub fn from_json(json: &str) -> Result<(Target, TargetWarnings), String> {
let mut base = Target {
llvm_target: json.llvm_target,
metadata: Default::default(),
pointer_width: json
.target_pointer_width
.parse()
.map_err(|err| format!("invalid target-pointer-width: {err}"))?,
pointer_width: json.target_pointer_width,
data_layout: json.data_layout,
arch: json.arch,
options: Default::default(),
@@ -245,19 +242,17 @@ fn to_json(&self) -> Json {
target.update_to_cli();
macro_rules! target_val {
($attr:ident) => {{
let name = (stringify!($attr)).replace("_", "-");
d.insert(name, target.$attr.to_json());
($attr:ident) => {
target_val!($attr, (stringify!($attr)).replace("_", "-"))
};
($attr:ident, $json_name:expr) => {{
let name = $json_name;
d.insert(name.into(), target.$attr.to_json());
}};
}
macro_rules! target_option_val {
($attr:ident) => {{
let name = (stringify!($attr)).replace("_", "-");
if default.$attr != target.$attr {
d.insert(name, target.$attr.to_json());
}
}};
($attr:ident) => {{ target_option_val!($attr, (stringify!($attr)).replace("_", "-")) }};
($attr:ident, $json_name:expr) => {{
let name = $json_name;
if default.$attr != target.$attr {
@@ -290,7 +285,7 @@ macro_rules! target_option_val {
target_val!(llvm_target);
target_val!(metadata);
d.insert("target-pointer-width".to_string(), self.pointer_width.to_string().to_json());
target_val!(pointer_width, "target-pointer-width");
target_val!(arch);
target_val!(data_layout);
@@ -463,7 +458,7 @@ struct TargetSpecJsonMetadata {
#[serde(deny_unknown_fields)]
struct TargetSpecJson {
llvm_target: StaticCow<str>,
target_pointer_width: String,
target_pointer_width: u16,
data_layout: StaticCow<str>,
arch: StaticCow<str>,
+1 -1
View File
@@ -2331,7 +2331,7 @@ pub struct Target {
/// Used for generating target documentation.
pub metadata: TargetMetadata,
/// Number of bits in a pointer. Influences the `target_pointer_width` `cfg` variable.
pub pointer_width: u32,
pub pointer_width: u16,
/// Architecture to use for ABI considerations. Valid options include: "x86",
/// "x86_64", "arm", "aarch64", "mips", "powerpc", "powerpc64", and others.
pub arch: StaticCow<str>,
+1 -1
View File
@@ -7,7 +7,7 @@ fn report_unused_fields() {
"arch": "powerpc64",
"data-layout": "e-m:e-i64:64-n32:64",
"llvm-target": "powerpc64le-elf",
"target-pointer-width": "64",
"target-pointer-width": 64,
"code-mode": "foo"
}
"#;
+1 -1
View File
@@ -354,7 +354,7 @@
//! sign := '+' | '-'
//! width := count
//! precision := count | '*'
//! type := '?' | 'x?' | 'X?' | identifier
//! type := '?' | 'x?' | 'X?' | 'o' | 'x' | 'X' | 'p' | 'b' | 'e' | 'E'
//! count := parameter | integer
//! parameter := argument '$'
//! ```
@@ -19,5 +19,5 @@
},
"panic-strategy": "abort",
"relocation-model": "static",
"target-pointer-width": "32"
"target-pointer-width": 32
}
+35 -2
View File
@@ -776,12 +776,45 @@ pub fn select_unpredictable<T>(condition: bool, true_val: T, false_val: T) -> T
// Change this to use ManuallyDrop instead.
let mut true_val = MaybeUninit::new(true_val);
let mut false_val = MaybeUninit::new(false_val);
struct DropOnPanic<T> {
// Invariant: valid pointer and points to an initialized value that is not further used,
// i.e. it can be dropped by this guard.
inner: *mut T,
}
impl<T> Drop for DropOnPanic<T> {
fn drop(&mut self) {
// SAFETY: Must be guaranteed on construction of local type `DropOnPanic`.
unsafe { self.inner.drop_in_place() }
}
}
let true_ptr = true_val.as_mut_ptr();
let false_ptr = false_val.as_mut_ptr();
// SAFETY: The value that is not selected is dropped, and the selected one
// is returned. This is necessary because the intrinsic doesn't drop the
// value that is not selected.
unsafe {
crate::intrinsics::select_unpredictable(!condition, &mut true_val, &mut false_val)
.assume_init_drop();
// Extract the selected value first, ensure it is dropped as well if dropping the unselected
// value panics. We construct a temporary by-pointer guard around the selected value while
// dropping the unselected value. Arguments overlap here, so we can not use mutable
// reference for these arguments.
let guard = crate::intrinsics::select_unpredictable(condition, true_ptr, false_ptr);
let drop = crate::intrinsics::select_unpredictable(condition, false_ptr, true_ptr);
// SAFETY: both pointers are well-aligned and point to initialized values inside a
// `MaybeUninit` each. In both possible values for `condition` the pointer `guard` and
// `drop` do not alias (even though the two argument pairs we have selected from did alias
// each other).
let guard = DropOnPanic { inner: guard };
drop.drop_in_place();
crate::mem::forget(guard);
// Note that it is important to use the values here. Reading from the pointer we got makes
// LLVM forget the !unpredictable annotation sometimes (in tests, integer sized values in
// particular seemed to confuse it, also observed in llvm/llvm-project #82340).
crate::intrinsics::select_unpredictable(condition, true_val, false_val).assume_init()
}
}
+2 -3
View File
@@ -2166,10 +2166,9 @@ pub unsafe fn write_volatile<T>(dst: *mut T, src: T) {
}
}
/// Align pointer `p`.
/// Calculate an element-offset that increases a pointer's alignment.
///
/// Calculate offset (in terms of elements of `size_of::<T>()` stride) that has to be applied
/// to pointer `p` so that pointer `p` would get aligned to `a`.
/// Calculate an element-offset (not byte-offset) that when added to a given pointer `p`, increases `p`'s alignment to at least the given alignment `a`.
///
/// # Safety
/// `a` must be a power of two.
+36
View File
@@ -21,3 +21,39 @@ fn drop(&mut self) {
assert!(a_dropped.get());
assert!(b_dropped.get());
}
#[test]
#[should_panic = "message canary"]
fn select_unpredictable_drop_on_panic() {
use core::cell::Cell;
struct X<'a> {
cell: &'a Cell<u16>,
expect: u16,
write: u16,
}
impl Drop for X<'_> {
fn drop(&mut self) {
let value = self.cell.get();
self.cell.set(self.write);
assert_eq!(value, self.expect, "message canary");
}
}
let cell = Cell::new(0);
// Trigger a double-panic if the selected cell was not dropped during panic.
let _armed = X { cell: &cell, expect: 0xdead, write: 0 };
let selected = X { cell: &cell, write: 0xdead, expect: 1 };
let unselected = X { cell: &cell, write: 1, expect: 0xff };
// The correct drop order is:
//
// 1. `unselected` drops, writes 1, and panics as 0 != 0xff
// 2. `selected` drops during unwind, writes 0xdead and does not panic as 1 == 1
// 3. `armed` drops during unwind, writes 0 and does not panic as 0xdead == 0xdead
//
// If `selected` is not dropped, `armed` panics as 1 != 0xdead
let _unreachable = core::hint::select_unpredictable(true, selected, unselected);
}
+2 -1
View File
@@ -2,7 +2,8 @@
set -euo pipefail
LINUX_VERSION=v6.16-rc1
# https://github.com/rust-lang/rust/pull/144443
LINUX_VERSION=7770d51bce622b13195b2d3c85407282fc9c27e5
# Build rustc, rustdoc, cargo, clippy-driver and rustfmt
../x.py build --stage 2 library rustdoc clippy rustfmt
+1 -7
View File
@@ -6,7 +6,6 @@
use build_helper::git::GitConfig;
use camino::{Utf8Path, Utf8PathBuf};
use semver::Version;
use serde::de::{Deserialize, Deserializer, Error as _};
use crate::executor::ColorConfig;
use crate::fatal;
@@ -1072,7 +1071,7 @@ pub struct TargetCfg {
pub(crate) abi: String,
#[serde(rename = "target-family", default)]
pub(crate) families: Vec<String>,
#[serde(rename = "target-pointer-width", deserialize_with = "serde_parse_u32")]
#[serde(rename = "target-pointer-width")]
pub(crate) pointer_width: u32,
#[serde(rename = "target-endian", default)]
endian: Endian,
@@ -1182,11 +1181,6 @@ fn query_rustc_output(config: &Config, args: &[&str], envs: HashMap<String, Stri
String::from_utf8(output.stdout).unwrap()
}
fn serde_parse_u32<'de, D: Deserializer<'de>>(deserializer: D) -> Result<u32, D::Error> {
let string = String::deserialize(deserializer)?;
string.parse().map_err(D::Error::custom)
}
#[derive(Debug, Clone)]
pub struct TestPaths {
pub file: Utf8PathBuf, // e.g., compile-test/foo/bar/baz.rs
@@ -1,7 +1,7 @@
{
"llvm-target": "x86_64-unknown-none",
"target-endian": "little",
"target-pointer-width": "64",
"target-pointer-width": 64,
"target-c-int-width": 32,
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128",
"arch": "x86_64",
@@ -53,5 +53,5 @@
"target-family": [
"unix"
],
"target-pointer-width": "64"
"target-pointer-width": 64
}
@@ -33,5 +33,5 @@
"thread"
],
"target-family": "unix",
"target-pointer-width": "64"
"target-pointer-width": 64
}
@@ -4,7 +4,7 @@
"linker-flavor": "gcc",
"llvm-target": "x86_64-unknown-linux-gnu",
"target-endian": "big",
"target-pointer-width": "64",
"target-pointer-width": 64,
"arch": "x86_64",
"os": "linux"
}
@@ -2,5 +2,5 @@
"arch": "x86_64",
"data-layout": "e-m:e-i64:16:32:64",
"llvm-target": "x86_64-unknown-unknown-gnu",
"target-pointer-width": "64"
"target-pointer-width": 64
}
@@ -3,7 +3,7 @@
"linker-flavor": "gcc",
"llvm-target": "i686-unknown-linux-gnu",
"target-endian": "little",
"target-pointer-width": "32",
"target-pointer-width": 32,
"arch": "x86",
"os": "linux"
}
@@ -2,7 +2,7 @@
"data-layout": "e-p:32:32-f64:32:64-i64:32:64-f80:32:32-n8:16:32",
"linker-flavor": "gcc",
"target-endian": "little",
"target-pointer-width": "32",
"target-pointer-width": 32,
"arch": "x86",
"os": "foo"
}
@@ -4,7 +4,7 @@
"linker-flavor": "gcc",
"llvm-target": "x86_64-unknown-linux-gnu",
"target-endian": "little",
"target-pointer-width": "64",
"target-pointer-width": 64,
"arch": "x86_64",
"os": "linux"
}
@@ -3,7 +3,7 @@
"linker-flavor": "gcc",
"llvm-target": "i686-unknown-linux-gnu",
"target-endian": "little",
"target-pointer-width": "32",
"target-pointer-width": 32,
"arch": "x86",
"os": "linux",
"need-explicit-cpu": true
+1 -1
View File
@@ -3,7 +3,7 @@
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128",
"arch": "x86_64",
"target-endian": "little",
"target-pointer-width": "64",
"target-pointer-width": 64,
"os": "ericos",
"linker-flavor": "ld.lld",
"linker": "rust-lld",
+1 -1
View File
@@ -3,7 +3,7 @@
"data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128",
"arch": "x86_64",
"target-endian": "little",
"target-pointer-width": "64",
"target-pointer-width": 64,
"os": "none",
"linker-flavor": "ld.lld",
"linker": "rust-lld",
+5 -3
View File
@@ -13,9 +13,11 @@ fn main() {
format!("{?:#?}", bar);
//~^ ERROR invalid format string: expected format parameter to occur after `:`
format!("Hello {<5:}!", "x");
//~^ ERROR invalid format string: expected format parameter to occur after `:`
//~^ ERROR invalid format string: expected alignment specifier after `:` in format string; example: `{:>?}`
format!("Hello {^5:}!", "x");
//~^ ERROR invalid format string: expected format parameter to occur after `:`
//~^ ERROR invalid format string: expected alignment specifier after `:` in format string; example: `{:>?}`
format!("Hello {>5:}!", "x");
//~^ ERROR invalid format string: expected format parameter to occur after `:`
//~^ ERROR invalid format string: expected alignment specifier after `:` in format string; example: `{:>?}`
println!("{0:#X>18}", 12345);
//~^ ERROR invalid format string: expected alignment specifier after `:` in format string; example: `{:>?}`
}
+10 -4
View File
@@ -50,23 +50,29 @@ LL | format!("{?:#?}", bar);
|
= note: `?` comes after `:`, try `:?` instead
error: invalid format string: expected format parameter to occur after `:`
error: invalid format string: expected alignment specifier after `:` in format string; example: `{:>?}`
--> $DIR/format-string-wrong-order.rs:15:21
|
LL | format!("Hello {<5:}!", "x");
| ^ expected `<` to occur after `:` in format string
error: invalid format string: expected format parameter to occur after `:`
error: invalid format string: expected alignment specifier after `:` in format string; example: `{:>?}`
--> $DIR/format-string-wrong-order.rs:17:21
|
LL | format!("Hello {^5:}!", "x");
| ^ expected `^` to occur after `:` in format string
error: invalid format string: expected format parameter to occur after `:`
error: invalid format string: expected alignment specifier after `:` in format string; example: `{:>?}`
--> $DIR/format-string-wrong-order.rs:19:21
|
LL | format!("Hello {>5:}!", "x");
| ^ expected `>` to occur after `:` in format string
error: aborting due to 9 previous errors
error: invalid format string: expected alignment specifier after `:` in format string; example: `{:>?}`
--> $DIR/format-string-wrong-order.rs:21:20
|
LL | println!("{0:#X>18}", 12345);
| ^ expected `>` to occur after `:` in format string
error: aborting due to 10 previous errors