Skip to content

Commit 75d5f10

Browse files
committed
Bugfix: 'can_have_side_effects()' would return 'false' for struct/enum/array/tuple literals 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
1 parent 27a43f0 commit 75d5f10

File tree

5 files changed

+62
-6
lines changed

5 files changed

+62
-6
lines changed

compiler/rustc_hir/src/hir.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1843,7 +1843,7 @@ impl Expr<'_> {
18431843
.iter()
18441844
.map(|field| field.expr)
18451845
.chain(init.into_iter())
1846-
.all(|e| e.can_have_side_effects()),
1846+
.any(|e| e.can_have_side_effects()),
18471847

18481848
ExprKind::Array(args)
18491849
| ExprKind::Tup(args)
@@ -1857,7 +1857,7 @@ impl Expr<'_> {
18571857
..
18581858
},
18591859
args,
1860-
) => args.iter().all(|arg| arg.can_have_side_effects()),
1860+
) => args.iter().any(|arg| arg.can_have_side_effects()),
18611861
ExprKind::If(..)
18621862
| ExprKind::Match(..)
18631863
| ExprKind::MethodCall(..)

tests/ui/async-await/in-trait/return-type-suggestion.rs

-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ trait A {
66
async fn e() {
77
Ok(())
88
//~^ ERROR mismatched types
9-
//~| HELP consider using a semicolon here
109
}
1110
}
1211

tests/ui/async-await/in-trait/return-type-suggestion.stderr

+1-3
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@ error[E0308]: mismatched types
22
--> $DIR/return-type-suggestion.rs:7:9
33
|
44
LL | Ok(())
5-
| ^^^^^^- help: consider using a semicolon here: `;`
6-
| |
7-
| expected `()`, found `Result<(), _>`
5+
| ^^^^^^ expected `()`, found `Result<(), _>`
86
|
97
= note: expected unit type `()`
108
found enum `Result<(), _>`

tests/ui/return/return-struct.rs

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
struct S;
2+
3+
enum Age {
4+
Years(i64, i64)
5+
}
6+
7+
fn foo() {
8+
let mut age = 29;
9+
Age::Years({age += 1; age}, 55)
10+
//~^ ERROR mismatched types
11+
}
12+
13+
fn bar() {
14+
let mut age = 29;
15+
Age::Years(age, 55)
16+
//~^ ERROR mismatched types
17+
}
18+
19+
fn baz() {
20+
S
21+
//~^ ERROR mismatched types
22+
}
23+
24+
fn main() {}

tests/ui/return/return-struct.stderr

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/return-struct.rs:9:5
3+
|
4+
LL | Age::Years({age += 1; age}, 55)
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found `Age`
6+
|
7+
help: consider using a semicolon here
8+
|
9+
LL | Age::Years({age += 1; age}, 55);
10+
| +
11+
help: try adding a return type
12+
|
13+
LL | fn foo() -> Age {
14+
| ++++++
15+
16+
error[E0308]: mismatched types
17+
--> $DIR/return-struct.rs:15:5
18+
|
19+
LL | fn bar() {
20+
| - help: try adding a return type: `-> Age`
21+
LL | let mut age = 29;
22+
LL | Age::Years(age, 55)
23+
| ^^^^^^^^^^^^^^^^^^^ expected `()`, found `Age`
24+
25+
error[E0308]: mismatched types
26+
--> $DIR/return-struct.rs:20:5
27+
|
28+
LL | fn baz() {
29+
| - help: try adding a return type: `-> S`
30+
LL | S
31+
| ^ expected `()`, found `S`
32+
33+
error: aborting due to 3 previous errors
34+
35+
For more information about this error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)