Skip to content

Commit 0634557

Browse files
committed
Auto merge of #111424 - JakobDegen:inline-unsized, r=tmiasko
Don't inline functions with unsized args Fixes #111355 . I have some ideas for how we can get this back in the future, out of scope for this PR though. r? `@cjgillot`
2 parents d77014a + 60cc72c commit 0634557

File tree

3 files changed

+77
-3
lines changed

3 files changed

+77
-3
lines changed

Diff for: compiler/rustc_mir_transform/src/inline.rs

+12-3
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,18 @@ impl<'tcx> Inliner<'tcx> {
168168
) -> Result<std::ops::Range<BasicBlock>, &'static str> {
169169
let callee_attrs = self.tcx.codegen_fn_attrs(callsite.callee.def_id());
170170
self.check_codegen_attributes(callsite, callee_attrs)?;
171+
172+
let terminator = caller_body[callsite.block].terminator.as_ref().unwrap();
173+
let TerminatorKind::Call { args, destination, .. } = &terminator.kind else { bug!() };
174+
let destination_ty = destination.ty(&caller_body.local_decls, self.tcx).ty;
175+
for arg in args {
176+
if !arg.ty(&caller_body.local_decls, self.tcx).is_sized(self.tcx, self.param_env) {
177+
// We do not allow inlining functions with unsized params. Inlining these functions
178+
// could create unsized locals, which are unsound and being phased out.
179+
return Err("Call has unsized argument");
180+
}
181+
}
182+
171183
self.check_mir_is_available(caller_body, &callsite.callee)?;
172184
let callee_body = try_instance_mir(self.tcx, callsite.callee.def)?;
173185
self.check_mir_body(callsite, callee_body, callee_attrs)?;
@@ -189,9 +201,6 @@ impl<'tcx> Inliner<'tcx> {
189201
// Check call signature compatibility.
190202
// Normally, this shouldn't be required, but trait normalization failure can create a
191203
// validation ICE.
192-
let terminator = caller_body[callsite.block].terminator.as_ref().unwrap();
193-
let TerminatorKind::Call { args, destination, .. } = &terminator.kind else { bug!() };
194-
let destination_ty = destination.ty(&caller_body.local_decls, self.tcx).ty;
195204
let output_type = callee_body.return_ty();
196205
if !util::is_subtype(self.tcx, self.param_env, output_type, destination_ty) {
197206
trace!(?output_type, ?destination_ty);
+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
- // MIR for `caller` before Inline
2+
+ // MIR for `caller` after Inline
3+
4+
fn caller(_1: Box<[i32]>) -> () {
5+
debug x => _1; // in scope 0 at $DIR/unsized_argument.rs:+0:11: +0:12
6+
let mut _0: (); // return place in scope 0 at $DIR/unsized_argument.rs:+0:26: +0:26
7+
let _2: (); // in scope 0 at $DIR/unsized_argument.rs:+1:5: +1:15
8+
let mut _3: std::boxed::Box<[i32]>; // in scope 0 at $DIR/unsized_argument.rs:+1:13: +1:14
9+
let mut _4: (); // in scope 0 at $DIR/unsized_argument.rs:+1:14: +1:15
10+
let mut _5: (); // in scope 0 at $DIR/unsized_argument.rs:+1:14: +1:15
11+
let mut _6: (); // in scope 0 at $DIR/unsized_argument.rs:+1:14: +1:15
12+
let mut _7: *const [i32]; // in scope 0 at $DIR/unsized_argument.rs:+1:13: +1:14
13+
14+
bb0: {
15+
StorageLive(_2); // scope 0 at $DIR/unsized_argument.rs:+1:5: +1:15
16+
StorageLive(_3); // scope 0 at $DIR/unsized_argument.rs:+1:13: +1:14
17+
_3 = move _1; // scope 0 at $DIR/unsized_argument.rs:+1:13: +1:14
18+
_7 = (((_3.0: std::ptr::Unique<[i32]>).0: std::ptr::NonNull<[i32]>).0: *const [i32]); // scope 0 at $DIR/unsized_argument.rs:+1:5: +1:15
19+
_2 = callee(move (*_7)) -> [return: bb3, unwind: bb4]; // scope 0 at $DIR/unsized_argument.rs:+1:5: +1:15
20+
// mir::Constant
21+
// + span: $DIR/unsized_argument.rs:9:5: 9:11
22+
// + literal: Const { ty: fn([i32]) {callee}, val: Value(<ZST>) }
23+
}
24+
25+
bb1: {
26+
StorageDead(_3); // scope 0 at $DIR/unsized_argument.rs:+1:14: +1:15
27+
StorageDead(_2); // scope 0 at $DIR/unsized_argument.rs:+1:15: +1:16
28+
_0 = const (); // scope 0 at $DIR/unsized_argument.rs:+0:26: +2:2
29+
return; // scope 0 at $DIR/unsized_argument.rs:+2:2: +2:2
30+
}
31+
32+
bb2 (cleanup): {
33+
resume; // scope 0 at $DIR/unsized_argument.rs:+0:1: +2:2
34+
}
35+
36+
bb3: {
37+
_4 = alloc::alloc::box_free::<[i32], std::alloc::Global>(move (_3.0: std::ptr::Unique<[i32]>), move (_3.1: std::alloc::Global)) -> bb1; // scope 0 at $DIR/unsized_argument.rs:+1:14: +1:15
38+
// mir::Constant
39+
// + span: $DIR/unsized_argument.rs:9:14: 9:15
40+
// + literal: Const { ty: unsafe fn(Unique<[i32]>, std::alloc::Global) {alloc::alloc::box_free::<[i32], std::alloc::Global>}, val: Value(<ZST>) }
41+
}
42+
43+
bb4 (cleanup): {
44+
_6 = alloc::alloc::box_free::<[i32], std::alloc::Global>(move (_3.0: std::ptr::Unique<[i32]>), move (_3.1: std::alloc::Global)) -> [return: bb2, unwind terminate]; // scope 0 at $DIR/unsized_argument.rs:+1:14: +1:15
45+
// mir::Constant
46+
// + span: $DIR/unsized_argument.rs:9:14: 9:15
47+
// + literal: Const { ty: unsafe fn(Unique<[i32]>, std::alloc::Global) {alloc::alloc::box_free::<[i32], std::alloc::Global>}, val: Value(<ZST>) }
48+
}
49+
}
50+

Diff for: tests/mir-opt/inline/unsized_argument.rs

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// needs-unwind
2+
#![feature(unsized_fn_params)]
3+
4+
#[inline(always)]
5+
fn callee(y: [i32]) {}
6+
7+
// EMIT_MIR unsized_argument.caller.Inline.diff
8+
fn caller(x: Box<[i32]>) {
9+
callee(*x);
10+
}
11+
12+
fn main() {
13+
let b = Box::new([1]);
14+
caller(b);
15+
}

0 commit comments

Comments
 (0)