Rollup merge of #119062 - compiler-errors:asm-in-let-else, r=davidtwco,est31
Deny braced macro invocations in let-else Fixes #119057 Pending T-lang decision cc `@dtolnay`
This commit is contained in:
commit
2e4c6fc998
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
// Predicates on exprs and stmts that the pretty-printer and parser use
|
// Predicates on exprs and stmts that the pretty-printer and parser use
|
||||||
|
|
||||||
use crate::ast;
|
use crate::{ast, token::Delimiter};
|
||||||
|
|
||||||
/// Does this expression require a semicolon to be treated
|
/// Does this expression require a semicolon to be treated
|
||||||
/// as a statement? The negation of this: 'can this expression
|
/// as a statement? The negation of this: 'can this expression
|
||||||
@ -59,8 +59,12 @@ pub fn expr_trailing_brace(mut expr: &ast::Expr) -> Option<&ast::Expr> {
|
|||||||
| While(..)
|
| While(..)
|
||||||
| ConstBlock(_) => break Some(expr),
|
| ConstBlock(_) => break Some(expr),
|
||||||
|
|
||||||
// FIXME: These can end in `}`, but changing these would break stable code.
|
MacCall(mac) => {
|
||||||
InlineAsm(_) | OffsetOf(_, _) | MacCall(_) | IncludedBytes(_) | FormatArgs(_) => {
|
break (mac.args.delim == Delimiter::Brace).then_some(expr);
|
||||||
|
}
|
||||||
|
|
||||||
|
InlineAsm(_) | OffsetOf(_, _) | IncludedBytes(_) | FormatArgs(_) => {
|
||||||
|
// These should have been denied pre-expansion.
|
||||||
break None;
|
break None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -724,6 +724,8 @@ parse_sugg_turbofish_syntax = use `::<...>` instead of `<...>` to specify lifeti
|
|||||||
|
|
||||||
parse_sugg_wrap_expression_in_parentheses = wrap the expression in parentheses
|
parse_sugg_wrap_expression_in_parentheses = wrap the expression in parentheses
|
||||||
|
|
||||||
|
parse_sugg_wrap_macro_in_parentheses = use parentheses instead of braces for this macro
|
||||||
|
|
||||||
parse_sugg_wrap_pattern_in_parens = wrap the pattern in parentheses
|
parse_sugg_wrap_pattern_in_parens = wrap the pattern in parentheses
|
||||||
|
|
||||||
parse_switch_mut_let_order =
|
parse_switch_mut_let_order =
|
||||||
|
@ -722,19 +722,32 @@ pub(crate) struct LabeledLoopInBreak {
|
|||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
#[subdiagnostic]
|
#[subdiagnostic]
|
||||||
pub sub: WrapExpressionInParentheses,
|
pub sub: WrapInParentheses,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Subdiagnostic)]
|
#[derive(Subdiagnostic)]
|
||||||
#[multipart_suggestion(
|
|
||||||
parse_sugg_wrap_expression_in_parentheses,
|
pub(crate) enum WrapInParentheses {
|
||||||
applicability = "machine-applicable"
|
#[multipart_suggestion(
|
||||||
)]
|
parse_sugg_wrap_expression_in_parentheses,
|
||||||
pub(crate) struct WrapExpressionInParentheses {
|
applicability = "machine-applicable"
|
||||||
#[suggestion_part(code = "(")]
|
)]
|
||||||
pub left: Span,
|
Expression {
|
||||||
#[suggestion_part(code = ")")]
|
#[suggestion_part(code = "(")]
|
||||||
pub right: Span,
|
left: Span,
|
||||||
|
#[suggestion_part(code = ")")]
|
||||||
|
right: Span,
|
||||||
|
},
|
||||||
|
#[multipart_suggestion(
|
||||||
|
parse_sugg_wrap_macro_in_parentheses,
|
||||||
|
applicability = "machine-applicable"
|
||||||
|
)]
|
||||||
|
MacroArgs {
|
||||||
|
#[suggestion_part(code = "(")]
|
||||||
|
left: Span,
|
||||||
|
#[suggestion_part(code = ")")]
|
||||||
|
right: Span,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
@ -936,7 +949,7 @@ pub(crate) struct InvalidExpressionInLetElse {
|
|||||||
pub span: Span,
|
pub span: Span,
|
||||||
pub operator: &'static str,
|
pub operator: &'static str,
|
||||||
#[subdiagnostic]
|
#[subdiagnostic]
|
||||||
pub sugg: WrapExpressionInParentheses,
|
pub sugg: WrapInParentheses,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
@ -945,7 +958,7 @@ pub(crate) struct InvalidCurlyInLetElse {
|
|||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
#[subdiagnostic]
|
#[subdiagnostic]
|
||||||
pub sugg: WrapExpressionInParentheses,
|
pub sugg: WrapInParentheses,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
|
@ -1844,7 +1844,7 @@ impl<'a> Parser<'a> {
|
|||||||
let lexpr = self.parse_expr_labeled(label, true)?;
|
let lexpr = self.parse_expr_labeled(label, true)?;
|
||||||
self.dcx().emit_err(errors::LabeledLoopInBreak {
|
self.dcx().emit_err(errors::LabeledLoopInBreak {
|
||||||
span: lexpr.span,
|
span: lexpr.span,
|
||||||
sub: errors::WrapExpressionInParentheses {
|
sub: errors::WrapInParentheses::Expression {
|
||||||
left: lexpr.span.shrink_to_lo(),
|
left: lexpr.span.shrink_to_lo(),
|
||||||
right: lexpr.span.shrink_to_hi(),
|
right: lexpr.span.shrink_to_hi(),
|
||||||
},
|
},
|
||||||
|
@ -389,7 +389,7 @@ impl<'a> Parser<'a> {
|
|||||||
self.dcx().emit_err(errors::InvalidExpressionInLetElse {
|
self.dcx().emit_err(errors::InvalidExpressionInLetElse {
|
||||||
span: init.span,
|
span: init.span,
|
||||||
operator: op.node.as_str(),
|
operator: op.node.as_str(),
|
||||||
sugg: errors::WrapExpressionInParentheses {
|
sugg: errors::WrapInParentheses::Expression {
|
||||||
left: init.span.shrink_to_lo(),
|
left: init.span.shrink_to_lo(),
|
||||||
right: init.span.shrink_to_hi(),
|
right: init.span.shrink_to_hi(),
|
||||||
},
|
},
|
||||||
@ -400,12 +400,19 @@ impl<'a> Parser<'a> {
|
|||||||
|
|
||||||
fn check_let_else_init_trailing_brace(&self, init: &ast::Expr) {
|
fn check_let_else_init_trailing_brace(&self, init: &ast::Expr) {
|
||||||
if let Some(trailing) = classify::expr_trailing_brace(init) {
|
if let Some(trailing) = classify::expr_trailing_brace(init) {
|
||||||
self.dcx().emit_err(errors::InvalidCurlyInLetElse {
|
let sugg = match &trailing.kind {
|
||||||
span: trailing.span.with_lo(trailing.span.hi() - BytePos(1)),
|
ExprKind::MacCall(mac) => errors::WrapInParentheses::MacroArgs {
|
||||||
sugg: errors::WrapExpressionInParentheses {
|
left: mac.args.dspan.open,
|
||||||
|
right: mac.args.dspan.close,
|
||||||
|
},
|
||||||
|
_ => errors::WrapInParentheses::Expression {
|
||||||
left: trailing.span.shrink_to_lo(),
|
left: trailing.span.shrink_to_lo(),
|
||||||
right: trailing.span.shrink_to_hi(),
|
right: trailing.span.shrink_to_hi(),
|
||||||
},
|
},
|
||||||
|
};
|
||||||
|
self.dcx().emit_err(errors::InvalidCurlyInLetElse {
|
||||||
|
span: trailing.span.with_lo(trailing.span.hi() - BytePos(1)),
|
||||||
|
sugg,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -161,4 +161,29 @@ fn q() {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn r() {
|
||||||
|
let ok = format_args!("") else { return; };
|
||||||
|
|
||||||
|
let bad = format_args! {""} else { return; };
|
||||||
|
//~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed
|
||||||
|
}
|
||||||
|
|
||||||
|
fn s() {
|
||||||
|
macro_rules! a {
|
||||||
|
() => { {} }
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! b {
|
||||||
|
(1) => {
|
||||||
|
let x = a!() else { return; };
|
||||||
|
};
|
||||||
|
(2) => {
|
||||||
|
let x = a! {} else { return; };
|
||||||
|
//~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
b!(1); b!(2);
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
@ -228,5 +228,31 @@ LL | x
|
|||||||
LL ~ }) else {
|
LL ~ }) else {
|
||||||
|
|
|
|
||||||
|
|
||||||
error: aborting due to 17 previous errors
|
error: right curly brace `}` before `else` in a `let...else` statement not allowed
|
||||||
|
--> $DIR/bad-let-else-statement.rs:167:31
|
||||||
|
|
|
||||||
|
LL | let bad = format_args! {""} else { return; };
|
||||||
|
| ^
|
||||||
|
|
|
||||||
|
help: use parentheses instead of braces for this macro
|
||||||
|
|
|
||||||
|
LL | let bad = format_args! ("") else { return; };
|
||||||
|
| ~ ~
|
||||||
|
|
||||||
|
error: right curly brace `}` before `else` in a `let...else` statement not allowed
|
||||||
|
--> $DIR/bad-let-else-statement.rs:181:25
|
||||||
|
|
|
||||||
|
LL | let x = a! {} else { return; };
|
||||||
|
| ^
|
||||||
|
...
|
||||||
|
LL | b!(1); b!(2);
|
||||||
|
| ----- in this macro invocation
|
||||||
|
|
|
||||||
|
= note: this error originates in the macro `b` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
help: use parentheses instead of braces for this macro
|
||||||
|
|
|
||||||
|
LL | let x = a! () else { return; };
|
||||||
|
| ~~
|
||||||
|
|
||||||
|
error: aborting due to 19 previous errors
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user