Skip to content

Commit dedc3b3

Browse files
committed
Make function bodies with &! arguments unreachable
1 parent 408bbd0 commit dedc3b3

File tree

2 files changed

+40
-0
lines changed

2 files changed

+40
-0
lines changed

compiler/rustc_mir_transform/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ mod multiple_return_terminators;
8686
mod normalize_array_len;
8787
mod nrvo;
8888
mod prettify;
89+
mod ralf_refs;
8990
mod ref_prop;
9091
mod remove_noop_landing_pads;
9192
mod remove_storage_markers;
@@ -545,6 +546,7 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
545546
&check_alignment::CheckAlignment,
546547
&reveal_all::RevealAll, // has to be done before inlining, since inlined code is in RevealAll mode.
547548
&lower_slice_len::LowerSliceLenCalls, // has to be done before inlining, otherwise actual call will be almost always inlined. Also simple, so can just do first
549+
&ralf_refs::RalfRefs,
548550
&unreachable_prop::UnreachablePropagation,
549551
&uninhabited_enum_branching::UninhabitedEnumBranching,
550552
&o1(simplify::SimplifyCfg::AfterUninhabitedEnumBranching),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
use crate::MirPass;
2+
use rustc_middle::mir::*;
3+
use rustc_middle::ty::print::with_no_trimmed_paths;
4+
use rustc_middle::ty::TyCtxt;
5+
6+
pub struct RalfRefs;
7+
8+
impl<'tcx> MirPass<'tcx> for RalfRefs {
9+
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
10+
sess.mir_opt_level() >= 1
11+
}
12+
13+
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
14+
let def_id = body.source.def_id();
15+
if tcx.type_of(body.source.def_id()).subst_identity().is_generator() {
16+
return;
17+
}
18+
let param_env = tcx.param_env_reveal_all_normalized(def_id);
19+
for arg in body.local_decls.iter().skip(1).take(body.arg_count) {
20+
let ty = arg.ty.peel_refs();
21+
let Ok(layout) = tcx.layout_of(param_env.and(ty)) else { continue; };
22+
if layout.abi.is_uninhabited() {
23+
debug!(
24+
"Deleting {}::{}",
25+
tcx.crate_name(def_id.krate),
26+
with_no_trimmed_paths!(tcx.def_path_str(def_id))
27+
);
28+
let blocks = body.basic_blocks.as_mut();
29+
blocks.truncate(1);
30+
let block = &mut blocks[START_BLOCK];
31+
block.statements.clear();
32+
block.terminator.as_mut().unwrap().kind = TerminatorKind::Unreachable;
33+
block.is_cleanup = false;
34+
return;
35+
}
36+
}
37+
}
38+
}

0 commit comments

Comments
 (0)