Rollup merge of #69201 - Aaron1011:feature/permit-if-attr, r=Centril
Permit attributes on 'if' expressions Previously, attributes on 'if' expressions (e.g. `#[attr] if true {}`) were disallowed during parsing. This made it impossible for macros to perform any custom handling of such attributes (e.g. stripping them away), since a compilation error would be emitted before they ever had a chance to run. This PR permits attributes on 'if' expressions ('if-attrs' from here on). Both built-in attributes (e.g. `#[allow]`, `#[cfg]`) and proc-macro attributes are supported. We still do *not* accept attributes on 'other parts' of an if-else chain. That is, the following code snippet still fails to parse: ```rust if true {} #[attr] else if false {} else #[attr] if false {} #[attr] else {} ``` Closes https://github.com/rust-lang/rust/issues/68618
This commit is contained in:
commit
4ec997503c
@ -718,20 +718,11 @@ impl<'a> Parser<'a> {
|
||||
expr.map(|mut expr| {
|
||||
attrs.extend::<Vec<_>>(expr.attrs.into());
|
||||
expr.attrs = attrs;
|
||||
self.error_attr_on_if_expr(&expr);
|
||||
expr
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
fn error_attr_on_if_expr(&self, expr: &Expr) {
|
||||
if let (ExprKind::If(..), [a0, ..]) = (&expr.kind, &*expr.attrs) {
|
||||
// Just point to the first attribute in there...
|
||||
self.struct_span_err(a0.span, "attributes are not yet allowed on `if` expressions")
|
||||
.emit();
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_dot_or_call_expr_with_(&mut self, mut e: P<Expr>, lo: Span) -> PResult<'a, P<Expr>> {
|
||||
loop {
|
||||
if self.eat(&token::Question) {
|
||||
|
37
src/test/pretty/if-attr.rs
Normal file
37
src/test/pretty/if-attr.rs
Normal file
@ -0,0 +1,37 @@
|
||||
// pp-exact
|
||||
|
||||
#[cfg(FALSE)]
|
||||
fn simple_attr() {
|
||||
|
||||
#[attr]
|
||||
if true { }
|
||||
|
||||
#[allow_warnings]
|
||||
if true { }
|
||||
}
|
||||
|
||||
#[cfg(FALSE)]
|
||||
fn if_else_chain() {
|
||||
|
||||
#[first_attr]
|
||||
if true { } else if false { } else { }
|
||||
}
|
||||
|
||||
#[cfg(FALSE)]
|
||||
fn if_let() {
|
||||
|
||||
#[attr]
|
||||
if let Some(_) = Some(true) { }
|
||||
}
|
||||
|
||||
#[cfg(FALSE)]
|
||||
fn let_attr_if() {
|
||||
let _ = #[attr] if let _ = 0 { };
|
||||
let _ = #[attr] if true { };
|
||||
|
||||
let _ = #[attr] if let _ = 0 { } else { };
|
||||
let _ = #[attr] if true { } else { };
|
||||
}
|
||||
|
||||
|
||||
fn main() { }
|
5
src/test/ui/if-attrs/bad-cfg.rs
Normal file
5
src/test/ui/if-attrs/bad-cfg.rs
Normal file
@ -0,0 +1,5 @@
|
||||
#![feature(stmt_expr_attributes)]
|
||||
|
||||
fn main() {
|
||||
let _ = #[cfg(FALSE)] if true {}; //~ ERROR removing an expression
|
||||
}
|
8
src/test/ui/if-attrs/bad-cfg.stderr
Normal file
8
src/test/ui/if-attrs/bad-cfg.stderr
Normal file
@ -0,0 +1,8 @@
|
||||
error: removing an expression is not supported in this position
|
||||
--> $DIR/bad-cfg.rs:4:13
|
||||
|
|
||||
LL | let _ = #[cfg(FALSE)] if true {};
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
12
src/test/ui/if-attrs/builtin-if-attr.rs
Normal file
12
src/test/ui/if-attrs/builtin-if-attr.rs
Normal file
@ -0,0 +1,12 @@
|
||||
// check-pass
|
||||
|
||||
fn main() {
|
||||
#[allow(unused_variables)]
|
||||
if true {
|
||||
let a = 1;
|
||||
} else if false {
|
||||
let b = 1;
|
||||
} else {
|
||||
let c = 1;
|
||||
}
|
||||
}
|
43
src/test/ui/if-attrs/cfg-false-if-attr.rs
Normal file
43
src/test/ui/if-attrs/cfg-false-if-attr.rs
Normal file
@ -0,0 +1,43 @@
|
||||
// check-pass
|
||||
|
||||
#[cfg(FALSE)]
|
||||
fn simple_attr() {
|
||||
#[attr] if true {}
|
||||
#[allow_warnings] if true {}
|
||||
}
|
||||
|
||||
#[cfg(FALSE)]
|
||||
fn if_else_chain() {
|
||||
#[first_attr] if true {
|
||||
} else if false {
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(FALSE)]
|
||||
fn if_let() {
|
||||
#[attr] if let Some(_) = Some(true) {}
|
||||
}
|
||||
|
||||
fn bar() {
|
||||
#[cfg(FALSE)]
|
||||
if true {
|
||||
let x: () = true; // Should not error due to the #[cfg(FALSE)]
|
||||
}
|
||||
|
||||
#[cfg_attr(not(unset_attr), cfg(FALSE))]
|
||||
if true {
|
||||
let a: () = true; // Should not error due to the applied #[cfg(FALSE)]
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! custom_macro {
|
||||
($expr:expr) => {}
|
||||
}
|
||||
|
||||
custom_macro! {
|
||||
#[attr] if true {}
|
||||
}
|
||||
|
||||
|
||||
fn main() {}
|
25
src/test/ui/if-attrs/else-attrs.rs
Normal file
25
src/test/ui/if-attrs/else-attrs.rs
Normal file
@ -0,0 +1,25 @@
|
||||
#[cfg(FALSE)]
|
||||
fn if_else_parse_error() {
|
||||
if true {
|
||||
} #[attr] else if false { //~ ERROR expected
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(FALSE)]
|
||||
fn else_attr_ifparse_error() {
|
||||
if true {
|
||||
} else #[attr] if false { //~ ERROR expected
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(FALSE)]
|
||||
fn else_parse_error() {
|
||||
if true {
|
||||
} else if false {
|
||||
} #[attr] else { //~ ERROR expected
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
}
|
27
src/test/ui/if-attrs/else-attrs.stderr
Normal file
27
src/test/ui/if-attrs/else-attrs.stderr
Normal file
@ -0,0 +1,27 @@
|
||||
error: expected expression, found keyword `else`
|
||||
--> $DIR/else-attrs.rs:4:15
|
||||
|
|
||||
LL | } #[attr] else if false {
|
||||
| ^^^^ expected expression
|
||||
|
||||
error: expected `{`, found `#`
|
||||
--> $DIR/else-attrs.rs:11:12
|
||||
|
|
||||
LL | } else #[attr] if false {
|
||||
| ^ expected `{`
|
||||
|
|
||||
help: try placing this code inside a block
|
||||
|
|
||||
LL | } else #[attr] { if false {
|
||||
LL | } else {
|
||||
LL | } }
|
||||
|
|
||||
|
||||
error: expected expression, found keyword `else`
|
||||
--> $DIR/else-attrs.rs:20:15
|
||||
|
|
||||
LL | } #[attr] else {
|
||||
| ^^^^ expected expression
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
15
src/test/ui/if-attrs/gate-whole-expr.rs
Normal file
15
src/test/ui/if-attrs/gate-whole-expr.rs
Normal file
@ -0,0 +1,15 @@
|
||||
// run-pass
|
||||
|
||||
fn main() {
|
||||
let x = 1;
|
||||
|
||||
#[cfg(FALSE)]
|
||||
if false {
|
||||
x = 2;
|
||||
} else if true {
|
||||
x = 3;
|
||||
} else {
|
||||
x = 4;
|
||||
}
|
||||
assert_eq!(x, 1);
|
||||
}
|
13
src/test/ui/if-attrs/let-chains-attr.rs
Normal file
13
src/test/ui/if-attrs/let-chains-attr.rs
Normal file
@ -0,0 +1,13 @@
|
||||
// check-pass
|
||||
|
||||
#![feature(let_chains)] //~ WARN the feature `let_chains` is incomplete
|
||||
|
||||
#[cfg(FALSE)]
|
||||
fn foo() {
|
||||
#[attr]
|
||||
if let Some(_) = Some(true) && let Ok(_) = Ok(1) {
|
||||
} else if let Some(false) = Some(true) {
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
8
src/test/ui/if-attrs/let-chains-attr.stderr
Normal file
8
src/test/ui/if-attrs/let-chains-attr.stderr
Normal file
@ -0,0 +1,8 @@
|
||||
warning: the feature `let_chains` is incomplete and may cause the compiler to crash
|
||||
--> $DIR/let-chains-attr.rs:3:12
|
||||
|
|
||||
LL | #![feature(let_chains)]
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
|
6
src/test/ui/if-attrs/stmt-expr-gated.rs
Normal file
6
src/test/ui/if-attrs/stmt-expr-gated.rs
Normal file
@ -0,0 +1,6 @@
|
||||
fn main() {
|
||||
let _ = #[deny(warnings)] if true { //~ ERROR attributes on expressions
|
||||
} else if false {
|
||||
} else {
|
||||
};
|
||||
}
|
12
src/test/ui/if-attrs/stmt-expr-gated.stderr
Normal file
12
src/test/ui/if-attrs/stmt-expr-gated.stderr
Normal file
@ -0,0 +1,12 @@
|
||||
error[E0658]: attributes on expressions are experimental
|
||||
--> $DIR/stmt-expr-gated.rs:2:13
|
||||
|
|
||||
LL | let _ = #[deny(warnings)] if true {
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
|
||||
= help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
@ -38,8 +38,6 @@ fn main() {}
|
||||
//~^ ERROR an inner attribute is not permitted in this context
|
||||
#[cfg(FALSE)] fn e() { let _ = #[attr] &mut #![attr] 0; }
|
||||
//~^ ERROR an inner attribute is not permitted in this context
|
||||
#[cfg(FALSE)] fn e() { let _ = #[attr] if 0 {}; }
|
||||
//~^ ERROR attributes are not yet allowed on `if` expressions
|
||||
#[cfg(FALSE)] fn e() { let _ = if 0 #[attr] {}; }
|
||||
//~^ ERROR expected `{`, found `#`
|
||||
#[cfg(FALSE)] fn e() { let _ = if 0 {#![attr]}; }
|
||||
@ -51,14 +49,11 @@ fn main() {}
|
||||
#[cfg(FALSE)] fn e() { let _ = if 0 {} else {#![attr]}; }
|
||||
//~^ ERROR an inner attribute is not permitted in this context
|
||||
#[cfg(FALSE)] fn e() { let _ = if 0 {} else #[attr] if 0 {}; }
|
||||
//~^ ERROR attributes are not yet allowed on `if` expressions
|
||||
//~| ERROR expected `{`, found `#`
|
||||
//~^ ERROR expected `{`, found `#`
|
||||
#[cfg(FALSE)] fn e() { let _ = if 0 {} else if 0 #[attr] {}; }
|
||||
//~^ ERROR expected `{`, found `#`
|
||||
#[cfg(FALSE)] fn e() { let _ = if 0 {} else if 0 {#![attr]}; }
|
||||
//~^ ERROR an inner attribute is not permitted in this context
|
||||
#[cfg(FALSE)] fn e() { let _ = #[attr] if let _ = 0 {}; }
|
||||
//~^ ERROR attributes are not yet allowed on `if` expressions
|
||||
#[cfg(FALSE)] fn e() { let _ = if let _ = 0 #[attr] {}; }
|
||||
//~^ ERROR expected `{`, found `#`
|
||||
#[cfg(FALSE)] fn e() { let _ = if let _ = 0 {#![attr]}; }
|
||||
@ -70,8 +65,7 @@ fn main() {}
|
||||
#[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else {#![attr]}; }
|
||||
//~^ ERROR an inner attribute is not permitted in this context
|
||||
#[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else #[attr] if let _ = 0 {}; }
|
||||
//~^ ERROR attributes are not yet allowed on `if` expressions
|
||||
//~| ERROR expected `{`, found `#`
|
||||
//~^ ERROR expected `{`, found `#`
|
||||
#[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else if let _ = 0 #[attr] {}; }
|
||||
//~^ ERROR expected `{`, found `#`
|
||||
#[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else if let _ = 0 {#![attr]}; }
|
||||
|
@ -136,14 +136,8 @@ LL | #[cfg(FALSE)] fn e() { let _ = #[attr] &mut #![attr] 0; }
|
||||
|
|
||||
= note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them.
|
||||
|
||||
error: attributes are not yet allowed on `if` expressions
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:41:32
|
||||
|
|
||||
LL | #[cfg(FALSE)] fn e() { let _ = #[attr] if 0 {}; }
|
||||
| ^^^^^^^
|
||||
|
||||
error: expected `{`, found `#`
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:43:37
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:41:37
|
||||
|
|
||||
LL | #[cfg(FALSE)] fn e() { let _ = if 0 #[attr] {}; }
|
||||
| -- ^ --- help: try placing this code inside a block: `{ {}; }`
|
||||
@ -152,7 +146,7 @@ LL | #[cfg(FALSE)] fn e() { let _ = if 0 #[attr] {}; }
|
||||
| this `if` expression has a condition, but no block
|
||||
|
||||
error: an inner attribute is not permitted in this context
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:45:38
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:43:38
|
||||
|
|
||||
LL | #[cfg(FALSE)] fn e() { let _ = if 0 {#![attr]}; }
|
||||
| ^^^^^^^^
|
||||
@ -160,13 +154,13 @@ LL | #[cfg(FALSE)] fn e() { let _ = if 0 {#![attr]}; }
|
||||
= note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them.
|
||||
|
||||
error: expected one of `.`, `;`, `?`, `else`, or an operator, found `#`
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:47:40
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:45:40
|
||||
|
|
||||
LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} #[attr] else {}; }
|
||||
| ^ expected one of `.`, `;`, `?`, `else`, or an operator
|
||||
|
||||
error: expected `{`, found `#`
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:49:45
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:47:45
|
||||
|
|
||||
LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} else #[attr] {}; }
|
||||
| ^ --- help: try placing this code inside a block: `{ {}; }`
|
||||
@ -174,21 +168,15 @@ LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} else #[attr] {}; }
|
||||
| expected `{`
|
||||
|
||||
error: an inner attribute is not permitted in this context
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:51:46
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:49:46
|
||||
|
|
||||
LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} else {#![attr]}; }
|
||||
| ^^^^^^^^
|
||||
|
|
||||
= note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them.
|
||||
|
||||
error: attributes are not yet allowed on `if` expressions
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:53:45
|
||||
|
|
||||
LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} else #[attr] if 0 {}; }
|
||||
| ^^^^^^^
|
||||
|
||||
error: expected `{`, found `#`
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:53:45
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:51:45
|
||||
|
|
||||
LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} else #[attr] if 0 {}; }
|
||||
| ^ -------- help: try placing this code inside a block: `{ if 0 {}; }`
|
||||
@ -196,7 +184,7 @@ LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} else #[attr] if 0 {}; }
|
||||
| expected `{`
|
||||
|
||||
error: expected `{`, found `#`
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:56:50
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:53:50
|
||||
|
|
||||
LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} else if 0 #[attr] {}; }
|
||||
| -- ^ --- help: try placing this code inside a block: `{ {}; }`
|
||||
@ -205,21 +193,15 @@ LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} else if 0 #[attr] {}; }
|
||||
| this `if` expression has a condition, but no block
|
||||
|
||||
error: an inner attribute is not permitted in this context
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:58:51
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:55:51
|
||||
|
|
||||
LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} else if 0 {#![attr]}; }
|
||||
| ^^^^^^^^
|
||||
|
|
||||
= note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them.
|
||||
|
||||
error: attributes are not yet allowed on `if` expressions
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:60:32
|
||||
|
|
||||
LL | #[cfg(FALSE)] fn e() { let _ = #[attr] if let _ = 0 {}; }
|
||||
| ^^^^^^^
|
||||
|
||||
error: expected `{`, found `#`
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:62:45
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:57:45
|
||||
|
|
||||
LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 #[attr] {}; }
|
||||
| -- ^ --- help: try placing this code inside a block: `{ {}; }`
|
||||
@ -228,7 +210,7 @@ LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 #[attr] {}; }
|
||||
| this `if` expression has a condition, but no block
|
||||
|
||||
error: an inner attribute is not permitted in this context
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:64:46
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:59:46
|
||||
|
|
||||
LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {#![attr]}; }
|
||||
| ^^^^^^^^
|
||||
@ -236,13 +218,13 @@ LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {#![attr]}; }
|
||||
= note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them.
|
||||
|
||||
error: expected one of `.`, `;`, `?`, `else`, or an operator, found `#`
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:66:48
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:61:48
|
||||
|
|
||||
LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} #[attr] else {}; }
|
||||
| ^ expected one of `.`, `;`, `?`, `else`, or an operator
|
||||
|
||||
error: expected `{`, found `#`
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:68:53
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:63:53
|
||||
|
|
||||
LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else #[attr] {}; }
|
||||
| ^ --- help: try placing this code inside a block: `{ {}; }`
|
||||
@ -250,21 +232,15 @@ LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else #[attr] {}; }
|
||||
| expected `{`
|
||||
|
||||
error: an inner attribute is not permitted in this context
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:70:54
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:65:54
|
||||
|
|
||||
LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else {#![attr]}; }
|
||||
| ^^^^^^^^
|
||||
|
|
||||
= note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them.
|
||||
|
||||
error: attributes are not yet allowed on `if` expressions
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:72:53
|
||||
|
|
||||
LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else #[attr] if let _ = 0 {}; }
|
||||
| ^^^^^^^
|
||||
|
||||
error: expected `{`, found `#`
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:72:53
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:67:53
|
||||
|
|
||||
LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else #[attr] if let _ = 0 {}; }
|
||||
| ^ ---------------- help: try placing this code inside a block: `{ if let _ = 0 {}; }`
|
||||
@ -272,7 +248,7 @@ LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else #[attr] if let _ = 0 {}
|
||||
| expected `{`
|
||||
|
||||
error: expected `{`, found `#`
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:75:66
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:69:66
|
||||
|
|
||||
LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else if let _ = 0 #[attr] {}; }
|
||||
| -- ^ --- help: try placing this code inside a block: `{ {}; }`
|
||||
@ -281,7 +257,7 @@ LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else if let _ = 0 #[attr] {}
|
||||
| this `if` expression has a condition, but no block
|
||||
|
||||
error: an inner attribute is not permitted in this context
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:77:67
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:71:67
|
||||
|
|
||||
LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else if let _ = 0 {#![attr]}; }
|
||||
| ^^^^^^^^
|
||||
@ -289,7 +265,7 @@ LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else if let _ = 0 {#![attr]}
|
||||
= note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them.
|
||||
|
||||
error: an inner attribute is not permitted following an outer attribute
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:80:32
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:74:32
|
||||
|
|
||||
LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] let _ = 0; }
|
||||
| ------- ^^^^^^^^ not permitted following an outer attribute
|
||||
@ -299,7 +275,7 @@ LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] let _ = 0; }
|
||||
= note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them.
|
||||
|
||||
error: an inner attribute is not permitted following an outer attribute
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:82:32
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:76:32
|
||||
|
|
||||
LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] 0; }
|
||||
| ------- ^^^^^^^^ not permitted following an outer attribute
|
||||
@ -309,7 +285,7 @@ LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] 0; }
|
||||
= note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them.
|
||||
|
||||
error: an inner attribute is not permitted following an outer attribute
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:84:32
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:78:32
|
||||
|
|
||||
LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] foo!(); }
|
||||
| ------- ^^^^^^^^ not permitted following an outer attribute
|
||||
@ -319,7 +295,7 @@ LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] foo!(); }
|
||||
= note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them.
|
||||
|
||||
error: an inner attribute is not permitted following an outer attribute
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:86:32
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:80:32
|
||||
|
|
||||
LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] foo![]; }
|
||||
| ------- ^^^^^^^^ not permitted following an outer attribute
|
||||
@ -329,7 +305,7 @@ LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] foo![]; }
|
||||
= note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them.
|
||||
|
||||
error: an inner attribute is not permitted following an outer attribute
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:88:32
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:82:32
|
||||
|
|
||||
LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] foo!{}; }
|
||||
| ------- ^^^^^^^^ not permitted following an outer attribute
|
||||
@ -339,7 +315,7 @@ LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] foo!{}; }
|
||||
= note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them.
|
||||
|
||||
error[E0586]: inclusive range with no end
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:94:35
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:88:35
|
||||
|
|
||||
LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] 10 => () } }
|
||||
| ^^^ help: use `..` instead
|
||||
@ -347,13 +323,13 @@ LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] 10 => () } }
|
||||
= note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||
|
||||
error: expected one of `=>`, `if`, or `|`, found `#`
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:94:38
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:88:38
|
||||
|
|
||||
LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] 10 => () } }
|
||||
| ^ expected one of `=>`, `if`, or `|`
|
||||
|
||||
error[E0586]: inclusive range with no end
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:97:35
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:91:35
|
||||
|
|
||||
LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] -10 => () } }
|
||||
| ^^^ help: use `..` instead
|
||||
@ -361,19 +337,19 @@ LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] -10 => () } }
|
||||
= note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||
|
||||
error: expected one of `=>`, `if`, or `|`, found `#`
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:97:38
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:91:38
|
||||
|
|
||||
LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] -10 => () } }
|
||||
| ^ expected one of `=>`, `if`, or `|`
|
||||
|
||||
error: unexpected token: `#`
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:100:39
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:94:39
|
||||
|
|
||||
LL | #[cfg(FALSE)] fn e() { match 0 { 0..=-#[attr] 10 => () } }
|
||||
| ^
|
||||
|
||||
error[E0586]: inclusive range with no end
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:102:35
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:96:35
|
||||
|
|
||||
LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] FOO => () } }
|
||||
| ^^^ help: use `..` instead
|
||||
@ -381,47 +357,47 @@ LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] FOO => () } }
|
||||
= note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||
|
||||
error: expected one of `=>`, `if`, or `|`, found `#`
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:102:38
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:96:38
|
||||
|
|
||||
LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] FOO => () } }
|
||||
| ^ expected one of `=>`, `if`, or `|`
|
||||
|
||||
error: unexpected token: `#`
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:106:34
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:100:34
|
||||
|
|
||||
LL | #[cfg(FALSE)] fn e() { let _ = x.#![attr]foo(); }
|
||||
| ^
|
||||
|
||||
error: expected one of `.`, `;`, `?`, or an operator, found `#`
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:106:34
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:100:34
|
||||
|
|
||||
LL | #[cfg(FALSE)] fn e() { let _ = x.#![attr]foo(); }
|
||||
| ^ expected one of `.`, `;`, `?`, or an operator
|
||||
|
||||
error: unexpected token: `#`
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:109:34
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:103:34
|
||||
|
|
||||
LL | #[cfg(FALSE)] fn e() { let _ = x.#[attr]foo(); }
|
||||
| ^
|
||||
|
||||
error: expected one of `.`, `;`, `?`, or an operator, found `#`
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:109:34
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:103:34
|
||||
|
|
||||
LL | #[cfg(FALSE)] fn e() { let _ = x.#[attr]foo(); }
|
||||
| ^ expected one of `.`, `;`, `?`, or an operator
|
||||
|
||||
error: expected statement after outer attribute
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:114:37
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:108:37
|
||||
|
|
||||
LL | #[cfg(FALSE)] fn e() { { fn foo() { #[attr]; } } }
|
||||
| ^^^^^^^
|
||||
|
||||
error: expected statement after outer attribute
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:116:37
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:110:37
|
||||
|
|
||||
LL | #[cfg(FALSE)] fn e() { { fn foo() { #[attr] } } }
|
||||
| ^^^^^^^
|
||||
|
||||
error: aborting due to 57 previous errors
|
||||
error: aborting due to 53 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0586`.
|
||||
|
@ -1,9 +0,0 @@
|
||||
fn main() {
|
||||
#[attr] if true {};
|
||||
//~^ ERROR cannot find attribute
|
||||
//~| ERROR attributes are not yet allowed on `if` expressions
|
||||
#[attr] if true {};
|
||||
//~^ ERROR cannot find attribute
|
||||
//~| ERROR attributes are not yet allowed on `if` expressions
|
||||
let _recovery_witness: () = 0; //~ ERROR mismatched types
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
error: attributes are not yet allowed on `if` expressions
|
||||
--> $DIR/recovery-attr-on-if.rs:2:5
|
||||
|
|
||||
LL | #[attr] if true {};
|
||||
| ^^^^^^^
|
||||
|
||||
error: attributes are not yet allowed on `if` expressions
|
||||
--> $DIR/recovery-attr-on-if.rs:5:5
|
||||
|
|
||||
LL | #[attr] if true {};
|
||||
| ^^^^^^^
|
||||
|
||||
error: cannot find attribute `attr` in this scope
|
||||
--> $DIR/recovery-attr-on-if.rs:5:7
|
||||
|
|
||||
LL | #[attr] if true {};
|
||||
| ^^^^
|
||||
|
||||
error: cannot find attribute `attr` in this scope
|
||||
--> $DIR/recovery-attr-on-if.rs:2:7
|
||||
|
|
||||
LL | #[attr] if true {};
|
||||
| ^^^^
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/recovery-attr-on-if.rs:8:33
|
||||
|
|
||||
LL | let _recovery_witness: () = 0;
|
||||
| -- ^ expected `()`, found integer
|
||||
| |
|
||||
| expected due to this
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
Loading…
Reference in New Issue
Block a user