Repository: rust-lang/rust
Pull request #138484: Use lit span when suggesting suffix lit cast
Author: login: xizheyin
Labels: name: T-compiler
description: Relevant to the compiler team, which will review and decide on the PR/issue.
name: S-waiting-on-bors
description: Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Created: 2025-03-14T08:10:32Z | Merged: 2025-03-16T05:16:07Z

Fixes #138392 


Linked issue #138392: Integer literal type suggestions do not account for parentheses
### Code

```Rust
fn main() {
    let x: u8 = (4i32);
}
```

### Current output

```Shell
error[E0308]: mismatched types
 --> src/main.rs:2:17
  |
2 |     let x: u8 = (4i32);
  |            --   ^^^^^^ expected `u8`, found `i32`
  |            |
  |            expected due to this
  |
help: change the type of the numeric literal from `i32` to `u8`
  |
2 |     let x: u8 = (4i32)u8;
  |                       ++
```

### Desired output

```Shell
error[E0308]: mismatched types
 --> src/main.rs:2:17
  |
2 |     let x: u8 = (4i32);
  |            --   ^^^^^^ expected `u8`, found `i32`
  |            |
  |            expected due to this
  |
help: change the type of the numeric literal from `i32` to `u8`
  |
2 |     let x: u8 = 4u8;
  |
```

### Rationale and extra context

_No response_

### Other cases

```Rust

```

### Rust Version

```Shell
1.87.0-nightly

(2025-03-11 6650252439d4e03368b3)
```

### Anything else?

_No response_

<!-- TRIAGEBOT_START -->

<!-- TRIAGEBOT_ASSIGN_START -->

<!-- TRIAGEBOT_ASSIGN_DATA_START$${"user":"xizheyin"}$$TRIAGEBOT_ASSIGN_DATA_END -->

<!-- TRIAGEBOT_ASSIGN_END -->
<!-- TRIAGEBOT_END -->
Linked issue comments: user: login: xizheyin
created_at: 2025-03-14T07:22:36Z
body: @rustbot claim
author_association: MEMBER

Diff:
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
index 37aaaed5477dd..f19e36206a7f5 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
@@ -2983,7 +2983,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             return false;
         }
 
