about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_lint/src/for_loops_over_fallibles.rs12
-rw-r--r--compiler/rustc_mir_transform/src/check_unnecessary_transmutes.rs27
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_pc_windows_msvc.rs8
-rw-r--r--src/bootstrap/src/bin/main.rs4
-rw-r--r--src/tools/miri/tests/pass/shims/x86/intrinsics-x86-sse2.rs1
-rw-r--r--tests/ui/lint/for-loops-over-falibles/macro-issue-140747.rs10
-rw-r--r--tests/ui/lint/for-loops-over-falibles/macro-issue-140747.stderr24
-rw-r--r--tests/ui/transmute/unnecessary-transmutation.fixed9
-rw-r--r--tests/ui/transmute/unnecessary-transmutation.rs9
-rw-r--r--tests/ui/transmute/unnecessary-transmutation.stderr54
-rw-r--r--triagebot.toml2
11 files changed, 137 insertions, 23 deletions
diff --git a/compiler/rustc_lint/src/for_loops_over_fallibles.rs b/compiler/rustc_lint/src/for_loops_over_fallibles.rs
index 757fc1f58bd..a56b753bda7 100644
--- a/compiler/rustc_lint/src/for_loops_over_fallibles.rs
+++ b/compiler/rustc_lint/src/for_loops_over_fallibles.rs
@@ -49,6 +49,8 @@ impl<'tcx> LateLintPass<'tcx> for ForLoopsOverFallibles {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
         let Some((pat, arg)) = extract_for_loop(expr) else { return };
 
+        let arg_span = arg.span.source_callsite();
+
         let ty = cx.typeck_results().expr_ty(arg);
 
         let (adt, args, ref_mutability) = match ty.kind() {
@@ -78,27 +80,27 @@ impl<'tcx> LateLintPass<'tcx> for ForLoopsOverFallibles {
             && let Ok(recv_snip) = cx.sess().source_map().span_to_snippet(recv.span)
         {
             ForLoopsOverFalliblesLoopSub::RemoveNext {
-                suggestion: recv.span.between(arg.span.shrink_to_hi()),
+                suggestion: recv.span.between(arg_span.shrink_to_hi()),
                 recv_snip,
             }
         } else {
             ForLoopsOverFalliblesLoopSub::UseWhileLet {
                 start_span: expr.span.with_hi(pat.span.lo()),
-                end_span: pat.span.between(arg.span),
+                end_span: pat.span.between(arg_span),
                 var,
             }
         };
         let question_mark = suggest_question_mark(cx, adt, args, expr.span)
-            .then(|| ForLoopsOverFalliblesQuestionMark { suggestion: arg.span.shrink_to_hi() });
+            .then(|| ForLoopsOverFalliblesQuestionMark { suggestion: arg_span.shrink_to_hi() });
         let suggestion = ForLoopsOverFalliblesSuggestion {
             var,
             start_span: expr.span.with_hi(pat.span.lo()),
-            end_span: pat.span.between(arg.span),
+            end_span: pat.span.between(arg_span),
         };
 
         cx.emit_span_lint(
             FOR_LOOPS_OVER_FALLIBLES,
-            arg.span,
+            arg_span,
             ForLoopsOverFalliblesDiag { article, ref_prefix, ty, sub, question_mark, suggestion },
         );
     }
diff --git a/compiler/rustc_mir_transform/src/check_unnecessary_transmutes.rs b/compiler/rustc_mir_transform/src/check_unnecessary_transmutes.rs
index 4aff127908e..8da17a056e3 100644
--- a/compiler/rustc_mir_transform/src/check_unnecessary_transmutes.rs
+++ b/compiler/rustc_mir_transform/src/check_unnecessary_transmutes.rs
@@ -55,18 +55,45 @@ impl<'a, 'tcx> UnnecessaryTransmuteChecker<'a, 'tcx> {
             },
             // char → u32
             (Char, Uint(UintTy::U32)) => err(format!("u32::from({arg})")),
+            // char (→ u32) → i32
+            (Char, Int(IntTy::I32)) => err(format!("u32::from({arg}).cast_signed()")),
             // u32 → char
             (Uint(UintTy::U32), Char) => Error {
                 sugg: format!("char::from_u32_unchecked({arg})"),
                 help: Some("consider `char::from_u32(…).unwrap()`"),
                 span,
             },
+            // i32 → char
+            (Int(IntTy::I32), Char) => Error {
+                sugg: format!("char::from_u32_unchecked(i32::cast_unsigned({arg}))"),
+                help: Some("consider `char::from_u32(i32::cast_unsigned(…)).unwrap()`"),
+                span,
+            },
             // uNN → iNN
             (Uint(ty), Int(_)) => err(format!("{}::cast_signed({arg})", ty.name_str())),
             // iNN → uNN
             (Int(ty), Uint(_)) => err(format!("{}::cast_unsigned({arg})", ty.name_str())),
+            // fNN → xsize
+            (Float(ty), Uint(UintTy::Usize)) => {
+                err(format!("{}::to_bits({arg}) as usize", ty.name_str()))
+            }
+            (Float(ty), Int(IntTy::Isize)) => {
+                err(format!("{}::to_bits({arg}) as isize", ty.name_str()))
+            }
+            // fNN (→ uNN) → iNN
+            (Float(ty), Int(..)) => err(format!("{}::to_bits({arg}).cast_signed()", ty.name_str())),
             // fNN → uNN
             (Float(ty), Uint(..)) => err(format!("{}::to_bits({arg})", ty.name_str())),
+            // xsize → fNN
+            (Uint(UintTy::Usize) | Int(IntTy::Isize), Float(ty)) => {
+                err(format!("{}::from_bits({arg} as _)", ty.name_str(),))
+            }
+            // iNN (→ uNN) → fNN
+            (Int(int_ty), Float(ty)) => err(format!(
+                "{}::from_bits({}::cast_unsigned({arg}))",
+                ty.name_str(),
+                int_ty.name_str()
+            )),
             // uNN → fNN
             (Uint(_), Float(ty)) => err(format!("{}::from_bits({arg})", ty.name_str())),
             // bool → { x8 }
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_msvc.rs
index 0d25b19f3fc..c5704c57448 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_msvc.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_msvc.rs
@@ -1,10 +1,16 @@
-use crate::spec::{LinkerFlavor, Lld, Target, TargetMetadata, base};
+use crate::spec::{FramePointer, LinkerFlavor, Lld, Target, TargetMetadata, base};
 
 pub(crate) fn target() -> Target {
     let mut base = base::windows_msvc::opts();
     base.max_atomic_width = Some(128);
     base.features = "+v8a,+neon,+fp-armv8".into();
 
+    // Microsoft recommends enabling frame pointers on Arm64 Windows.
+    // From https://learn.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions?view=msvc-170#integer-registers
+    // "The frame pointer (x29) is required for compatibility with fast stack walking used by ETW
+    // and other services. It must point to the previous {x29, x30} pair on the stack."
+    base.frame_pointer = FramePointer::NonLeaf;
+
     // MSVC emits a warning about code that may trip "Cortex-A53 MPCore processor bug #843419" (see
     // https://developer.arm.com/documentation/epm048406/latest) which is sometimes emitted by LLVM.
     // Since Arm64 Windows 10+ isn't supported on that processor, it's safe to disable the warning.
diff --git a/src/bootstrap/src/bin/main.rs b/src/bootstrap/src/bin/main.rs
index cbfe00a757c..833f8027951 100644
--- a/src/bootstrap/src/bin/main.rs
+++ b/src/bootstrap/src/bin/main.rs
@@ -163,7 +163,7 @@ fn check_version(config: &Config) -> Option<String> {
             msg.push_str("WARNING: The `change-id` is missing in the `bootstrap.toml`. This means that you will not be able to track the major changes made to the bootstrap configurations.\n");
             msg.push_str("NOTE: to silence this warning, ");
             msg.push_str(&format!(
-                "add `change-id = {latest_change_id}` or change-id = \"ignore\" at the top of `bootstrap.toml`"
+                "add `change-id = {latest_change_id}` or `change-id = \"ignore\"` at the top of `bootstrap.toml`"
             ));
             return Some(msg);
         }
@@ -195,7 +195,7 @@ fn check_version(config: &Config) -> Option<String> {
 
     msg.push_str("NOTE: to silence this warning, ");
     msg.push_str(&format!(
-        "update `bootstrap.toml` to use `change-id = {latest_change_id}` or change-id = \"ignore\" instead"
+        "update `bootstrap.toml` to use `change-id = {latest_change_id}` or `change-id = \"ignore\"` instead"
     ));
 
     if io::stdout().is_terminal() {
diff --git a/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-sse2.rs b/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-sse2.rs
index 7aaf9c2624f..731d8b57763 100644
--- a/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-sse2.rs
+++ b/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-sse2.rs
@@ -1,5 +1,6 @@
 // We're testing x86 target specific features
 //@only-target: x86_64 i686
+#![allow(unnecessary_transmutes)]
 
 #[cfg(target_arch = "x86")]
 use std::arch::x86::*;
diff --git a/tests/ui/lint/for-loops-over-falibles/macro-issue-140747.rs b/tests/ui/lint/for-loops-over-falibles/macro-issue-140747.rs
new file mode 100644
index 00000000000..33a89ced963
--- /dev/null
+++ b/tests/ui/lint/for-loops-over-falibles/macro-issue-140747.rs
@@ -0,0 +1,10 @@
+#![forbid(for_loops_over_fallibles)]
+
+fn main() {
+    macro_rules! x {
+        () => {
+            None::<i32>
+        };
+    }
+    for _ in x! {} {} //~ ERROR for loop over an `Option`. This is more readably written as an `if let` statement [for_loops_over_fallibles]
+}
diff --git a/tests/ui/lint/for-loops-over-falibles/macro-issue-140747.stderr b/tests/ui/lint/for-loops-over-falibles/macro-issue-140747.stderr
new file mode 100644
index 00000000000..550d26045fb
--- /dev/null
+++ b/tests/ui/lint/for-loops-over-falibles/macro-issue-140747.stderr
@@ -0,0 +1,24 @@
+error: for loop over an `Option`. This is more readably written as an `if let` statement
+  --> $DIR/macro-issue-140747.rs:9:14
+   |
+LL |     for _ in x! {} {}
+   |              ^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/macro-issue-140747.rs:1:11
+   |
+LL | #![forbid(for_loops_over_fallibles)]
+   |           ^^^^^^^^^^^^^^^^^^^^^^^^
+help: to check pattern in a loop use `while let`
+   |
+LL -     for _ in x! {} {}
+LL +     while let Some(_) = x! {} {}
+   |
+help: consider using `if let` to clear intent
+   |
+LL -     for _ in x! {} {}
+LL +     if let Some(_) = x! {} {}
+   |
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/transmute/unnecessary-transmutation.fixed b/tests/ui/transmute/unnecessary-transmutation.fixed
index 1a0df143cc5..bf7d769348a 100644
--- a/tests/ui/transmute/unnecessary-transmutation.fixed
+++ b/tests/ui/transmute/unnecessary-transmutation.fixed
@@ -49,6 +49,10 @@ fn main() {
         //~^ ERROR
         let y: char = char::from_u32_unchecked(y);
         //~^ ERROR
+        let y: i32 = u32::from('🐱').cast_signed();
+        //~^ ERROR
+        let y: char = char::from_u32_unchecked(i32::cast_unsigned(y));
+        //~^ ERROR
 
         let x: u16 = i16::cast_unsigned(8i16);
         //~^ ERROR
@@ -72,6 +76,11 @@ fn main() {
         let y: u64 = f64::to_bits(2.0);
         //~^ ERROR
 
+        let y: f64 = f64::from_bits(i64::cast_unsigned(1i64));
+        //~^ ERROR
+        let y: i64 = f64::to_bits(1f64).cast_signed();
+        //~^ ERROR
+
         let z: bool = (1u8 == 1);
         //~^ ERROR
         let z: u8 = (z) as u8;
diff --git a/tests/ui/transmute/unnecessary-transmutation.rs b/tests/ui/transmute/unnecessary-transmutation.rs
index 6b979263c56..b9de529f1cc 100644
--- a/tests/ui/transmute/unnecessary-transmutation.rs
+++ b/tests/ui/transmute/unnecessary-transmutation.rs
@@ -49,6 +49,10 @@ fn main() {
         //~^ ERROR
         let y: char = transmute(y);
         //~^ ERROR
+        let y: i32 = transmute('🐱');
+        //~^ ERROR
+        let y: char = transmute(y);
+        //~^ ERROR
 
         let x: u16 = transmute(8i16);
         //~^ ERROR
@@ -72,6 +76,11 @@ fn main() {
         let y: u64 = transmute(2.0);
         //~^ ERROR
 
+        let y: f64 = transmute(1i64);
+        //~^ ERROR
+        let y: i64 = transmute(1f64);
+        //~^ ERROR
+
         let z: bool = transmute(1u8);
         //~^ ERROR
         let z: u8 = transmute(z);
diff --git a/tests/ui/transmute/unnecessary-transmutation.stderr b/tests/ui/transmute/unnecessary-transmutation.stderr
index b661aa13c98..a19f1bebf16 100644
--- a/tests/ui/transmute/unnecessary-transmutation.stderr
+++ b/tests/ui/transmute/unnecessary-transmutation.stderr
@@ -154,82 +154,108 @@ LL |         let y: char = transmute(y);
    = help: consider `char::from_u32(…).unwrap()`
 
 error: unnecessary transmute
-  --> $DIR/unnecessary-transmutation.rs:53:22
+  --> $DIR/unnecessary-transmutation.rs:52:22
+   |
+LL |         let y: i32 = transmute('🐱');
+   |                      ^^^^^^^^^^^^^^^ help: replace this with: `u32::from('🐱').cast_signed()`
+
+error: unnecessary transmute
+  --> $DIR/unnecessary-transmutation.rs:54:23
+   |
+LL |         let y: char = transmute(y);
+   |                       ^^^^^^^^^^^^ help: replace this with: `char::from_u32_unchecked(i32::cast_unsigned(y))`
+   |
+   = help: consider `char::from_u32(i32::cast_unsigned(…)).unwrap()`
+
+error: unnecessary transmute
+  --> $DIR/unnecessary-transmutation.rs:57:22
    |
 LL |         let x: u16 = transmute(8i16);
    |                      ^^^^^^^^^^^^^^^ help: replace this with: `i16::cast_unsigned(8i16)`
 
 error: unnecessary transmute
-  --> $DIR/unnecessary-transmutation.rs:55:22
+  --> $DIR/unnecessary-transmutation.rs:59:22
    |
 LL |         let x: i16 = transmute(x);
    |                      ^^^^^^^^^^^^ help: replace this with: `u16::cast_signed(x)`
 
 error: unnecessary transmute
-  --> $DIR/unnecessary-transmutation.rs:57:22
+  --> $DIR/unnecessary-transmutation.rs:61:22
    |
 LL |         let x: u32 = transmute(4i32);
    |                      ^^^^^^^^^^^^^^^ help: replace this with: `i32::cast_unsigned(4i32)`
 
 error: unnecessary transmute
-  --> $DIR/unnecessary-transmutation.rs:59:22
+  --> $DIR/unnecessary-transmutation.rs:63:22
    |
 LL |         let x: i32 = transmute(x);
    |                      ^^^^^^^^^^^^ help: replace this with: `u32::cast_signed(x)`
 
 error: unnecessary transmute
-  --> $DIR/unnecessary-transmutation.rs:61:22
+  --> $DIR/unnecessary-transmutation.rs:65:22
    |
 LL |         let x: u64 = transmute(7i64);
    |                      ^^^^^^^^^^^^^^^ help: replace this with: `i64::cast_unsigned(7i64)`
 
 error: unnecessary transmute
-  --> $DIR/unnecessary-transmutation.rs:63:22
+  --> $DIR/unnecessary-transmutation.rs:67:22
    |
 LL |         let x: i64 = transmute(x);
    |                      ^^^^^^^^^^^^ help: replace this with: `u64::cast_signed(x)`
 
 error: unnecessary transmute
-  --> $DIR/unnecessary-transmutation.rs:66:22
+  --> $DIR/unnecessary-transmutation.rs:70:22
    |
 LL |         let y: f32 = transmute(1u32);
    |                      ^^^^^^^^^^^^^^^ help: replace this with: `f32::from_bits(1u32)`
 
 error: unnecessary transmute
-  --> $DIR/unnecessary-transmutation.rs:68:22
+  --> $DIR/unnecessary-transmutation.rs:72:22
    |
 LL |         let y: u32 = transmute(y);
    |                      ^^^^^^^^^^^^ help: replace this with: `f32::to_bits(y)`
 
 error: unnecessary transmute
-  --> $DIR/unnecessary-transmutation.rs:70:22
+  --> $DIR/unnecessary-transmutation.rs:74:22
    |
 LL |         let y: f64 = transmute(3u64);
    |                      ^^^^^^^^^^^^^^^ help: replace this with: `f64::from_bits(3u64)`
 
 error: unnecessary transmute
-  --> $DIR/unnecessary-transmutation.rs:72:22
+  --> $DIR/unnecessary-transmutation.rs:76:22
    |
 LL |         let y: u64 = transmute(2.0);
    |                      ^^^^^^^^^^^^^^ help: replace this with: `f64::to_bits(2.0)`
 
 error: unnecessary transmute
-  --> $DIR/unnecessary-transmutation.rs:75:23
+  --> $DIR/unnecessary-transmutation.rs:79:22
+   |
+LL |         let y: f64 = transmute(1i64);
+   |                      ^^^^^^^^^^^^^^^ help: replace this with: `f64::from_bits(i64::cast_unsigned(1i64))`
+
+error: unnecessary transmute
+  --> $DIR/unnecessary-transmutation.rs:81:22
+   |
+LL |         let y: i64 = transmute(1f64);
+   |                      ^^^^^^^^^^^^^^^ help: replace this with: `f64::to_bits(1f64).cast_signed()`
+
+error: unnecessary transmute
+  --> $DIR/unnecessary-transmutation.rs:84:23
    |
 LL |         let z: bool = transmute(1u8);
    |                       ^^^^^^^^^^^^^^ help: replace this with: `(1u8 == 1)`
 
 error: unnecessary transmute
-  --> $DIR/unnecessary-transmutation.rs:77:21
+  --> $DIR/unnecessary-transmutation.rs:86:21
    |
 LL |         let z: u8 = transmute(z);
    |                     ^^^^^^^^^^^^ help: replace this with: `(z) as u8`
 
 error: unnecessary transmute
-  --> $DIR/unnecessary-transmutation.rs:82:21
+  --> $DIR/unnecessary-transmutation.rs:91:21
    |
 LL |         let z: i8 = transmute(z);
    |                     ^^^^^^^^^^^^ help: replace this with: `(z) as i8`
 
-error: aborting due to 32 previous errors
+error: aborting due to 36 previous errors
 
diff --git a/triagebot.toml b/triagebot.toml
index b3a319037bd..1f0afdc4442 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -1002,7 +1002,7 @@ message = "This PR changes a file inside `tests/crashes`. If a crash was fixed,
 
 [mentions."tests/rustdoc-json"]
 message = """
-These commits modify `test/rustdoc-json`.
+These commits modify `tests/rustdoc-json`.
 rustdoc-json is a **public** (but unstable) interface.
 
 Please ensure that if you've changed the output: