more reuse in block parsing & improve diagnostics.
This commit is contained in:
parent
883e90dd81
commit
8ee220c447
@ -535,6 +535,16 @@ impl Token {
|
||||
false
|
||||
}
|
||||
|
||||
// Is the token an interpolated block (`$b:block`)?
|
||||
pub fn is_whole_block(&self) -> bool {
|
||||
if let Interpolated(ref nt) = self.kind {
|
||||
if let NtBlock(..) = **nt {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
/// Returns `true` if the token is either the `mut` or `const` keyword.
|
||||
pub fn is_mutability(&self) -> bool {
|
||||
self.is_keyword(kw::Mut) || self.is_keyword(kw::Const)
|
||||
|
@ -1077,7 +1077,7 @@ impl<'a> Parser<'a> {
|
||||
self.parse_for_expr(label, lo, attrs)
|
||||
} else if self.eat_keyword(kw::Loop) {
|
||||
self.parse_loop_expr(label, lo, attrs)
|
||||
} else if self.check(&token::OpenDelim(token::Brace)) {
|
||||
} else if self.check(&token::OpenDelim(token::Brace)) || self.token.is_whole_block() {
|
||||
self.parse_block_expr(label, lo, BlockCheckMode::Default, attrs)
|
||||
} else {
|
||||
let msg = "expected `while`, `for`, `loop` or `{` after a label";
|
||||
@ -1361,18 +1361,20 @@ impl<'a> Parser<'a> {
|
||||
opt_label: Option<Label>,
|
||||
lo: Span,
|
||||
blk_mode: BlockCheckMode,
|
||||
outer_attrs: AttrVec,
|
||||
mut attrs: AttrVec,
|
||||
) -> PResult<'a, P<Expr>> {
|
||||
if let Some(label) = opt_label {
|
||||
self.sess.gated_spans.gate(sym::label_break_value, label.ident.span);
|
||||
}
|
||||
|
||||
self.expect(&token::OpenDelim(token::Brace))?;
|
||||
if self.token.is_whole_block() {
|
||||
self.struct_span_err(self.token.span, "cannot use a `block` macro fragment here")
|
||||
.span_label(lo.to(self.token.span), "the `block` fragment is within this context")
|
||||
.emit();
|
||||
}
|
||||
|
||||
let mut attrs = outer_attrs;
|
||||
attrs.extend(self.parse_inner_attributes()?);
|
||||
|
||||
let blk = self.parse_block_tail(lo, blk_mode)?;
|
||||
let (inner_attrs, blk) = self.parse_block_common(lo, blk_mode)?;
|
||||
attrs.extend(inner_attrs);
|
||||
Ok(self.mk_expr(blk.span, ExprKind::Block(blk, opt_label), attrs))
|
||||
}
|
||||
|
||||
|
@ -240,13 +240,11 @@ impl<'a> Parser<'a> {
|
||||
pub fn parse_block(&mut self) -> PResult<'a, P<Block>> {
|
||||
maybe_whole!(self, NtBlock, |x| x);
|
||||
|
||||
let lo = self.token.span;
|
||||
|
||||
if !self.eat(&token::OpenDelim(token::Brace)) {
|
||||
return self.error_block_no_opening_brace();
|
||||
}
|
||||
|
||||
self.parse_block_tail(lo, BlockCheckMode::Default)
|
||||
self.parse_block_tail(self.prev_token.span, BlockCheckMode::Default)
|
||||
}
|
||||
|
||||
fn error_block_no_opening_brace<T>(&mut self) -> PResult<'a, T> {
|
||||
@ -301,15 +299,22 @@ impl<'a> Parser<'a> {
|
||||
pub(super) fn parse_inner_attrs_and_block(
|
||||
&mut self,
|
||||
) -> PResult<'a, (Vec<Attribute>, P<Block>)> {
|
||||
maybe_whole!(self, NtBlock, |x| (Vec::new(), x));
|
||||
self.parse_block_common(self.token.span, BlockCheckMode::Default)
|
||||
}
|
||||
|
||||
let lo = self.token.span;
|
||||
/// Parses a block. Inner attributes are allowed.
|
||||
pub(super) fn parse_block_common(
|
||||
&mut self,
|
||||
lo: Span,
|
||||
blk_mode: BlockCheckMode,
|
||||
) -> PResult<'a, (Vec<Attribute>, P<Block>)> {
|
||||
maybe_whole!(self, NtBlock, |x| (Vec::new(), x));
|
||||
|
||||
if !self.eat(&token::OpenDelim(token::Brace)) {
|
||||
return self.error_block_no_opening_brace();
|
||||
}
|
||||
|
||||
Ok((self.parse_inner_attributes()?, self.parse_block_tail(lo, BlockCheckMode::Default)?))
|
||||
Ok((self.parse_inner_attributes()?, self.parse_block_tail(lo, blk_mode)?))
|
||||
}
|
||||
|
||||
/// Parses the rest of a block expression or function body.
|
||||
|
@ -2,7 +2,10 @@ error: expected `{`, found `'b`
|
||||
--> $DIR/label_break_value_illegal_uses.rs:6:12
|
||||
|
|
||||
LL | unsafe 'b: {}
|
||||
| ^^ expected `{`
|
||||
| ^^----
|
||||
| |
|
||||
| expected `{`
|
||||
| help: try placing this code inside a block: `{ 'b: {} }`
|
||||
|
||||
error: expected `{`, found `'b`
|
||||
--> $DIR/label_break_value_illegal_uses.rs:10:13
|
||||
|
15
src/test/ui/parser/bad-interpolated-block.rs
Normal file
15
src/test/ui/parser/bad-interpolated-block.rs
Normal file
@ -0,0 +1,15 @@
|
||||
#![feature(label_break_value)]
|
||||
|
||||
fn main() {}
|
||||
|
||||
macro_rules! m {
|
||||
($b:block) => {
|
||||
'lab: $b; //~ ERROR cannot use a `block` macro fragment here
|
||||
unsafe $b; //~ ERROR cannot use a `block` macro fragment here
|
||||
|x: u8| -> () $b; //~ ERROR cannot use a `block` macro fragment here
|
||||
}
|
||||
}
|
||||
|
||||
fn foo() {
|
||||
m!({});
|
||||
}
|
39
src/test/ui/parser/bad-interpolated-block.stderr
Normal file
39
src/test/ui/parser/bad-interpolated-block.stderr
Normal file
@ -0,0 +1,39 @@
|
||||
error: cannot use a `block` macro fragment here
|
||||
--> $DIR/bad-interpolated-block.rs:7:15
|
||||
|
|
||||
LL | 'lab: $b;
|
||||
| ------^^
|
||||
| |
|
||||
| the `block` fragment is within this context
|
||||
...
|
||||
LL | m!({});
|
||||
| ------- in this macro invocation
|
||||
|
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: cannot use a `block` macro fragment here
|
||||
--> $DIR/bad-interpolated-block.rs:8:16
|
||||
|
|
||||
LL | unsafe $b;
|
||||
| -------^^
|
||||
| |
|
||||
| the `block` fragment is within this context
|
||||
...
|
||||
LL | m!({});
|
||||
| ------- in this macro invocation
|
||||
|
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: cannot use a `block` macro fragment here
|
||||
--> $DIR/bad-interpolated-block.rs:9:23
|
||||
|
|
||||
LL | |x: u8| -> () $b;
|
||||
| ^^ the `block` fragment is within this context
|
||||
...
|
||||
LL | m!({});
|
||||
| ------- in this macro invocation
|
||||
|
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
@ -3,5 +3,5 @@
|
||||
|
||||
fn main() {
|
||||
let x = || -> i32 22;
|
||||
//~^ ERROR expected one of `!`, `(`, `+`, `::`, `<`, or `{`, found `22`
|
||||
//~^ ERROR expected `{`, found `22`
|
||||
}
|
||||
|
@ -1,8 +1,11 @@
|
||||
error: expected one of `!`, `(`, `+`, `::`, `<`, or `{`, found `22`
|
||||
error: expected `{`, found `22`
|
||||
--> $DIR/closure-return-syntax.rs:5:23
|
||||
|
|
||||
LL | let x = || -> i32 22;
|
||||
| ^^ expected one of `!`, `(`, `+`, `::`, `<`, or `{`
|
||||
| ^^-
|
||||
| |
|
||||
| expected `{`
|
||||
| help: try placing this code inside a block: `{ 22; }`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -1,10 +1,11 @@
|
||||
error: expected `{`, found `std`
|
||||
--> $DIR/unsafe-block-without-braces.rs:3:9
|
||||
|
|
||||
LL | unsafe //{
|
||||
| - expected `{`
|
||||
LL | std::mem::transmute::<f32, u32>(1.0);
|
||||
| ^^^ unexpected token
|
||||
| ^^^----------------------------------
|
||||
| |
|
||||
| expected `{`
|
||||
| help: try placing this code inside a block: `{ std::mem::transmute::<f32, u32>(1.0); }`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user