1
Fork 0

Use non-exhaustive matches for TyKind

Also no longer export noop async_drop_in_place_raw
This commit is contained in:
Daria Sukhonina 2024-04-17 20:49:53 +03:00
parent 24a24ec6ba
commit 80c0b7e90f
13 changed files with 150 additions and 182 deletions

View file

@ -364,7 +364,7 @@ fn exported_symbols_provider_local(
)); ));
} }
MonoItem::Fn(Instance { MonoItem::Fn(Instance {
def: InstanceDef::AsyncDropGlueCtorShim(def_id, ty), def: InstanceDef::AsyncDropGlueCtorShim(def_id, Some(ty)),
args, args,
}) => { }) => {
// A little sanity-check // A little sanity-check

View file

@ -187,7 +187,7 @@ fn dump_path<'tcx>(
})); }));
s s
} }
ty::InstanceDef::AsyncDropGlueCtorShim(_, ty) => { ty::InstanceDef::AsyncDropGlueCtorShim(_, Some(ty)) => {
// Unfortunately, pretty-printed typed are not very filename-friendly. // Unfortunately, pretty-printed typed are not very filename-friendly.
// We dome some filtering. // We dome some filtering.
let mut s = ".".to_owned(); let mut s = ".".to_owned();

View file

@ -350,13 +350,14 @@ macro_rules! make_mir_visitor {
receiver_by_ref: _, receiver_by_ref: _,
} | } |
ty::InstanceDef::CoroutineKindShim { coroutine_def_id: _def_id } | ty::InstanceDef::CoroutineKindShim { coroutine_def_id: _def_id } |
ty::InstanceDef::AsyncDropGlueCtorShim(_def_id, None) |
ty::InstanceDef::DropGlue(_def_id, None) => {} ty::InstanceDef::DropGlue(_def_id, None) => {}
ty::InstanceDef::FnPtrShim(_def_id, ty) | ty::InstanceDef::FnPtrShim(_def_id, ty) |
ty::InstanceDef::DropGlue(_def_id, Some(ty)) | ty::InstanceDef::DropGlue(_def_id, Some(ty)) |
ty::InstanceDef::CloneShim(_def_id, ty) | ty::InstanceDef::CloneShim(_def_id, ty) |
ty::InstanceDef::FnPtrAddrShim(_def_id, ty) | ty::InstanceDef::FnPtrAddrShim(_def_id, ty) |
ty::InstanceDef::AsyncDropGlueCtorShim(_def_id, ty) => { ty::InstanceDef::AsyncDropGlueCtorShim(_def_id, Some(ty)) => {
// FIXME(eddyb) use a better `TyContext` here. // FIXME(eddyb) use a better `TyContext` here.
self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)); self.visit_ty($(& $mutability)? *ty, TyContext::Location(location));
} }

View file

@ -173,7 +173,7 @@ pub enum InstanceDef<'tcx> {
/// ///
/// The `DefId` is for `core::future::async_drop::async_drop_in_place`, the `Ty` /// The `DefId` is for `core::future::async_drop::async_drop_in_place`, the `Ty`
/// is the type `T`. /// is the type `T`.
AsyncDropGlueCtorShim(DefId, Ty<'tcx>), AsyncDropGlueCtorShim(DefId, Option<Ty<'tcx>>),
} }
impl<'tcx> Instance<'tcx> { impl<'tcx> Instance<'tcx> {
@ -406,7 +406,8 @@ fn fmt_instance(
InstanceDef::DropGlue(_, Some(ty)) => write!(f, " - shim(Some({ty}))"), InstanceDef::DropGlue(_, Some(ty)) => write!(f, " - shim(Some({ty}))"),
InstanceDef::CloneShim(_, ty) => write!(f, " - shim({ty})"), InstanceDef::CloneShim(_, ty) => write!(f, " - shim({ty})"),
InstanceDef::FnPtrAddrShim(_, ty) => write!(f, " - shim({ty})"), InstanceDef::FnPtrAddrShim(_, ty) => write!(f, " - shim({ty})"),
InstanceDef::AsyncDropGlueCtorShim(_, ty) => write!(f, " - shim({ty})"), InstanceDef::AsyncDropGlueCtorShim(_, None) => write!(f, " - shim(None)"),
InstanceDef::AsyncDropGlueCtorShim(_, Some(ty)) => write!(f, " - shim(Some({ty}))"),
} }
} }

