about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2024-04-07 19:28:01 -0400
committerMichael Goulet <michael@errs.io>2024-04-09 14:06:08 -0400
commita439eb259da620fa95c67c0c6e89f196bcb61f08 (patch)
tree0ead45dbc88a673add2b2cf6574078fd03f8884d
parent033becf83c62814357f4810db149471db46ab816 (diff)
downloadrust-a439eb259da620fa95c67c0c6e89f196bcb61f08.tar.gz
rust-a439eb259da620fa95c67c0c6e89f196bcb61f08.zip
Don't use bytepos offsets when computing semicolon span for removal
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/suggest.rs11
-rw-r--r--tests/ui/typeck/remove-semi-but-confused-char.rs11
-rw-r--r--tests/ui/typeck/remove-semi-but-confused-char.stderr25
3 files changed, 45 insertions, 2 deletions
diff --git a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs
index 9a05fb1c30f..89c55602f22 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs
@@ -15,7 +15,7 @@ use rustc_middle::traits::{
 };
 use rustc_middle::ty::print::with_no_trimmed_paths;
 use rustc_middle::ty::{self as ty, GenericArgKind, IsSuggestable, Ty, TypeVisitableExt};
-use rustc_span::{sym, BytePos, Span};
+use rustc_span::{sym, Span};
 
 use crate::errors::{
     ConsiderAddingAwait, FnConsiderCasting, FnItemsAreDistinct, FnUniqTypes,
@@ -763,8 +763,15 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
             let mac_call = rustc_span::source_map::original_sp(last_stmt.span, blk.span);
             self.tcx.sess.source_map().mac_call_stmt_semi_span(mac_call)?
         } else {
-            last_stmt.span.with_lo(last_stmt.span.hi() - BytePos(1))
+            self.tcx
+                .sess
+                .source_map()
+                .span_extend_while(last_expr.span, |c| c.is_whitespace())
+                .ok()?
+                .shrink_to_hi()
+                .with_hi(last_stmt.span.hi())
         };
+
         Some((span, needs_box))
     }
 
diff --git a/tests/ui/typeck/remove-semi-but-confused-char.rs b/tests/ui/typeck/remove-semi-but-confused-char.rs
new file mode 100644
index 00000000000..ccc6f59344c
--- /dev/null
+++ b/tests/ui/typeck/remove-semi-but-confused-char.rs
@@ -0,0 +1,11 @@
+// Ensures our "remove semicolon" suggestion isn't hardcoded with a character width,
+// in case it was accidentally mixed up with a greek question mark.
+// issue: rust-lang/rust#123607
+
+pub fn square(num: i32) -> i32 {
+    //~^ ERROR mismatched types
+    num * num;
+    //~^ ERROR unknown start of token
+}
+
+fn main() {}
diff --git a/tests/ui/typeck/remove-semi-but-confused-char.stderr b/tests/ui/typeck/remove-semi-but-confused-char.stderr
new file mode 100644
index 00000000000..2d0b53a60ce
--- /dev/null
+++ b/tests/ui/typeck/remove-semi-but-confused-char.stderr
@@ -0,0 +1,25 @@
+error: unknown start of token: \u{37e}
+  --> $DIR/remove-semi-but-confused-char.rs:7:14
+   |
+LL |     num * num;
+   |              ^
+   |
+help: Unicode character ';' (Greek Question Mark) looks like ';' (Semicolon), but it is not
+   |
+LL |     num * num;
+   |              ~
+
+error[E0308]: mismatched types
+  --> $DIR/remove-semi-but-confused-char.rs:5:28
+   |
+LL | pub fn square(num: i32) -> i32 {
+   |        ------              ^^^ expected `i32`, found `()`
+   |        |
+   |        implicitly returns `()` as its body has no tail or `return` expression
+LL |
+LL |     num * num;
+   |              - help: remove this semicolon to return this value
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.