diff options
| author | Daria Sukhonina <dariasukhonina@gmail.com> | 2024-04-17 20:49:53 +0300 |
|---|---|---|
| committer | Daria Sukhonina <dariasukhonina@gmail.com> | 2024-04-17 20:49:53 +0300 |
| commit | 80c0b7e90fd064ea6c5fe8594b301e0fcc55af68 (patch) | |
| tree | 9fc2a36e7ac92fadeade7457d139f05002b03898 /compiler/rustc_middle/src/ty | |
| parent | 24a24ec6ba24bfe5e0980d22f585c98a608ec701 (diff) | |
| download | rust-80c0b7e90fd064ea6c5fe8594b301e0fcc55af68.tar.gz rust-80c0b7e90fd064ea6c5fe8594b301e0fcc55af68.zip | |
Use non-exhaustive matches for TyKind
Also no longer export noop async_drop_in_place_raw
Diffstat (limited to 'compiler/rustc_middle/src/ty')
| -rw-r--r-- | compiler/rustc_middle/src/ty/instance.rs | 5 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/sty.rs | 43 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/util.rs | 117 |
3 files changed, 74 insertions, 91 deletions
diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index 904f1aff94b..c7c4225c80e 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -173,7 +173,7 @@ pub enum InstanceDef<'tcx> { /// /// The `DefId` is for `core::future::async_drop::async_drop_in_place`, the `Ty` /// is the type `T`. - AsyncDropGlueCtorShim(DefId, Ty<'tcx>), + AsyncDropGlueCtorShim(DefId, Option<Ty<'tcx>>), } impl<'tcx> Instance<'tcx> { @@ -406,7 +406,8 @@ fn fmt_instance( InstanceDef::DropGlue(_, Some(ty)) => write!(f, " - shim(Some({ty}))"), InstanceDef::CloneShim(_, 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}))"), } } diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 135ade6d684..2a2781655c4 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -2319,6 +2319,10 @@ impl<'tcx> Ty<'tcx> { /// 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> { + 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() { ty::Param(_) | ty::Alias(..) | ty::Infer(ty::TyVar(_)) => { let assoc_items = tcx @@ -2333,9 +2337,6 @@ impl<'tcx> Ty<'tcx> { .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 .adt_async_destructor_ty( tcx, @@ -2357,34 +2358,10 @@ impl<'tcx> Ty<'tcx> { ty::Adt(adt_def, _) => { assert!(adt_def.is_union()); - match self.surface_async_dropper_ty(tcx, param_env) { - None => Ty::async_destructor_combinator(tcx, LangItem::AsyncDropNoop) - .instantiate_identity(), - Some(surface_drop) => { - Ty::async_destructor_combinator(tcx, LangItem::AsyncDropFuse) - .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() - } + let surface_drop = self.surface_async_dropper_ty(tcx, param_env).unwrap(); - ty::Dynamic(..) | ty::CoroutineWitness(..) | ty::Coroutine(..) | ty::Pat(..) => { - bug!("`async_destructor_ty` is not yet implemented for type: {self:?}") + Ty::async_destructor_combinator(tcx, LangItem::AsyncDropFuse) + .instantiate(tcx, &[surface_drop.into()]) } ty::Bound(..) @@ -2393,6 +2370,8 @@ impl<'tcx> Ty<'tcx> { | ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => { 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::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 chain = Ty::async_destructor_combinator(tcx, LangItem::AsyncDropChain); @@ -2425,7 +2406,7 @@ impl<'tcx> Ty<'tcx> { .reduce(|other, matched| { 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) { Ty::async_destructor_combinator(tcx, LangItem::AsyncDropChain) diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 1c3e8ffc13e..cd9d17cf930 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -1306,8 +1306,7 @@ impl<'tcx> Ty<'tcx> { /// Checks whether values of this type `T` implements the `AsyncDrop` /// trait. pub fn has_surface_async_drop(self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> bool { - self.trivially_has_surface_async_drop() - && tcx.has_surface_async_drop_raw(param_env.and(self)) + self.could_have_surface_async_drop() && tcx.has_surface_async_drop_raw(param_env.and(self)) } /// 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` /// implementation. Returning `true` means nothing -- could be /// `AsyncDrop`, might not be. - fn trivially_has_surface_async_drop(self) -> bool { - match self.kind() { - ty::Int(_) - | ty::Uint(_) - | ty::Float(_) - | ty::Bool - | ty::Char - | ty::Str - | ty::Never - | ty::Ref(..) - | ty::RawPtr(_, _) - | ty::FnDef(..) - | ty::FnPtr(_) - | ty::Error(_) - | ty::Tuple(_) - | ty::Slice(_) - | 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, - } + fn could_have_surface_async_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` implements the `AsyncDrop` /// trait. 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` - /// implementation. + /// Fast path helper for testing if a type has `Drop` 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 - /// `AsyncDrop`, might not be. - fn trivially_has_surface_drop(self) -> bool { + /// `Drop`, might not be. + 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() { ty::Int(_) | ty::Uint(_) @@ -1371,26 +1386,12 @@ impl<'tcx> Ty<'tcx> { | ty::Str | ty::Never | ty::Ref(..) - | ty::RawPtr(_, _) + | ty::RawPtr(..) | ty::FnDef(..) - | ty::FnPtr(_) - | ty::Error(_) - | ty::Tuple(_) - | ty::Slice(_) - | 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, + | ty::FnPtr(_) => true, + ty::Tuple(tys) => tys.is_empty(), + ty::Adt(adt_def, _) => adt_def.is_manually_drop(), + _ => false, } } |
