rust-lang / rust-lang/rustc_public

ICE: `TooGeneric` when set opt-level=1

Open
#101 2 comments 3 reactions 1 assignee View on GitHub

@makai410 is already working on this.

Since Feb 10, 2026.

bug
Dominant language
Rust
Stars
125
Forks
19
PR merge metrics
No merged PRs in 30d

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

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

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.