about summary refs log tree commit diff
path: root/compiler/rustc_middle/src/ty
diff options
context:
space:
mode:
authorDaria Sukhonina <dariasukhonina@gmail.com>2024-04-17 20:49:53 +0300
committerDaria Sukhonina <dariasukhonina@gmail.com>2024-04-17 20:49:53 +0300
commit80c0b7e90fd064ea6c5fe8594b301e0fcc55af68 (patch)
tree9fc2a36e7ac92fadeade7457d139f05002b03898 /compiler/rustc_middle/src/ty
parent24a24ec6ba24bfe5e0980d22f585c98a608ec701 (diff)
downloadrust-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.rs5
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs43
-rw-r--r--compiler/rustc_middle/src/ty/util.rs117
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,
         }
     }