- 
                Notifications
    
You must be signed in to change notification settings  - Fork 18
 
Open
Description
Minimal reproducible example
#![feature(rustc_private)]
extern crate rustc_middle;
#[macro_use]
extern crate rustc_smir;
extern crate rustc_driver;
extern crate rustc_interface;
extern crate stable_mir;
use std::io::Write;
use std::ops::ControlFlow;
use rustc_smir::rustc_internal;
const CRATE_NAME: &str = "ice";
fn test() -> ControlFlow<()> {
    let local = stable_mir::local_crate();
    for def in local.fn_defs() {
        let _ = def.body();
    }
    ControlFlow::Continue(())
}
fn main() {
    let path = "input.rs";
    generate_input(&path).unwrap();
    let args = &[
        "rustc".to_string(),
        "-Copt-level=1".to_string(),
        "--crate-type=lib".to_string(),
        "--crate-name".to_string(),
        CRATE_NAME.to_string(),
        path.to_string(),
    ];
    run!(args.to_vec(), test).unwrap();
}
fn generate_input(path: &str) -> std::io::Result<()> {
    let mut file = std::fs::File::create(path)?;
    write!(
        file,
        r#"
        #![allow(dead_code, unused_variables)]
        use std::fmt::Debug;
        pub trait Meow<A: Clone + Debug> {{
            fn foo(&self, a: Option<&A>) -> A;
            fn fzz(&self) -> A {{
                self.foo(None)
            }}
        }}
        fn main() {{}}
    "#
    )?;
    Ok(())
}Backtrace
thread 'rustc' panicked at compiler/rustc_smir/src/rustc_smir/alloc.rs:30:10:
Failed to convert: Scalar(0x0000000000000000) to std::option::Option<&'{erased} A/#1>: Error("TooGeneric(Alias(Projection, AliasTy { args: [A/#1], def_id: DefId(2:2374 ~ core[9e5e]::ptr::metadata::Pointee::Metadata), .. }))")
stack backtrace:
   0: rust_begin_unwind
   1: core::panicking::panic_fmt
   2: core::result::unwrap_failed
   3: rustc_smir::rustc_smir::alloc::new_allocation
   4: <rustc_middle::mir::consts::Const as rustc_smir::rustc_smir::Stable>::stable
   5: <rustc_middle::mir::syntax::Operand as rustc_smir::rustc_smir::Stable>::stable
   6: <rustc_middle::mir::syntax::TerminatorKind as rustc_smir::rustc_smir::Stable>::stable
   7: <rustc_middle::mir::terminator::Terminator as rustc_smir::rustc_smir::Stable>::stable
   8: <rustc_middle::mir::Body as rustc_smir::rustc_smir::Stable>::stable
   9: <rustc_smir::rustc_smir::context::TablesWrapper as stable_mir::compiler_interface::Context>::mir_body
  10: <stable_mir::ty::FnDef>::body
  11: reprod::test
             at ./reprod/src/main.rs:19:17
  12: reprod::main::{{closure}}
             at /home/gh-makai410/.rustup/toolchains/nightly-2025-03-02-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/compiler/rustc_smir/src/rustc_internal/mod.rs:279:31
  13: <reprod::main::StableMir<B,C,F> as rustc_driver_impl::Callbacks>::after_analysis::{{closure}}
             at /home/gh-makai410/.rustup/toolchains/nightly-2025-03-02-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/compiler/rustc_smir/src/rustc_internal/mod.rs:386:44
  14: rustc_smir::rustc_internal::init::{{closure}}
             at /home/gh-makai410/.rustup/toolchains/nightly-2025-03-02-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/compiler/rustc_smir/src/rustc_internal/mod.rs:196:33
  15: scoped_tls::ScopedKey<T>::set
             at /rust/deps/scoped-tls-1.0.1/src/lib.rs:137:9
  16: rustc_smir::rustc_internal::init
             at /home/gh-makai410/.rustup/toolchains/nightly-2025-03-02-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/compiler/rustc_smir/src/rustc_internal/mod.rs:196:5
  17: rustc_smir::rustc_internal::run::{{closure}}
             at /home/gh-makai410/.rustup/toolchains/nightly-2025-03-02-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/compiler/rustc_smir/src/rustc_internal/mod.rs:227:53
  18: stable_mir::compiler_interface::run::{{closure}}
             at /home/gh-makai410/.rustup/toolchains/nightly-2025-03-02-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/compiler/stable_mir/src/compiler_interface.rs:268:40
  19: scoped_tls::ScopedKey<T>::set
             at /rust/deps/scoped-tls-1.0.1/src/lib.rs:137:9
  20: stable_mir::compiler_interface::run
             at /home/gh-makai410/.rustup/toolchains/nightly-2025-03-02-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/compiler/stable_mir/src/compiler_interface.rs:268:9
  21: rustc_smir::rustc_internal::run
             at /home/gh-makai410/.rustup/toolchains/nightly-2025-03-02-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/compiler/rustc_smir/src/rustc_internal/mod.rs:227:5
  22: <reprod::main::StableMir<B,C,F> as rustc_driver_impl::Callbacks>::after_analysis
             at /home/gh-makai410/.rustup/toolchains/nightly-2025-03-02-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/compiler/rustc_smir/src/rustc_internal/mod.rs:385:21
  23: rustc_interface::passes::create_and_enter_global_ctxt::<core::option::Option<rustc_interface::queries::Linker>, rustc_driver_impl::run_compiler::{closure#0}::{closure#2}>::{closure#2}::{closure#0}
  24: rustc_interface::interface::run_compiler::<(), rustc_driver_impl::run_compiler::{closure#0}>::{closure#1}
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
Context
When compiling with -Copt-level=1, rustc optimizes the None parameter in self.foo(None) into const transmute(0): Option<&A>, while the unoptimized version generates a temporary variable to pass Option::<&A>::None.
The unoptimized mir output:
// WARNING: This output format is intended for human consumers only
// and is subject to change without notice. Knock yourself out.
// HINT: See also -Z dump-mir for MIR at specific points during compilation.
fn Meow::fzz(_1: &Self) -> A {
    debug self => _1;
    let mut _0: A;
    let mut _2: std::option::Option<&A>;
    bb0: {
        _2 = Option::<&A>::None;
        _0 = <Self as Meow<A>>::foo(copy _1, move _2) -> [return: bb1, unwind continue];
    }
    bb1: {
        return;
    }
}
fn main() -> () {
    let mut _0: ();
    bb0: {
        return;
    }
}
with -Copt-level=1:
// WARNING: This output format is intended for human consumers only
// and is subject to change without notice. Knock yourself out.
// HINT: See also -Z dump-mir for MIR at specific points during compilation.
fn Meow::fzz(_1: &Self) -> A {
    debug self => _1;
    let mut _0: A;
    bb0: {
        _0 = <Self as Meow<A>>::foo(move _1, const {transmute(0x0000000000000000): Option<&A>}) -> [return: bb1, unwind continue];
    }
    bb1: {
        return;
    }
}
fn main() -> () {
    let mut _0: ();
    bb0: {
        return;
    }
}
Possibly related code
celinval and MolotovCherry
Metadata
Metadata
Assignees
Labels
No labels