Skip to content

ICE: TooGeneric when set opt-level=1 #101

Description

@makai410

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

https://github.com/rust-lang/rust/blob/c43786c9b7b8d8dcc3f9c604e0e3074c16ed69d3/compiler/rustc_smir/src/rustc_smir/alloc.rs#L45-L56

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions