Skip to content

Commit

Permalink
Don't build by-move body when async closure is tainted
Browse files Browse the repository at this point in the history
  • Loading branch information
compiler-errors committed Sep 7, 2024
1 parent 9afe713 commit bce7c4b
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 2 deletions.
11 changes: 9 additions & 2 deletions compiler/rustc_mir_transform/src/coroutine/by_move_body.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,11 @@ pub fn coroutine_by_move_body_def_id<'tcx>(
) -> DefId {
let body = tcx.mir_built(coroutine_def_id).borrow();

// If the typeck results are tainted, no need to make a by-ref body.
if body.tainted_by_errors.is_some() {
return coroutine_def_id.to_def_id();
}

let Some(hir::CoroutineKind::Desugared(_, hir::CoroutineSource::Closure)) =
tcx.coroutine_kind(coroutine_def_id)
else {
Expand All @@ -98,7 +103,9 @@ pub fn coroutine_by_move_body_def_id<'tcx>(
// the MIR body will be constructed well.
let coroutine_ty = body.local_decls[ty::CAPTURE_STRUCT_LOCAL].ty;

let ty::Coroutine(_, args) = *coroutine_ty.kind() else { bug!("{body:#?}") };
let ty::Coroutine(_, args) = *coroutine_ty.kind() else {
bug!("tried to create by-move body of non-coroutine receiver");
};
let args = args.as_coroutine();

let coroutine_kind = args.kind_ty().to_opt_closure_kind().unwrap();
Expand All @@ -107,7 +114,7 @@ pub fn coroutine_by_move_body_def_id<'tcx>(
let ty::CoroutineClosure(_, parent_args) =
*tcx.type_of(parent_def_id).instantiate_identity().kind()
else {
bug!();
bug!("coroutine's parent was not a coroutine-closure");
};
if parent_args.references_error() {
return coroutine_def_id.to_def_id();
Expand Down
18 changes: 18 additions & 0 deletions tests/ui/async-await/async-closures/tainted-body-2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//@ edition: 2021

#![feature(async_closure)]

// Ensure that building a by-ref async closure body doesn't ICE when the parent
// body is tainted.

fn main() {
missing;
//~^ ERROR cannot find value `missing` in this scope

// We don't do numerical inference fallback when the body is tainted.
// This leads to writeback folding the type of the coroutine-closure
// into an error type, since its signature contains that numerical
// infer var.
let c = async |_| {};
c(1);
}
9 changes: 9 additions & 0 deletions tests/ui/async-await/async-closures/tainted-body-2.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
error[E0425]: cannot find value `missing` in this scope
--> $DIR/tainted-body-2.rs:9:5
|
LL | missing;
| ^^^^^^^ not found in this scope

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0425`.

0 comments on commit bce7c4b

Please sign in to comment.