Skip to content

Commit aed02c5

Browse files
Rollup merge of rust-lang#155218 - jakubadamw:issue-139570, r=tiif
coroutines: Skip the closure signature annotation check for tainted bodies When a coroutine has too many parameters, `check_match` fails and `construct_error` builds a MIR body with only the coroutine's computed arguments (env + resume type). The user-provided signature, however, still reflects all the parameters the user wrote. `check_signature_annotation` then tries to `zip_eq` these two mismatched iterators, causing a panic. Checking `tainted_by_errors` and bailing early avoids this, since `construct_error` bodies cannot meaningfully be compared against user annotations. Example currently ICEing: ```rust fn main() { |(1, 42), ()| yield; } ``` Closes rust-lang#139570.
2 parents b728626 + d14be60 commit aed02c5

4 files changed

Lines changed: 40 additions & 4 deletions

File tree

compiler/rustc_borrowck/src/type_check/input_output.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,15 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
3232
return;
3333
}
3434

35+
// If the MIR body was constructed via `construct_error` (because an
36+
// earlier pass like match checking failed), its args may not match
37+
// the user-provided signature (e.g. a coroutine with too many
38+
// parameters). Bail out as this can cause panic,
39+
// see <https://github.com/rust-lang/rust/issues/139570>.
40+
if self.body.tainted_by_errors.is_some() {
41+
return;
42+
}
43+
3544
let user_provided_poly_sig = self.tcx().closure_user_provided_sig(mir_def_id);
3645

3746
// Instantiate the canonicalized variables from user-provided signature

tests/crashes/139570.rs

Lines changed: 0 additions & 4 deletions
This file was deleted.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//! Regression test for <https://github.com/rust-lang/rust/issues/139570>.
2+
//! A coroutine with too many parameters should emit errors without an ICE.
3+
4+
#![feature(coroutines)]
5+
6+
fn main() {
7+
#[coroutine]
8+
|(1, 42), ()| {
9+
//~^ ERROR too many parameters for a coroutine
10+
//~| ERROR refutable pattern in closure argument
11+
yield
12+
};
13+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
error[E0628]: too many parameters for a coroutine (expected 0 or 1 parameters)
2+
--> $DIR/too-many-parameters-ice.rs:8:5
3+
|
4+
LL | |(1, 42), ()| {
5+
| ^^^^^^^^^^^^^
6+
7+
error[E0005]: refutable pattern in closure argument
8+
--> $DIR/too-many-parameters-ice.rs:8:6
9+
|
10+
LL | |(1, 42), ()| {
11+
| ^^^^^^^ patterns `(i32::MIN..=0_i32, _)` and `(2_i32..=i32::MAX, _)` not covered
12+
|
13+
= note: the matched value is of type `(i32, i32)`
14+
15+
error: aborting due to 2 previous errors
16+
17+
Some errors have detailed explanations: E0005, E0628.
18+
For more information about an error, try `rustc --explain E0005`.

0 commit comments

Comments
 (0)