Skip to content

Commit c639215

Browse files
committed
Address review comments: fix span and add run-rustfix
- Change error span to start from 'const' keyword instead of binop RHS - Add decl_lo parameter to missing_semi_from_binop() for better spans - Add run-rustfix directive to test file - Simplify test to focus on const item recovery cases
1 parent fb11399 commit c639215

File tree

6 files changed

+66
-61
lines changed

6 files changed

+66
-61
lines changed

compiler/rustc_parse/src/parser/item.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ impl<'a> Parser<'a> {
286286
// CONST ITEM
287287
self.recover_const_mut(const_span);
288288
self.recover_missing_kw_before_item()?;
289-
let (ident, generics, ty, rhs) = self.parse_const_item(attrs)?;
289+
let (ident, generics, ty, rhs) = self.parse_const_item(attrs, const_span)?;
290290
ItemKind::Const(Box::new(ConstItem {
291291
defaultness: def_(),
292292
ident,
@@ -1522,6 +1522,7 @@ impl<'a> Parser<'a> {
15221522
fn parse_const_item(
15231523
&mut self,
15241524
attrs: &[Attribute],
1525+
const_span: Span,
15251526
) -> PResult<'a, (Ident, Generics, Box<Ty>, Option<ast::ConstItemRhs>)> {
15261527
let ident = self.parse_ident_or_underscore()?;
15271528

@@ -1612,7 +1613,7 @@ impl<'a> Parser<'a> {
16121613

16131614
generics.where_clause = where_clause;
16141615

1615-
if let Some(recovered_rhs) = self.try_recover_const_missing_semi(&rhs) {
1616+
if let Some(recovered_rhs) = self.try_recover_const_missing_semi(&rhs, const_span) {
16161617
return Ok((ident, generics, ty, Some(ConstItemRhs::Body(recovered_rhs))));
16171618
}
16181619
self.expect_semi()?;
@@ -3475,7 +3476,11 @@ impl<'a> Parser<'a> {
34753476
/// (e.g., `foo() \n &bar` was parsed as `foo() & bar`).
34763477
///
34773478
/// Returns a corrected expression if recovery is successful.
3478-
fn try_recover_const_missing_semi(&mut self, rhs: &Option<ConstItemRhs>) -> Option<Box<Expr>> {
3479+
fn try_recover_const_missing_semi(
3480+
&mut self,
3481+
rhs: &Option<ConstItemRhs>,
3482+
const_span: Span,
3483+
) -> Option<Box<Expr>> {
34793484
if self.token == TokenKind::Semi {
34803485
return None;
34813486
}
@@ -3485,7 +3490,9 @@ impl<'a> Parser<'a> {
34853490
if !self.in_fn_body || !self.may_recover() || rhs.span.from_expansion() {
34863491
return None;
34873492
}
3488-
if let Some((span, guar)) = self.missing_semi_from_binop("const", rhs) {
3493+
if let Some((span, guar)) =
3494+
self.missing_semi_from_binop("const", rhs, Some(const_span.shrink_to_lo()))
3495+
{
34893496
self.fn_body_missing_semi_guar = Some(guar);
34903497
Some(self.mk_expr(span, ExprKind::Err(guar)))
34913498
} else {

compiler/rustc_parse/src/parser/mod.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1691,6 +1691,7 @@ impl<'a> Parser<'a> {
16911691
&self,
16921692
kind_desc: &str,
16931693
expr: &Expr,
1694+
decl_lo: Option<Span>,
16941695
) -> Option<(Span, ErrorGuaranteed)> {
16951696
if self.token == TokenKind::Semi {
16961697
return None;
@@ -1711,7 +1712,9 @@ impl<'a> Parser<'a> {
17111712
.struct_span_err(lhs_end_span, format!("expected `;`, found {token_str}"));
17121713
err.span_label(self.token.span, "unexpected token");
17131714

1714-
let continuation_span = lhs_end_span.until(rhs.span.shrink_to_hi());
1715+
// Use the declaration start if provided, otherwise fall back to lhs_end_span.
1716+
let continuation_start = decl_lo.unwrap_or(lhs_end_span);
1717+
let continuation_span = continuation_start.until(rhs.span.shrink_to_hi());
17151718
err.span_label(
17161719
continuation_span,
17171720
format!(

compiler/rustc_parse/src/parser/stmt.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -929,7 +929,9 @@ impl<'a> Parser<'a> {
929929
LocalKind::Init(expr) | LocalKind::InitElse(expr, _) => expr,
930930
LocalKind::Decl => return None,
931931
};
932-
if let Some((span, guar)) = self.missing_semi_from_binop("`let` binding", expr) {
932+
if let Some((span, guar)) =
933+
self.missing_semi_from_binop("`let` binding", expr, Some(local.span.shrink_to_lo()))
934+
{
933935
self.fn_body_missing_semi_guar = Some(guar);
934936
*expr = self.mk_expr(span, ExprKind::Err(guar));
935937
return Some(guar);
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
//@ run-rustfix
2+
#![feature(const_trait_impl)]
3+
#![allow(dead_code)]
4+
#![allow(unused)]
5+
6+
const trait ConstDefault {
7+
fn const_default() -> Self;
8+
}
9+
10+
impl const ConstDefault for u8 {
11+
fn const_default() -> Self { 0 }
12+
}
13+
14+
const fn val() -> u8 {
15+
42
16+
}
17+
18+
const C: u8 = u8::const_default()
19+
&1; //~ ERROR expected `;`, found keyword `const`
20+
21+
const fn foo() -> &'static u8 {
22+
const C: u8 = u8::const_default(); //~ ERROR expected `;`
23+
&C
24+
}
25+
26+
const fn bar() {
27+
const C: u8 = 1
28+
+ 2; //~ ERROR expected `;`, found `}`
29+
}
30+
31+
const fn baz() {
32+
const C: u8 = 1
33+
+ val(); //~ ERROR expected `;`, found `}`
34+
}
35+
36+
fn main() {}

tests/ui/parser/const-recover-semi-issue-151149.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1+
//@ run-rustfix
12
#![feature(const_trait_impl)]
3+
#![allow(dead_code)]
4+
#![allow(unused)]
25

36
const trait ConstDefault {
47
fn const_default() -> Self;
@@ -20,19 +23,14 @@ const fn foo() -> &'static u8 {
2023
&C
2124
}
2225

23-
const fn bar() -> u8 { //~ ERROR mismatched types
26+
const fn bar() {
2427
const C: u8 = 1
2528
+ 2 //~ ERROR expected `;`, found `}`
2629
}
2730

28-
const fn baz() -> u8 { //~ ERROR mismatched types
31+
const fn baz() {
2932
const C: u8 = 1
3033
+ val() //~ ERROR expected `;`, found `}`
3134
}
3235

33-
fn buzz() -> &'static u8 {
34-
let r = 1 //~ ERROR expected `;`
35-
&r
36-
}
37-
3836
fn main() {}
Lines changed: 7 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: expected `;`, found keyword `const`
2-
--> $DIR/const-recover-semi-issue-151149.rs:16:3
2+
--> $DIR/const-recover-semi-issue-151149.rs:19:3
33
|
44
LL | &1
55
| ^ help: add `;` here
@@ -8,17 +8,17 @@ LL | const fn foo() -> &'static u8 {
88
| ----- unexpected token
99

1010
error: expected `;`, found `}`
11-
--> $DIR/const-recover-semi-issue-151149.rs:19:38
11+
--> $DIR/const-recover-semi-issue-151149.rs:22:38
1212
|
1313
LL | const C: u8 = u8::const_default()
14-
| ______________________________________^
14+
| _____- ^
1515
LL | | &C
1616
| |______- to finish parsing this const, expected this to be followed by a `;`
1717
LL | }
1818
| - unexpected token
1919
|
2020
note: the const was parsed as having a bit-and binary expression
21-
--> $DIR/const-recover-semi-issue-151149.rs:19:19
21+
--> $DIR/const-recover-semi-issue-151149.rs:22:19
2222
|
2323
LL | const C: u8 = u8::const_default()
2424
| ------------------- parsed as the left-hand expression
@@ -32,61 +32,20 @@ LL | const C: u8 = u8::const_default();
3232
| +
3333

3434
error: expected `;`, found `}`
35-
--> $DIR/const-recover-semi-issue-151149.rs:25:9
35+
--> $DIR/const-recover-semi-issue-151149.rs:28:9
3636
|
3737
LL | + 2
3838
| ^ help: add `;` here
3939
LL | }
4040
| - unexpected token
4141

4242
error: expected `;`, found `}`
43-
--> $DIR/const-recover-semi-issue-151149.rs:30:13
43+
--> $DIR/const-recover-semi-issue-151149.rs:33:13
4444
|
4545
LL | + val()
4646
| ^ help: add `;` here
4747
LL | }
4848
| - unexpected token
4949

50-
error: expected `;`, found `}`
51-
--> $DIR/const-recover-semi-issue-151149.rs:34:14
52-
|
53-
LL | let r = 1
54-
| ______________^
55-
LL | | &r
56-
| |______- to finish parsing this `let` binding, expected this to be followed by a `;`
57-
LL | }
58-
| - unexpected token
59-
|
60-
note: the `let` binding was parsed as having a bit-and binary expression
61-
--> $DIR/const-recover-semi-issue-151149.rs:34:13
62-
|
63-
LL | let r = 1
64-
| - parsed as the left-hand expression
65-
LL | &r
66-
| -- parsed as the right-hand expression
67-
| |
68-
| this was parsed as a bit-and
69-
help: you may have meant to write a `;` to terminate the `let` binding earlier
70-
|
71-
LL | let r = 1;
72-
| +
73-
74-
error[E0308]: mismatched types
75-
--> $DIR/const-recover-semi-issue-151149.rs:23:19
76-
|
77-
LL | const fn bar() -> u8 {
78-
| --- ^^ expected `u8`, found `()`
79-
| |
80-
| implicitly returns `()` as its body has no tail or `return` expression
81-
82-
error[E0308]: mismatched types
83-
--> $DIR/const-recover-semi-issue-151149.rs:28:19
84-
|
85-
LL | const fn baz() -> u8 {
86-
| --- ^^ expected `u8`, found `()`
87-
| |
88-
| implicitly returns `()` as its body has no tail or `return` expression
89-
90-
error: aborting due to 7 previous errors
50+
error: aborting due to 4 previous errors
9151

92-
For more information about this error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)