diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2023-08-10 15:08:53 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-08-10 15:08:53 +0200 |
| commit | 710b989b32b6cd140770298c2af5c533bbffb240 (patch) | |
| tree | 015ae4b52ce6dbae6180dae666317a85f1887001 | |
| parent | 5b558639f6fe70c25018546ea85ba929b44afc20 (diff) | |
| parent | 75d5f107ddbac9e0872f1551e70dfbf5d441f3e0 (diff) | |
Rollup merge of #114678 - MortenLohne:bugfix/hir-has-side-effects, r=compiler-errors
`Expr::can_have_side_effects()` is incorrect for struct/enum/array/tuple literals It would return 'false' unless *all* sub-expressions had side effects. This would easily allow side effects to slip through, and also wrongly label empty literals as having side effects. Add some tests for the last point The function is only used for simple lints and error messages, so not a serious bug.
| -rw-r--r-- | compiler/rustc_hir/src/hir.rs | 4 | ||||
| -rw-r--r-- | tests/ui/async-await/in-trait/return-type-suggestion.rs | 1 | ||||
| -rw-r--r-- | tests/ui/async-await/in-trait/return-type-suggestion.stderr | 4 | ||||
| -rw-r--r-- | tests/ui/return/return-struct.rs | 24 | ||||
| -rw-r--r-- | tests/ui/return/return-struct.stderr | 35 |
5 files changed, 62 insertions, 6 deletions
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 92a91766d91..6340f1dcca1 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1843,7 +1843,7 @@ impl Expr<'_> { .iter() .map(|field| field.expr) .chain(init.into_iter()) - .all(|e| e.can_have_side_effects()), + .any(|e| e.can_have_side_effects()), ExprKind::Array(args) | ExprKind::Tup(args) @@ -1857,7 +1857,7 @@ impl Expr<'_> { .. }, args, - ) => args.iter().all(|arg| arg.can_have_side_effects()), + ) => args.iter().any(|arg| arg.can_have_side_effects()), ExprKind::If(..) | ExprKind::Match(..) | ExprKind::MethodCall(..) diff --git a/tests/ui/async-await/in-trait/return-type-suggestion.rs b/tests/ui/async-await/in-trait/return-type-suggestion.rs index 92a9e035e89..cdab4ea0f37 100644 --- a/tests/ui/async-await/in-trait/return-type-suggestion.rs +++ b/tests/ui/async-await/in-trait/return-type-suggestion.rs @@ -6,7 +6,6 @@ trait A { async fn e() { Ok(()) //~^ ERROR mismatched types - //~| HELP consider using a semicolon here } } diff --git a/tests/ui/async-await/in-trait/return-type-suggestion.stderr b/tests/ui/async-await/in-trait/return-type-suggestion.stderr index d9309459812..179c9ed93db 100644 --- a/tests/ui/async-await/in-trait/return-type-suggestion.stderr +++ b/tests/ui/async-await/in-trait/return-type-suggestion.stderr @@ -2,9 +2,7 @@ error[E0308]: mismatched types --> $DIR/return-type-suggestion.rs:7:9 | LL | Ok(()) - | ^^^^^^- help: consider using a semicolon here: `;` - | | - | expected `()`, found `Result<(), _>` + | ^^^^^^ expected `()`, found `Result<(), _>` | = note: expected unit type `()` found enum `Result<(), _>` diff --git a/tests/ui/return/return-struct.rs b/tests/ui/return/return-struct.rs new file mode 100644 index 00000000000..446445c17ba --- /dev/null +++ b/tests/ui/return/return-struct.rs @@ -0,0 +1,24 @@ +struct S; + +enum Age { + Years(i64, i64) +} + +fn foo() { + let mut age = 29; + Age::Years({age += 1; age}, 55) + //~^ ERROR mismatched types +} + +fn bar() { + let mut age = 29; + Age::Years(age, 55) + //~^ ERROR mismatched types +} + +fn baz() { + S + //~^ ERROR mismatched types +} + +fn main() {} diff --git a/tests/ui/return/return-struct.stderr b/tests/ui/return/return-struct.stderr new file mode 100644 index 00000000000..e6c0363e363 --- /dev/null +++ b/tests/ui/return/return-struct.stderr @@ -0,0 +1,35 @@ +error[E0308]: mismatched types + --> $DIR/return-struct.rs:9:5 + | +LL | Age::Years({age += 1; age}, 55) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found `Age` + | +help: consider using a semicolon here + | +LL | Age::Years({age += 1; age}, 55); + | + +help: try adding a return type + | +LL | fn foo() -> Age { + | ++++++ + +error[E0308]: mismatched types + --> $DIR/return-struct.rs:15:5 + | +LL | fn bar() { + | - help: try adding a return type: `-> Age` +LL | let mut age = 29; +LL | Age::Years(age, 55) + | ^^^^^^^^^^^^^^^^^^^ expected `()`, found `Age` + +error[E0308]: mismatched types + --> $DIR/return-struct.rs:20:5 + | +LL | fn baz() { + | - help: try adding a return type: `-> S` +LL | S + | ^ expected `()`, found `S` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0308`. |
