Skip to content

Commit 836f706

Browse files
authored
Rollup merge of #100338 - lyming2007:issue-100285-fix, r=petrochenkov
when there are 3 or more return statements in the loop emit the first 3 errors and duplicated diagnostic information modified: compiler/rustc_typeck/src/check/coercion.rs new file: src/test/ui/typeck/issue-100285.rs new file: src/test/ui/typeck/issue-100285.stderr
2 parents 3694b7d + 0471e27 commit 836f706

File tree

3 files changed

+65
-1
lines changed

3 files changed

+65
-1
lines changed

compiler/rustc_typeck/src/check/coercion.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1594,7 +1594,9 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
15941594
let hir::ExprKind::Loop(_, _, _, loop_span) = expr.kind else { return;};
15951595
let mut span: MultiSpan = vec![loop_span].into();
15961596
span.push_span_label(loop_span, "this might have zero elements to iterate on");
1597-
for ret_expr in ret_exprs {
1597+
const MAXITER: usize = 3;
1598+
let iter = ret_exprs.iter().take(MAXITER);
1599+
for ret_expr in iter {
15981600
span.push_span_label(
15991601
ret_expr.span,
16001602
"if the loop doesn't execute, this value would never get returned",
@@ -1604,6 +1606,12 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
16041606
span,
16051607
"the function expects a value to always be returned, but loops might run zero times",
16061608
);
1609+
if MAXITER < ret_exprs.len() {
1610+
err.note(&format!(
1611+
"if the loop doesn't execute, {} other values would never get returned",
1612+
ret_exprs.len() - MAXITER
1613+
));
1614+
}
16071615
err.help(
16081616
"return a value for the case when the loop has zero elements to iterate on, or \
16091617
consider changing the return type to account for that possibility",

src/test/ui/typeck/issue-100285.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
fn foo(n: i32) -> i32 {
2+
for i in 0..0 {
3+
//~^ ERROR: mismatched types [E0308]
4+
if n < 0 {
5+
return i;
6+
} else if n < 10 {
7+
return 1;
8+
} else if n < 20 {
9+
return 2;
10+
} else if n < 30 {
11+
return 3;
12+
} else if n < 40 {
13+
return 4;
14+
} else {
15+
return 5;
16+
}
17+
18+
}
19+
//~| help: return a value for the case when the loop has zero elements to iterate on, or consider changing the return type to account for that possibility
20+
}
21+
22+
fn main() {}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/issue-100285.rs:2:5
3+
|
4+
LL | fn foo(n: i32) -> i32 {
5+
| --- expected `i32` because of return type
6+
LL | / for i in 0..0 {
7+
LL | |
8+
LL | | if n < 0 {
9+
LL | | return i;
10+
... |
11+
LL | |
12+
LL | | }
13+
| |_____^ expected `i32`, found `()`
14+
|
15+
note: the function expects a value to always be returned, but loops might run zero times
16+
--> $DIR/issue-100285.rs:2:5
17+
|
18+
LL | for i in 0..0 {
19+
| ^^^^^^^^^^^^^ this might have zero elements to iterate on
20+
...
21+
LL | return i;
22+
| -------- if the loop doesn't execute, this value would never get returned
23+
LL | } else if n < 10 {
24+
LL | return 1;
25+
| -------- if the loop doesn't execute, this value would never get returned
26+
LL | } else if n < 20 {
27+
LL | return 2;
28+
| -------- if the loop doesn't execute, this value would never get returned
29+
= note: if the loop doesn't execute, 3 other values would never get returned
30+
= help: return a value for the case when the loop has zero elements to iterate on, or consider changing the return type to account for that possibility
31+
32+
error: aborting due to previous error
33+
34+
For more information about this error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)