Skip to content

Commit 4bc891a

Browse files
authored
Rollup merge of #123609 - compiler-errors:greek-question-mark, r=jieyouxu
Don't use bytepos offsets when computing semicolon span for removal Causes problems when we recover confusable characters w/ a different byte width Fixes #123607
2 parents c14b468 + 3253c02 commit 4bc891a

File tree

9 files changed

+60
-27
lines changed

9 files changed

+60
-27
lines changed

Diff for: compiler/rustc_ast_passes/src/ast_validation.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,7 @@ impl<'a> AstValidator<'a> {
346346
in_impl: matches!(parent, TraitOrTraitImpl::TraitImpl { .. }),
347347
const_context_label: parent_constness,
348348
remove_const_sugg: (
349-
self.session.source_map().span_extend_while(span, |c| c == ' ').unwrap_or(span),
349+
self.session.source_map().span_extend_while_whitespace(span),
350350
match parent_constness {
351351
Some(_) => rustc_errors::Applicability::MachineApplicable,
352352
None => rustc_errors::Applicability::MaybeIncorrect,

Diff for: compiler/rustc_hir_typeck/src/expr.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -2023,8 +2023,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
20232023
.tcx
20242024
.sess
20252025
.source_map()
2026-
.span_extend_while(range_start.span, |c| c.is_whitespace())
2027-
.unwrap_or(range_start.span)
2026+
.span_extend_while_whitespace(range_start.span)
20282027
.shrink_to_hi()
20292028
.to(range_end.span);
20302029

Diff for: compiler/rustc_infer/src/infer/error_reporting/suggest.rs

+9-6
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use rustc_middle::traits::{
1515
};
1616
use rustc_middle::ty::print::with_no_trimmed_paths;
1717
use rustc_middle::ty::{self as ty, GenericArgKind, IsSuggestable, Ty, TypeVisitableExt};
18-
use rustc_span::{sym, BytePos, Span};
18+
use rustc_span::{sym, Span};
1919

2020
use crate::errors::{
2121
ConsiderAddingAwait, FnConsiderCasting, FnItemsAreDistinct, FnUniqTypes,
@@ -763,8 +763,14 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
763763
let mac_call = rustc_span::source_map::original_sp(last_stmt.span, blk.span);
764764
self.tcx.sess.source_map().mac_call_stmt_semi_span(mac_call)?
765765
} else {
766-
last_stmt.span.with_lo(last_stmt.span.hi() - BytePos(1))
766+
self.tcx
767+
.sess
768+
.source_map()
769+
.span_extend_while_whitespace(last_expr.span)
770+
.shrink_to_hi()
771+
.with_hi(last_stmt.span.hi())
767772
};
773+
768774
Some((span, needs_box))
769775
}
770776

@@ -867,10 +873,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
867873
format!(" {ident} ")
868874
};
869875
let left_span = sm.span_through_char(blk.span, '{').shrink_to_hi();
870-
(
871-
sm.span_extend_while(left_span, |c| c.is_whitespace()).unwrap_or(left_span),
872-
sugg,
873-
)
876+
(sm.span_extend_while_whitespace(left_span), sugg)
874877
};
875878
Some(SuggestRemoveSemiOrReturnBinding::Add { sp: span, code: sugg, ident: *ident })
876879
}

