about summary refs log tree commit diff
path: root/compiler/rustc_trait_selection/src/solve/assembly
diff options
context:
space:
mode:
authorLukas Markeffsky <@>2024-03-13 23:33:45 +0100
committerLukas Markeffsky <@>2024-03-14 21:28:47 +0100
commit8ad94111adb790723a7db2e7449204b5f68e9c48 (patch)
treefed38688370152c6b3f8b969e0fea6180411f8eb /compiler/rustc_trait_selection/src/solve/assembly
parent0e7e1bfdbc52931d03e40438a74b400276e46bbd (diff)
clean up ADT sized constraint computation
Diffstat (limited to 'compiler/rustc_trait_selection/src/solve/assembly')
-rw-r--r--compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs14
1 files changed, 12 insertions, 2 deletions
diff --git a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs
index 2bfb86b592b..8822e55736f 100644
--- a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs
+++ b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs
@@ -157,10 +157,20 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_sized_trait<'tcx>(
         // impl Sized for (T1, T2, .., Tn) where T1: Sized, T2: Sized, .. Tn: Sized
         ty::Tuple(tys) => Ok(tys.iter().map(ty::Binder::dummy).collect()),
 
-        // impl Sized for Adt where T: Sized forall T in field types
+        // impl Sized for Adt<Args...> where sized_constraint(Adt)<Args...>: Sized
+        //   `sized_constraint(Adt)` is the deepest struct trail that can be determined
+        //   by the definition of `Adt`, independent of the generic args.
+        // impl Sized for Adt<Args...> if sized_constraint(Adt) == None
+        //   As a performance optimization, `sized_constraint(Adt)` can return `None`
+        //   if the ADTs definition implies that it is sized by for all possible args.
+        //   In this case, the builtin impl will have no nested subgoals. This is a
+        //   "best effort" optimization and `sized_constraint` may return `Some`, even
+        //   if the ADT is sized for all possible args.
         ty::Adt(def, args) => {
             let sized_crit = def.sized_constraint(ecx.tcx());
-            Ok(sized_crit.iter_instantiated(ecx.tcx(), args).map(ty::Binder::dummy).collect())
+            Ok(sized_crit.map_or_else(Vec::new, |ty| {
+                vec![ty::Binder::dummy(ty.instantiate(ecx.tcx(), args))]
+            }))
         }
     }
 }