Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 8ee220c

Browse files
committed
more reuse in block parsing & improve diagnostics.
1 parent 883e90d commit 8ee220c

File tree

9 files changed

+98
-20
lines changed

9 files changed

+98
-20
lines changed

src/librustc_ast/token.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,16 @@ impl Token {
535535
false
536536
}
537537

538+
// Is the token an interpolated block (`$b:block`)?
539+
pub fn is_whole_block(&self) -> bool {
540+
if let Interpolated(ref nt) = self.kind {
541+
if let NtBlock(..) = **nt {
542+
return true;
543+
}
544+
}
545+
false
546+
}
547+
538548
/// Returns `true` if the token is either the `mut` or `const` keyword.
539549
pub fn is_mutability(&self) -> bool {
540550
self.is_keyword(kw::Mut) || self.is_keyword(kw::Const)

src/librustc_parse/parser/expr.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1077,7 +1077,7 @@ impl<'a> Parser<'a> {
10771077
self.parse_for_expr(label, lo, attrs)
10781078
} else if self.eat_keyword(kw::Loop) {
10791079
self.parse_loop_expr(label, lo, attrs)
1080-
} else if self.check(&token::OpenDelim(token::Brace)) {
1080+
} else if self.check(&token::OpenDelim(token::Brace)) || self.token.is_whole_block() {
10811081
self.parse_block_expr(label, lo, BlockCheckMode::Default, attrs)
10821082
} else {
10831083
let msg = "expected `while`, `for`, `loop` or `{` after a label";
@@ -1361,18 +1361,20 @@ impl<'a> Parser<'a> {
13611361
opt_label: Option<Label>,
13621362
lo: Span,
13631363
blk_mode: BlockCheckMode,
1364-
outer_attrs: AttrVec,
1364+
mut attrs: AttrVec,
13651365
) -> PResult<'a, P<Expr>> {
13661366
if let Some(label) = opt_label {
13671367
self.sess.gated_spans.gate(sym::label_break_value, label.ident.span);
13681368
}
13691369

1370-
self.expect(&token::OpenDelim(token::Brace))?;
1371-
1372-
let mut attrs = outer_attrs;
1373-
attrs.extend(self.parse_inner_attributes()?);
1370+
if self.token.is_whole_block() {
1371+
self.struct_span_err(self.token.span, "cannot use a `block` macro fragment here")
1372+
.span_label(lo.to(self.token.span), "the `block` fragment is within this context")
1373+
.emit();
1374+
}
13741375

1375-
let blk = self.parse_block_tail(lo, blk_mode)?;
1376+
let (inner_attrs, blk) = self.parse_block_common(lo, blk_mode)?;
1377+
attrs.extend(inner_attrs);
13761378
Ok(self.mk_expr(blk.span, ExprKind::Block(blk, opt_label), attrs))
13771379
}
13781380

src/librustc_parse/parser/stmt.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -240,13 +240,11 @@ impl<'a> Parser<'a> {
240240
pub fn parse_block(&mut self) -> PResult<'a, P<Block>> {
241241
maybe_whole!(self, NtBlock, |x| x);
242242

243-
let lo = self.token.span;
244-
245243
if !self.eat(&token::OpenDelim(token::Brace)) {
246244
return self.error_block_no_opening_brace();
247245
}
248246

249-
self.parse_block_tail(lo, BlockCheckMode::Default)
247+
self.parse_block_tail(self.prev_token.span, BlockCheckMode::Default)
250248
}
251249

252250
fn error_block_no_opening_brace<T>(&mut self) -> PResult<'a, T> {
@@ -301,15 +299,22 @@ impl<'a> Parser<'a> {
301299
pub(super) fn parse_inner_attrs_and_block(
302300
&mut self,
303301
) -> PResult<'a, (Vec<Attribute>, P<Block>)> {
304-
maybe_whole!(self, NtBlock, |x| (Vec::new(), x));
302+
self.parse_block_common(self.token.span, BlockCheckMode::Default)
303+
}
305304

306-
let lo = self.token.span;
305+
/// Parses a block. Inner attributes are allowed.
306+
pub(super) fn parse_block_common(
307+
&mut self,
308+
lo: Span,
309+
blk_mode: BlockCheckMode,
310+
) -> PResult<'a, (Vec<Attribute>, P<Block>)> {
311+
maybe_whole!(self, NtBlock, |x| (Vec::new(), x));
307312

308313
if !self.eat(&token::OpenDelim(token::Brace)) {
309314
return self.error_block_no_opening_brace();
310315
}
311316

312-
Ok((self.parse_inner_attributes()?, self.parse_block_tail(lo, BlockCheckMode::Default)?))
317+
Ok((self.parse_inner_attributes()?, self.parse_block_tail(lo, blk_mode)?))
313318
}
314319

