Skip to content

Commit 46fd49c

Browse files
avoid calling for types which can't be ZSTs
1 parent 93c1380 commit 46fd49c

File tree

1 file changed

+30
-12
lines changed

1 file changed

+30
-12
lines changed

compiler/rustc_mir/src/transform/remove_zsts.rs

+30-12
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
use crate::transform::MirPass;
44
use rustc_middle::mir::{Body, StatementKind};
5-
use rustc_middle::ty::TyCtxt;
5+
use rustc_middle::ty::{self, Ty, TyCtxt};
66

77
pub struct RemoveZsts;
88

@@ -15,17 +15,23 @@ impl<'tcx> MirPass<'tcx> for RemoveZsts {
1515
match statement.kind {
1616
StatementKind::Assign(box (place, _)) => {
1717
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();
2935
}
3036
}
3137
_ => {}
@@ -34,3 +40,15 @@ impl<'tcx> MirPass<'tcx> for RemoveZsts {
3440
}
3541
}
3642
}
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

Comments
 (0)