2
2
3
3
use crate :: transform:: MirPass ;
4
4
use rustc_middle:: mir:: { Body , StatementKind } ;
5
- use rustc_middle:: ty:: TyCtxt ;
5
+ use rustc_middle:: ty:: { self , Ty , TyCtxt } ;
6
6
7
7
pub struct RemoveZsts ;
8
8
@@ -15,17 +15,23 @@ impl<'tcx> MirPass<'tcx> for RemoveZsts {
15
15
match statement. kind {
16
16
StatementKind :: Assign ( box ( place, _) ) => {
17
17
let place_ty = place. ty ( local_decls, tcx) . ty ;
18
- if let Ok ( layout) = tcx. layout_of ( param_env. and ( place_ty) ) {
19
- if layout. is_zst ( ) {
20
- if tcx. consider_optimizing ( || {
21
- format ! (
22
- "RemoveZsts - Place: {:?} SourceInfo: {:?}" ,
23
- place, statement. source_info
24
- )
25
- } ) {
26
- statement. make_nop ( ) ;
27
- }
28
- }
18
+ if !maybe_zst ( place_ty) {
19
+ continue ;
20
+ }
21
+ let layout = match tcx. layout_of ( param_env. and ( place_ty) ) {
22
+ Ok ( layout) => layout,
23
+ Err ( _) => continue ,
24
+ } ;
25
+ if !layout. is_zst ( ) {
26
+ continue ;
27
+ }
28
+ if tcx. consider_optimizing ( || {
29
+ format ! (
30
+ "RemoveZsts - Place: {:?} SourceInfo: {:?}" ,
31
+ place, statement. source_info
32
+ )
33
+ } ) {
34
+ statement. make_nop ( ) ;
29
35
}
30
36
}
31
37
_ => { }
@@ -34,3 +40,15 @@ impl<'tcx> MirPass<'tcx> for RemoveZsts {
34
40
}
35
41
}
36
42
}
43
+
44
+ /// A cheap, approximate check to avoid unnecessary `layout_of` calls.
45
+ fn maybe_zst ( ty : Ty < ' _ > ) -> bool {
46
+ match ty. kind ( ) {
47
+ // maybe ZST (could be more precise)
48
+ ty:: Adt ( ..) | ty:: Array ( ..) | ty:: Closure ( ..) | ty:: Tuple ( ..) | ty:: Opaque ( ..) => true ,
49
+ // definitely ZST
50
+ ty:: FnDef ( ..) | ty:: Never => true ,
51
+ // unreachable or can't be ZST
52
+ _ => false ,
53
+ }
54
+ }
0 commit comments