Diff for: compiler/rustc_lint/src/context/diagnostics.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -215,10 +215,7 @@ pub(super) fn builtin(sess: &Session, diagnostic: BuiltinLintDiag, diag: &mut Di
215215
if let Some(deletion_span) = deletion_span {
216216
let msg = "elide the single-use lifetime";
217217
let (use_span, replace_lt) = if elide {
218-
let use_span = sess
219-
.source_map()
220-
.span_extend_while(use_span, char::is_whitespace)
221-
.unwrap_or(use_span);
218+
let use_span = sess.source_map().span_extend_while_whitespace(use_span);
222219
(use_span, String::new())
223220
} else {
224221
(use_span, "'_".to_owned())

Diff for: compiler/rustc_span/src/source_map.rs

+9-6
Original file line numberDiff line numberDiff line change
@@ -654,6 +654,12 @@ impl SourceMap {
654654
})
655655
}
656656

657+
/// Extends the span to include any trailing whitespace, or returns the original
658+
/// span if a `SpanSnippetError` was encountered.
659+
pub fn span_extend_while_whitespace(&self, span: Span) -> Span {
660+
self.span_extend_while(span, char::is_whitespace).unwrap_or(span)
661+
}
662+
657663
/// Extends the given `Span` to previous character while the previous character matches the predicate
658664
pub fn span_extend_prev_while(
659665
&self,
@@ -1034,12 +1040,9 @@ impl SourceMap {
10341040
/// // ^^^^^^ input
10351041
/// ```
10361042
pub fn mac_call_stmt_semi_span(&self, mac_call: Span) -> Option<Span> {
1037-
let span = self.span_extend_while(mac_call, char::is_whitespace).ok()?;
1038-
let span = span.shrink_to_hi().with_hi(BytePos(span.hi().0.checked_add(1)?));
1039-
if self.span_to_snippet(span).as_deref() != Ok(";") {
1040-
return None;
1041-
}
1042-
Some(span)
1043+
let span = self.span_extend_while_whitespace(mac_call);
1044+
let span = self.next_point(span);
1045+
if self.span_to_snippet(span).as_deref() == Ok(";") { Some(span) } else { None }
10431046
}
10441047
}
10451048

Diff for: compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs

+2-6
Original file line numberDiff line numberDiff line change
@@ -1592,8 +1592,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
15921592
.tcx
15931593
.sess
15941594
.source_map()
1595-
.span_extend_while(expr_span, char::is_whitespace)
1596-
.unwrap_or(expr_span)
1595+
.span_extend_while_whitespace(expr_span)
15971596
.shrink_to_hi()
15981597
.to(await_expr.span.shrink_to_hi());
15991598
err.span_suggestion(
@@ -4851,10 +4850,7 @@ pub fn suggest_desugaring_async_fn_to_impl_future_in_trait<'tcx>(
48514850
let hir::IsAsync::Async(async_span) = sig.header.asyncness else {
48524851
return None;
48534852
};
4854-
let Ok(async_span) = tcx.sess.source_map().span_extend_while(async_span, |c| c.is_whitespace())
4855-
else {
4856-
return None;
4857-
};
4853+
let async_span = tcx.sess.source_map().span_extend_while_whitespace(async_span);
48584854

48594855
let future = tcx.hir_node_by_def_id(opaque_def_id).expect_item().expect_opaque_ty();
48604856
let [hir::GenericBound::Trait(trait_ref, _)] = future.bounds else {

Diff for: src/tools/clippy/clippy_lints/src/lifetimes.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -294,8 +294,7 @@ fn elision_suggestions(
294294
let span = cx
295295
.sess()
296296
.source_map()
297-
.span_extend_while(usage.ident.span, |ch| ch.is_ascii_whitespace())
298-
.unwrap_or(usage.ident.span);
297+
.span_extend_while_whitespace(usage.ident.span);
299298

300299
(span, String::new())
301300
},

Diff for: tests/ui/typeck/remove-semi-but-confused-char.rs

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Ensures our "remove semicolon" suggestion isn't hardcoded with a character width,
2+
// in case it was accidentally mixed up with a greek question mark.
3+
// issue: rust-lang/rust#123607
4+
5+
pub fn square(num: i32) -> i32 {
6+
//~^ ERROR mismatched types
7+
num * num;
8+
//~^ ERROR unknown start of token
9+
}
10+
11+
fn main() {}

Diff for: tests/ui/typeck/remove-semi-but-confused-char.stderr

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
error: unknown start of token: \u{37e}
2+
--> $DIR/remove-semi-but-confused-char.rs:7:14
3+
|
4+
LL | num * num;
5+
| ^
6+
|
7+
help: Unicode character ';' (Greek Question Mark) looks like ';' (Semicolon), but it is not
8+
|
9+
LL | num * num;
10+
| ~
11+
12+
error[E0308]: mismatched types
13+
--> $DIR/remove-semi-but-confused-char.rs:5:28
14+
|
15+
LL | pub fn square(num: i32) -> i32 {
16+
| ------ ^^^ expected `i32`, found `()`
17+
| |
18+
| implicitly returns `()` as its body has no tail or `return` expression
19+
LL |
20+
LL | num * num;
21+
| - help: remove this semicolon to return this value
22+
23+
error: aborting due to 2 previous errors
24+
25+
For more information about this error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)