315320
/// Parses the rest of a block expression or function body.

src/test/ui/label/label_break_value_illegal_uses.stderr

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ error: expected `{`, found `'b`
22
--> $DIR/label_break_value_illegal_uses.rs:6:12
33
|
44
LL | unsafe 'b: {}
5-
| ^^ expected `{`
5+
| ^^----
6+
| |
7+
| expected `{`
8+
| help: try placing this code inside a block: `{ 'b: {} }`
69

710
error: expected `{`, found `'b`
811
--> $DIR/label_break_value_illegal_uses.rs:10:13
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#![feature(label_break_value)]
2+
3+
fn main() {}
4+
5+
macro_rules! m {
6+
($b:block) => {
7+
'lab: $b; //~ ERROR cannot use a `block` macro fragment here
8+
unsafe $b; //~ ERROR cannot use a `block` macro fragment here
9+
|x: u8| -> () $b; //~ ERROR cannot use a `block` macro fragment here
10+
}
11+
}
12+
13+
fn foo() {
14+
m!({});
15+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
error: cannot use a `block` macro fragment here
2+
--> $DIR/bad-interpolated-block.rs:7:15
3+
|
4+
LL | 'lab: $b;
5+
| ------^^
6+
| |
7+
| the `block` fragment is within this context
8+
...
9+
LL | m!({});
10+
| ------- in this macro invocation
11+
|
12+
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
13+
14+
error: cannot use a `block` macro fragment here
15+
--> $DIR/bad-interpolated-block.rs:8:16
16+
|
17+
LL | unsafe $b;
18+
| -------^^
19+
| |
20+
| the `block` fragment is within this context
21+
...
22+
LL | m!({});
23+
| ------- in this macro invocation
24+
|
25+
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
26+
27+
error: cannot use a `block` macro fragment here
28+
--> $DIR/bad-interpolated-block.rs:9:23
29+
|
30+
LL | |x: u8| -> () $b;
31+
| ^^ the `block` fragment is within this context
32+
...
33+
LL | m!({});
34+
| ------- in this macro invocation
35+
|
36+
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
37+
38+
error: aborting due to 3 previous errors
39+

src/test/ui/parser/closure-return-syntax.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@
33

44
fn main() {
55
let x = || -> i32 22;
6-
//~^ ERROR expected one of `!`, `(`, `+`, `::`, `<`, or `{`, found `22`
6+
//~^ ERROR expected `{`, found `22`
77
}
Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1-
error: expected one of `!`, `(`, `+`, `::`, `<`, or `{`, found `22`
1+
error: expected `{`, found `22`
22
--> $DIR/closure-return-syntax.rs:5:23
33
|
44
LL | let x = || -> i32 22;
5-
| ^^ expected one of `!`, `(`, `+`, `::`, `<`, or `{`
5+
| ^^-
6+
| |
7+
| expected `{`
8+
| help: try placing this code inside a block: `{ 22; }`
69

710
error: aborting due to previous error
811

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
error: expected `{`, found `std`
22
--> $DIR/unsafe-block-without-braces.rs:3:9
33
|
4-
LL | unsafe //{
5-
| - expected `{`
64
LL | std::mem::transmute::<f32, u32>(1.0);
7-
| ^^^ unexpected token
5+
| ^^^----------------------------------
6+
| |
7+
| expected `{`
8+
| help: try placing this code inside a block: `{ std::mem::transmute::<f32, u32>(1.0); }`
89

910
error: aborting due to previous error
1011

0 commit comments

Comments
 (0)