Skip to content

Commit a8e75c5

Browse files
committed
Auto merge of rust-lang#133135 - jieyouxu:rollup-4q1wbyq, r=jieyouxu
Rollup of 6 pull requests Successful merges: - rust-lang#133029 (ABI checks: add support for some tier3 arches, warn on others.) - rust-lang#133051 (Increase accuracy of `if` condition misparse suggestion) - rust-lang#133060 (Trim whitespace in RemoveLet primary span) - rust-lang#133093 (Let chains tests) - rust-lang#133116 (stabilize const_ptr_is_null) - rust-lang#133126 (alloc: fix `String`'s doc) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 23e7ecb + defc866 commit a8e75c5

Some content is hidden

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

41 files changed

+602
-111
lines changed

Diff for: compiler/rustc_const_eval/src/const_eval/machine.rs

+6
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,12 @@ impl<'tcx> CompileTimeInterpCx<'tcx> {
263263
}
264264

265265
/// See documentation on the `ptr_guaranteed_cmp` intrinsic.
266+
/// Returns `2` if the result is unknown.
267+
/// Returns `1` if the pointers are guaranteed equal.
268+
/// Returns `0` if the pointers are guaranteed inequal.
269+
///
270+
/// Note that this intrinsic is exposed on stable for comparison with null. In other words, any
271+
/// change to this function that affects comparison with null is insta-stable!
266272
fn guaranteed_cmp(&mut self, a: Scalar, b: Scalar) -> InterpResult<'tcx, u8> {
267273
interp_ok(match (a, b) {
268274
// Comparisons between integers are always known.

Diff for: compiler/rustc_monomorphize/src/mono_checks/abi_check.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,7 @@ fn do_check_abi<'tcx>(
3636
target_feature_def: DefId,
3737
mut emit_err: impl FnMut(Option<&'static str>),
3838
) {
39-
let Some(feature_def) = tcx.sess.target.features_for_correct_vector_abi() else {
40-
return;
41-
};
39+
let feature_def = tcx.sess.target.features_for_correct_vector_abi();
4240
let codegen_attrs = tcx.codegen_fn_attrs(target_feature_def);
4341
for arg_abi in abi.args.iter().chain(std::iter::once(&abi.ret)) {
4442
let size = arg_abi.layout.size;

Diff for: compiler/rustc_parse/src/errors.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -650,8 +650,9 @@ pub(crate) struct LeftArrowOperator {
650650
#[diag(parse_remove_let)]
651651
pub(crate) struct RemoveLet {
652652
#[primary_span]
653-
#[suggestion(applicability = "machine-applicable", code = "", style = "verbose")]
654653
pub span: Span,
654+
#[suggestion(applicability = "machine-applicable", code = "", style = "verbose")]
655+
pub suggestion: Span,
655656
}
656657

657658
#[derive(Diagnostic)]

Diff for: compiler/rustc_parse/src/parser/expr.rs

+10-1
Original file line numberDiff line numberDiff line change
@@ -2683,6 +2683,13 @@ impl<'a> Parser<'a> {
26832683
// ^^
26842684
// }
26852685
//
2686+
// We account for macro calls that were meant as conditions as well.
2687+
//
2688+
// if ... {
2689+
// } else if macro! { foo bar } {
2690+
// ^^
2691+
// }
2692+
//
26862693
// If $cond is "statement-like" such as ExprKind::While then we
26872694
// want to suggest wrapping in braces.
26882695
//
@@ -2693,7 +2700,9 @@ impl<'a> Parser<'a> {
26932700
// }
26942701
// ^
26952702
if self.check(&TokenKind::OpenDelim(Delimiter::Brace))
2696-
&& classify::expr_requires_semi_to_be_stmt(&cond) =>
2703+
&& (classify::expr_requires_semi_to_be_stmt(&cond)
2704+
|| matches!(cond.kind, ExprKind::MacCall(..)))
2705+
=>
26972706
{
26982707
self.dcx().emit_err(errors::ExpectedElseBlock {
26992708
first_tok_span,

Diff for: compiler/rustc_parse/src/parser/pat.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -685,7 +685,7 @@ impl<'a> Parser<'a> {
685685
self.bump();
686686
// Trim extra space after the `let`
687687
let span = lo.with_hi(self.token.span.lo());
688-
self.dcx().emit_err(RemoveLet { span });
688+
self.dcx().emit_err(RemoveLet { span: lo, suggestion: span });
689689
lo = self.token.span;
690690
}
691691

Diff for: compiler/rustc_parse/src/parser/stmt.rs

+102-7
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,7 @@ impl<'a> Parser<'a> {
475475
}
476476

477477
fn error_block_no_opening_brace_msg(&mut self, msg: Cow<'static, str>) -> Diag<'a> {
478+
let prev = self.prev_token.span;
478479
let sp = self.token.span;
479480
let mut e = self.dcx().struct_span_err(sp, msg);
480481
let do_not_suggest_help = self.token.is_keyword(kw::In) || self.token == token::Colon;
@@ -514,8 +515,97 @@ impl<'a> Parser<'a> {
514515
} else {
515516
stmt.span
516517
};
518+
self.suggest_fixes_misparsed_for_loop_head(
519+
&mut e,
520+
prev.between(sp),
521+
stmt_span,
522+
&stmt.kind,
523+
);
524+
}
525+
Err(e) => {
526+
self.recover_stmt_(SemiColonMode::Break, BlockMode::Ignore);
527+
e.cancel();
528+
}
529+
_ => {}
530+
}
531+
e.span_label(sp, "expected `{`");
532+
e
533+
}
534+
535+
fn suggest_fixes_misparsed_for_loop_head(
536+
&self,
537+
e: &mut Diag<'_>,
538+
between: Span,
539+
stmt_span: Span,
540+
stmt_kind: &StmtKind,
541+
) {
542+
match (&self.token.kind, &stmt_kind) {
543+
(token::OpenDelim(Delimiter::Brace), StmtKind::Expr(expr))
544+
if let ExprKind::Call(..) = expr.kind =>
545+
{
546+
// for _ in x y() {}
547+
e.span_suggestion_verbose(
548+
between,
549+
"you might have meant to write a method call",
550+
".".to_string(),
551+
Applicability::MaybeIncorrect,
552+
);
553+
}
554+
(token::OpenDelim(Delimiter::Brace), StmtKind::Expr(expr))
555+
if let ExprKind::Field(..) = expr.kind =>
556+
{
557+
// for _ in x y.z {}
558+
e.span_suggestion_verbose(
559+
between,
560+
"you might have meant to write a field access",
561+
".".to_string(),
562+
Applicability::MaybeIncorrect,
563+
);
564+
}
565+
(token::CloseDelim(Delimiter::Brace), StmtKind::Expr(expr))
566+
if let ExprKind::Struct(expr) = &expr.kind
567+
&& let None = expr.qself
568+
&& expr.path.segments.len() == 1 =>
569+
{
570+
// This is specific to "mistyped `if` condition followed by empty body"
571+
//
572+
// for _ in x y {}
573+
e.span_suggestion_verbose(
574+
between,
575+
"you might have meant to write a field access",
576+
".".to_string(),
577+
Applicability::MaybeIncorrect,
578+
);
579+
}
580+
(token::OpenDelim(Delimiter::Brace), StmtKind::Expr(expr))
581+
if let ExprKind::Lit(lit) = expr.kind
582+
&& let None = lit.suffix
583+
&& let token::LitKind::Integer | token::LitKind::Float = lit.kind =>
584+
{
585+
// for _ in x 0 {}
586+
// for _ in x 0.0 {}
587+
e.span_suggestion_verbose(
588+
between,
589+
format!("you might have meant to write a field access"),
590+
".".to_string(),
591+
Applicability::MaybeIncorrect,
592+
);
593+
}
594+
(token::OpenDelim(Delimiter::Brace), StmtKind::Expr(expr))
595+
if let ExprKind::Loop(..)
596+
| ExprKind::If(..)
597+
| ExprKind::While(..)
598+
| ExprKind::Match(..)
599+
| ExprKind::ForLoop { .. }
600+
| ExprKind::TryBlock(..)
601+
| ExprKind::Ret(..)
602+
| ExprKind::Closure(..)
603+
| ExprKind::Struct(..)
604+
| ExprKind::Try(..) = expr.kind =>
605+
{
606+
// These are more likely to have been meant as a block body.
517607
e.multipart_suggestion(
518-
"try placing this code inside a block",
608+
"you might have meant to write this as part of a block",
519609
vec![
520610
(stmt_span.shrink_to_lo(), "{ ".to_string()),
521611
(stmt_span.shrink_to_hi(), " }".to_string()),
@@ -524,14 +614,19 @@ impl<'a> Parser<'a> {
524614
Applicability::MaybeIncorrect,
525615
);
526616
}
527-
Err(e) => {
528-
self.recover_stmt_(SemiColonMode::Break, BlockMode::Ignore);
529-
e.cancel();
617+
(token::OpenDelim(Delimiter::Brace), _) => {}
618+
(_, _) => {
619+
e.multipart_suggestion(
620+
"you might have meant to write this as part of a block",
621+
vec![
622+
(stmt_span.shrink_to_lo(), "{ ".to_string()),
623+
(stmt_span.shrink_to_hi(), " }".to_string()),
624+
],
625+
// Speculative; has been misleading in the past (#46836).
626+
Applicability::MaybeIncorrect,
627+
);
530628
}
531-
_ => {}
532629
}
533-
e.span_label(sp, "expected `{`");
534-
e
535630
}
536631

537632
fn error_block_no_opening_brace<T>(&mut self) -> PResult<'a, T> {

Diff for: compiler/rustc_target/src/target_features.rs

+23-14
Original file line numberDiff line numberDiff line change
@@ -598,7 +598,12 @@ const S390X_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[
598598
const RISCV_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] =
599599
&[/*(64, "zvl64b"), */ (128, "v")];
600600
// Always warn on SPARC, as the necessary target features cannot be enabled in Rust at the moment.
601-
const SPARC_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[/*(128, "vis")*/];
601+
const SPARC_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[/*(64, "vis")*/];
602+
603+
const HEXAGON_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] =
604+
&[/*(512, "hvx-length64b"),*/ (1024, "hvx-length128b")];
605+
const MIPS_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "msa")];
606+
const CSKY_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "vdspv1")];
602607

603608
impl super::spec::Target {
604609
pub fn rust_target_features(&self) -> &'static [(&'static str, Stability, ImpliedFeatures)] {
@@ -620,20 +625,24 @@ impl super::spec::Target {
620625
}
621626
}
622627

623-
// Returns None if we do not support ABI checks on the given target yet.
624-
pub fn features_for_correct_vector_abi(&self) -> Option<&'static [(u64, &'static str)]> {
628+
pub fn features_for_correct_vector_abi(&self) -> &'static [(u64, &'static str)] {
625629
match &*self.arch {
626-
"x86" | "x86_64" => Some(X86_FEATURES_FOR_CORRECT_VECTOR_ABI),
627-
"aarch64" | "arm64ec" => Some(AARCH64_FEATURES_FOR_CORRECT_VECTOR_ABI),
628-
"arm" => Some(ARM_FEATURES_FOR_CORRECT_VECTOR_ABI),
629-
"powerpc" | "powerpc64" => Some(POWERPC_FEATURES_FOR_CORRECT_VECTOR_ABI),
630-
"loongarch64" => Some(&[]), // on-stack ABI, so we complain about all by-val vectors
631-
"riscv32" | "riscv64" => Some(RISCV_FEATURES_FOR_CORRECT_VECTOR_ABI),
632-
"wasm32" | "wasm64" => Some(WASM_FEATURES_FOR_CORRECT_VECTOR_ABI),
633-
"s390x" => Some(S390X_FEATURES_FOR_CORRECT_VECTOR_ABI),
634-
"sparc" | "sparc64" => Some(SPARC_FEATURES_FOR_CORRECT_VECTOR_ABI),
635-
// FIXME: add support for non-tier2 architectures
636-
_ => None,
630+
"x86" | "x86_64" => X86_FEATURES_FOR_CORRECT_VECTOR_ABI,
631+
"aarch64" | "arm64ec" => AARCH64_FEATURES_FOR_CORRECT_VECTOR_ABI,
632+
"arm" => ARM_FEATURES_FOR_CORRECT_VECTOR_ABI,
633+
"powerpc" | "powerpc64" => POWERPC_FEATURES_FOR_CORRECT_VECTOR_ABI,
634+
"loongarch64" => &[], // on-stack ABI, so we complain about all by-val vectors
635+
"riscv32" | "riscv64" => RISCV_FEATURES_FOR_CORRECT_VECTOR_ABI,
636+
"wasm32" | "wasm64" => WASM_FEATURES_FOR_CORRECT_VECTOR_ABI,
637+
"s390x" => S390X_FEATURES_FOR_CORRECT_VECTOR_ABI,
638+
"sparc" | "sparc64" => SPARC_FEATURES_FOR_CORRECT_VECTOR_ABI,
639+
"hexagon" => HEXAGON_FEATURES_FOR_CORRECT_VECTOR_ABI,
640+
"mips" | "mips32r6" | "mips64" | "mips64r6" => MIPS_FEATURES_FOR_CORRECT_VECTOR_ABI,
641+
"bpf" => &[], // no vector ABI
642+
"csky" => CSKY_FEATURES_FOR_CORRECT_VECTOR_ABI,
643+
// FIXME: for some tier3 targets, we are overly cautious and always give warnings
644+
// when passing args in vector registers.
645+
_ => &[],
637646
}
638647
}
639648

Diff for: library/alloc/src/string.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ use crate::vec::Vec;
116116
/// `String`s are always valid UTF-8. If you need a non-UTF-8 string, consider
117117
/// [`OsString`]. It is similar, but without the UTF-8 constraint. Because UTF-8
118118
/// is a variable width encoding, `String`s are typically smaller than an array of
119-
/// the same `chars`:
119+
/// the same `char`s:
120120
///
121121
/// ```
122122
/// use std::mem;

Diff for: library/core/src/intrinsics/mod.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -3292,8 +3292,8 @@ pub const unsafe fn ptr_offset_from_unsigned<T>(_ptr: *const T, _base: *const T)
32923292

32933293
/// See documentation of `<*const T>::guaranteed_eq` for details.
32943294
/// Returns `2` if the result is unknown.
3295-
/// Returns `1` if the pointers are guaranteed equal
3296-
/// Returns `0` if the pointers are guaranteed inequal
3295+
/// Returns `1` if the pointers are guaranteed equal.
3296+
/// Returns `0` if the pointers are guaranteed inequal.
32973297
#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_raw_ptr_comparison", issue = "53020"))]
32983298
#[rustc_intrinsic]
32993299
#[rustc_nounwind]
@@ -4014,9 +4014,9 @@ pub const unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: us
40144014
count: usize = count,
40154015
) => {
40164016
let zero_size = count == 0 || size == 0;
4017-
ub_checks::is_aligned_and_not_null(src, align, zero_size)
4018-
&& ub_checks::is_aligned_and_not_null(dst, align, zero_size)
4019-
&& ub_checks::is_nonoverlapping(src, dst, size, count)
4017+
ub_checks::maybe_is_aligned_and_not_null(src, align, zero_size)
4018+
&& ub_checks::maybe_is_aligned_and_not_null(dst, align, zero_size)
4019+
&& ub_checks::maybe_is_nonoverlapping(src, dst, size, count)
40204020
}
40214021
);
40224022

@@ -4120,8 +4120,8 @@ pub const unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize) {
41204120
align: usize = align_of::<T>(),
41214121
zero_size: bool = T::IS_ZST || count == 0,
41224122
) =>
4123-
ub_checks::is_aligned_and_not_null(src, align, zero_size)
4124-
&& ub_checks::is_aligned_and_not_null(dst, align, zero_size)
4123+
ub_checks::maybe_is_aligned_and_not_null(src, align, zero_size)
4124+
&& ub_checks::maybe_is_aligned_and_not_null(dst, align, zero_size)
41254125
);
41264126
copy(src, dst, count)
41274127
}
@@ -4202,7 +4202,7 @@ pub const unsafe fn write_bytes<T>(dst: *mut T, val: u8, count: usize) {
42024202
addr: *const () = dst as *const (),
42034203
align: usize = align_of::<T>(),
42044204
zero_size: bool = T::IS_ZST || count == 0,
4205-
) => ub_checks::is_aligned_and_not_null(addr, align, zero_size)
4205+
) => ub_checks::maybe_is_aligned_and_not_null(addr, align, zero_size)
42064206
);
42074207
write_bytes(dst, val, count)
42084208
}

Diff for: library/core/src/lib.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@
109109
// tidy-alphabetical-start
110110
#![cfg_attr(bootstrap, feature(const_exact_div))]
111111
#![cfg_attr(bootstrap, feature(const_fmt_arguments_new))]
112+
#![cfg_attr(bootstrap, feature(const_ub_checks))]
112113
#![feature(array_ptr_get)]
113114
#![feature(asm_experimental_arch)]
114115
#![feature(const_align_of_val)]
@@ -121,7 +122,6 @@
121122
#![feature(const_heap)]
122123
#![feature(const_nonnull_new)]
123124
#![feature(const_pin_2)]
124-
#![feature(const_ptr_is_null)]
125125
#![feature(const_ptr_sub_ptr)]
126126
#![feature(const_raw_ptr_comparison)]
127127
#![feature(const_size_of_val)]
@@ -132,7 +132,6 @@
132132
#![feature(const_type_id)]
133133
#![feature(const_type_name)]
134134
#![feature(const_typed_swap)]
135-
#![feature(const_ub_checks)]
136135
#![feature(core_intrinsics)]
137136
#![feature(coverage_attribute)]
138137
#![feature(do_not_recommend)]

Diff for: library/core/src/ptr/const_ptr.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,18 @@ impl<T: ?Sized> *const T {
2929
/// assert!(!ptr.is_null());
3030
/// ```
3131
#[stable(feature = "rust1", since = "1.0.0")]
32-
#[rustc_const_unstable(feature = "const_ptr_is_null", issue = "74939")]
32+
#[rustc_const_stable(feature = "const_ptr_is_null", since = "CURRENT_RUSTC_VERSION")]
3333
#[rustc_diagnostic_item = "ptr_const_is_null"]
3434
#[inline]
35+
#[rustc_allow_const_fn_unstable(const_eval_select)]
3536
pub const fn is_null(self) -> bool {
3637
// Compare via a cast to a thin pointer, so fat pointers are only
3738
// considering their "data" part for null-ness.
3839
let ptr = self as *const u8;
3940
const_eval_select!(
4041
@capture { ptr: *const u8 } -> bool:
41-
if const #[rustc_const_unstable(feature = "const_ptr_is_null", issue = "74939")] {
42+
// This use of `const_raw_ptr_comparison` has been explicitly blessed by t-lang.
43+
if const #[rustc_allow_const_fn_unstable(const_raw_ptr_comparison)] {
4244
match (ptr).guaranteed_eq(null_mut()) {
4345
Some(res) => res,
4446
// To remain maximally convervative, we stop execution when we don't
@@ -280,7 +282,7 @@ impl<T: ?Sized> *const T {
280282
/// }
281283
/// ```
282284
#[stable(feature = "ptr_as_ref", since = "1.9.0")]
283-
#[rustc_const_unstable(feature = "const_ptr_is_null", issue = "74939")]
285+
#[rustc_const_stable(feature = "const_ptr_is_null", since = "CURRENT_RUSTC_VERSION")]
284286
#[inline]
285287
pub const unsafe fn as_ref<'a>(self) -> Option<&'a T> {
286288
// SAFETY: the caller must guarantee that `self` is valid

0 commit comments

Comments
 (0)