1
Fork 0

Rollup merge of #120950 - compiler-errors:miri-async-closurs, r=RalfJung,oli-obk

Fix async closures in CTFE

First commit renames `is_coroutine_or_closure` into `is_closure_like`, because `is_coroutine_or_closure_or_coroutine_closure` seems confusing and long.

Second commit fixes some forgotten cases where we want to handle `TyKind::CoroutineClosure` the same as closures and coroutines.

The test exercises the change to `ValidityVisitor::aggregate_field_path_elem` which is the source of #120946, but not the change to `UsedParamsNeedSubstVisitor`, though I feel like it's not that big of a deal. Let me know if you'd like for me to look into constructing a test for the latter, though I have no idea what it'd look like (we can't assert against `TooGeneric` anywhere?).

Fixes #120946

r? oli-obk cc ``@RalfJung``
This commit is contained in:
Matthias Krüger 2024-02-12 23:18:53 +01:00 committed by GitHub
commit 15896bdd18
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
21 changed files with 86 additions and 39 deletions

View file

@ -491,7 +491,7 @@ fn write_mir_sig(tcx: TyCtxt<'_>, body: &Body<'_>, w: &mut dyn io::Write) -> io:
let kind = tcx.def_kind(def_id);
let is_function = match kind {
DefKind::Fn | DefKind::AssocFn | DefKind::Ctor(..) => true,
_ => tcx.is_closure_or_coroutine(def_id),
_ => tcx.is_closure_like(def_id),
};
match (kind, body.source.promoted) {
(_, Some(i)) => write!(w, "{i:?} in ")?,

View file

@ -197,7 +197,7 @@ pub struct ClosureTypeInfo<'tcx> {
}
fn closure_typeinfo<'tcx>(tcx: TyCtxt<'tcx>, def: LocalDefId) -> ClosureTypeInfo<'tcx> {
debug_assert!(tcx.is_closure_or_coroutine(def.to_def_id()));
debug_assert!(tcx.is_closure_like(def.to_def_id()));
let typeck_results = tcx.typeck(def);
let user_provided_sig = typeck_results.user_provided_sigs[&def];
let captures = typeck_results.closure_min_captures_flattened(def);
@ -217,7 +217,7 @@ impl<'tcx> TyCtxt<'tcx> {
}
pub fn closure_captures(self, def_id: LocalDefId) -> &'tcx [&'tcx ty::CapturedPlace<'tcx>] {
if !self.is_closure_or_coroutine(def_id.to_def_id()) {
if !self.is_closure_like(def_id.to_def_id()) {
return &[];
};
self.closure_typeinfo(def_id).captures

View file

@ -465,10 +465,7 @@ impl<'tcx> Instance<'tcx> {
) -> Option<Instance<'tcx>> {
debug!("resolve(def_id={:?}, args={:?})", def_id, args);
// Use either `resolve_closure` or `resolve_for_vtable`
assert!(
!tcx.is_closure_or_coroutine(def_id),
"Called `resolve_for_fn_ptr` on closure: {def_id:?}"
);
assert!(!tcx.is_closure_like(def_id), "Called `resolve_for_fn_ptr` on closure: {def_id:?}");
Instance::resolve(tcx, param_env, def_id, args).ok().flatten().map(|mut resolved| {
match resolved.def {
InstanceDef::Item(def) if resolved.def.requires_caller_location(tcx) => {
@ -530,7 +527,7 @@ impl<'tcx> Instance<'tcx> {
})
)
{
if tcx.is_closure_or_coroutine(def) {
if tcx.is_closure_like(def) {
debug!(" => vtable fn pointer created for closure with #[track_caller]: {:?} for method {:?} {:?}",
def, def_id, args);

View file

@ -541,13 +541,15 @@ impl<'tcx> TyCtxt<'tcx> {
Ok(())
}
/// Returns `true` if `def_id` refers to a closure (e.g., `|x| x * 2`). Note
/// that closures have a `DefId`, but the closure *expression* also
/// has a `HirId` that is located within the context where the
/// closure appears (and, sadly, a corresponding `NodeId`, since
/// those are not yet phased out). The parent of the closure's
/// `DefId` will also be the context where it appears.
pub fn is_closure_or_coroutine(self, def_id: DefId) -> bool {
/// Returns `true` if `def_id` refers to a closure, coroutine, or coroutine-closure
/// (i.e. an async closure). These are all represented by `hir::Closure`, and all
/// have the same `DefKind`.
///
/// Note that closures have a `DefId`, but the closure *expression* also has a
// `HirId` that is located within the context where the closure appears (and, sadly,
// a corresponding `NodeId`, since those are not yet phased out). The parent of
// the closure's `DefId` will also be the context where it appears.
pub fn is_closure_like(self, def_id: DefId) -> bool {
matches!(self.def_kind(def_id), DefKind::Closure)
}