View file

@ -2319,6 +2319,10 @@ impl<'tcx> Ty<'tcx> {
/// Returns the type of the async destructor of this type. /// Returns the type of the async destructor of this type.
pub fn async_destructor_ty(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Ty<'tcx> { pub fn async_destructor_ty(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Ty<'tcx> {
if self.is_async_destructor_noop(tcx, param_env) || matches!(self.kind(), ty::Error(_)) {
return Ty::async_destructor_combinator(tcx, LangItem::AsyncDropNoop)
.instantiate_identity();
}
match *self.kind() { match *self.kind() {
ty::Param(_) | ty::Alias(..) | ty::Infer(ty::TyVar(_)) => { ty::Param(_) | ty::Alias(..) | ty::Infer(ty::TyVar(_)) => {
let assoc_items = tcx let assoc_items = tcx
@ -2333,9 +2337,6 @@ impl<'tcx> Ty<'tcx> {
.instantiate(tcx, &[dtor.into()]) .instantiate(tcx, &[dtor.into()])
} }
ty::Adt(adt_def, _) if adt_def.is_manually_drop() => {
Ty::async_destructor_combinator(tcx, LangItem::AsyncDropNoop).instantiate_identity()
}
ty::Adt(adt_def, args) if adt_def.is_enum() || adt_def.is_struct() => self ty::Adt(adt_def, args) if adt_def.is_enum() || adt_def.is_struct() => self
.adt_async_destructor_ty( .adt_async_destructor_ty(
tcx, tcx,
@ -2357,35 +2358,11 @@ impl<'tcx> Ty<'tcx> {
ty::Adt(adt_def, _) => { ty::Adt(adt_def, _) => {
assert!(adt_def.is_union()); assert!(adt_def.is_union());
match self.surface_async_dropper_ty(tcx, param_env) { let surface_drop = self.surface_async_dropper_ty(tcx, param_env).unwrap();
None => Ty::async_destructor_combinator(tcx, LangItem::AsyncDropNoop)
.instantiate_identity(),
Some(surface_drop) => {
Ty::async_destructor_combinator(tcx, LangItem::AsyncDropFuse) Ty::async_destructor_combinator(tcx, LangItem::AsyncDropFuse)
.instantiate(tcx, &[surface_drop.into()]) .instantiate(tcx, &[surface_drop.into()])
} }
}
}
ty::Never
| ty::Bool
| ty::Char
| ty::Int(_)
| ty::Uint(_)
| ty::Float(_)
| ty::Str
| ty::RawPtr(_, _)
| ty::Ref(..)
| ty::FnDef(..)
| ty::FnPtr(..)
| ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
| ty::Error(_) => {
Ty::async_destructor_combinator(tcx, LangItem::AsyncDropNoop).instantiate_identity()
}
ty::Dynamic(..) | ty::CoroutineWitness(..) | ty::Coroutine(..) | ty::Pat(..) => {
bug!("`async_destructor_ty` is not yet implemented for type: {self:?}")
}
ty::Bound(..) ty::Bound(..)
| ty::Foreign(_) | ty::Foreign(_)
@ -2393,6 +2370,8 @@ impl<'tcx> Ty<'tcx> {
| ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => { | ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
bug!("`async_destructor_ty` applied to unexpected type: {self:?}") bug!("`async_destructor_ty` applied to unexpected type: {self:?}")
} }
_ => bug!("`async_destructor_ty` is not yet implemented for type: {self:?}"),
} }
} }
@ -2406,6 +2385,8 @@ impl<'tcx> Ty<'tcx> {
I: Iterator + ExactSizeIterator, I: Iterator + ExactSizeIterator,
I::Item: IntoIterator<Item = Ty<'tcx>>, I::Item: IntoIterator<Item = Ty<'tcx>>,
{ {
debug_assert!(!self.is_async_destructor_noop(tcx, param_env));
let defer = Ty::async_destructor_combinator(tcx, LangItem::AsyncDropDefer); let defer = Ty::async_destructor_combinator(tcx, LangItem::AsyncDropDefer);
let chain = Ty::async_destructor_combinator(tcx, LangItem::AsyncDropChain); let chain = Ty::async_destructor_combinator(tcx, LangItem::AsyncDropChain);
@ -2425,7 +2406,7 @@ impl<'tcx> Ty<'tcx> {
.reduce(|other, matched| { .reduce(|other, matched| {
either.instantiate(tcx, &[other.into(), matched.into(), self.into()]) either.instantiate(tcx, &[other.into(), matched.into(), self.into()])
}) })
.unwrap_or(noop); .unwrap();
let dtor = if let Some(dropper_ty) = self.surface_async_dropper_ty(tcx, param_env) { let dtor = if let Some(dropper_ty) = self.surface_async_dropper_ty(tcx, param_env) {
Ty::async_destructor_combinator(tcx, LangItem::AsyncDropChain) Ty::async_destructor_combinator(tcx, LangItem::AsyncDropChain)

View file

@ -1306,8 +1306,7 @@ impl<'tcx> Ty<'tcx> {
/// Checks whether values of this type `T` implements the `AsyncDrop` /// Checks whether values of this type `T` implements the `AsyncDrop`
/// trait. /// trait.
pub fn has_surface_async_drop(self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> bool { pub fn has_surface_async_drop(self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> bool {
self.trivially_has_surface_async_drop() self.could_have_surface_async_drop() && tcx.has_surface_async_drop_raw(param_env.and(self))
&& tcx.has_surface_async_drop_raw(param_env.and(self))
} }
/// Fast path helper for testing if a type has `AsyncDrop` /// Fast path helper for testing if a type has `AsyncDrop`
@ -1316,52 +1315,68 @@ impl<'tcx> Ty<'tcx> {
/// Returning `false` means the type is known to not have `AsyncDrop` /// Returning `false` means the type is known to not have `AsyncDrop`
/// implementation. Returning `true` means nothing -- could be /// implementation. Returning `true` means nothing -- could be
/// `AsyncDrop`, might not be. /// `AsyncDrop`, might not be.
fn trivially_has_surface_async_drop(self) -> bool { fn could_have_surface_async_drop(self) -> bool {
match self.kind() { !self.is_async_destructor_trivially_noop()
ty::Int(_) && !matches!(
| ty::Uint(_) self.kind(),
| ty::Float(_) ty::Tuple(_)
| ty::Bool
| ty::Char
| ty::Str
| ty::Never
| ty::Ref(..)
| ty::RawPtr(_, _)
| ty::FnDef(..)
| ty::FnPtr(_)
| ty::Error(_)
| ty::Tuple(_)
| ty::Slice(_) | ty::Slice(_)
| ty::Array(_, _) | ty::Array(_, _)
| ty::Closure(..) | ty::Closure(..)
| ty::CoroutineClosure(..) | ty::CoroutineClosure(..)
| ty::Coroutine(..) | ty::Coroutine(..)
| ty::CoroutineWitness(..) )
| ty::Pat(..) => false,
ty::Adt(..)
| ty::Bound(..)
| ty::Dynamic(..)
| ty::Foreign(_)
| ty::Infer(_)
| ty::Alias(..)
| ty::Param(_)
| ty::Placeholder(_) => true,
}
} }
/// Checks whether values of this type `T` implements the `AsyncDrop` /// Checks whether values of this type `T` implements the `AsyncDrop`
/// trait. /// trait.
pub fn has_surface_drop(self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> bool { pub fn has_surface_drop(self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> bool {
self.trivially_has_surface_drop() && tcx.has_surface_drop_raw(param_env.and(self)) self.could_have_surface_drop() && tcx.has_surface_drop_raw(param_env.and(self))
} }
/// Fast path helper for testing if a type has `AsyncDrop` /// Fast path helper for testing if a type has `Drop` implementation.
/// implementation.
/// ///
/// Returning `false` means the type is known to not have `AsyncDrop` /// Returning `false` means the type is known to not have `Drop`
/// implementation. Returning `true` means nothing -- could be /// implementation. Returning `true` means nothing -- could be
/// `AsyncDrop`, might not be. /// `Drop`, might not be.
fn trivially_has_surface_drop(self) -> bool { fn could_have_surface_drop(self) -> bool {
self.is_async_destructor_trivially_noop()
&& !matches!(
self.kind(),
ty::Tuple(_)
| ty::Slice(_)
| ty::Array(_, _)
| ty::Closure(..)
| ty::CoroutineClosure(..)
| ty::Coroutine(..)
)
}
/// Checks whether values of this type `T` implement has noop async destructor.
//
// FIXME: implement optimization to make ADTs, which do not need drop,
// to skip fields or to have noop async destructor.
pub fn is_async_destructor_noop(
self,
tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
) -> bool {
self.is_async_destructor_trivially_noop()
|| if let ty::Adt(adt_def, _) = self.kind() {
(adt_def.is_union() || adt_def.is_payloadfree())
&& !self.has_surface_async_drop(tcx, param_env)
&& !self.has_surface_drop(tcx, param_env)
} else {
false
}
}
/// Fast path helper for testing if a type has noop async destructor.
///
/// Returning `true` means the type is known to have noop async destructor
/// implementation. Returning `true` means nothing -- could be
/// `Drop`, might not be.
fn is_async_destructor_trivially_noop(self) -> bool {
match self.kind() { match self.kind() {
ty::Int(_) ty::Int(_)
| ty::Uint(_) | ty::Uint(_)
@ -1371,26 +1386,12 @@ impl<'tcx> Ty<'tcx> {
| ty::Str | ty::Str
| ty::Never | ty::Never
| ty::Ref(..) | ty::Ref(..)
| ty::RawPtr(_, _) | ty::RawPtr(..)
| ty::FnDef(..) | ty::FnDef(..)
| ty::FnPtr(_) | ty::FnPtr(_) => true,
| ty::Error(_) ty::Tuple(tys) => tys.is_empty(),
| ty::Tuple(_) ty::Adt(adt_def, _) => adt_def.is_manually_drop(),
| ty::Slice(_) _ => false,
| ty::Array(_, _)
| ty::Closure(..)
| ty::CoroutineClosure(..)
| ty::Coroutine(..)
| ty::CoroutineWitness(..)
| ty::Pat(..) => false,
ty::Adt(..)
| ty::Bound(..)
| ty::Dynamic(..)
| ty::Foreign(_)
| ty::Infer(_)
| ty::Alias(..)
| ty::Param(_)
| ty::Placeholder(_) => true,
} }
} }

View file

@ -1072,8 +1072,8 @@ fn try_instance_mir<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
instance: InstanceDef<'tcx>, instance: InstanceDef<'tcx>,
) -> Result<&'tcx Body<'tcx>, &'static str> { ) -> Result<&'tcx Body<'tcx>, &'static str> {
if let ty::InstanceDef::DropGlue(_, Some(ty)) | ty::InstanceDef::AsyncDropGlueCtorShim(_, ty) = if let ty::InstanceDef::DropGlue(_, Some(ty))
instance | ty::InstanceDef::AsyncDropGlueCtorShim(_, Some(ty)) = instance
&& let ty::Adt(def, args) = ty.kind() && let ty::Adt(def, args) = ty.kind()
{ {
let fields = def.all_fields(); let fields = def.all_fields();

View file

@ -24,9 +24,11 @@ use super::{local_decls_for_sig, new_body};
pub fn build_async_destructor_ctor_shim<'tcx>( pub fn build_async_destructor_ctor_shim<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
def_id: DefId, def_id: DefId,
self_ty: Ty<'tcx>, ty: Option<Ty<'tcx>>,
) -> Body<'tcx> { ) -> Body<'tcx> {
AsyncDestructorCtorShimBuilder::new(tcx, def_id, self_ty).build() debug!("build_drop_shim(def_id={:?}, ty={:?})", def_id, ty);
AsyncDestructorCtorShimBuilder::new(tcx, def_id, ty).build()
} }
/// Builder for async_drop_in_place shim. Functions as a stack machine /// Builder for async_drop_in_place shim. Functions as a stack machine
@ -40,7 +42,7 @@ pub fn build_async_destructor_ctor_shim<'tcx>(
struct AsyncDestructorCtorShimBuilder<'tcx> { struct AsyncDestructorCtorShimBuilder<'tcx> {
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
def_id: DefId, def_id: DefId,
self_ty: Ty<'tcx>, self_ty: Option<Ty<'tcx>>,
span: Span, span: Span,
source_info: SourceInfo, source_info: SourceInfo,
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
@ -64,12 +66,12 @@ impl<'tcx> AsyncDestructorCtorShimBuilder<'tcx> {
const INPUT_COUNT: usize = 1; const INPUT_COUNT: usize = 1;
const MAX_STACK_LEN: usize = 2; const MAX_STACK_LEN: usize = 2;
fn new(tcx: TyCtxt<'tcx>, def_id: DefId, self_ty: Ty<'tcx>) -> Self { fn new(tcx: TyCtxt<'tcx>, def_id: DefId, self_ty: Option<Ty<'tcx>>) -> Self {
// Assuming `async_drop_in_place::<()>` is the same as for any type with noop async destructor
let arg_ty = if let Some(ty) = self_ty { ty } else { tcx.types.unit };
let sig = tcx.fn_sig(def_id).instantiate(tcx, &[arg_ty.into()]);
let sig = tcx.instantiate_bound_regions_with_erased(sig);
let span = tcx.def_span(def_id); let span = tcx.def_span(def_id);
let Some(sig) = tcx.fn_sig(def_id).instantiate(tcx, &[self_ty.into()]).no_bound_vars()
else {
span_bug!(span, "async_drop_in_place_raw with bound vars for `{self_ty}`");
};
let source_info = SourceInfo::outermost(span); let source_info = SourceInfo::outermost(span);
@ -110,7 +112,9 @@ impl<'tcx> AsyncDestructorCtorShimBuilder<'tcx> {
} }
fn build(self) -> Body<'tcx> { fn build(self) -> Body<'tcx> {
let (tcx, def_id, self_ty) = (self.tcx, self.def_id, self.self_ty); let (tcx, def_id, Some(self_ty)) = (self.tcx, self.def_id, self.self_ty) else {
return self.build_noop();
};
let surface_drop_kind = || { let surface_drop_kind = || {
let param_env = tcx.param_env_reveal_all_normalized(def_id); let param_env = tcx.param_env_reveal_all_normalized(def_id);
@ -127,8 +131,6 @@ impl<'tcx> AsyncDestructorCtorShimBuilder<'tcx> {
ty::Array(elem_ty, _) => self.build_slice(true, *elem_ty), ty::Array(elem_ty, _) => self.build_slice(true, *elem_ty),
ty::Slice(elem_ty) => self.build_slice(false, *elem_ty), ty::Slice(elem_ty) => self.build_slice(false, *elem_ty),
ty::Adt(adt_def, _) if adt_def.is_manually_drop() => self.build_noop(),
ty::Tuple(elem_tys) => self.build_chain(None, elem_tys.iter()), ty::Tuple(elem_tys) => self.build_chain(None, elem_tys.iter()),
ty::Adt(adt_def, args) if adt_def.is_struct() => { ty::Adt(adt_def, args) if adt_def.is_struct() => {
let field_tys = adt_def.non_enum_variant().fields.iter().map(|f| f.ty(tcx, args)); let field_tys = adt_def.non_enum_variant().fields.iter().map(|f| f.ty(tcx, args));
@ -143,35 +145,14 @@ impl<'tcx> AsyncDestructorCtorShimBuilder<'tcx> {
self.build_enum(*adt_def, *args, surface_drop_kind()) self.build_enum(*adt_def, *args, surface_drop_kind())
} }
ty::Never
| ty::Bool
| ty::Char
| ty::Int(_)
| ty::Uint(_)
| ty::Float(_)
| ty::Str
| ty::RawPtr(_, _)
| ty::Ref(_, _, _)
| ty::FnDef(_, _)
| ty::FnPtr(_)
| ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
| ty::Error(_) => self.build_noop(),
ty::Adt(adt_def, _) => { ty::Adt(adt_def, _) => {
assert!(adt_def.is_union()); assert!(adt_def.is_union());
match surface_drop_kind() { match surface_drop_kind().unwrap() {
Some(SurfaceDropKind::Async) => self.build_fused_async_surface(), SurfaceDropKind::Async => self.build_fused_async_surface(),
Some(SurfaceDropKind::Sync) => self.build_fused_sync_surface(), SurfaceDropKind::Sync => self.build_fused_sync_surface(),
None => self.build_noop(),
} }
} }
ty::Dynamic(..) | ty::CoroutineWitness(..) | ty::Coroutine(..) | ty::Pat(..) => {
bug!(
"Building async destructor constructor shim is not yet implemented for type: {self_ty:?}"
)
}
ty::Bound(..) ty::Bound(..)
| ty::Foreign(_) | ty::Foreign(_)
| ty::Placeholder(_) | ty::Placeholder(_)
@ -180,6 +161,12 @@ impl<'tcx> AsyncDestructorCtorShimBuilder<'tcx> {
| ty::Alias(..) => { | ty::Alias(..) => {
bug!("Building async destructor for unexpected type: {self_ty:?}") bug!("Building async destructor for unexpected type: {self_ty:?}")
} }
_ => {
bug!(
"Building async destructor constructor shim is not yet implemented for type: {self_ty:?}"
)
}
} }
} }
@ -430,11 +417,15 @@ impl<'tcx> AsyncDestructorCtorShimBuilder<'tcx> {
} }
fn combine_async_surface(&mut self) -> Ty<'tcx> { fn combine_async_surface(&mut self) -> Ty<'tcx> {
self.apply_combinator(1, LangItem::SurfaceAsyncDropInPlace, &[self.self_ty.into()]) self.apply_combinator(1, LangItem::SurfaceAsyncDropInPlace, &[self.self_ty.unwrap().into()])
} }
fn combine_sync_surface(&mut self) -> Ty<'tcx> { fn combine_sync_surface(&mut self) -> Ty<'tcx> {
self.apply_combinator(1, LangItem::AsyncDropSurfaceDropInPlace, &[self.self_ty.into()]) self.apply_combinator(
1,
LangItem::AsyncDropSurfaceDropInPlace,
&[self.self_ty.unwrap().into()],
)
} }
fn combine_fuse(&mut self, inner_future_ty: Ty<'tcx>) -> Ty<'tcx> { fn combine_fuse(&mut self, inner_future_ty: Ty<'tcx>) -> Ty<'tcx> {
@ -457,7 +448,7 @@ impl<'tcx> AsyncDestructorCtorShimBuilder<'tcx> {
self.apply_combinator( self.apply_combinator(
4, 4,
LangItem::AsyncDropEither, LangItem::AsyncDropEither,
&[other.into(), matched.into(), self.self_ty.into()], &[other.into(), matched.into(), self.self_ty.unwrap().into()],
) )
} }
@ -477,7 +468,18 @@ impl<'tcx> AsyncDestructorCtorShimBuilder<'tcx> {
debug_assert_eq!( debug_assert_eq!(
output.ty(&self.locals, self.tcx), output.ty(&self.locals, self.tcx),
self.self_ty.async_destructor_ty(self.tcx, self.param_env), self.self_ty.map(|ty| ty.async_destructor_ty(self.tcx, self.param_env)).unwrap_or_else(
|| {
self.tcx
.fn_sig(
self.tcx.require_lang_item(LangItem::AsyncDropNoop, Some(self.span)),
)
.instantiate_identity()
.output()
.no_bound_vars()
.unwrap()
}
),
); );
let dead_storage = match &output { let dead_storage = match &output {
Operand::Move(place) => Some(Statement { Operand::Move(place) => Some(Statement {

View file

@ -966,14 +966,14 @@ fn visit_instance_use<'tcx>(
ty::InstanceDef::ThreadLocalShim(..) => { ty::InstanceDef::ThreadLocalShim(..) => {
bug!("{:?} being reified", instance); bug!("{:?} being reified", instance);
} }
ty::InstanceDef::DropGlue(_, None) => { ty::InstanceDef::DropGlue(_, None) | ty::InstanceDef::AsyncDropGlueCtorShim(_, None) => {
// Don't need to emit noop drop glue if we are calling directly. // Don't need to emit noop drop glue if we are calling directly.
if !is_direct_call { if !is_direct_call {
output.push(create_fn_mono_item(tcx, instance, source)); output.push(create_fn_mono_item(tcx, instance, source));
} }
} }
ty::InstanceDef::DropGlue(_, Some(_)) ty::InstanceDef::DropGlue(_, Some(_))
| ty::InstanceDef::AsyncDropGlueCtorShim(..) | ty::InstanceDef::AsyncDropGlueCtorShim(_, Some(_))
| ty::InstanceDef::VTableShim(..) | ty::InstanceDef::VTableShim(..)
| ty::InstanceDef::ReifyShim(..) | ty::InstanceDef::ReifyShim(..)
| ty::InstanceDef::ClosureOnceShim { .. } | ty::InstanceDef::ClosureOnceShim { .. }

View file

@ -772,7 +772,7 @@ fn mono_item_visibility<'tcx>(
let def_id = match instance.def { let def_id = match instance.def {
InstanceDef::Item(def_id) InstanceDef::Item(def_id)
| InstanceDef::DropGlue(def_id, Some(_)) | InstanceDef::DropGlue(def_id, Some(_))
| InstanceDef::AsyncDropGlueCtorShim(def_id, _) => def_id, | InstanceDef::AsyncDropGlueCtorShim(def_id, Some(_)) => def_id,
// We match the visibility of statics here // We match the visibility of statics here
InstanceDef::ThreadLocalShim(def_id) => { InstanceDef::ThreadLocalShim(def_id) => {
@ -789,6 +789,7 @@ fn mono_item_visibility<'tcx>(
| InstanceDef::ConstructCoroutineInClosureShim { .. } | InstanceDef::ConstructCoroutineInClosureShim { .. }
| InstanceDef::CoroutineKindShim { .. } | InstanceDef::CoroutineKindShim { .. }
| InstanceDef::DropGlue(..) | InstanceDef::DropGlue(..)
| InstanceDef::AsyncDropGlueCtorShim(..)
| InstanceDef::CloneShim(..) | InstanceDef::CloneShim(..)
| InstanceDef::FnPtrAddrShim(..) => return Visibility::Hidden, | InstanceDef::FnPtrAddrShim(..) => return Visibility::Hidden,
}; };

View file

@ -819,7 +819,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
goal: Goal<'tcx, Self>, goal: Goal<'tcx, Self>,
) -> QueryResult<'tcx> { ) -> QueryResult<'tcx> {
let self_ty = goal.predicate.self_ty(); let self_ty = goal.predicate.self_ty();
let discriminant_ty = match *self_ty.kind() { let async_destructor_ty = match *self_ty.kind() {
ty::Bool ty::Bool
| ty::Char | ty::Char
| ty::Int(..) | ty::Int(..)
@ -833,14 +833,10 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
| ty::Closure(..) | ty::Closure(..)
| ty::CoroutineClosure(..) | ty::CoroutineClosure(..)
| ty::Infer(ty::IntVar(..) | ty::FloatVar(..)) | ty::Infer(ty::IntVar(..) | ty::FloatVar(..))
| ty::Coroutine(..)
| ty::CoroutineWitness(..)
| ty::Pat(..)
| ty::Never | ty::Never
| ty::Adt(_, _) | ty::Adt(_, _)
| ty::Str | ty::Str
| ty::Slice(_) | ty::Slice(_)
| ty::Dynamic(_, _, _)
| ty::Tuple(_) | ty::Tuple(_)
| ty::Error(_) => self_ty.async_destructor_ty(ecx.tcx(), goal.param_env), | ty::Error(_) => self_ty.async_destructor_ty(ecx.tcx(), goal.param_env),
@ -858,10 +854,14 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
"unexpected self ty `{:?}` when normalizing `<T as AsyncDestruct>::AsyncDestructor`", "unexpected self ty `{:?}` when normalizing `<T as AsyncDestruct>::AsyncDestructor`",
goal.predicate.self_ty() goal.predicate.self_ty()
), ),
_ => bug!(
"`consider_builtin_async_destruct_candidate` is not yet implemented for type: {self_ty:?}"
),
}; };
ecx.probe_misc_candidate("builtin async destruct").enter(|ecx| { ecx.probe_misc_candidate("builtin async destruct").enter(|ecx| {
ecx.eq(goal.param_env, goal.predicate.term, discriminant_ty.into()) ecx.eq(goal.param_env, goal.predicate.term, async_destructor_ty.into())
.expect("expected goal term to be fully unconstrained"); .expect("expected goal term to be fully unconstrained");
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
}) })

View file

@ -1100,14 +1100,14 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
| ty::Infer(ty::InferTy::IntVar(_) | ty::InferTy::FloatVar(..)) => true, | ty::Infer(ty::InferTy::IntVar(_) | ty::InferTy::FloatVar(..)) => true,
// type parameters, opaques, and unnormalized projections don't have // type parameters, opaques, and unnormalized projections don't have
// a known discriminant and may need to be normalized further or rely // a known async destructor and may need to be normalized further or rely
// on param env for async destructor projections // on param env for async destructor projections
ty::Param(_) ty::Param(_)
| ty::Foreign(_) | ty::Foreign(_)
| ty::Alias(..) | ty::Alias(..)
| ty::Bound(..) | ty::Bound(..)
| ty::Placeholder(..) | ty::Placeholder(..)
| ty::Infer(..) | ty::Infer(_)
| ty::Error(_) => false, | ty::Error(_) => false,
} }
} else if lang_items.pointee_trait() == Some(trait_ref.def_id) { } else if lang_items.pointee_trait() == Some(trait_ref.def_id) {

View file

@ -57,44 +57,25 @@ fn resolve_instance<'tcx>(
} else if Some(def_id) == tcx.lang_items().async_drop_in_place_fn() { } else if Some(def_id) == tcx.lang_items().async_drop_in_place_fn() {
let ty = args.type_at(0); let ty = args.type_at(0);
if ty.is_async_destructor_noop(tcx, param_env) {
match *ty.kind() { match *ty.kind() {
ty::Array(..) ty::Closure(..)
| ty::Slice(_)
| ty::Tuple(_)
| ty::Bool
| ty::Char
| ty::Int(_)
| ty::Uint(_)
| ty::Float(_)
| ty::Str
| ty::RawPtr(_, _)
| ty::Ref(..)
| ty::FnDef(..)
| ty::FnPtr(..)
| ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
| ty::Adt(..)
| ty::Closure(..)
| ty::CoroutineClosure(..) | ty::CoroutineClosure(..)
| ty::CoroutineWitness(..) | ty::Coroutine(..)
| ty::Pat(..) | ty::Tuple(..)
| ty::Never | ty::Adt(..)
| ty::Coroutine(..) => {}
ty::Param(_)
| ty::Error(_)
| ty::Dynamic(..) | ty::Dynamic(..)
| ty::Alias(..) | ty::Array(..)
| ty::Infer(ty::TyVar(_)) | ty::Slice(..) => {}
| ty::Bound(..) // Async destructor ctor shims can only be built from ADTs.
| ty::Foreign(_) _ => return Ok(None),
| ty::Placeholder(_)
| ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
return Ok(None);
} }
debug!(" => nontrivial async drop glue ctor");
ty::InstanceDef::AsyncDropGlueCtorShim(def_id, Some(ty))
} else {
debug!(" => trivial async drop glue ctor");
ty::InstanceDef::AsyncDropGlueCtorShim(def_id, None)
} }
debug!(" => async drop glue ctor");
ty::InstanceDef::AsyncDropGlueCtorShim(def_id, ty)
} else { } else {
debug!(" => free item"); debug!(" => free item");
// FIXME(effects): we may want to erase the effect param if that is present on this item. // FIXME(effects): we may want to erase the effect param if that is present on this item.