@@ -2371,6 +2371,57 @@ impl<'tcx> Ty<'tcx> {
2371
2371
}
2372
2372
}
2373
2373
}
2374
+
2375
+ /// Fast path helper for primitives which are always `Copy` and which
2376
+ /// have a side-effect-free `Clone` impl.
2377
+ ///
2378
+ /// Returning true means the type is known to be pure and `Copy+Clone`.
2379
+ /// Returning `false` means nothing -- could be `Copy`, might not be.
2380
+ ///
2381
+ /// This is mostly useful for optimizations, as there are the types
2382
+ /// on which we can replace cloning with dereferencing.
2383
+ pub fn is_trivially_pure_clone_copy ( self ) -> bool {
2384
+ match self . kind ( ) {
2385
+ ty:: Bool | ty:: Char | ty:: Never => true ,
2386
+
2387
+ // These aren't even `Clone`
2388
+ ty:: Str | ty:: Slice ( ..) | ty:: Foreign ( ..) | ty:: Dynamic ( ..) => false ,
2389
+
2390
+ ty:: Int ( ..) | ty:: Uint ( ..) | ty:: Float ( ..) => true ,
2391
+
2392
+ // The voldemort ZSTs are fine.
2393
+ ty:: FnDef ( ..) => true ,
2394
+
2395
+ ty:: Array ( element_ty, _len) => element_ty. is_trivially_pure_clone_copy ( ) ,
2396
+
2397
+ // A 100-tuple isn't "trivial", so doing this only for reasonable sizes.
2398
+ ty:: Tuple ( field_tys) => {
2399
+ field_tys. len ( ) <= 3 && field_tys. iter ( ) . all ( Self :: is_trivially_pure_clone_copy)
2400
+ }
2401
+
2402
+ // Sometimes traits aren't implemented for every ABI or arity,
2403
+ // because we can't be generic over everything yet.
2404
+ ty:: FnPtr ( ..) => false ,
2405
+
2406
+ // Definitely absolutely not copy.
2407
+ ty:: Ref ( _, _, hir:: Mutability :: Mut ) => false ,
2408
+
2409
+ // Thin pointers & thin shared references are pure-clone-copy, but for
2410
+ // anything with custom metadata it might be more complicated.
2411
+ ty:: Ref ( _, _, hir:: Mutability :: Not ) | ty:: RawPtr ( ..) => false ,
2412
+
2413
+ ty:: Generator ( ..) | ty:: GeneratorWitness ( ..) => false ,
2414
+
2415
+ // Might be, but not "trivial" so just giving the safe answer.
2416
+ ty:: Adt ( ..) | ty:: Closure ( ..) | ty:: Opaque ( ..) => false ,
2417
+
2418
+ ty:: Projection ( ..) | ty:: Param ( ..) | ty:: Infer ( ..) | ty:: Error ( ..) => false ,
2419
+
2420
+ ty:: Bound ( ..) | ty:: Placeholder ( ..) => {
2421
+ bug ! ( "`is_trivially_pure_clone_copy` applied to unexpected type: {:?}" , self ) ;
2422
+ }
2423
+ }
2424
+ }
2374
2425
}
2375
2426
2376
2427
/// Extra information about why we ended up with a particular variance.
0 commit comments