Rollup merge of #123834 - compiler-errors:async-closure-with-tainted-body, r=oli-obk
Don't do coroutine-closure-specific upvar analysis if tainted by errors See the comment Fixes #123821 Fixes #123818
This commit is contained in:
commit
1524fe04ad
4 changed files with 50 additions and 3 deletions
|
@ -43,7 +43,8 @@ use rustc_middle::hir::place::{Place, PlaceBase, PlaceWithHirId, Projection, Pro
|
||||||
use rustc_middle::mir::FakeReadCause;
|
use rustc_middle::mir::FakeReadCause;
|
||||||
use rustc_middle::traits::ObligationCauseCode;
|
use rustc_middle::traits::ObligationCauseCode;
|
||||||
use rustc_middle::ty::{
|
use rustc_middle::ty::{
|
||||||
self, ClosureSizeProfileData, Ty, TyCtxt, TypeckResults, UpvarArgs, UpvarCapture,
|
self, ClosureSizeProfileData, Ty, TyCtxt, TypeVisitableExt as _, TypeckResults, UpvarArgs,
|
||||||
|
UpvarCapture,
|
||||||
};
|
};
|
||||||
use rustc_session::lint;
|
use rustc_session::lint;
|
||||||
use rustc_span::sym;
|
use rustc_span::sym;
|
||||||
|
@ -191,6 +192,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
let args = self.resolve_vars_if_possible(args);
|
||||||
let closure_def_id = closure_def_id.expect_local();
|
let closure_def_id = closure_def_id.expect_local();
|
||||||
|
|
||||||
assert_eq!(self.tcx.hir().body_owner_def_id(body.id()), closure_def_id);
|
assert_eq!(self.tcx.hir().body_owner_def_id(body.id()), closure_def_id);
|
||||||
|
@ -361,7 +363,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
// For coroutine-closures, we additionally must compute the
|
// For coroutine-closures, we additionally must compute the
|
||||||
// `coroutine_captures_by_ref_ty` type, which is used to generate the by-ref
|
// `coroutine_captures_by_ref_ty` type, which is used to generate the by-ref
|
||||||
// version of the coroutine-closure's output coroutine.
|
// version of the coroutine-closure's output coroutine.
|
||||||
if let UpvarArgs::CoroutineClosure(args) = args {
|
if let UpvarArgs::CoroutineClosure(args) = args
|
||||||
|
&& !args.references_error()
|
||||||
|
{
|
||||||
let closure_env_region: ty::Region<'_> = ty::Region::new_bound(
|
let closure_env_region: ty::Region<'_> = ty::Region::new_bound(
|
||||||
self.tcx,
|
self.tcx,
|
||||||
ty::INNERMOST,
|
ty::INNERMOST,
|
||||||
|
|
|
@ -771,7 +771,7 @@ impl<'tcx> CoroutineArgs<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, HashStable)]
|
#[derive(Debug, Copy, Clone, HashStable, TypeFoldable, TypeVisitable)]
|
||||||
pub enum UpvarArgs<'tcx> {
|
pub enum UpvarArgs<'tcx> {
|
||||||
Closure(GenericArgsRef<'tcx>),
|
Closure(GenericArgsRef<'tcx>),
|
||||||
Coroutine(GenericArgsRef<'tcx>),
|
Coroutine(GenericArgsRef<'tcx>),
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
//@ edition: 2021
|
||||||
|
|
||||||
|
#![feature(async_closure)]
|
||||||
|
|
||||||
|
struct DropMe;
|
||||||
|
|
||||||
|
trait Impossible {}
|
||||||
|
fn trait_error<T: Impossible>() {}
|
||||||
|
|
||||||
|
pub fn main() {
|
||||||
|
let b = DropMe;
|
||||||
|
let async_closure = async move || {
|
||||||
|
// Type error here taints the environment. This causes us to fallback all
|
||||||
|
// variables to `Error`. This means that when we compute the upvars for the
|
||||||
|
// *outer* coroutine-closure, we don't actually see any upvars since `MemCategorization`
|
||||||
|
// and `ExprUseVisitor`` will bail early when it sees error. This means
|
||||||
|
// that our underlying assumption that the parent and child captures are
|
||||||
|
// compatible ends up being broken, previously leading to an ICE.
|
||||||
|
trait_error::<()>();
|
||||||
|
//~^ ERROR the trait bound `(): Impossible` is not satisfied
|
||||||
|
let _b = b;
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
error[E0277]: the trait bound `(): Impossible` is not satisfied
|
||||||
|
--> $DIR/dont-ice-when-body-tainted-by-errors.rs:19:23
|
||||||
|
|
|
||||||
|
LL | trait_error::<()>();
|
||||||
|
| ^^ the trait `Impossible` is not implemented for `()`
|
||||||
|
|
|
||||||
|
help: this trait has no implementations, consider adding one
|
||||||
|
--> $DIR/dont-ice-when-body-tainted-by-errors.rs:7:1
|
||||||
|
|
|
||||||
|
LL | trait Impossible {}
|
||||||
|
| ^^^^^^^^^^^^^^^^
|
||||||
|
note: required by a bound in `trait_error`
|
||||||
|
--> $DIR/dont-ice-when-body-tainted-by-errors.rs:8:19
|
||||||
|
|
|
||||||
|
LL | fn trait_error<T: Impossible>() {}
|
||||||
|
| ^^^^^^^^^^ required by this bound in `trait_error`
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
Loading…
Add table
Add a link
Reference in a new issue