-        let Ok(src) = self.tcx.sess.source_map().span_to_snippet(expr.span) else {
+        let span = if let hir::ExprKind::Lit(lit) = &expr.kind { lit.span } else { expr.span };
+        let Ok(src) = self.tcx.sess.source_map().span_to_snippet(span) else {
             return false;
         };
 
@@ -3078,10 +3079,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 // Remove fractional part from literal, for example `42.0f32` into `42`
                 let src = src.trim_end_matches(&checked_ty.to_string());
                 let len = src.split('.').next().unwrap().len();
-                expr.span.with_lo(expr.span.lo() + BytePos(len as u32))
+                span.with_lo(span.lo() + BytePos(len as u32))
             } else {
                 let len = src.trim_end_matches(&checked_ty.to_string()).len();
-                expr.span.with_lo(expr.span.lo() + BytePos(len as u32))
+                span.with_lo(span.lo() + BytePos(len as u32))
             },
             if expr.precedence() < ExprPrecedence::Unambiguous {
                 // Readd `)`
diff --git a/tests/ui/cast/cast_lit_suffix-issue-138392.fixed b/tests/ui/cast/cast_lit_suffix-issue-138392.fixed
new file mode 100644
index 0000000000000..c6fbd09f89c51
--- /dev/null
+++ b/tests/ui/cast/cast_lit_suffix-issue-138392.fixed
@@ -0,0 +1,6 @@
+//@ run-rustfix
+#![allow(unused_parens)]
+fn main() {
+    let _x: u8 = (4u8); //~ ERROR: mismatched types
+    let _y: u8 = (4u8); //~ ERROR: mismatched types
+}
diff --git a/tests/ui/cast/cast_lit_suffix-issue-138392.rs b/tests/ui/cast/cast_lit_suffix-issue-138392.rs
new file mode 100644
index 0000000000000..86dbbbbf12628
--- /dev/null
+++ b/tests/ui/cast/cast_lit_suffix-issue-138392.rs
@@ -0,0 +1,6 @@
+//@ run-rustfix
+#![allow(unused_parens)]
+fn main() {
+    let _x: u8 = (4i32); //~ ERROR: mismatched types
+    let _y: u8 = (4.0f32); //~ ERROR: mismatched types
+}
diff --git a/tests/ui/cast/cast_lit_suffix-issue-138392.stderr b/tests/ui/cast/cast_lit_suffix-issue-138392.stderr
new file mode 100644
index 0000000000000..998fcfc36dc3f
--- /dev/null
+++ b/tests/ui/cast/cast_lit_suffix-issue-138392.stderr
@@ -0,0 +1,31 @@
+error[E0308]: mismatched types
+  --> $DIR/cast_lit_suffix-issue-138392.rs:4:18
+   |
+LL |     let _x: u8 = (4i32);
+   |             --   ^^^^^^ expected `u8`, found `i32`
+   |             |
+   |             expected due to this
+   |
+help: change the type of the numeric literal from `i32` to `u8`
+   |
+LL -     let _x: u8 = (4i32);
+LL +     let _x: u8 = (4u8);
+   |
+
+error[E0308]: mismatched types
+  --> $DIR/cast_lit_suffix-issue-138392.rs:5:18
+   |
+LL |     let _y: u8 = (4.0f32);
+   |             --   ^^^^^^^^ expected `u8`, found `f32`
+   |             |
+   |             expected due to this
+   |
+help: change the type of the numeric literal from `f32` to `u8`
+   |
+LL -     let _y: u8 = (4.0f32);
+LL +     let _y: u8 = (4u8);
+   |
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.


Reviews:
user: login: jieyouxu
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-14T09:34:55Z
user: login: xizheyin
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-14T10:16:15Z
user: login: jieyouxu
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-14T10:23:19Z
user: login: xizheyin
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-14T10:38:49Z
user: login: jieyouxu
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-14T11:12:54Z
user: login: xizheyin
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-14T12:45:22Z
user: login: compiler-errors
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-03-15T18:04:08Z

Review comments:
path: tests/ui/cast/cast_lit_suffix-issue-138392.rs
user: login: jieyouxu
body: Suggestion: since this is exercising a suggestion to check that it produces sth reasonable, run rustfix on it

```
//@ run-rustfix
```
created_at: 2025-03-14T09:34:55Z
author_association: MEMBER
path: tests/ui/cast/cast_lit_suffix-issue-138392.rs
user: login: xizheyin
body: Thank you. But I have a question, after it applies the suggestion, it produces a warning. But the warning is necessary because this bracket is one of the reasons why the bug occurs. How should this situation be handled?
```
warning: unnecessary parentheses around assigned value
  --> /home/nju/rust/tests/ui/cast/cast_lit_suffix-issue-138392.fixed:4:18
   |
LL |     let _y: u8 = (4u8); //~ ERROR: mismatched types
   |                  ^   ^
   |
help: remove these parentheses
   |
LL -     let _y: u8 = (4u8); //~ ERROR: mismatched types
LL +     let _y: u8 = 4u8; //~ ERROR: mismatched types
   |
```
created_at: 2025-03-14T10:16:15Z
author_association: MEMBER
path: tests/ui/cast/cast_lit_suffix-issue-138392.rs
user: login: jieyouxu
body: Can you elaborate what you mean by

> But the warning is necessary because this bracket is one of the reasons why the bug occurs.
created_at: 2025-03-14T10:23:19Z
author_association: MEMBER
path: tests/ui/cast/cast_lit_suffix-issue-138392.rs
user: login: xizheyin
body: The buggy code is
```
let _x: u8 = (4i32); //~ ERROR: mismatched types
```
After fixing the error suggestion, it become
```
let _x: u8 = (4u8); //~ ERROR: mismatched types
```
However, it still has the warning:
```
warning: unnecessary parentheses around assigned value
  --> /home/nju/rust/tests/ui/cast/cast_lit_suffix-issue-138392.fixed:4:18
   |
LL |     let _x: u8 = (4u8); //~ ERROR: mismatched types
   |                  ^   ^
   |
help: remove these parentheses
   |
LL -     let _x: u8 = (4u8); //~ ERROR: mismatched types
LL +     let _x: u8 = 4u8; //~ ERROR: mismatched types
   |
```
So, it can not pass the test.

created_at: 2025-03-14T10:38:49Z
author_association: MEMBER
path: tests/ui/cast/cast_lit_suffix-issue-138392.rs
user: login: jieyouxu
body: Oh. In this case, I would consider slapping an `#![allow(unused_parens)]` because you're testing the suggestion for the mismatched types *error* and not the `unused_parens` lint.
created_at: 2025-03-14T11:12:54Z
author_association: MEMBER
path: tests/ui/cast/cast_lit_suffix-issue-138392.rs
user: login: xizheyin
body: Oh! Thanks!
created_at: 2025-03-14T12:45:22Z
author_association: MEMBER

PR comments:
user: login: rustbot
created_at: 2025-03-14T08:10:36Z
body: r? @wesleywiser

rustbot has assigned @wesleywiser.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use `r?` to explicitly pick a reviewer
author_association: COLLABORATOR
user: login: compiler-errors
created_at: 2025-03-15T18:04:14Z
body: @bors r+ rollup
author_association: CONTRIBUTOR
user: login: bors
created_at: 2025-03-15T18:04:17Z
body: :pushpin: Commit bc6047a5a768b3029978b7f60322468a23f586ac has been approved by `compiler-errors`

It is now in the [queue](https://bors.rust-lang.org/homu/queue/rust) for this repository.

<!-- @bors r=compiler-errors bc6047a5a768b3029978b7f60322468a23f586ac -->
<!-- homu: {"type":"Approved","sha":"bc6047a5a768b3029978b7f60322468a23f586ac","approver":"compiler-errors","queue":"https://bors.rust-lang.org/homu/queue/rust"} -->
author_association: COLLABORATOR