Skip to content

Commit 9322d18

Browse files
committed
Auto merge of rust-lang#131690 - matthiaskrgr:rollup-mcau4ol, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - rust-lang#129424 (Stabilize `Pin::as_deref_mut()`) - rust-lang#131332 (Fix clobber_abi and disallow SVE-related registers in Arm64EC inline assembly) - rust-lang#131384 (Update precondition tests (especially for zero-size access to null)) - rust-lang#131430 (Special treatment empty tuple when suggest adding a string literal in format macro.) - rust-lang#131550 (Make some tweaks to extern block diagnostics) - rust-lang#131667 (Fix AArch64InlineAsmReg::emit) - rust-lang#131679 (compiletest: Document various parts of compiletest's `lib.rs`) - rust-lang#131682 (Tag PRs affecting compiletest with `A-compiletest`) Failed merges: - rust-lang#131496 (Stabilise `const_make_ascii`.) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 17a19e6 + ac9b212 commit 9322d18

File tree

69 files changed

+977
-200
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

69 files changed

+977
-200
lines changed

compiler/rustc_ast_passes/messages.ftl

+4-4
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,12 @@ ast_passes_equality_in_where = equality constraints are not yet supported in `wh
6262
6363
ast_passes_extern_block_suggestion = if you meant to declare an externally defined function, use an `extern` block
6464
65-
ast_passes_extern_fn_qualifiers = functions in `extern` blocks cannot have qualifiers
65+
ast_passes_extern_fn_qualifiers = functions in `extern` blocks cannot have `{$kw}` qualifier
6666
.label = in this `extern` block
67-
.suggestion = remove this qualifier
67+
.suggestion = remove the `{$kw}` qualifier
6868
69-
ast_passes_extern_invalid_safety = items in unadorned `extern` blocks cannot have safety qualifiers
70-
.suggestion = add unsafe to this `extern` block
69+
ast_passes_extern_invalid_safety = items in `extern` blocks without an `unsafe` qualifier cannot have safety qualifiers
70+
.suggestion = add `unsafe` to this `extern` block
7171
7272
ast_passes_extern_item_ascii = items in `extern` blocks cannot use non-ascii identifiers
7373
.label = in this `extern` block

compiler/rustc_ast_passes/src/ast_validation.rs

+9-6
Original file line numberDiff line numberDiff line change
@@ -524,21 +524,24 @@ impl<'a> AstValidator<'a> {
524524
// Deconstruct to ensure exhaustiveness
525525
FnHeader { safety: _, coroutine_kind, constness, ext }: FnHeader,
526526
) {
527-
let report_err = |span| {
528-
self.dcx()
529-
.emit_err(errors::FnQualifierInExtern { span, block: self.current_extern_span() });
527+
let report_err = |span, kw| {
528+
self.dcx().emit_err(errors::FnQualifierInExtern {
529+
span,
530+
kw,
531+
block: self.current_extern_span(),
532+
});
530533
};
531534
match coroutine_kind {
532-
Some(knd) => report_err(knd.span()),
535+
Some(kind) => report_err(kind.span(), kind.as_str()),
533536
None => (),
534537
}
535538
match constness {
536-
Const::Yes(span) => report_err(span),
539+
Const::Yes(span) => report_err(span, "const"),
537540
Const::No => (),
538541
}
539542
match ext {
540543
Extern::None => (),
541-
Extern::Implicit(span) | Extern::Explicit(_, span) => report_err(span),
544+
Extern::Implicit(span) | Extern::Explicit(_, span) => report_err(span, "extern"),
542545
}
543546
}
544547

compiler/rustc_ast_passes/src/errors.rs

+1
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,7 @@ pub(crate) struct FnQualifierInExtern {
295295
pub span: Span,
296296
#[label]
297297
pub block: Span,
298+
pub kw: &'static str,
298299
}
299300

300301
#[derive(Diagnostic)]

compiler/rustc_builtin_macros/src/format.rs

+18-4
Original file line numberDiff line numberDiff line change
@@ -195,12 +195,26 @@ fn make_format_args(
195195
Applicability::MaybeIncorrect,
196196
);
197197
} else {
198-
let sugg_fmt = match args.explicit_args().len() {
199-
0 => "{}".to_string(),
200-
count => {
201-
format!("{}{{}}", "{} ".repeat(count))
198+
// `{}` or `()`
199+
let should_suggest = |kind: &ExprKind| -> bool {
200+
match kind {
201+
ExprKind::Block(b, None) if b.stmts.is_empty() => true,
202+
ExprKind::Tup(v) if v.is_empty() => true,
203+
_ => false,
202204
}
203205
};
206+
207+
let mut sugg_fmt = String::new();
208+
for kind in std::iter::once(&efmt.kind)
209+
.chain(args.explicit_args().into_iter().map(|a| &a.expr.kind))
210+
{
211+
sugg_fmt.push_str(if should_suggest(kind) {
212+
"{:?} "
213+
} else {
214+
"{} "
215+
});
216+
}
217+
sugg_fmt = sugg_fmt.trim_end().to_string();
204218
err.span_suggestion(
205219
unexpanded_fmt_span.shrink_to_lo(),
206220
"you might be missing a string literal to format with",

compiler/rustc_codegen_llvm/src/asm.rs

+5-46
Original file line numberDiff line numberDiff line change
@@ -542,57 +542,16 @@ fn xmm_reg_index(reg: InlineAsmReg) -> Option<u32> {
542542

543543
/// If the register is an AArch64 integer register then return its index.
544544
fn a64_reg_index(reg: InlineAsmReg) -> Option<u32> {
545-
use AArch64InlineAsmReg::*;
546-
// Unlike `a64_vreg_index`, we can't subtract `x0` to get the u32 because
547-
// `x19` and `x29` are missing and the integer constants for the
548-
// `x0`..`x30` enum variants don't all match the register number. E.g. the
549-
// integer constant for `x18` is 18, but the constant for `x20` is 19.
550-
Some(match reg {
551-
InlineAsmReg::AArch64(r) => match r {
552-
x0 => 0,
553-
x1 => 1,
554-
x2 => 2,
555-
x3 => 3,
556-
x4 => 4,
557-
x5 => 5,
558-
x6 => 6,
559-
x7 => 7,
560-
x8 => 8,
561-
x9 => 9,
562-
x10 => 10,
563-
x11 => 11,
564-
x12 => 12,
565-
x13 => 13,
566-
x14 => 14,
567-
x15 => 15,
568-
x16 => 16,
569-
x17 => 17,
570-
x18 => 18,
571-
// x19 is reserved
572-
x20 => 20,
573-
x21 => 21,
574-
x22 => 22,
575-
x23 => 23,
576-
x24 => 24,
577-
x25 => 25,
578-
x26 => 26,
579-
x27 => 27,
580-
x28 => 28,
581-
// x29 is reserved
582-
x30 => 30,
583-
_ => return None,
584-
},
585-
_ => return None,
586-
})
545+
match reg {
546+
InlineAsmReg::AArch64(r) => r.reg_index(),
547+
_ => None,
548+
}
587549
}
588550

589551
/// If the register is an AArch64 vector register then return its index.
590552
fn a64_vreg_index(reg: InlineAsmReg) -> Option<u32> {
591-
use AArch64InlineAsmReg::*;
592553
match reg {
593-
InlineAsmReg::AArch64(reg) if reg as u32 >= v0 as u32 && reg as u32 <= v31 as u32 => {
594-
Some(reg as u32 - v0 as u32)
595-
}
554+
InlineAsmReg::AArch64(reg) => reg.vreg_index(),
596555
_ => None,
597556
}
598557
}

compiler/rustc_target/src/asm/aarch64.rs

+76-21
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ impl AArch64InlineAsmRegClass {
6464
neon: I8, I16, I32, I64, F16, F32, F64, F128,
6565
VecI8(8), VecI16(4), VecI32(2), VecI64(1), VecF16(4), VecF32(2), VecF64(1),
6666
VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF16(8), VecF32(4), VecF64(2);
67+
// Note: When adding support for SVE vector types, they must be rejected for Arm64EC.
6768
},
6869
Self::preg => &[],
6970
}
@@ -96,7 +97,7 @@ fn restricted_for_arm64ec(
9697
_is_clobber: bool,
9798
) -> Result<(), &'static str> {
9899
if arch == InlineAsmArch::Arm64EC {
99-
Err("x13, x14, x23, x24, x28, v16-v31 cannot be used for Arm64EC")
100+
Err("x13, x14, x23, x24, x28, v16-v31, p*, ffr cannot be used for Arm64EC")
100101
} else {
101102
Ok(())
102103
}
@@ -165,23 +166,23 @@ def_regs! {
165166
v29: vreg = ["v29", "b29", "h29", "s29", "d29", "q29", "z29"] % restricted_for_arm64ec,
166167
v30: vreg = ["v30", "b30", "h30", "s30", "d30", "q30", "z30"] % restricted_for_arm64ec,
167168
v31: vreg = ["v31", "b31", "h31", "s31", "d31", "q31", "z31"] % restricted_for_arm64ec,
168-
p0: preg = ["p0"],
169-
p1: preg = ["p1"],
170-
p2: preg = ["p2"],
171-
p3: preg = ["p3"],
172-
p4: preg = ["p4"],
173-
p5: preg = ["p5"],
174-
p6: preg = ["p6"],
175-
p7: preg = ["p7"],
176-
p8: preg = ["p8"],
177-
p9: preg = ["p9"],
178-
p10: preg = ["p10"],
179-
p11: preg = ["p11"],
180-
p12: preg = ["p12"],
181-
p13: preg = ["p13"],
182-
p14: preg = ["p14"],
183-
p15: preg = ["p15"],
184-
ffr: preg = ["ffr"],
169+
p0: preg = ["p0"] % restricted_for_arm64ec,
170+
p1: preg = ["p1"] % restricted_for_arm64ec,
171+
p2: preg = ["p2"] % restricted_for_arm64ec,
172+
p3: preg = ["p3"] % restricted_for_arm64ec,
173+
p4: preg = ["p4"] % restricted_for_arm64ec,
174+
p5: preg = ["p5"] % restricted_for_arm64ec,
175+
p6: preg = ["p6"] % restricted_for_arm64ec,
176+
p7: preg = ["p7"] % restricted_for_arm64ec,
177+
p8: preg = ["p8"] % restricted_for_arm64ec,
178+
p9: preg = ["p9"] % restricted_for_arm64ec,
179+
p10: preg = ["p10"] % restricted_for_arm64ec,
180+
p11: preg = ["p11"] % restricted_for_arm64ec,
181+
p12: preg = ["p12"] % restricted_for_arm64ec,
182+
p13: preg = ["p13"] % restricted_for_arm64ec,
183+
p14: preg = ["p14"] % restricted_for_arm64ec,
184+
p15: preg = ["p15"] % restricted_for_arm64ec,
185+
ffr: preg = ["ffr"] % restricted_for_arm64ec,
185186
#error = ["x19", "w19"] =>
186187
"x19 is used internally by LLVM and cannot be used as an operand for inline asm",
187188
#error = ["x29", "w29", "fp", "wfp"] =>
@@ -200,12 +201,66 @@ impl AArch64InlineAsmReg {
200201
_arch: InlineAsmArch,
201202
modifier: Option<char>,
202203
) -> fmt::Result {
203-
let (prefix, index) = if (self as u32) < Self::v0 as u32 {
204-
(modifier.unwrap_or('x'), self as u32 - Self::x0 as u32)
204+
let (prefix, index) = if let Some(index) = self.reg_index() {
205+
(modifier.unwrap_or('x'), index)
206+
} else if let Some(index) = self.vreg_index() {
207+
(modifier.unwrap_or('v'), index)
205208
} else {
206-
(modifier.unwrap_or('v'), self as u32 - Self::v0 as u32)
209+
return out.write_str(self.name());
207210
};
208211
assert!(index < 32);
209212
write!(out, "{prefix}{index}")
210213
}
214+
215+
/// If the register is an integer register then return its index.
216+
pub fn reg_index(self) -> Option<u32> {
217+
// Unlike `vreg_index`, we can't subtract `x0` to get the u32 because
218+
// `x19` and `x29` are missing and the integer constants for the
219+
// `x0`..`x30` enum variants don't all match the register number. E.g. the
220+
// integer constant for `x18` is 18, but the constant for `x20` is 19.
221+
use AArch64InlineAsmReg::*;
222+
Some(match self {
223+
x0 => 0,
224+
x1 => 1,
225+
x2 => 2,
226+
x3 => 3,
227+
x4 => 4,
228+
x5 => 5,
229+
x6 => 6,
230+
x7 => 7,
231+
x8 => 8,
232+
x9 => 9,
233+
x10 => 10,
234+
x11 => 11,
235+
x12 => 12,
236+
x13 => 13,
237+
x14 => 14,
238+
x15 => 15,
239+
x16 => 16,
240+
x17 => 17,
241+
x18 => 18,
242+
// x19 is reserved
243+
x20 => 20,
244+
x21 => 21,
245+
x22 => 22,
246+
x23 => 23,
247+
x24 => 24,
248+
x25 => 25,
249+
x26 => 26,
250+
x27 => 27,
251+
x28 => 28,
252+
// x29 is reserved
253+
x30 => 30,
254+
_ => return None,
255+
})
256+
}
257+
258+
/// If the register is a vector register then return its index.
259+
pub fn vreg_index(self) -> Option<u32> {
260+
use AArch64InlineAsmReg::*;
261+
if self as u32 >= v0 as u32 && self as u32 <= v31 as u32 {
262+
return Some(self as u32 - v0 as u32);
263+
}
264+
None
265+
}
211266
}

compiler/rustc_target/src/asm/mod.rs

+15-2
Original file line numberDiff line numberDiff line change
@@ -890,6 +890,7 @@ pub enum InlineAsmClobberAbi {
890890
Arm,
891891
AArch64,
892892
AArch64NoX18,
893+
Arm64EC,
893894
RiscV,
894895
LoongArch,
895896
S390x,
@@ -932,7 +933,7 @@ impl InlineAsmClobberAbi {
932933
_ => Err(&["C", "system", "efiapi"]),
933934
},
934935
InlineAsmArch::Arm64EC => match name {
935-
"C" | "system" => Ok(InlineAsmClobberAbi::AArch64NoX18),
936+
"C" | "system" => Ok(InlineAsmClobberAbi::Arm64EC),
936937
_ => Err(&["C", "system"]),
937938
},
938939
InlineAsmArch::RiscV32 | InlineAsmArch::RiscV64 => match name {
@@ -1033,7 +1034,6 @@ impl InlineAsmClobberAbi {
10331034
p0, p1, p2, p3, p4, p5, p6, p7,
10341035
p8, p9, p10, p11, p12, p13, p14, p15,
10351036
ffr,
1036-
10371037
}
10381038
},
10391039
InlineAsmClobberAbi::AArch64NoX18 => clobbered_regs! {
@@ -1052,7 +1052,20 @@ impl InlineAsmClobberAbi {
10521052
p0, p1, p2, p3, p4, p5, p6, p7,
10531053
p8, p9, p10, p11, p12, p13, p14, p15,
10541054
ffr,
1055+
}
1056+
},
1057+
InlineAsmClobberAbi::Arm64EC => clobbered_regs! {
1058+
AArch64 AArch64InlineAsmReg {
1059+
// x13 and x14 cannot be used in Arm64EC.
1060+
x0, x1, x2, x3, x4, x5, x6, x7,
1061+
x8, x9, x10, x11, x12, x15,
1062+
x16, x17, x30,
10551063

1064+
// Technically the low 64 bits of v8-v15 are preserved, but
1065+
// we have no way of expressing this using clobbers.
1066+
v0, v1, v2, v3, v4, v5, v6, v7,
1067+
v8, v9, v10, v11, v12, v13, v14, v15,
1068+
// v16-v31, p*, and ffr cannot be used in Arm64EC.
10561069
}
10571070
},
10581071
InlineAsmClobberAbi::Arm => clobbered_regs! {

library/core/src/ascii/ascii_char.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -506,7 +506,7 @@ impl AsciiChar {
506506
pub const unsafe fn digit_unchecked(d: u8) -> Self {
507507
assert_unsafe_precondition!(
508508
check_language_ub,
509-
"`AsciiChar::digit_unchecked` input cannot exceed 9.",
509+
"`ascii::Char::digit_unchecked` input cannot exceed 9.",
510510
(d: u8 = d) => d < 10
511511
);
512512

library/core/src/intrinsics.rs

+12-7
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464
#![allow(missing_docs)]
6565

6666
use crate::marker::{DiscriminantKind, Tuple};
67+
use crate::mem::SizedTypeProperties;
6768
use crate::{ptr, ub_checks};
6869

6970
pub mod mir;
@@ -3364,10 +3365,12 @@ pub const unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: us
33643365
size: usize = size_of::<T>(),
33653366
align: usize = align_of::<T>(),
33663367
count: usize = count,
3367-
) =>
3368-
ub_checks::is_aligned_and_not_null(src, align)
3369-
&& ub_checks::is_aligned_and_not_null(dst, align)
3370-
&& ub_checks::is_nonoverlapping(src, dst, size, count)
3368+
) => {
3369+
let zero_size = count == 0 || size == 0;
3370+
ub_checks::is_aligned_and_not_null(src, align, zero_size)
3371+
&& ub_checks::is_aligned_and_not_null(dst, align, zero_size)
3372+
&& ub_checks::is_nonoverlapping(src, dst, size, count)
3373+
}
33713374
);
33723375

33733376
// SAFETY: the safety contract for `copy_nonoverlapping` must be
@@ -3465,9 +3468,10 @@ pub const unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize) {
34653468
src: *const () = src as *const (),
34663469
dst: *mut () = dst as *mut (),
34673470
align: usize = align_of::<T>(),
3471+
zero_size: bool = T::IS_ZST || count == 0,
34683472
) =>
3469-
ub_checks::is_aligned_and_not_null(src, align)
3470-
&& ub_checks::is_aligned_and_not_null(dst, align)
3473+
ub_checks::is_aligned_and_not_null(src, align, zero_size)
3474+
&& ub_checks::is_aligned_and_not_null(dst, align, zero_size)
34713475
);
34723476
copy(src, dst, count)
34733477
}
@@ -3544,7 +3548,8 @@ pub const unsafe fn write_bytes<T>(dst: *mut T, val: u8, count: usize) {
35443548
(
35453549
addr: *const () = dst as *const (),
35463550
align: usize = align_of::<T>(),
3547-
) => ub_checks::is_aligned_and_not_null(addr, align)
3551+
zero_size: bool = T::IS_ZST || count == 0,
3552+
) => ub_checks::is_aligned_and_not_null(addr, align, zero_size)
35483553
);
35493554
write_bytes(dst, val, count)
35503555
}

library/core/src/pin.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1422,7 +1422,7 @@ impl<Ptr: DerefMut> Pin<Ptr> {
14221422
/// move in the future, and this method does not enable the pointee to move. "Malicious"
14231423
/// implementations of `Ptr::DerefMut` are likewise ruled out by the contract of
14241424
/// `Pin::new_unchecked`.
1425-
#[unstable(feature = "pin_deref_mut", issue = "86918")]
1425+
#[stable(feature = "pin_deref_mut", since = "CURRENT_RUSTC_VERSION")]
14261426
#[must_use = "`self` will be dropped if the result is not used"]
14271427
#[inline(always)]
14281428
pub fn as_deref_mut(self: Pin<&mut Pin<Ptr>>) -> Pin<&mut Ptr::Target> {

0 commit comments

Comments
 (0)