From f63b88c761f935d9b2c220a1b4e3abf0c0681c69 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Sat, 15 Feb 2020 19:04:20 -0500 Subject: 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]`) 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 {} ``` --- src/test/pretty/if-attr.rs | 28 +++++++++++++++++++ src/test/ui/parser/attr-stmt-expr-attr-bad.rs | 10 ++----- src/test/ui/parser/if-attrs/cfg-false-if-attr.rs | 31 ++++++++++++++++++++++ src/test/ui/parser/if-attrs/else-attrs.rs | 25 +++++++++++++++++ src/test/ui/parser/if-attrs/else-attrs.stderr | 27 +++++++++++++++++++ src/test/ui/parser/if-attrs/let-chains-attr.rs | 13 +++++++++ src/test/ui/parser/if-attrs/let-chains-attr.stderr | 8 ++++++ src/test/ui/parser/recovery-attr-on-if.rs | 2 -- src/test/ui/parser/recovery-attr-on-if.stderr | 18 +++---------- 9 files changed, 137 insertions(+), 25 deletions(-) create mode 100644 src/test/pretty/if-attr.rs create mode 100644 src/test/ui/parser/if-attrs/cfg-false-if-attr.rs create mode 100644 src/test/ui/parser/if-attrs/else-attrs.rs create mode 100644 src/test/ui/parser/if-attrs/else-attrs.stderr create mode 100644 src/test/ui/parser/if-attrs/let-chains-attr.rs create mode 100644 src/test/ui/parser/if-attrs/let-chains-attr.stderr (limited to 'src/test') diff --git a/src/test/pretty/if-attr.rs b/src/test/pretty/if-attr.rs new file mode 100644 index 00000000000..463476737a9 --- /dev/null +++ b/src/test/pretty/if-attr.rs @@ -0,0 +1,28 @@ +// 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) { } +} + + +fn main() { } diff --git a/src/test/ui/parser/attr-stmt-expr-attr-bad.rs b/src/test/ui/parser/attr-stmt-expr-attr-bad.rs index 118bff8144c..f3980a59648 100644 --- a/src/test/ui/parser/attr-stmt-expr-attr-bad.rs +++ b/src/test/ui/parser/attr-stmt-expr-attr-bad.rs @@ -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]}; } diff --git a/src/test/ui/parser/if-attrs/cfg-false-if-attr.rs b/src/test/ui/parser/if-attrs/cfg-false-if-attr.rs new file mode 100644 index 00000000000..2932ec1a231 --- /dev/null +++ b/src/test/ui/parser/if-attrs/cfg-false-if-attr.rs @@ -0,0 +1,31 @@ +// 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) {} +} + +macro_rules! custom_macro { + ($expr:expr) => {} +} + +custom_macro! { + #[attr] if true {} +} + + +fn main() {} diff --git a/src/test/ui/parser/if-attrs/else-attrs.rs b/src/test/ui/parser/if-attrs/else-attrs.rs new file mode 100644 index 00000000000..4394b2100c1 --- /dev/null +++ b/src/test/ui/parser/if-attrs/else-attrs.rs @@ -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() { +} diff --git a/src/test/ui/parser/if-attrs/else-attrs.stderr b/src/test/ui/parser/if-attrs/else-attrs.stderr new file mode 100644 index 00000000000..af25b6abc0a --- /dev/null +++ b/src/test/ui/parser/if-attrs/else-attrs.stderr @@ -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 + diff --git a/src/test/ui/parser/if-attrs/let-chains-attr.rs b/src/test/ui/parser/if-attrs/let-chains-attr.rs new file mode 100644 index 00000000000..5237a9ff396 --- /dev/null +++ b/src/test/ui/parser/if-attrs/let-chains-attr.rs @@ -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() {} diff --git a/src/test/ui/parser/if-attrs/let-chains-attr.stderr b/src/test/ui/parser/if-attrs/let-chains-attr.stderr new file mode 100644 index 00000000000..a6c91bb9203 --- /dev/null +++ b/src/test/ui/parser/if-attrs/let-chains-attr.stderr @@ -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 + diff --git a/src/test/ui/parser/recovery-attr-on-if.rs b/src/test/ui/parser/recovery-attr-on-if.rs index 0d1f5be7b49..b4fb25ec8d3 100644 --- a/src/test/ui/parser/recovery-attr-on-if.rs +++ b/src/test/ui/parser/recovery-attr-on-if.rs @@ -1,9 +1,7 @@ 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 } diff --git a/src/test/ui/parser/recovery-attr-on-if.stderr b/src/test/ui/parser/recovery-attr-on-if.stderr index a02846827c9..cbf2714a1a1 100644 --- a/src/test/ui/parser/recovery-attr-on-if.stderr +++ b/src/test/ui/parser/recovery-attr-on-if.stderr @@ -1,17 +1,5 @@ -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 + --> $DIR/recovery-attr-on-if.rs:4:7 | LL | #[attr] if true {}; | ^^^^ @@ -23,13 +11,13 @@ LL | #[attr] if true {}; | ^^^^ error[E0308]: mismatched types - --> $DIR/recovery-attr-on-if.rs:8:33 + --> $DIR/recovery-attr-on-if.rs:6:33 | LL | let _recovery_witness: () = 0; | -- ^ expected `()`, found integer | | | expected due to this -error: aborting due to 5 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0308`. -- cgit 1.4.1-3-g733a5 From e912d9d7ecd9d326affd18f7b133dafb72ee8896 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Sat, 15 Feb 2020 19:13:36 -0500 Subject: Test #[allow(unused)] on `if` expression --- src/test/ui/parser/if-attrs/builtin-if-attr.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 src/test/ui/parser/if-attrs/builtin-if-attr.rs (limited to 'src/test') diff --git a/src/test/ui/parser/if-attrs/builtin-if-attr.rs b/src/test/ui/parser/if-attrs/builtin-if-attr.rs new file mode 100644 index 00000000000..7e290661501 --- /dev/null +++ b/src/test/ui/parser/if-attrs/builtin-if-attr.rs @@ -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; + } +} -- cgit 1.4.1-3-g733a5 From e9ec47bb70810f972e6565d496120b0b00f261f0 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Wed, 19 Feb 2020 10:45:21 -0500 Subject: Test that stmt_expr_attrs properly gates if-attrs --- src/test/ui/parser/if-attrs/stmt-expr-gated.rs | 6 ++++++ src/test/ui/parser/if-attrs/stmt-expr-gated.stderr | 12 ++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 src/test/ui/parser/if-attrs/stmt-expr-gated.rs create mode 100644 src/test/ui/parser/if-attrs/stmt-expr-gated.stderr (limited to 'src/test') diff --git a/src/test/ui/parser/if-attrs/stmt-expr-gated.rs b/src/test/ui/parser/if-attrs/stmt-expr-gated.rs new file mode 100644 index 00000000000..38599c8e67c --- /dev/null +++ b/src/test/ui/parser/if-attrs/stmt-expr-gated.rs @@ -0,0 +1,6 @@ +fn main() { + let _ = #[deny(warnings)] if true { //~ ERROR attributes on expressions + } else if false { + } else { + }; +} diff --git a/src/test/ui/parser/if-attrs/stmt-expr-gated.stderr b/src/test/ui/parser/if-attrs/stmt-expr-gated.stderr new file mode 100644 index 00000000000..47dac39a9ae --- /dev/null +++ b/src/test/ui/parser/if-attrs/stmt-expr-gated.stderr @@ -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 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`. -- cgit 1.4.1-3-g733a5 From 9a299e4e210ff91ec59bf9f09bdb402196e02bd5 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Wed, 19 Feb 2020 10:47:27 -0500 Subject: Test trying to cfg-remove an `if` expression --- src/test/ui/parser/if-attrs/bad-cfg.rs | 5 +++++ src/test/ui/parser/if-attrs/bad-cfg.stderr | 8 ++++++++ 2 files changed, 13 insertions(+) create mode 100644 src/test/ui/parser/if-attrs/bad-cfg.rs create mode 100644 src/test/ui/parser/if-attrs/bad-cfg.stderr (limited to 'src/test') diff --git a/src/test/ui/parser/if-attrs/bad-cfg.rs b/src/test/ui/parser/if-attrs/bad-cfg.rs new file mode 100644 index 00000000000..3f84929a00e --- /dev/null +++ b/src/test/ui/parser/if-attrs/bad-cfg.rs @@ -0,0 +1,5 @@ +#![feature(stmt_expr_attributes)] + +fn main() { + let _ = #[cfg(FALSE)] if true {}; //~ ERROR removing an expression +} diff --git a/src/test/ui/parser/if-attrs/bad-cfg.stderr b/src/test/ui/parser/if-attrs/bad-cfg.stderr new file mode 100644 index 00000000000..8a2890886a1 --- /dev/null +++ b/src/test/ui/parser/if-attrs/bad-cfg.stderr @@ -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 + -- cgit 1.4.1-3-g733a5 From b00f6745c4df0e979dd53dcbf43ededf5728e349 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Wed, 19 Feb 2020 10:48:13 -0500 Subject: Remove recovery test --- src/test/ui/parser/recovery-attr-on-if.rs | 7 ------- src/test/ui/parser/recovery-attr-on-if.stderr | 23 ----------------------- 2 files changed, 30 deletions(-) delete mode 100644 src/test/ui/parser/recovery-attr-on-if.rs delete mode 100644 src/test/ui/parser/recovery-attr-on-if.stderr (limited to 'src/test') diff --git a/src/test/ui/parser/recovery-attr-on-if.rs b/src/test/ui/parser/recovery-attr-on-if.rs deleted file mode 100644 index b4fb25ec8d3..00000000000 --- a/src/test/ui/parser/recovery-attr-on-if.rs +++ /dev/null @@ -1,7 +0,0 @@ -fn main() { - #[attr] if true {}; - //~^ ERROR cannot find attribute - #[attr] if true {}; - //~^ ERROR cannot find attribute - let _recovery_witness: () = 0; //~ ERROR mismatched types -} diff --git a/src/test/ui/parser/recovery-attr-on-if.stderr b/src/test/ui/parser/recovery-attr-on-if.stderr deleted file mode 100644 index cbf2714a1a1..00000000000 --- a/src/test/ui/parser/recovery-attr-on-if.stderr +++ /dev/null @@ -1,23 +0,0 @@ -error: cannot find attribute `attr` in this scope - --> $DIR/recovery-attr-on-if.rs:4: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:6:33 - | -LL | let _recovery_witness: () = 0; - | -- ^ expected `()`, found integer - | | - | expected due to this - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0308`. -- cgit 1.4.1-3-g733a5 From e11cdfdae48f8793c618834227114bcb5a6d57bd Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Wed, 19 Feb 2020 10:49:34 -0500 Subject: Add run-pass test suggested by @joshtriplett --- src/test/ui/parser/if-attrs/gate-whole-expr.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 src/test/ui/parser/if-attrs/gate-whole-expr.rs (limited to 'src/test') diff --git a/src/test/ui/parser/if-attrs/gate-whole-expr.rs b/src/test/ui/parser/if-attrs/gate-whole-expr.rs new file mode 100644 index 00000000000..efce28e1d5b --- /dev/null +++ b/src/test/ui/parser/if-attrs/gate-whole-expr.rs @@ -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); +} -- cgit 1.4.1-3-g733a5 From 7f19358c9ef51a130e0177d327eaac5adc6d73ad Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Wed, 19 Feb 2020 10:50:03 -0500 Subject: Move if-attr tests to their own directory --- src/test/ui/if-attrs/bad-cfg.rs | 5 ++++ src/test/ui/if-attrs/bad-cfg.stderr | 8 ++++++ src/test/ui/if-attrs/builtin-if-attr.rs | 12 +++++++++ src/test/ui/if-attrs/cfg-false-if-attr.rs | 31 ++++++++++++++++++++++ src/test/ui/if-attrs/else-attrs.rs | 25 +++++++++++++++++ src/test/ui/if-attrs/else-attrs.stderr | 27 +++++++++++++++++++ src/test/ui/if-attrs/gate-whole-expr.rs | 15 +++++++++++ src/test/ui/if-attrs/let-chains-attr.rs | 13 +++++++++ src/test/ui/if-attrs/let-chains-attr.stderr | 8 ++++++ src/test/ui/if-attrs/stmt-expr-gated.rs | 6 +++++ src/test/ui/if-attrs/stmt-expr-gated.stderr | 12 +++++++++ src/test/ui/parser/if-attrs/bad-cfg.rs | 5 ---- src/test/ui/parser/if-attrs/bad-cfg.stderr | 8 ------ src/test/ui/parser/if-attrs/builtin-if-attr.rs | 12 --------- src/test/ui/parser/if-attrs/cfg-false-if-attr.rs | 31 ---------------------- src/test/ui/parser/if-attrs/else-attrs.rs | 25 ----------------- src/test/ui/parser/if-attrs/else-attrs.stderr | 27 ------------------- src/test/ui/parser/if-attrs/gate-whole-expr.rs | 15 ----------- src/test/ui/parser/if-attrs/let-chains-attr.rs | 13 --------- src/test/ui/parser/if-attrs/let-chains-attr.stderr | 8 ------ src/test/ui/parser/if-attrs/stmt-expr-gated.rs | 6 ----- src/test/ui/parser/if-attrs/stmt-expr-gated.stderr | 12 --------- 22 files changed, 162 insertions(+), 162 deletions(-) create mode 100644 src/test/ui/if-attrs/bad-cfg.rs create mode 100644 src/test/ui/if-attrs/bad-cfg.stderr create mode 100644 src/test/ui/if-attrs/builtin-if-attr.rs create mode 100644 src/test/ui/if-attrs/cfg-false-if-attr.rs create mode 100644 src/test/ui/if-attrs/else-attrs.rs create mode 100644 src/test/ui/if-attrs/else-attrs.stderr create mode 100644 src/test/ui/if-attrs/gate-whole-expr.rs create mode 100644 src/test/ui/if-attrs/let-chains-attr.rs create mode 100644 src/test/ui/if-attrs/let-chains-attr.stderr create mode 100644 src/test/ui/if-attrs/stmt-expr-gated.rs create mode 100644 src/test/ui/if-attrs/stmt-expr-gated.stderr delete mode 100644 src/test/ui/parser/if-attrs/bad-cfg.rs delete mode 100644 src/test/ui/parser/if-attrs/bad-cfg.stderr delete mode 100644 src/test/ui/parser/if-attrs/builtin-if-attr.rs delete mode 100644 src/test/ui/parser/if-attrs/cfg-false-if-attr.rs delete mode 100644 src/test/ui/parser/if-attrs/else-attrs.rs delete mode 100644 src/test/ui/parser/if-attrs/else-attrs.stderr delete mode 100644 src/test/ui/parser/if-attrs/gate-whole-expr.rs delete mode 100644 src/test/ui/parser/if-attrs/let-chains-attr.rs delete mode 100644 src/test/ui/parser/if-attrs/let-chains-attr.stderr delete mode 100644 src/test/ui/parser/if-attrs/stmt-expr-gated.rs delete mode 100644 src/test/ui/parser/if-attrs/stmt-expr-gated.stderr (limited to 'src/test') diff --git a/src/test/ui/if-attrs/bad-cfg.rs b/src/test/ui/if-attrs/bad-cfg.rs new file mode 100644 index 00000000000..3f84929a00e --- /dev/null +++ b/src/test/ui/if-attrs/bad-cfg.rs @@ -0,0 +1,5 @@ +#![feature(stmt_expr_attributes)] + +fn main() { + let _ = #[cfg(FALSE)] if true {}; //~ ERROR removing an expression +} diff --git a/src/test/ui/if-attrs/bad-cfg.stderr b/src/test/ui/if-attrs/bad-cfg.stderr new file mode 100644 index 00000000000..8a2890886a1 --- /dev/null +++ b/src/test/ui/if-attrs/bad-cfg.stderr @@ -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 + diff --git a/src/test/ui/if-attrs/builtin-if-attr.rs b/src/test/ui/if-attrs/builtin-if-attr.rs new file mode 100644 index 00000000000..7e290661501 --- /dev/null +++ b/src/test/ui/if-attrs/builtin-if-attr.rs @@ -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; + } +} diff --git a/src/test/ui/if-attrs/cfg-false-if-attr.rs b/src/test/ui/if-attrs/cfg-false-if-attr.rs new file mode 100644 index 00000000000..2932ec1a231 --- /dev/null +++ b/src/test/ui/if-attrs/cfg-false-if-attr.rs @@ -0,0 +1,31 @@ +// 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) {} +} + +macro_rules! custom_macro { + ($expr:expr) => {} +} + +custom_macro! { + #[attr] if true {} +} + + +fn main() {} diff --git a/src/test/ui/if-attrs/else-attrs.rs b/src/test/ui/if-attrs/else-attrs.rs new file mode 100644 index 00000000000..4394b2100c1 --- /dev/null +++ b/src/test/ui/if-attrs/else-attrs.rs @@ -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() { +} diff --git a/src/test/ui/if-attrs/else-attrs.stderr b/src/test/ui/if-attrs/else-attrs.stderr new file mode 100644 index 00000000000..af25b6abc0a --- /dev/null +++ b/src/test/ui/if-attrs/else-attrs.stderr @@ -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 + diff --git a/src/test/ui/if-attrs/gate-whole-expr.rs b/src/test/ui/if-attrs/gate-whole-expr.rs new file mode 100644 index 00000000000..efce28e1d5b --- /dev/null +++ b/src/test/ui/if-attrs/gate-whole-expr.rs @@ -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); +} diff --git a/src/test/ui/if-attrs/let-chains-attr.rs b/src/test/ui/if-attrs/let-chains-attr.rs new file mode 100644 index 00000000000..5237a9ff396 --- /dev/null +++ b/src/test/ui/if-attrs/let-chains-attr.rs @@ -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() {} diff --git a/src/test/ui/if-attrs/let-chains-attr.stderr b/src/test/ui/if-attrs/let-chains-attr.stderr new file mode 100644 index 00000000000..a6c91bb9203 --- /dev/null +++ b/src/test/ui/if-attrs/let-chains-attr.stderr @@ -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 + diff --git a/src/test/ui/if-attrs/stmt-expr-gated.rs b/src/test/ui/if-attrs/stmt-expr-gated.rs new file mode 100644 index 00000000000..38599c8e67c --- /dev/null +++ b/src/test/ui/if-attrs/stmt-expr-gated.rs @@ -0,0 +1,6 @@ +fn main() { + let _ = #[deny(warnings)] if true { //~ ERROR attributes on expressions + } else if false { + } else { + }; +} diff --git a/src/test/ui/if-attrs/stmt-expr-gated.stderr b/src/test/ui/if-attrs/stmt-expr-gated.stderr new file mode 100644 index 00000000000..47dac39a9ae --- /dev/null +++ b/src/test/ui/if-attrs/stmt-expr-gated.stderr @@ -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 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`. diff --git a/src/test/ui/parser/if-attrs/bad-cfg.rs b/src/test/ui/parser/if-attrs/bad-cfg.rs deleted file mode 100644 index 3f84929a00e..00000000000 --- a/src/test/ui/parser/if-attrs/bad-cfg.rs +++ /dev/null @@ -1,5 +0,0 @@ -#![feature(stmt_expr_attributes)] - -fn main() { - let _ = #[cfg(FALSE)] if true {}; //~ ERROR removing an expression -} diff --git a/src/test/ui/parser/if-attrs/bad-cfg.stderr b/src/test/ui/parser/if-attrs/bad-cfg.stderr deleted file mode 100644 index 8a2890886a1..00000000000 --- a/src/test/ui/parser/if-attrs/bad-cfg.stderr +++ /dev/null @@ -1,8 +0,0 @@ -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 - diff --git a/src/test/ui/parser/if-attrs/builtin-if-attr.rs b/src/test/ui/parser/if-attrs/builtin-if-attr.rs deleted file mode 100644 index 7e290661501..00000000000 --- a/src/test/ui/parser/if-attrs/builtin-if-attr.rs +++ /dev/null @@ -1,12 +0,0 @@ -// check-pass - -fn main() { - #[allow(unused_variables)] - if true { - let a = 1; - } else if false { - let b = 1; - } else { - let c = 1; - } -} diff --git a/src/test/ui/parser/if-attrs/cfg-false-if-attr.rs b/src/test/ui/parser/if-attrs/cfg-false-if-attr.rs deleted file mode 100644 index 2932ec1a231..00000000000 --- a/src/test/ui/parser/if-attrs/cfg-false-if-attr.rs +++ /dev/null @@ -1,31 +0,0 @@ -// 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) {} -} - -macro_rules! custom_macro { - ($expr:expr) => {} -} - -custom_macro! { - #[attr] if true {} -} - - -fn main() {} diff --git a/src/test/ui/parser/if-attrs/else-attrs.rs b/src/test/ui/parser/if-attrs/else-attrs.rs deleted file mode 100644 index 4394b2100c1..00000000000 --- a/src/test/ui/parser/if-attrs/else-attrs.rs +++ /dev/null @@ -1,25 +0,0 @@ -#[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() { -} diff --git a/src/test/ui/parser/if-attrs/else-attrs.stderr b/src/test/ui/parser/if-attrs/else-attrs.stderr deleted file mode 100644 index af25b6abc0a..00000000000 --- a/src/test/ui/parser/if-attrs/else-attrs.stderr +++ /dev/null @@ -1,27 +0,0 @@ -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 - diff --git a/src/test/ui/parser/if-attrs/gate-whole-expr.rs b/src/test/ui/parser/if-attrs/gate-whole-expr.rs deleted file mode 100644 index efce28e1d5b..00000000000 --- a/src/test/ui/parser/if-attrs/gate-whole-expr.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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); -} diff --git a/src/test/ui/parser/if-attrs/let-chains-attr.rs b/src/test/ui/parser/if-attrs/let-chains-attr.rs deleted file mode 100644 index 5237a9ff396..00000000000 --- a/src/test/ui/parser/if-attrs/let-chains-attr.rs +++ /dev/null @@ -1,13 +0,0 @@ -// 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() {} diff --git a/src/test/ui/parser/if-attrs/let-chains-attr.stderr b/src/test/ui/parser/if-attrs/let-chains-attr.stderr deleted file mode 100644 index a6c91bb9203..00000000000 --- a/src/test/ui/parser/if-attrs/let-chains-attr.stderr +++ /dev/null @@ -1,8 +0,0 @@ -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 - diff --git a/src/test/ui/parser/if-attrs/stmt-expr-gated.rs b/src/test/ui/parser/if-attrs/stmt-expr-gated.rs deleted file mode 100644 index 38599c8e67c..00000000000 --- a/src/test/ui/parser/if-attrs/stmt-expr-gated.rs +++ /dev/null @@ -1,6 +0,0 @@ -fn main() { - let _ = #[deny(warnings)] if true { //~ ERROR attributes on expressions - } else if false { - } else { - }; -} diff --git a/src/test/ui/parser/if-attrs/stmt-expr-gated.stderr b/src/test/ui/parser/if-attrs/stmt-expr-gated.stderr deleted file mode 100644 index 47dac39a9ae..00000000000 --- a/src/test/ui/parser/if-attrs/stmt-expr-gated.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0658]: attributes on expressions are experimental - --> $DIR/stmt-expr-gated.rs:2:13 - | -LL | let _ = #[deny(warnings)] if true { - | ^^^^^^^^^^^^^^^^^ - | - = note: see issue #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`. -- cgit 1.4.1-3-g733a5 From 1b681d6652bacce6b741ca66725f25b9afb16bc8 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Wed, 19 Feb 2020 11:01:51 -0500 Subject: Test that cfg-gated if-exprs are not type-checked --- src/test/ui/if-attrs/cfg-false-if-attr.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'src/test') diff --git a/src/test/ui/if-attrs/cfg-false-if-attr.rs b/src/test/ui/if-attrs/cfg-false-if-attr.rs index 2932ec1a231..1f77a1bb342 100644 --- a/src/test/ui/if-attrs/cfg-false-if-attr.rs +++ b/src/test/ui/if-attrs/cfg-false-if-attr.rs @@ -19,6 +19,18 @@ 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) => {} } -- cgit 1.4.1-3-g733a5 From 37c2c38aeb0d50f7b956200c698bc59fce6e7181 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Wed, 19 Feb 2020 11:05:31 -0500 Subject: Extent pretty-print test --- src/test/pretty/if-attr.rs | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src/test') diff --git a/src/test/pretty/if-attr.rs b/src/test/pretty/if-attr.rs index 463476737a9..652604fc7f3 100644 --- a/src/test/pretty/if-attr.rs +++ b/src/test/pretty/if-attr.rs @@ -24,5 +24,14 @@ fn if_let() { 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() { } -- cgit 1.4.1-3-g733a5 From 66b152cf9fd53b27027c66378a73404b92c6e35b Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Wed, 19 Feb 2020 11:36:04 -0500 Subject: Fix tabs --- src/test/ui/if-attrs/gate-whole-expr.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'src/test') diff --git a/src/test/ui/if-attrs/gate-whole-expr.rs b/src/test/ui/if-attrs/gate-whole-expr.rs index efce28e1d5b..63772d54b53 100644 --- a/src/test/ui/if-attrs/gate-whole-expr.rs +++ b/src/test/ui/if-attrs/gate-whole-expr.rs @@ -1,15 +1,15 @@ // run-pass fn main() { - let x = 1; + let x = 1; - #[cfg(FALSE)] - if false { - x = 2; - } else if true { - x = 3; - } else { - x = 4; - } - assert_eq!(x, 1); + #[cfg(FALSE)] + if false { + x = 2; + } else if true { + x = 3; + } else { + x = 4; + } + assert_eq!(x, 1); } -- cgit 1.4.1-3-g733a5 From e50fd5a3dc587b5b970b6b969eff7e8547dede70 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Wed, 4 Mar 2020 16:54:16 -0500 Subject: Update stderr --- src/test/ui/parser/attr-stmt-expr-attr-bad.stderr | 94 +++++++++-------------- 1 file changed, 35 insertions(+), 59 deletions(-) (limited to 'src/test') diff --git a/src/test/ui/parser/attr-stmt-expr-attr-bad.stderr b/src/test/ui/parser/attr-stmt-expr-attr-bad.stderr index b03db85422d..3cc3a455c12 100644 --- a/src/test/ui/parser/attr-stmt-expr-attr-bad.stderr +++ b/src/test/ui/parser/attr-stmt-expr-attr-bad.stderr @@ -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 attibute @@ -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 attibute @@ -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 attibute @@ -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 attibute @@ -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 attibute @@ -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`. -- cgit 1.4.1-3-g733a5 From 4971d03ccfe9452753deb84fd958fd0b0e63f156 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 5 Mar 2020 23:31:39 +0100 Subject: fix some cases of unexpected exceptions leaving validation --- src/librustc/mir/interpret/error.rs | 13 +++-- src/librustc_mir/const_eval/eval_queries.rs | 7 ++- src/librustc_mir/interpret/eval_context.rs | 12 +--- src/librustc_mir/interpret/place.rs | 8 +-- src/librustc_mir/interpret/validity.rs | 64 +++++++++++++++++----- src/librustc_mir/transform/const_prop.rs | 5 +- src/test/ui/consts/const-eval/dangling.rs | 2 +- src/test/ui/consts/const-eval/dangling.stderr | 2 +- src/test/ui/consts/const-eval/ub-wide-ptr.rs | 6 +- src/test/ui/consts/const-eval/ub-wide-ptr.stderr | 58 +++++++++++++------- src/test/ui/consts/const-points-to-static.stderr | 2 +- src/test/ui/consts/issue-63952.stderr | 2 +- .../miri_unleashed/const_refers_to_static.stderr | 4 +- 13 files changed, 122 insertions(+), 63 deletions(-) (limited to 'src/test') diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs index 2310867400c..731c3ee0d6a 100644 --- a/src/librustc/mir/interpret/error.rs +++ b/src/librustc/mir/interpret/error.rs @@ -245,7 +245,7 @@ fn print_backtrace(backtrace: &mut Backtrace) { eprintln!("\n\nAn error occurred in miri:\n{:?}", backtrace); } -impl From for InterpErrorInfo<'tcx> { +impl From for InterpErrorInfo<'_> { fn from(err: ErrorHandled) -> Self { match err { ErrorHandled::Reported => err_inval!(ReferencedConstant), @@ -291,7 +291,7 @@ pub enum InvalidProgramInfo<'tcx> { Layout(layout::LayoutError<'tcx>), } -impl fmt::Debug for InvalidProgramInfo<'tcx> { +impl fmt::Debug for InvalidProgramInfo<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { use InvalidProgramInfo::*; match self { @@ -304,7 +304,7 @@ impl fmt::Debug for InvalidProgramInfo<'tcx> { } /// Error information for when the program caused Undefined Behavior. -pub enum UndefinedBehaviorInfo { +pub enum UndefinedBehaviorInfo<'tcx> { /// Free-form case. Only for errors that are never caught! Ub(String), /// Free-form case for experimental UB. Only for errors that are never caught! @@ -321,9 +321,11 @@ pub enum UndefinedBehaviorInfo { RemainderByZero, /// Overflowing inbounds pointer arithmetic. PointerArithOverflow, + /// Invalid metadata in a wide pointer (using `str` to avoid allocations). + InvalidMeta(&'tcx str), } -impl fmt::Debug for UndefinedBehaviorInfo { +impl fmt::Debug for UndefinedBehaviorInfo<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { use UndefinedBehaviorInfo::*; match self { @@ -338,6 +340,7 @@ impl fmt::Debug for UndefinedBehaviorInfo { DivisionByZero => write!(f, "dividing by zero"), RemainderByZero => write!(f, "calculating the remainder with a divisor of zero"), PointerArithOverflow => write!(f, "overflowing in-bounds pointer arithmetic"), + InvalidMeta(msg) => write!(f, "invalid metadata in wide pointer: {}", msg), } } } @@ -577,7 +580,7 @@ impl fmt::Debug for ResourceExhaustionInfo { pub enum InterpError<'tcx> { /// The program caused undefined behavior. - UndefinedBehavior(UndefinedBehaviorInfo), + UndefinedBehavior(UndefinedBehaviorInfo<'tcx>), /// The program did something the interpreter does not support (some of these *might* be UB /// but the interpreter is not sure). Unsupported(UnsupportedOpInfo<'tcx>), diff --git a/src/librustc_mir/const_eval/eval_queries.rs b/src/librustc_mir/const_eval/eval_queries.rs index 7a8e61db6d0..ffbff00cf37 100644 --- a/src/librustc_mir/const_eval/eval_queries.rs +++ b/src/librustc_mir/const_eval/eval_queries.rs @@ -186,7 +186,12 @@ fn validate_and_turn_into_const<'tcx>( if cid.promoted.is_none() { let mut ref_tracking = RefTracking::new(mplace); while let Some((mplace, path)) = ref_tracking.todo.pop() { - ecx.validate_operand(mplace.into(), path, Some(&mut ref_tracking))?; + ecx.const_validate_operand( + mplace.into(), + path, + &mut ref_tracking, + /*may_ref_to_static*/ is_static, + )?; } } // Now that we validated, turn this into a proper constant. diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index e683422e611..9b28b7a20c0 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -457,10 +457,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // Check if this brought us over the size limit. if size.bytes() >= self.tcx.data_layout().obj_size_bound() { - throw_ub_format!( - "wide pointer metadata contains invalid information: \ - total size is bigger than largest supported object" - ); + throw_ub!(InvalidMeta("total size is bigger than largest supported object")); } Ok(Some((size, align))) } @@ -476,10 +473,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // Make sure the slice is not too big. let size = elem.size.checked_mul(len, &*self.tcx).ok_or_else(|| { - err_ub_format!( - "invalid slice: \ - total size is bigger than largest supported object" - ) + err_ub!(InvalidMeta("slice is bigger than largest supported object")) })?; Ok(Some((size, elem.align.abi))) } @@ -685,7 +679,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // invariant -- that is, unless a function somehow has a ptr to // its return place... but the way MIR is currently generated, the // return place is always a local and then this cannot happen. - self.validate_operand(self.place_to_op(return_place)?, vec![], None)?; + self.validate_operand(self.place_to_op(return_place)?)?; } } else { // Uh, that shouldn't happen... the function did not intend to return diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index fff9c740f7e..a4815b9696e 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -689,7 +689,7 @@ where if M::enforce_validity(self) { // Data got changed, better make sure it matches the type! - self.validate_operand(self.place_to_op(dest)?, vec![], None)?; + self.validate_operand(self.place_to_op(dest)?)?; } Ok(()) @@ -706,7 +706,7 @@ where if M::enforce_validity(self) { // Data got changed, better make sure it matches the type! - self.validate_operand(dest.into(), vec![], None)?; + self.validate_operand(dest.into())?; } Ok(()) @@ -843,7 +843,7 @@ where if M::enforce_validity(self) { // Data got changed, better make sure it matches the type! - self.validate_operand(self.place_to_op(dest)?, vec![], None)?; + self.validate_operand(self.place_to_op(dest)?)?; } Ok(()) @@ -951,7 +951,7 @@ where if M::enforce_validity(self) { // Data got changed, better make sure it matches the type! - self.validate_operand(dest.into(), vec![], None)?; + self.validate_operand(dest.into())?; } Ok(()) diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs index b3de44f36d2..05bb010959b 100644 --- a/src/librustc_mir/interpret/validity.rs +++ b/src/librustc_mir/interpret/validity.rs @@ -171,6 +171,7 @@ struct ValidityVisitor<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> { path: Vec, ref_tracking_for_consts: Option<&'rt mut RefTracking, Vec>>, + may_ref_to_static: bool, ecx: &'rt InterpCx<'mir, 'tcx, M>, } @@ -324,9 +325,17 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, 'tcx, M self.check_wide_ptr_meta(place.meta, place.layout)?; } // Make sure this is dereferenceable and all. - let (size, align) = self - .ecx - .size_and_align_of(place.meta, place.layout)? + let size_and_align = match self.ecx.size_and_align_of(place.meta, place.layout) { + Ok(res) => res, + Err(err) => match err.kind { + err_ub!(InvalidMeta(msg)) => throw_validation_failure!( + format_args!("invalid {} metadata: {}", kind, msg), + self.path + ), + _ => bug!("Unexpected error during ptr size_and_align_of: {}", err), + }, + }; + let (size, align) = size_and_align // for the purpose of validity, consider foreign types to have // alignment and size determined by the layout (size will be 0, // alignment should take attributes into account). @@ -387,6 +396,12 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, 'tcx, M if !did.is_local() || self.ecx.tcx.is_foreign_item(did) { return Ok(()); } + if !self.may_ref_to_static && self.ecx.tcx.is_static(did) { + throw_validation_failure!( + format_args!("a {} pointing to a static variable", kind), + self.path + ); + } } } // Proceed recursively even for ZST, no reason to skip them! @@ -781,26 +796,20 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> } impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { - /// This function checks the data at `op`. `op` is assumed to cover valid memory if it - /// is an indirect operand. - /// It will error if the bits at the destination do not match the ones described by the layout. - /// - /// `ref_tracking_for_consts` can be `None` to avoid recursive checking below references. - /// This also toggles between "run-time" (no recursion) and "compile-time" (with recursion) - /// validation (e.g., pointer values are fine in integers at runtime) and various other const - /// specific validation checks. - pub fn validate_operand( + fn validate_operand_internal( &self, op: OpTy<'tcx, M::PointerTag>, path: Vec, ref_tracking_for_consts: Option< &mut RefTracking, Vec>, >, + may_ref_to_static: bool, ) -> InterpResult<'tcx> { - trace!("validate_operand: {:?}, {:?}", *op, op.layout.ty); + trace!("validate_operand_internal: {:?}, {:?}", *op, op.layout.ty); // Construct a visitor - let mut visitor = ValidityVisitor { path, ref_tracking_for_consts, ecx: self }; + let mut visitor = + ValidityVisitor { path, ref_tracking_for_consts, may_ref_to_static, ecx: self }; // Try to cast to ptr *once* instead of all the time. let op = self.force_op_ptr(op).unwrap_or(op); @@ -815,4 +824,31 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Err(err) => Err(err), } } + + /// This function checks the data at `op` to be const-valid. + /// `op` is assumed to cover valid memory if it is an indirect operand. + /// It will error if the bits at the destination do not match the ones described by the layout. + /// + /// `ref_tracking` is used to record references that we encounter so that they + /// can be checked recursively by an outside driving loop. + /// + /// `may_ref_to_static` controls whether references are allowed to point to statics. + #[inline(always)] + pub fn const_validate_operand( + &self, + op: OpTy<'tcx, M::PointerTag>, + path: Vec, + ref_tracking: &mut RefTracking, Vec>, + may_ref_to_static: bool, + ) -> InterpResult<'tcx> { + self.validate_operand_internal(op, path, Some(ref_tracking), may_ref_to_static) + } + + /// This function checks the data at `op` to be runtime-valid. + /// `op` is assumed to cover valid memory if it is an indirect operand. + /// It will error if the bits at the destination do not match the ones described by the layout. + #[inline(always)] + pub fn validate_operand(&self, op: OpTy<'tcx, M::PointerTag>) -> InterpResult<'tcx> { + self.validate_operand_internal(op, vec![], None, false) + } } diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 1fea9281b93..a07c8575b30 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -637,11 +637,12 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { source_info: SourceInfo, ) { trace!("attepting to replace {:?} with {:?}", rval, value); - if let Err(e) = self.ecx.validate_operand( + if let Err(e) = self.ecx.const_validate_operand( value, vec![], // FIXME: is ref tracking too expensive? - Some(&mut interpret::RefTracking::empty()), + &mut interpret::RefTracking::empty(), + /*may_ref_to_static*/ true, ) { trace!("validation error, attempt failed: {:?}", e); return; diff --git a/src/test/ui/consts/const-eval/dangling.rs b/src/test/ui/consts/const-eval/dangling.rs index b5d72d46f28..c6b8e8eb611 100644 --- a/src/test/ui/consts/const-eval/dangling.rs +++ b/src/test/ui/consts/const-eval/dangling.rs @@ -6,7 +6,7 @@ use std::{mem, usize}; const TEST: () = { unsafe { //~ NOTE let slice: *const [u8] = mem::transmute((1usize, usize::MAX)); let _val = &*slice; //~ ERROR: any use of this value will cause an error - //~^ NOTE: total size is bigger than largest supported object + //~^ NOTE: slice is bigger than largest supported object //~^^ on by default } }; diff --git a/src/test/ui/consts/const-eval/dangling.stderr b/src/test/ui/consts/const-eval/dangling.stderr index 286de080097..b9ddc93b03b 100644 --- a/src/test/ui/consts/const-eval/dangling.stderr +++ b/src/test/ui/consts/const-eval/dangling.stderr @@ -4,7 +4,7 @@ error: any use of this value will cause an error LL | / const TEST: () = { unsafe { LL | | let slice: *const [u8] = mem::transmute((1usize, usize::MAX)); LL | | let _val = &*slice; - | | ^^^^^^^ invalid slice: total size is bigger than largest supported object + | | ^^^^^^^ invalid metadata in wide pointer: slice is bigger than largest supported object LL | | LL | | LL | | } }; diff --git a/src/test/ui/consts/const-eval/ub-wide-ptr.rs b/src/test/ui/consts/const-eval/ub-wide-ptr.rs index 26d37884746..2d48309b727 100644 --- a/src/test/ui/consts/const-eval/ub-wide-ptr.rs +++ b/src/test/ui/consts/const-eval/ub-wide-ptr.rs @@ -31,12 +31,16 @@ const STR_VALID: &str = unsafe { mem::transmute((&42u8, 1usize)) }; // bad str const STR_TOO_LONG: &str = unsafe { mem::transmute((&42u8, 999usize)) }; //~^ ERROR it is undefined behavior to use this value +const NESTED_STR_MUCH_TOO_LONG: (&str,) = (unsafe { mem::transmute((&42, usize::MAX)) },); +//~^ ERROR it is undefined behavior to use this value // bad str const STR_LENGTH_PTR: &str = unsafe { mem::transmute((&42u8, &3)) }; //~^ ERROR it is undefined behavior to use this value // bad str in user-defined unsized type const MY_STR_LENGTH_PTR: &MyStr = unsafe { mem::transmute((&42u8, &3)) }; //~^ ERROR it is undefined behavior to use this value +const MY_STR_MUCH_TOO_LONG: &MyStr = unsafe { mem::transmute((&42u8, usize::MAX)) }; +//~^ ERROR it is undefined behavior to use this value // invalid UTF-8 const STR_NO_UTF8: &str = unsafe { mem::transmute::<&[u8], _>(&[0xFF]) }; @@ -83,7 +87,7 @@ const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute // # raw slice const RAW_SLICE_VALID: *const [u8] = unsafe { mem::transmute((&42u8, 1usize)) }; // ok const RAW_SLICE_TOO_LONG: *const [u8] = unsafe { mem::transmute((&42u8, 999usize)) }; // ok because raw -const RAW_SLICE_MUCH_TOO_LONG: *const [u8] = unsafe { mem::transmute((&42u8, usize::max_value())) }; // ok because raw +const RAW_SLICE_MUCH_TOO_LONG: *const [u8] = unsafe { mem::transmute((&42u8, usize::MAX)) }; // ok because raw const RAW_SLICE_LENGTH_UNINIT: *const [u8] = unsafe { //~^ ERROR it is undefined behavior to use this value let uninit_len = MaybeUninit:: { uninit: () }; diff --git a/src/test/ui/consts/const-eval/ub-wide-ptr.stderr b/src/test/ui/consts/const-eval/ub-wide-ptr.stderr index 22adf0e55ee..a562c64b124 100644 --- a/src/test/ui/consts/const-eval/ub-wide-ptr.stderr +++ b/src/test/ui/consts/const-eval/ub-wide-ptr.stderr @@ -7,7 +7,15 @@ LL | const STR_TOO_LONG: &str = unsafe { mem::transmute((&42u8, 999usize)) }; = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:35:1 + --> $DIR/ub-wide-ptr.rs:34:1 + | +LL | const NESTED_STR_MUCH_TOO_LONG: (&str,) = (unsafe { mem::transmute((&42, usize::MAX)) },); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered invalid reference metadata: slice is bigger than largest supported object at .0 + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-wide-ptr.rs:37:1 | LL | const STR_LENGTH_PTR: &str = unsafe { mem::transmute((&42u8, &3)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-integer slice length in wide pointer @@ -15,7 +23,7 @@ LL | const STR_LENGTH_PTR: &str = unsafe { mem::transmute((&42u8, &3)) }; = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:38:1 + --> $DIR/ub-wide-ptr.rs:40:1 | LL | const MY_STR_LENGTH_PTR: &MyStr = unsafe { mem::transmute((&42u8, &3)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-integer slice length in wide pointer @@ -25,13 +33,21 @@ LL | const MY_STR_LENGTH_PTR: &MyStr = unsafe { mem::transmute((&42u8, &3)) }; error[E0080]: it is undefined behavior to use this value --> $DIR/ub-wide-ptr.rs:42:1 | +LL | const MY_STR_MUCH_TOO_LONG: &MyStr = unsafe { mem::transmute((&42u8, usize::MAX)) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered invalid reference metadata: slice is bigger than largest supported object + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-wide-ptr.rs:46:1 + | LL | const STR_NO_UTF8: &str = unsafe { mem::transmute::<&[u8], _>(&[0xFF]) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized or non-UTF-8 data in str at . | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:45:1 + --> $DIR/ub-wide-ptr.rs:49:1 | LL | const MYSTR_NO_UTF8: &MyStr = unsafe { mem::transmute::<&[u8], _>(&[0xFF]) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized or non-UTF-8 data in str at ..0 @@ -39,7 +55,7 @@ LL | const MYSTR_NO_UTF8: &MyStr = unsafe { mem::transmute::<&[u8], _>(&[0xFF]) = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:52:1 + --> $DIR/ub-wide-ptr.rs:56:1 | LL | / const SLICE_LENGTH_UNINIT: &[u8] = unsafe { LL | | @@ -51,7 +67,7 @@ LL | | }; = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:58:1 + --> $DIR/ub-wide-ptr.rs:62:1 | LL | const SLICE_TOO_LONG: &[u8] = unsafe { mem::transmute((&42u8, 999usize)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a dangling reference (not entirely in bounds) @@ -59,7 +75,7 @@ LL | const SLICE_TOO_LONG: &[u8] = unsafe { mem::transmute((&42u8, 999usize)) }; = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:61:1 + --> $DIR/ub-wide-ptr.rs:65:1 | LL | const SLICE_LENGTH_PTR: &[u8] = unsafe { mem::transmute((&42u8, &3)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-integer slice length in wide pointer @@ -67,7 +83,7 @@ LL | const SLICE_LENGTH_PTR: &[u8] = unsafe { mem::transmute((&42u8, &3)) }; = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:64:1 + --> $DIR/ub-wide-ptr.rs:68:1 | LL | const SLICE_TOO_LONG_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, 999usize)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a dangling box (not entirely in bounds) @@ -75,7 +91,7 @@ LL | const SLICE_TOO_LONG_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, 999us = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:67:1 + --> $DIR/ub-wide-ptr.rs:71:1 | LL | const SLICE_LENGTH_PTR_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, &3)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-integer slice length in wide pointer @@ -83,7 +99,7 @@ LL | const SLICE_LENGTH_PTR_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, &3) = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:71:1 + --> $DIR/ub-wide-ptr.rs:75:1 | LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 3 at .[0], but expected a boolean @@ -91,7 +107,7 @@ LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }]; = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:77:1 + --> $DIR/ub-wide-ptr.rs:81:1 | LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 3 at ..0, but expected a boolean @@ -99,7 +115,7 @@ LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3 = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:80:1 + --> $DIR/ub-wide-ptr.rs:84:1 | LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 3 at ..1[0], but expected a boolean @@ -107,7 +123,7 @@ LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::tran = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:87:1 + --> $DIR/ub-wide-ptr.rs:91:1 | LL | / const RAW_SLICE_LENGTH_UNINIT: *const [u8] = unsafe { LL | | @@ -119,7 +135,7 @@ LL | | }; = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:95:1 + --> $DIR/ub-wide-ptr.rs:99:1 | LL | const TRAIT_OBJ_SHORT_VTABLE_1: &dyn Trait = unsafe { mem::transmute((&92u8, &3u8)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer in wide pointer or too small vtable @@ -127,7 +143,7 @@ LL | const TRAIT_OBJ_SHORT_VTABLE_1: &dyn Trait = unsafe { mem::transmute((&92u8 = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:98:1 + --> $DIR/ub-wide-ptr.rs:102:1 | LL | const TRAIT_OBJ_SHORT_VTABLE_2: &dyn Trait = unsafe { mem::transmute((&92u8, &3u64)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer in wide pointer or too small vtable @@ -135,7 +151,7 @@ LL | const TRAIT_OBJ_SHORT_VTABLE_2: &dyn Trait = unsafe { mem::transmute((&92u8 = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:101:1 + --> $DIR/ub-wide-ptr.rs:105:1 | LL | const TRAIT_OBJ_INT_VTABLE: &dyn Trait = unsafe { mem::transmute((&92u8, 4usize)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer in wide pointer or too small vtable @@ -143,7 +159,7 @@ LL | const TRAIT_OBJ_INT_VTABLE: &dyn Trait = unsafe { mem::transmute((&92u8, 4u = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:105:1 + --> $DIR/ub-wide-ptr.rs:109:1 | LL | const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_, &bool>(&3u8) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 3 at .., but expected a boolean @@ -151,7 +167,7 @@ LL | const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_, = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:109:1 + --> $DIR/ub-wide-ptr.rs:113:1 | LL | const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute((&92u8, 0usize)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer in wide pointer or too small vtable @@ -159,7 +175,7 @@ LL | const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:111:1 + --> $DIR/ub-wide-ptr.rs:115:1 | LL | const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transmute((&92u8, &3u64)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer in wide pointer or too small vtable @@ -167,17 +183,17 @@ LL | const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transm = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. error[E0080]: could not evaluate static initializer - --> $DIR/ub-wide-ptr.rs:117:5 + --> $DIR/ub-wide-ptr.rs:121:5 | LL | mem::transmute::<_, &dyn Trait>((&92u8, 0usize)) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid use of NULL pointer error[E0080]: could not evaluate static initializer - --> $DIR/ub-wide-ptr.rs:121:5 + --> $DIR/ub-wide-ptr.rs:125:5 | LL | mem::transmute::<_, &dyn Trait>((&92u8, &3u64)) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Memory access failed: pointer must be in-bounds at offset N, but is outside bounds of allocation N which has size N -error: aborting due to 22 previous errors +error: aborting due to 24 previous errors For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-points-to-static.stderr b/src/test/ui/consts/const-points-to-static.stderr index 8949358e293..f2ca7ff7825 100644 --- a/src/test/ui/consts/const-points-to-static.stderr +++ b/src/test/ui/consts/const-points-to-static.stderr @@ -8,7 +8,7 @@ error[E0080]: it is undefined behavior to use this value --> $DIR/const-points-to-static.rs:5:1 | LL | const TEST: &u8 = &MY_STATIC; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a reference pointing to a static variable | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. diff --git a/src/test/ui/consts/issue-63952.stderr b/src/test/ui/consts/issue-63952.stderr index d5ed970fc35..5e85be45b16 100644 --- a/src/test/ui/consts/issue-63952.stderr +++ b/src/test/ui/consts/issue-63952.stderr @@ -8,7 +8,7 @@ LL | | ptr: &42, ... | LL | | .slice LL | | }; - | |__^ invalid slice: total size is bigger than largest supported object + | |__^ type validation failed: encountered invalid reference metadata: slice is bigger than largest supported object | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. diff --git a/src/test/ui/consts/miri_unleashed/const_refers_to_static.stderr b/src/test/ui/consts/miri_unleashed/const_refers_to_static.stderr index 15e13942481..ad777cfe8ea 100644 --- a/src/test/ui/consts/miri_unleashed/const_refers_to_static.stderr +++ b/src/test/ui/consts/miri_unleashed/const_refers_to_static.stderr @@ -48,7 +48,7 @@ LL | | static FOO: AtomicUsize = AtomicUsize::new(0); LL | | unsafe { &*(&FOO as *const _ as *const usize) } LL | | LL | | }; - | |__^ constant accesses static + | |__^ type validation failed: encountered a reference pointing to a static variable | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. @@ -97,7 +97,7 @@ LL | | static FOO: usize = 0; LL | | &FOO LL | | LL | | }; - | |__^ constant accesses static + | |__^ type validation failed: encountered a reference pointing to a static variable | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. -- cgit 1.4.1-3-g733a5 From af0c44cb2908989159322a4f2bf6ce046a7be5fc Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Mon, 9 Mar 2020 09:11:40 +0900 Subject: Add test for issue-54239 --- .../issue-54239-private-type-triggers-lint.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 src/test/ui/async-await/issue-54239-private-type-triggers-lint.rs (limited to 'src/test') diff --git a/src/test/ui/async-await/issue-54239-private-type-triggers-lint.rs b/src/test/ui/async-await/issue-54239-private-type-triggers-lint.rs new file mode 100644 index 00000000000..16cf7ad52e4 --- /dev/null +++ b/src/test/ui/async-await/issue-54239-private-type-triggers-lint.rs @@ -0,0 +1,17 @@ +// Regression test for #54239, shouldn't trigger lint. +// check-pass +// edition:2018 + +#![deny(missing_debug_implementations)] + +struct DontLookAtMe(i32); + +async fn secret() -> DontLookAtMe { + DontLookAtMe(41) +} + +pub async fn looking() -> i32 { // Shouldn't trigger lint here. + secret().await.0 +} + +fn main() {} -- cgit 1.4.1-3-g733a5 From fc8be08a8e786514819ffff7c4239879afb8ea3c Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Mon, 9 Mar 2020 09:11:58 +0900 Subject: Add test for issue-57200 --- src/test/ui/impl-trait/issue-57200.rs | 14 ++++++++++++++ src/test/ui/impl-trait/issue-57200.stderr | 8 ++++++++ 2 files changed, 22 insertions(+) create mode 100644 src/test/ui/impl-trait/issue-57200.rs create mode 100644 src/test/ui/impl-trait/issue-57200.stderr (limited to 'src/test') diff --git a/src/test/ui/impl-trait/issue-57200.rs b/src/test/ui/impl-trait/issue-57200.rs new file mode 100644 index 00000000000..9a7290b3b75 --- /dev/null +++ b/src/test/ui/impl-trait/issue-57200.rs @@ -0,0 +1,14 @@ +// Regression test for #57200 + +#![feature(impl_trait_in_bindings)] +#![allow(incomplete_features)] + +fn bug<'a, 'b, T>() +where + 'a: 'b, +{ + let f: impl Fn(&'a T) -> &'b T = |x| x; + //~^ ERROR: lifetimes in impl Trait types in bindings are not currently supported +} + +fn main() {} diff --git a/src/test/ui/impl-trait/issue-57200.stderr b/src/test/ui/impl-trait/issue-57200.stderr new file mode 100644 index 00000000000..42fd0045315 --- /dev/null +++ b/src/test/ui/impl-trait/issue-57200.stderr @@ -0,0 +1,8 @@ +error: lifetimes in impl Trait types in bindings are not currently supported + --> $DIR/issue-57200.rs:10:12 + | +LL | let f: impl Fn(&'a T) -> &'b T = |x| x; + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + -- cgit 1.4.1-3-g733a5 From 437c07f6621739037e52560f54a880acaaaf27ac Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Mon, 9 Mar 2020 09:12:06 +0900 Subject: Add test for issue-57201 --- src/test/ui/impl-trait/issue-57201.rs | 14 ++++++++++++++ src/test/ui/impl-trait/issue-57201.stderr | 8 ++++++++ 2 files changed, 22 insertions(+) create mode 100644 src/test/ui/impl-trait/issue-57201.rs create mode 100644 src/test/ui/impl-trait/issue-57201.stderr (limited to 'src/test') diff --git a/src/test/ui/impl-trait/issue-57201.rs b/src/test/ui/impl-trait/issue-57201.rs new file mode 100644 index 00000000000..79b19b52d20 --- /dev/null +++ b/src/test/ui/impl-trait/issue-57201.rs @@ -0,0 +1,14 @@ +// Regression test for #57201 + +#![feature(impl_trait_in_bindings)] +#![allow(incomplete_features)] + +fn bug<'a, 'b, T>() +where + 'a: 'b, +{ + let f: &impl Fn(&'a T) -> &'b T = &|x| x; + //~^ ERROR: lifetimes in impl Trait types in bindings are not currently supported +} + +fn main() {} diff --git a/src/test/ui/impl-trait/issue-57201.stderr b/src/test/ui/impl-trait/issue-57201.stderr new file mode 100644 index 00000000000..5defd15b6b5 --- /dev/null +++ b/src/test/ui/impl-trait/issue-57201.stderr @@ -0,0 +1,8 @@ +error: lifetimes in impl Trait types in bindings are not currently supported + --> $DIR/issue-57201.rs:10:13 + | +LL | let f: &impl Fn(&'a T) -> &'b T = &|x| x; + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + -- cgit 1.4.1-3-g733a5 From 0005f29d89e9b5ab59f9159acb7aab51b5dad187 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Mon, 9 Mar 2020 09:12:25 +0900 Subject: Add test for issue-60473 --- src/test/ui/impl-trait/issue-60473.rs | 16 ++++++++++++++++ src/test/ui/impl-trait/issue-60473.stderr | 11 +++++++++++ 2 files changed, 27 insertions(+) create mode 100644 src/test/ui/impl-trait/issue-60473.rs create mode 100644 src/test/ui/impl-trait/issue-60473.stderr (limited to 'src/test') diff --git a/src/test/ui/impl-trait/issue-60473.rs b/src/test/ui/impl-trait/issue-60473.rs new file mode 100644 index 00000000000..596d8a2dd74 --- /dev/null +++ b/src/test/ui/impl-trait/issue-60473.rs @@ -0,0 +1,16 @@ +// Regression test for #60473 + +#![feature(impl_trait_in_bindings)] +#![allow(incomplete_features)] + +struct A<'a>(&'a ()); + +trait Trait { +} + +impl Trait for () { +} + +fn main() { + let x: impl Trait = (); //~ ERROR: opaque type expands to a recursive type +} diff --git a/src/test/ui/impl-trait/issue-60473.stderr b/src/test/ui/impl-trait/issue-60473.stderr new file mode 100644 index 00000000000..6a07f29727c --- /dev/null +++ b/src/test/ui/impl-trait/issue-60473.stderr @@ -0,0 +1,11 @@ +error[E0720]: opaque type expands to a recursive type + --> $DIR/issue-60473.rs:15:12 + | +LL | let x: impl Trait = (); + | ^^^^^^^^^^^^^ expands to a recursive type + | + = note: type resolves to itself + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0720`. -- cgit 1.4.1-3-g733a5 From 95d478546ff3b3b3f533e6b86274bde432148ab3 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Mon, 9 Mar 2020 09:12:41 +0900 Subject: Add test for issue-64620 --- src/test/ui/generator/issue-64620-yield-array-element.rs | 9 +++++++++ src/test/ui/generator/issue-64620-yield-array-element.stderr | 9 +++++++++ 2 files changed, 18 insertions(+) create mode 100644 src/test/ui/generator/issue-64620-yield-array-element.rs create mode 100644 src/test/ui/generator/issue-64620-yield-array-element.stderr (limited to 'src/test') diff --git a/src/test/ui/generator/issue-64620-yield-array-element.rs b/src/test/ui/generator/issue-64620-yield-array-element.rs new file mode 100644 index 00000000000..2cbe8f51614 --- /dev/null +++ b/src/test/ui/generator/issue-64620-yield-array-element.rs @@ -0,0 +1,9 @@ +// Regression test for #64620 + +#![feature(generators)] + +pub fn crash(arr: [usize; 1]) { + yield arr[0]; //~ ERROR: yield expression outside of generator literal +} + +fn main() {} diff --git a/src/test/ui/generator/issue-64620-yield-array-element.stderr b/src/test/ui/generator/issue-64620-yield-array-element.stderr new file mode 100644 index 00000000000..48383c2ed08 --- /dev/null +++ b/src/test/ui/generator/issue-64620-yield-array-element.stderr @@ -0,0 +1,9 @@ +error[E0627]: yield expression outside of generator literal + --> $DIR/issue-64620-yield-array-element.rs:6:5 + | +LL | yield arr[0]; + | ^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0627`. -- cgit 1.4.1-3-g733a5 From 579ce86d4b813c89eb8a483f79c427565b06c7d2 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Mon, 9 Mar 2020 09:12:53 +0900 Subject: Add test for issue-67166 --- src/test/ui/impl-trait/issue-67166.rs | 11 +++++++++++ src/test/ui/impl-trait/issue-67166.stderr | 11 +++++++++++ 2 files changed, 22 insertions(+) create mode 100644 src/test/ui/impl-trait/issue-67166.rs create mode 100644 src/test/ui/impl-trait/issue-67166.stderr (limited to 'src/test') diff --git a/src/test/ui/impl-trait/issue-67166.rs b/src/test/ui/impl-trait/issue-67166.rs new file mode 100644 index 00000000000..a877d4cfe3b --- /dev/null +++ b/src/test/ui/impl-trait/issue-67166.rs @@ -0,0 +1,11 @@ +// Regression test for #67166 + +#![feature(impl_trait_in_bindings)] +#![allow(incomplete_features)] + +pub fn run() { + let _foo: Box = Box::new(()); + //~^ ERROR: opaque type expands to a recursive type +} + +fn main() {} diff --git a/src/test/ui/impl-trait/issue-67166.stderr b/src/test/ui/impl-trait/issue-67166.stderr new file mode 100644 index 00000000000..abf30f67d5f --- /dev/null +++ b/src/test/ui/impl-trait/issue-67166.stderr @@ -0,0 +1,11 @@ +error[E0720]: opaque type expands to a recursive type + --> $DIR/issue-67166.rs:7:19 + | +LL | let _foo: Box = Box::new(()); + | ^^^^^^^^^^^^^^ expands to a recursive type + | + = note: type resolves to itself + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0720`. -- cgit 1.4.1-3-g733a5 From 676b9bc477dfe58971b7df9df4e3a053bb187dee Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Tue, 3 Mar 2020 15:04:57 -0800 Subject: unix: Don't override existing SIGSEGV/BUS handlers Although `stack_overflow::init` runs very early in the process, even before `main`, there may already be signal handlers installed for things like the address sanitizer. In that case, just leave it alone, and don't bother trying to allocate our own signal stacks either. --- src/libstd/sys/unix/stack_overflow.rs | 28 ++++++++++++++++++++-------- src/test/ui/sanitize/badfree.rs | 19 +++++++++++++++++++ 2 files changed, 39 insertions(+), 8 deletions(-) create mode 100644 src/test/ui/sanitize/badfree.rs (limited to 'src/test') diff --git a/src/libstd/sys/unix/stack_overflow.rs b/src/libstd/sys/unix/stack_overflow.rs index 528fe321efb..9e8be550755 100644 --- a/src/libstd/sys/unix/stack_overflow.rs +++ b/src/libstd/sys/unix/stack_overflow.rs @@ -13,6 +13,10 @@ impl Handler { pub unsafe fn new() -> Handler { make_handler() } + + fn null() -> Handler { + Handler { _data: crate::ptr::null_mut() } + } } impl Drop for Handler { @@ -108,13 +112,20 @@ mod imp { } static mut MAIN_ALTSTACK: *mut libc::c_void = ptr::null_mut(); + static mut NEED_ALTSTACK: bool = false; pub unsafe fn init() { let mut action: sigaction = mem::zeroed(); - action.sa_flags = SA_SIGINFO | SA_ONSTACK; - action.sa_sigaction = signal_handler as sighandler_t; - sigaction(SIGSEGV, &action, ptr::null_mut()); - sigaction(SIGBUS, &action, ptr::null_mut()); + for &signal in &[SIGSEGV, SIGBUS] { + sigaction(signal, ptr::null_mut(), &mut action); + // Configure our signal handler if one is not already set. + if action.sa_sigaction == SIG_DFL { + action.sa_flags = SA_SIGINFO | SA_ONSTACK; + action.sa_sigaction = signal_handler as sighandler_t; + sigaction(signal, &action, ptr::null_mut()); + NEED_ALTSTACK = true; + } + } let handler = make_handler(); MAIN_ALTSTACK = handler._data; @@ -152,6 +163,9 @@ mod imp { } pub unsafe fn make_handler() -> Handler { + if !NEED_ALTSTACK { + return Handler::null(); + } let mut stack = mem::zeroed(); sigaltstack(ptr::null(), &mut stack); // Configure alternate signal stack, if one is not already set. @@ -160,7 +174,7 @@ mod imp { sigaltstack(&stack, ptr::null_mut()); Handler { _data: stack.ss_sp as *mut libc::c_void } } else { - Handler { _data: ptr::null_mut() } + Handler::null() } } @@ -191,14 +205,12 @@ mod imp { target_os = "openbsd" )))] mod imp { - use crate::ptr; - pub unsafe fn init() {} pub unsafe fn cleanup() {} pub unsafe fn make_handler() -> super::Handler { - super::Handler { _data: ptr::null_mut() } + super::Handler::null() } pub unsafe fn drop_handler(_handler: &mut super::Handler) {} diff --git a/src/test/ui/sanitize/badfree.rs b/src/test/ui/sanitize/badfree.rs new file mode 100644 index 00000000000..1ca082c8b47 --- /dev/null +++ b/src/test/ui/sanitize/badfree.rs @@ -0,0 +1,19 @@ +// needs-sanitizer-support +// only-x86_64 +// +// compile-flags: -Z sanitizer=address -O +// +// run-fail +// error-pattern: AddressSanitizer: SEGV + +use std::ffi::c_void; + +extern "C" { + fn free(ptr: *mut c_void); +} + +fn main() { + unsafe { + free(1 as *mut c_void); + } +} -- cgit 1.4.1-3-g733a5 From ef98ec055ea30466a83f0b0efb2e40ebd3f89011 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Mon, 9 Mar 2020 16:50:46 +0900 Subject: Add FIXMEs --- src/test/ui/impl-trait/issue-57200.rs | 1 + src/test/ui/impl-trait/issue-57200.stderr | 2 +- src/test/ui/impl-trait/issue-57201.rs | 1 + src/test/ui/impl-trait/issue-57201.stderr | 2 +- src/test/ui/impl-trait/issue-60473.rs | 3 ++- src/test/ui/impl-trait/issue-60473.stderr | 2 +- src/test/ui/impl-trait/issue-67166.rs | 2 +- src/test/ui/impl-trait/issue-67166.stderr | 2 +- 8 files changed, 9 insertions(+), 6 deletions(-) (limited to 'src/test') diff --git a/src/test/ui/impl-trait/issue-57200.rs b/src/test/ui/impl-trait/issue-57200.rs index 9a7290b3b75..e0c71d1ac9a 100644 --- a/src/test/ui/impl-trait/issue-57200.rs +++ b/src/test/ui/impl-trait/issue-57200.rs @@ -1,4 +1,5 @@ // Regression test for #57200 +// FIXME: The error is temporary hack, we'll revisit here at some point. #![feature(impl_trait_in_bindings)] #![allow(incomplete_features)] diff --git a/src/test/ui/impl-trait/issue-57200.stderr b/src/test/ui/impl-trait/issue-57200.stderr index 42fd0045315..b44f332d58c 100644 --- a/src/test/ui/impl-trait/issue-57200.stderr +++ b/src/test/ui/impl-trait/issue-57200.stderr @@ -1,5 +1,5 @@ error: lifetimes in impl Trait types in bindings are not currently supported - --> $DIR/issue-57200.rs:10:12 + --> $DIR/issue-57200.rs:11:12 | LL | let f: impl Fn(&'a T) -> &'b T = |x| x; | ^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/impl-trait/issue-57201.rs b/src/test/ui/impl-trait/issue-57201.rs index 79b19b52d20..c1a98d8897b 100644 --- a/src/test/ui/impl-trait/issue-57201.rs +++ b/src/test/ui/impl-trait/issue-57201.rs @@ -1,4 +1,5 @@ // Regression test for #57201 +// FIXME: The error is temporary hack, we'll revisit here at some point. #![feature(impl_trait_in_bindings)] #![allow(incomplete_features)] diff --git a/src/test/ui/impl-trait/issue-57201.stderr b/src/test/ui/impl-trait/issue-57201.stderr index 5defd15b6b5..462b17bf45e 100644 --- a/src/test/ui/impl-trait/issue-57201.stderr +++ b/src/test/ui/impl-trait/issue-57201.stderr @@ -1,5 +1,5 @@ error: lifetimes in impl Trait types in bindings are not currently supported - --> $DIR/issue-57201.rs:10:13 + --> $DIR/issue-57201.rs:11:13 | LL | let f: &impl Fn(&'a T) -> &'b T = &|x| x; | ^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/impl-trait/issue-60473.rs b/src/test/ui/impl-trait/issue-60473.rs index 596d8a2dd74..50cf0c8c6d6 100644 --- a/src/test/ui/impl-trait/issue-60473.rs +++ b/src/test/ui/impl-trait/issue-60473.rs @@ -12,5 +12,6 @@ impl Trait for () { } fn main() { - let x: impl Trait = (); //~ ERROR: opaque type expands to a recursive type + let x: impl Trait = (); // FIXME: The error doesn't seem correct. + //~^ ERROR: opaque type expands to a recursive type } diff --git a/src/test/ui/impl-trait/issue-60473.stderr b/src/test/ui/impl-trait/issue-60473.stderr index 6a07f29727c..2d95be4e52c 100644 --- a/src/test/ui/impl-trait/issue-60473.stderr +++ b/src/test/ui/impl-trait/issue-60473.stderr @@ -1,7 +1,7 @@ error[E0720]: opaque type expands to a recursive type --> $DIR/issue-60473.rs:15:12 | -LL | let x: impl Trait = (); +LL | let x: impl Trait = (); // FIXME: The error doesn't seem correct. | ^^^^^^^^^^^^^ expands to a recursive type | = note: type resolves to itself diff --git a/src/test/ui/impl-trait/issue-67166.rs b/src/test/ui/impl-trait/issue-67166.rs index a877d4cfe3b..de7433a9bfc 100644 --- a/src/test/ui/impl-trait/issue-67166.rs +++ b/src/test/ui/impl-trait/issue-67166.rs @@ -4,7 +4,7 @@ #![allow(incomplete_features)] pub fn run() { - let _foo: Box = Box::new(()); + let _foo: Box = Box::new(()); // FIXME: The error doesn't much make sense. //~^ ERROR: opaque type expands to a recursive type } diff --git a/src/test/ui/impl-trait/issue-67166.stderr b/src/test/ui/impl-trait/issue-67166.stderr index abf30f67d5f..56cba3cff0b 100644 --- a/src/test/ui/impl-trait/issue-67166.stderr +++ b/src/test/ui/impl-trait/issue-67166.stderr @@ -1,7 +1,7 @@ error[E0720]: opaque type expands to a recursive type --> $DIR/issue-67166.rs:7:19 | -LL | let _foo: Box = Box::new(()); +LL | let _foo: Box = Box::new(()); // FIXME: The error doesn't much make sense. | ^^^^^^^^^^^^^^ expands to a recursive type | = note: type resolves to itself -- cgit 1.4.1-3-g733a5