Skip to content

unsized_fn_params allows some unsized locals #111175

Open

Description

@RalfJung

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);
}

Activity

  1. RalfJung commented on May 4, 2023

    @RalfJung
    MemberAuthor

    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.

  2. added
    A-MIRArea: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.html
    I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness
    requires-nightlyThis issue requires a nightly compiler in some way. When possible, use a F-* label instead.
    on May 4, 2023
  3. Jules-Bertholet commented on May 4, 2023

    @Jules-Bertholet
    Contributor

    The bad MIR builing is here:

    if let ExprKind::Deref { arg } = expr.kind {

    Any unsized function call operand other than a Box deref expression not wrapped in a block, is compiled by as_operand which introduces a temporary.

  4. Jules-Bertholet commented on May 23, 2023

    @Jules-Bertholet
    Contributor

    @rustbot label -I-unsound

    (#71416 has been closed)

  5. rustbot commented on May 23, 2023

    @rustbot
    Collaborator

    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.

  6. removed
    I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness
    on May 23, 2023
  7. changed the title [-]unsized_fn_params allows some unsized locals, hitting unsound alloca codegen path[/-] [+]unsized_fn_params allows some unsized locals[/+] on Aug 6, 2023
  8. RalfJung commented on Aug 6, 2023

    @RalfJung
    MemberAuthor

    This is still an issue with current rustc (fca59ab) -- a similar issue got fixed (#111355) but this one is still open.

  9. workingjubilee commented on Jun 4, 2025

    @workingjubilee
    Member

    Current LLVMIR: https://rust.godbolt.org/z/7zx7Yvr9h

    source_filename = "example.f256f209c7383c27-cgu.0"
    target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
    target triple = "x86_64-unknown-linux-gnu"
    
    define void @_ZN7example14forget_unsized17h4990435afa880043E(ptr align 4 %0, i64 %1) unnamed_addr #0 {
      %_2 = alloca [16 x i8], align 8
      %input = alloca [16 x i8], align 8
      store ptr %0, ptr %input, align 8
      %2 = getelementptr inbounds i8, ptr %input, i64 8
      store i64 %1, ptr %2, align 8
      %3 = load ptr, ptr %input, align 8
      %4 = getelementptr inbounds i8, ptr %input, i64 8
      %5 = load i64, ptr %4, align 8
      %6 = mul nuw nsw i64 %5, 4
      %7 = add i64 %6, 3
      %8 = alloca i8, i64 %7, align 1
      %9 = ptrtoint ptr %8 to i64
      %10 = sub i64 0, %9
      %11 = and i64 %10, 3
      %12 = getelementptr inbounds i8, ptr %8, i64 %11
      call void @llvm.memcpy.p0.p0.i64(ptr align 1 %12, ptr align 1 %3, i64 %6, i1 false)
      store ptr %12, ptr %_2, align 8
      %13 = getelementptr inbounds i8, ptr %_2, i64 8
      store i64 %5, ptr %13, align 8
      ret void
    }
    
    declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg) #1
    
    attributes #0 = { nonlazybind uwtable "probe-stack"="inline-asm" "target-cpu"="x86-64" }
    attributes #1 = { nocallback nofree nounwind willreturn memory(argmem: readwrite) }
    
    !llvm.module.flags = !{!0, !1}
    !llvm.ident = !{!2}
    
    !0 = !{i32 8, !"PIC Level", i32 2}
    !1 = !{i32 2, !"RtLibUseGOT", i32 1}
    !2 = !{!"rustc version 1.89.0-nightly (4d08223c0 2025-05-31)"}

    No significant differences aside from less struct types.

  10. kennytm commented on Jun 28, 2026

    @kennytm
    Member

    As of today (rustc 1.98.0-nightly (13f1859f2 2026-06-27)), thanks to #142911, the godbolt link above produces an ICE instead.

    error: internal compiler error: /rustc-dev/13f1859f2faf97a15664e655624baa7417fdc100/compiler/rustc_codegen_ssa/src/mir/statement.rs:29:29: cannot reallocate from `UnsizedPlace(*mut [i32])` into `move _1`; dynamic alloca is not supported
     --> <source>:5:24
      |
    5 |     intrinsics::forget(t)
      |                        ^
    
    
    thread 'rustc' (3) panicked at /rustc-dev/13f1859f2faf97a15664e655624baa7417fdc100/compiler/rustc_codegen_ssa/src/mir/statement.rs:29:29:
    Box<dyn Any>
    stack backtrace:
       0:     0x7071518db499 - <<std[510a1a308a396355]::sys::backtrace::BacktraceLock>::print::DisplayBacktrace as core[dead8b94c8efb5fe]::fmt::Display>::fmt
       1:     0x70715200f088 - core[dead8b94c8efb5fe]::fmt::write
       2:     0x7071518f1b06 - <std[510a1a308a396355]::sys::stdio::unix::Stderr as std[510a1a308a396355]::io::Write>::write_fmt
       3:     0x7071518b05fe - std[510a1a308a396355]::panicking::default_hook::{closure#0}
       4:     0x7071518ce013 - std[510a1a308a396355]::panicking::default_hook
       5:     0x7071508c2a71 - std[510a1a308a396355]::panicking::update_hook::<alloc[7e3139a9b6ccc374]::boxed::Box<rustc_driver_impl[98b146ff405b6486]::install_ice_hook::{closure#1}>>::{closure#0}
       6:     0x7071518ce462 - std[510a1a308a396355]::panicking::panic_with_hook
       7:     0x7071508f0891 - std[510a1a308a396355]::panicking::begin_panic::<rustc_errors[5f92a60276b11c1d]::ExplicitBug>::{closure#0}
       8:     0x7071508e9606 - std[510a1a308a396355]::sys::backtrace::__rust_end_short_backtrace::<std[510a1a308a396355]::panicking::begin_panic<rustc_errors[5f92a60276b11c1d]::ExplicitBug>::{closure#0}, !>
       9:     0x7071508e7597 - std[510a1a308a396355]::panicking::begin_panic::<rustc_errors[5f92a60276b11c1d]::ExplicitBug>
      10:     0x7071508fba21 - <rustc_errors[5f92a60276b11c1d]::diagnostic::BugAbort as rustc_errors[5f92a60276b11c1d]::diagnostic::EmissionGuarantee>::emit_producing_guarantee
      11:     0x707150e45cbc - <rustc_errors[5f92a60276b11c1d]::DiagCtxtHandle>::span_bug::<rustc_span[8cbe8aac731c2b5d]::span_encoding::Span, alloc[7e3139a9b6ccc374]::string::String>
      12:     0x707150e748d6 - rustc_middle[8c82ceeaed34a595]::util::bug::opt_span_bug_fmt::<rustc_span[8cbe8aac731c2b5d]::span_encoding::Span>::{closure#0}
      13:     0x707150e74a62 - rustc_middle[8c82ceeaed34a595]::ty::context::tls::with_opt::<rustc_middle[8c82ceeaed34a595]::util::bug::opt_span_bug_fmt<rustc_span[8cbe8aac731c2b5d]::span_encoding::Span>::{closure#0}, !>::{closure#0}
      14:     0x707150e601ab - rustc_middle[8c82ceeaed34a595]::ty::context::tls::with_context_opt::<rustc_middle[8c82ceeaed34a595]::ty::context::tls::with_opt<rustc_middle[8c82ceeaed34a595]::util::bug::opt_span_bug_fmt<rustc_span[8cbe8aac731c2b5d]::span_encoding::Span>::{closure#0}, !>::{closure#0}, !>
      15:     0x70714e800978 - rustc_middle[8c82ceeaed34a595]::util::bug::span_bug_fmt::<rustc_span[8cbe8aac731c2b5d]::span_encoding::Span>
      16:     0x7071533ff9d7 - rustc_codegen_ssa[a4c5ce6170abb040]::mir::codegen_mir::<rustc_codegen_llvm[97ce5075ddeccec9]::builder::GenericBuilder<rustc_codegen_llvm[97ce5075ddeccec9]::context::FullCx>>
      17:     0x707152241c9c - rustc_codegen_llvm[97ce5075ddeccec9]::base::compile_codegen_unit::module_codegen
      18:     0x7071532df67d - <rustc_codegen_llvm[97ce5075ddeccec9]::LlvmCodegenBackend as rustc_codegen_ssa[a4c5ce6170abb040]::traits::backend::ExtraBackendMethods>::compile_codegen_unit
      19:     0x7071532dba25 - rustc_codegen_ssa[a4c5ce6170abb040]::base::codegen_crate::<rustc_codegen_llvm[97ce5075ddeccec9]::LlvmCodegenBackend, rustc_codegen_llvm[97ce5075ddeccec9]::ModuleLlvm>
      20:     0x7071532d9c8d - <rustc_codegen_llvm[97ce5075ddeccec9]::LlvmCodegenBackend as rustc_codegen_ssa[a4c5ce6170abb040]::traits::backend::CodegenBackend>::codegen_crate
      21:     0x70715316fd9c - <rustc_interface[f28dd7f8f39e9b18]::queries::Linker>::codegen_and_build_linker
      22:     0x70715316a9c0 - rustc_interface[f28dd7f8f39e9b18]::interface::run_compiler::<(), rustc_driver_impl[98b146ff405b6486]::run_compiler::{closure#0}>::{closure#1}
      23:     0x7071531b147a - std[510a1a308a396355]::sys::backtrace::__rust_begin_short_backtrace::<rustc_interface[f28dd7f8f39e9b18]::util::run_in_thread_with_globals<rustc_interface[f28dd7f8f39e9b18]::util::run_in_thread_pool_with_globals<rustc_interface[f28dd7f8f39e9b18]::interface::run_compiler<(), rustc_driver_impl[98b146ff405b6486]::run_compiler::{closure#0}>::{closure#1}, ()>::{closure#0}, ()>::{closure#0}::{closure#0}, ()>
      24:     0x7071531b122d - <std[510a1a308a396355]::thread::lifecycle::spawn_unchecked<rustc_interface[f28dd7f8f39e9b18]::util::run_in_thread_with_globals<rustc_interface[f28dd7f8f39e9b18]::util::run_in_thread_pool_with_globals<rustc_interface[f28dd7f8f39e9b18]::interface::run_compiler<(), rustc_driver_impl[98b146ff405b6486]::run_compiler::{closure#0}>::{closure#1}, ()>::{closure#0}, ()>::{closure#0}::{closure#0}, ()>::{closure#1} as core[dead8b94c8efb5fe]::ops::function::FnOnce<()>>::call_once::{shim:vtable#0}
      25:     0x7071531a7750 - <std[510a1a308a396355]::sys::thread::unix::Thread>::new::thread_start
      26:     0x70714ca9caa4 - <unknown>
      27:     0x70714cb29c6c - <unknown>
      28:                0x0 - <unknown>
    
    note: using internal features is not supported and expected to cause internal compiler errors when used incorrectly
    
    note: please attach the file at `/app/rustc-ice-2026-06-28T07_38_15-1.txt` to your bug report
    
    note: rustc 1.98.0-nightly (13f1859f2 2026-06-27) running on x86_64-unknown-linux-gnu
    
    note: compiler flags: -C debuginfo=2 -C llvm-args=--x86-asm-syntax=intel --crate-type rlib -Z mir-opt-level=0 -C debuginfo=0
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-MIRArea: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.htmlF-unsized_fn_params`#![feature(unsized_fn_params)]`requires-nightlyThis issue requires a nightly compiler in some way. When possible, use a F-* label instead.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions