Repository navigation
Open
Labels
A-MIRArea: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.htmlArea: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.htmlF-unsized_fn_params`#![feature(unsized_fn_params)]``#![feature(unsized_fn_params)]`requires-nightlyThis issue requires a nightly compiler in some way. When possible, use a F-* label instead.This issue requires a nightly compiler in some way. When possible, use a F-* label instead.
Description
Found in rust-lang/miri#2872: this code
#![feature(core_intrinsics, unsized_fn_params)]
use std::intrinsics;
pub fn forget_unsized(t: [i32]) {
intrinsics::forget(t)
}with -Zmir-opt-level=0 generates this LLVM IR
define void @_ZN4test14forget_unsized17h6fbb3409c8556ed4E(ptr %0, i64 %1) unnamed_addr #0 {
start:
%_2 = alloca { ptr, i64 }, align 8
%t = alloca { ptr, i64 }, align 8
%2 = getelementptr inbounds { ptr, i64 }, ptr %t, i32 0, i32 0
store ptr %0, ptr %2, align 8
%3 = getelementptr inbounds { ptr, i64 }, ptr %t, i32 0, i32 1
store i64 %1, ptr %3, align 8
%4 = getelementptr inbounds { ptr, i64 }, ptr %t, i32 0, i32 0
%5 = load ptr, ptr %4, align 8, !noundef !2
%6 = getelementptr inbounds { ptr, i64 }, ptr %t, i32 0, i32 1
%7 = load i64, ptr %6, align 8, !noundef !2
%8 = mul nsw i64 %7, 4
%9 = alloca i8, i64 %8, align 16
call void @llvm.memcpy.p0.p0.i64(ptr align 16 %9, ptr align 1 %5, i64 %8, i1 false)
%10 = getelementptr inbounds { ptr, i64 }, ptr %_2, i32 0, i32 0
store ptr %9, ptr %10, align 8
%11 = getelementptr inbounds { ptr, i64 }, ptr %_2, i32 0, i32 1
store i64 %7, ptr %11, align 8
ret void
}
Notice the alloca. This is bad! Our alloca code path is unsound (it does not properly account for alignment); the point of the unsized_fn_params feature gate (separate from unsized_locals) was to avoid hitting that code path.
I repeat my stance that we should remove the unsound alloca code path (effectively de-imlementing unsized locals) to ensure this can never happen.
We don't have a MIR building ping group AFAIK, so Cc @rust-lang/wg-mir-opt I guess.
Here's a Miri testcase:
#![feature(forget_unsized, unsized_fn_params)]
fn main() {
let b: Box<[u32]> = Box::new([1, 2, 3]);
std::mem::forget_unsized(*b);
}Metadata
Metadata
Assignees
Labels
A-MIRArea: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.htmlArea: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.htmlF-unsized_fn_params`#![feature(unsized_fn_params)]``#![feature(unsized_fn_params)]`requires-nightlyThis issue requires a nightly compiler in some way. When possible, use a F-* label instead.This issue requires a nightly compiler in some way. When possible, use a F-* label instead.
Activity
RalfJung commentedon May 4, 2023
I forgot how exactly #78152 works, but for some reason it lets this pass. Either the analysis should reject this, or MIR building needs to not create an unsized local here.
Jules-Bertholet commentedon May 4, 2023
The bad MIR builing is here:
rust/compiler/rustc_mir_build/src/build/expr/as_operand.rs
Line 168 in eac3558
Any unsized function call operand other than a
Boxderef expression not wrapped in a block, is compiled byas_operandwhich introduces a temporary.Jules-Bertholet commentedon May 23, 2023
@rustbot label -I-unsound
(#71416 has been closed)
rustbot commentedon May 23, 2023
Error: Parsing relabel command in comment failed: ...'-I-unsound' | error: a label delta at >| ' (#71416 h'...
Please file an issue on GitHub at triagebot if there's a problem with this bot, or reach out on #t-infra on Zulip.
[-]unsized_fn_params allows some unsized locals, hitting unsound alloca codegen path[/-][+]unsized_fn_params allows some unsized locals[/+]RalfJung commentedon Aug 6, 2023
This is still an issue with current rustc (fca59ab) -- a similar issue got fixed (#111355) but this one is still open.
workingjubilee commentedon Jun 4, 2025
Current LLVMIR: https://rust.godbolt.org/z/7zx7Yvr9h
No significant differences aside from less struct types.
kennytm commentedon Jun 28, 2026
As of today (
rustc 1.98.0-nightly (13f1859f2 2026-06-27)), thanks to #142911, the godbolt link above produces an ICE instead.