Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ICE: layout: 🌲 : Size != Size #126460

Closed
matthiaskrgr opened this issue Jun 14, 2024 · 5 comments · Fixed by #126493
Closed

ICE: layout: 🌲 : Size != Size #126460

matthiaskrgr opened this issue Jun 14, 2024 · 5 comments · Fixed by #126493
Assignees
Labels
C-bug Category: This is a bug. F-transmutability `#![feature(transmutability)]` I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@matthiaskrgr
Copy link
Member

matthiaskrgr commented Jun 14, 2024

auto-reduced (treereduce-rust):

mod assert {
    use std::mem::{Assume, BikeshedIntrinsicFrom};

    pub fn is_maybe_transmutable<Src, Dst>()
    where
        Dst: BikeshedIntrinsicFrom<Src>,
    {
    }
}

fn distant_void() {
    enum Void {}

    enum DistantVoid {
        A(Void, u128),
    }

    assert::is_maybe_transmutable::<DistantVoid, ()>();
}
original code

original:

#![crate_type = "lib"]
#![feature(transmutability)]
#![allow(dead_code, incomplete_features, non_camel_case_types)]

mod assert {
    use std::mem::{Assume, BikeshedIntrinsicFrom};

    pub fn is_maybe_transmutable<Src, Dst>()
    where
        Dst: BikeshedIntrinsicFrom<Src, {
            Assume {
                alignment: true,
                lifetimes: true,
                safety: true,
                validity: true,
            }
        }>
    {}
}

fn void() {
    enum Void {}

    // This transmutation is vacuously acceptable; since one cannot construct a
    // `Void`, unsoundness cannot directly arise from transmuting a void into
    // anything else.
    assert::is_maybe_transmutable::<Void, u128>();

    assert::is_maybe_transmutable::<(), Void>(); //~ ERROR: cannot be safely transmuted
}

// Non-ZST uninhabited types are, nonetheless, uninhabited.
fn yawning_void() {
    enum Void {}

    struct YawningVoid(&'static Void);

    const _: () = {
        assert!(std::mem::size_of::<YawningVoid>() == std::mem::size_of::<u128>());
        // Just to be sure the above constant actually evaluated:
        assert!(false); //~ ERROR: evaluation of constant value failed
    };

    // This transmutation is vacuously acceptable; since one cannot construct a
    // `Void`, unsoundness cannot directly arise from transmuting a void into
    // anything else.
    assert::is_maybe_transmutable::<YawningVoid, u128>();

    assert::is_maybe_transmutable::<(), Void>(); //~ ERROR: cannot be safely transmuted
}

// References to uninhabited types are, logically, uninhabited, but for layout
// purposes are not ZSTs, and aren't treated as uninhabited when they appear in
// enum variants.
fn distant_void() {
    enum Void {}

    enum DistantVoid {
        A(Void, u128)
    }

    const _: () = {
        assert!(std::mem::size_of::<DistantVoid>() == std::mem::size_of::<usize>());
        // Just to be sure the above constant actually evaluated:
        assert!(false); //~ ERROR: evaluation of constant value failed
    };

    assert::is_maybe_transmutable::<DistantVoid, ()>();
    assert::is_maybe_transmutable::<(), Void>();
    assert::is_maybe_transmutable::<u128, DistantVoid>(); //~ ERROR: cannot be safely transmuted
}

Version information

rustc 1.81.0-nightly (0ef0dd245 2024-06-14)
binary: rustc
commit-hash: 0ef0dd24510b52da980889546fcd15254dc56a23
commit-date: 2024-06-14
host: x86_64-unknown-linux-gnu
release: 1.81.0-nightly
LLVM version: 18.1.7

Command:
/home/matthias/.rustup/toolchains/master/bin/rustc

Program output

warning: unused import: `Assume`
 --> /tmp/icemaker_global_tempdir.YrqnXGtTwvMr/rustc_testrunner_tmpdir_reporting.h955EYnc6qOm/mvce.rs:2:20
  |
2 |     use std::mem::{Assume, BikeshedIntrinsicFrom};
  |                    ^^^^^^
  |
  = note: `#[warn(unused_imports)]` on by default

error[E0601]: `main` function not found in crate `mvce`
  --> /tmp/icemaker_global_tempdir.YrqnXGtTwvMr/rustc_testrunner_tmpdir_reporting.h955EYnc6qOm/mvce.rs:19:2
   |
19 | }
   |  ^ consider adding a `main` function to `/tmp/icemaker_global_tempdir.YrqnXGtTwvMr/rustc_testrunner_tmpdir_reporting.h955EYnc6qOm/mvce.rs`

error[E0658]: use of unstable library feature 'transmutability'
 --> /tmp/icemaker_global_tempdir.YrqnXGtTwvMr/rustc_testrunner_tmpdir_reporting.h955EYnc6qOm/mvce.rs:2:20
  |
2 |     use std::mem::{Assume, BikeshedIntrinsicFrom};
  |                    ^^^^^^
  |
  = note: see issue #99571 <https://github.com/rust-lang/rust/issues/99571> for more information
  = help: add `#![feature(transmutability)]` to the crate attributes to enable
  = note: this compiler was built on 2024-06-14; consider upgrading it if it is out of date

error[E0658]: use of unstable library feature 'transmutability'
 --> /tmp/icemaker_global_tempdir.YrqnXGtTwvMr/rustc_testrunner_tmpdir_reporting.h955EYnc6qOm/mvce.rs:2:28
  |
2 |     use std::mem::{Assume, BikeshedIntrinsicFrom};
  |                            ^^^^^^^^^^^^^^^^^^^^^
  |
  = note: see issue #99571 <https://github.com/rust-lang/rust/issues/99571> for more information
  = help: add `#![feature(transmutability)]` to the crate attributes to enable
  = note: this compiler was built on 2024-06-14; consider upgrading it if it is out of date

error[E0658]: use of unstable library feature 'transmutability'
 --> /tmp/icemaker_global_tempdir.YrqnXGtTwvMr/rustc_testrunner_tmpdir_reporting.h955EYnc6qOm/mvce.rs:6:14
  |
6 |         Dst: BikeshedIntrinsicFrom<Src>,
  |              ^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = note: see issue #99571 <https://github.com/rust-lang/rust/issues/99571> for more information
  = help: add `#![feature(transmutability)]` to the crate attributes to enable
  = note: this compiler was built on 2024-06-14; consider upgrading it if it is out of date

thread 'rustc' panicked at compiler/rustc_transmute/src/layout/tree.rs:363:21:
assertion `left == right` failed
  left: Size(16 bytes)
 right: Size(0 bytes)
stack backtrace:
   0:     0x738fb540fae5 - std::backtrace_rs::backtrace::libunwind::trace::h66a8deddd31b55ec
                               at /rustc/0ef0dd24510b52da980889546fcd15254dc56a23/library/std/src/../../backtrace/src/backtrace/libunwind.rs:116:5
   1:     0x738fb540fae5 - std::backtrace_rs::backtrace::trace_unsynchronized::h9b8c457e5846198e
                               at /rustc/0ef0dd24510b52da980889546fcd15254dc56a23/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5
   2:     0x738fb540fae5 - std::sys_common::backtrace::_print_fmt::h9692bfa044125fab
                               at /rustc/0ef0dd24510b52da980889546fcd15254dc56a23/library/std/src/sys_common/backtrace.rs:68:5
   3:     0x738fb540fae5 - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::h8be930e4f4324fc1
                               at /rustc/0ef0dd24510b52da980889546fcd15254dc56a23/library/std/src/sys_common/backtrace.rs:44:22
   4:     0x738fb546077b - core::fmt::rt::Argument::fmt::h0147d2f1e77a5224
                               at /rustc/0ef0dd24510b52da980889546fcd15254dc56a23/library/core/src/fmt/rt.rs:165:63
   5:     0x738fb546077b - core::fmt::write::h5bef47ac6c98803f
                               at /rustc/0ef0dd24510b52da980889546fcd15254dc56a23/library/core/src/fmt/mod.rs:1168:21
   6:     0x738fb54046bf - std::io::Write::write_fmt::h7707c1b0ed1f3ef8
                               at /rustc/0ef0dd24510b52da980889546fcd15254dc56a23/library/std/src/io/mod.rs:1835:15
   7:     0x738fb540f8be - std::sys_common::backtrace::_print::h79275c8f6c586b21
                               at /rustc/0ef0dd24510b52da980889546fcd15254dc56a23/library/std/src/sys_common/backtrace.rs:47:5
   8:     0x738fb540f8be - std::sys_common::backtrace::print::hd651502311c26a72
                               at /rustc/0ef0dd24510b52da980889546fcd15254dc56a23/library/std/src/sys_common/backtrace.rs:34:9
   9:     0x738fb54122f9 - std::panicking::default_hook::{{closure}}::hb66aeb12a772476e
  10:     0x738fb541209c - std::panicking::default_hook::hf6dbbcad84c9cd63
                               at /rustc/0ef0dd24510b52da980889546fcd15254dc56a23/library/std/src/panicking.rs:292:9
  11:     0x738fb1cb38d0 - std[14120762d8ee0505]::panicking::update_hook::<alloc[303d001d1e4a23bb]::boxed::Box<rustc_driver_impl[2eb8f42bfae24b55]::install_ice_hook::{closure#0}>>::{closure#0}
  12:     0x738fb5412bff - <alloc::boxed::Box<F,A> as core::ops::function::Fn<Args>>::call::h4b173c3d0381eea2
                               at /rustc/0ef0dd24510b52da980889546fcd15254dc56a23/library/alloc/src/boxed.rs:2076:9
  13:     0x738fb5412bff - std::panicking::rust_panic_with_hook::h2897e2d711d501a3
                               at /rustc/0ef0dd24510b52da980889546fcd15254dc56a23/library/std/src/panicking.rs:801:13
  14:     0x738fb5412827 - std::panicking::begin_panic_handler::{{closure}}::he291252945efa2fd
                               at /rustc/0ef0dd24510b52da980889546fcd15254dc56a23/library/std/src/panicking.rs:667:13
  15:     0x738fb540ffa9 - std::sys_common::backtrace::__rust_end_short_backtrace::h9eb35470c0d5421a
                               at /rustc/0ef0dd24510b52da980889546fcd15254dc56a23/library/std/src/sys_common/backtrace.rs:171:18
  16:     0x738fb54124d4 - rust_begin_unwind
                               at /rustc/0ef0dd24510b52da980889546fcd15254dc56a23/library/std/src/panicking.rs:658:5
  17:     0x738fb545cd33 - core::panicking::panic_fmt::h0c4e40ffed79f183
                               at /rustc/0ef0dd24510b52da980889546fcd15254dc56a23/library/core/src/panicking.rs:74:14
  18:     0x738fb545d23e - core::panicking::assert_failed_inner::h4c5bb24f7c7d94d6
                               at /rustc/0ef0dd24510b52da980889546fcd15254dc56a23/library/core/src/panicking.rs:410:17
  19:     0x738fb2872743 - core[f72d5f6884de128e]::panicking::assert_failed::<rustc_abi[83820ffeb3f18086]::Size, rustc_abi[83820ffeb3f18086]::Size>
  20:     0x738fb288727a - <rustc_transmute[e92ab8e1bc88ca7b]::layout::tree::Tree<rustc_transmute[e92ab8e1bc88ca7b]::layout::rustc::Def, rustc_transmute[e92ab8e1bc88ca7b]::layout::rustc::Ref>>::from_enum
  21:     0x738fb288a5e0 - <rustc_transmute[e92ab8e1bc88ca7b]::rustc::TransmuteTypeEnv>::is_transmutable
  22:     0x738fb38a83f1 - <rustc_trait_selection[140929a543f288fa]::traits::select::SelectionContext>::confirm_candidate
  23:     0x738fb38b336c - <rustc_trait_selection[140929a543f288fa]::traits::select::SelectionContext>::evaluate_candidate::{closure#0}::{closure#0}
  24:     0x738fb3432518 - <rustc_trait_selection[140929a543f288fa]::traits::select::SelectionContext>::evaluate_predicate_recursively::{closure#0}::{closure#0}
  25:     0x738fb342cc44 - rustc_traits[d1080c708c588edf]::evaluate_obligation::evaluate_obligation
  26:     0x738fb342c3e9 - rustc_query_impl[bf2ac6a6ab127c0b]::plumbing::__rust_begin_short_backtrace::<rustc_query_impl[bf2ac6a6ab127c0b]::query_impl::evaluate_obligation::dynamic_query::{closure#2}::{closure#0}, rustc_middle[9ad05302be999b0c]::query::erase::Erased<[u8; 2usize]>>
  27:     0x738fb342b952 - rustc_query_system[ef35600543bbfea8]::query::plumbing::try_execute_query::<rustc_query_impl[bf2ac6a6ab127c0b]::DynamicConfig<rustc_query_system[ef35600543bbfea8]::query::caches::DefaultCache<rustc_type_ir[d4d4d4b06d59bf13]::canonical::Canonical<rustc_middle[9ad05302be999b0c]::ty::context::TyCtxt, rustc_middle[9ad05302be999b0c]::ty::ParamEnvAnd<rustc_middle[9ad05302be999b0c]::ty::predicate::Predicate>>, rustc_middle[9ad05302be999b0c]::query::erase::Erased<[u8; 2usize]>>, false, false, false>, rustc_query_impl[bf2ac6a6ab127c0b]::plumbing::QueryCtxt, false>
  28:     0x738fb342b5a4 - rustc_query_impl[bf2ac6a6ab127c0b]::query_impl::evaluate_obligation::get_query_non_incr::__rust_end_short_backtrace
  29:     0x738fafdcb2f3 - <rustc_trait_selection[140929a543f288fa]::traits::fulfill::FulfillProcessor as rustc_data_structures[b6a8240b22e27d5b]::obligation_forest::ObligationProcessor>::process_obligation
  30:     0x738fb3008cc9 - <rustc_data_structures[b6a8240b22e27d5b]::obligation_forest::ObligationForest<rustc_trait_selection[140929a543f288fa]::traits::fulfill::PendingPredicateObligation>>::process_obligations::<rustc_trait_selection[140929a543f288fa]::traits::fulfill::FulfillProcessor>
  31:     0x738faff8e3a9 - <rustc_hir_typeck[3a4328f626f4967a]::fn_ctxt::FnCtxt>::confirm_builtin_call
  32:     0x738fb3c48018 - <rustc_hir_typeck[3a4328f626f4967a]::fn_ctxt::FnCtxt>::check_expr_with_expectation_and_args
  33:     0x738fb3c42201 - <rustc_hir_typeck[3a4328f626f4967a]::fn_ctxt::FnCtxt>::check_block_with_expected
  34:     0x738fb3c48b57 - <rustc_hir_typeck[3a4328f626f4967a]::fn_ctxt::FnCtxt>::check_expr_with_expectation_and_args
  35:     0x738fb31ae6ee - rustc_hir_typeck[3a4328f626f4967a]::check::check_fn
  36:     0x738fb31a4efe - rustc_hir_typeck[3a4328f626f4967a]::typeck
  37:     0x738fb31a497b - rustc_query_impl[bf2ac6a6ab127c0b]::plumbing::__rust_begin_short_backtrace::<rustc_query_impl[bf2ac6a6ab127c0b]::query_impl::typeck::dynamic_query::{closure#2}::{closure#0}, rustc_middle[9ad05302be999b0c]::query::erase::Erased<[u8; 8usize]>>
  38:     0x738fb3327f6e - rustc_query_system[ef35600543bbfea8]::query::plumbing::try_execute_query::<rustc_query_impl[bf2ac6a6ab127c0b]::DynamicConfig<rustc_query_system[ef35600543bbfea8]::query::caches::VecCache<rustc_span[b896b2121b1330a3]::def_id::LocalDefId, rustc_middle[9ad05302be999b0c]::query::erase::Erased<[u8; 8usize]>>, false, false, false>, rustc_query_impl[bf2ac6a6ab127c0b]::plumbing::QueryCtxt, false>
  39:     0x738fb3326a55 - rustc_query_impl[bf2ac6a6ab127c0b]::query_impl::typeck::get_query_non_incr::__rust_end_short_backtrace
  40:     0x738fb332668b - <rustc_middle[9ad05302be999b0c]::hir::map::Map>::par_body_owners::<rustc_hir_analysis[6ff8012e04425284]::check_crate::{closure#4}>::{closure#0}
  41:     0x738fb3325147 - rustc_hir_analysis[6ff8012e04425284]::check_crate
  42:     0x738fb3a68587 - rustc_interface[5734b4e3a95409b6]::passes::analysis
  43:     0x738fb3a680c7 - rustc_query_impl[bf2ac6a6ab127c0b]::plumbing::__rust_begin_short_backtrace::<rustc_query_impl[bf2ac6a6ab127c0b]::query_impl::analysis::dynamic_query::{closure#2}::{closure#0}, rustc_middle[9ad05302be999b0c]::query::erase::Erased<[u8; 1usize]>>
  44:     0x738fb3e498a5 - rustc_query_system[ef35600543bbfea8]::query::plumbing::try_execute_query::<rustc_query_impl[bf2ac6a6ab127c0b]::DynamicConfig<rustc_query_system[ef35600543bbfea8]::query::caches::SingleCache<rustc_middle[9ad05302be999b0c]::query::erase::Erased<[u8; 1usize]>>, false, false, false>, rustc_query_impl[bf2ac6a6ab127c0b]::plumbing::QueryCtxt, false>
  45:     0x738fb3e4960f - rustc_query_impl[bf2ac6a6ab127c0b]::query_impl::analysis::get_query_non_incr::__rust_end_short_backtrace
  46:     0x738fb3ce6bd2 - rustc_interface[5734b4e3a95409b6]::interface::run_compiler::<core[f72d5f6884de128e]::result::Result<(), rustc_span[b896b2121b1330a3]::ErrorGuaranteed>, rustc_driver_impl[2eb8f42bfae24b55]::run_compiler::{closure#0}>::{closure#1}
  47:     0x738fb3d05089 - std[14120762d8ee0505]::sys_common::backtrace::__rust_begin_short_backtrace::<rustc_interface[5734b4e3a95409b6]::util::run_in_thread_with_globals<rustc_interface[5734b4e3a95409b6]::util::run_in_thread_pool_with_globals<rustc_interface[5734b4e3a95409b6]::interface::run_compiler<core[f72d5f6884de128e]::result::Result<(), rustc_span[b896b2121b1330a3]::ErrorGuaranteed>, rustc_driver_impl[2eb8f42bfae24b55]::run_compiler::{closure#0}>::{closure#1}, core[f72d5f6884de128e]::result::Result<(), rustc_span[b896b2121b1330a3]::ErrorGuaranteed>>::{closure#0}, core[f72d5f6884de128e]::result::Result<(), rustc_span[b896b2121b1330a3]::ErrorGuaranteed>>::{closure#0}::{closure#0}, core[f72d5f6884de128e]::result::Result<(), rustc_span[b896b2121b1330a3]::ErrorGuaranteed>>
  48:     0x738fb3d04e3a - <<std[14120762d8ee0505]::thread::Builder>::spawn_unchecked_<rustc_interface[5734b4e3a95409b6]::util::run_in_thread_with_globals<rustc_interface[5734b4e3a95409b6]::util::run_in_thread_pool_with_globals<rustc_interface[5734b4e3a95409b6]::interface::run_compiler<core[f72d5f6884de128e]::result::Result<(), rustc_span[b896b2121b1330a3]::ErrorGuaranteed>, rustc_driver_impl[2eb8f42bfae24b55]::run_compiler::{closure#0}>::{closure#1}, core[f72d5f6884de128e]::result::Result<(), rustc_span[b896b2121b1330a3]::ErrorGuaranteed>>::{closure#0}, core[f72d5f6884de128e]::result::Result<(), rustc_span[b896b2121b1330a3]::ErrorGuaranteed>>::{closure#0}::{closure#0}, core[f72d5f6884de128e]::result::Result<(), rustc_span[b896b2121b1330a3]::ErrorGuaranteed>>::{closure#2} as core[f72d5f6884de128e]::ops::function::FnOnce<()>>::call_once::{shim:vtable#0}
  49:     0x738fb541ca7b - <alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once::hb25f0033d53ed2e6
                               at /rustc/0ef0dd24510b52da980889546fcd15254dc56a23/library/alloc/src/boxed.rs:2062:9
  50:     0x738fb541ca7b - <alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once::hbb7141f8d9bd3912
                               at /rustc/0ef0dd24510b52da980889546fcd15254dc56a23/library/alloc/src/boxed.rs:2062:9
  51:     0x738fb541ca7b - std::sys::pal::unix::thread::Thread::new::thread_start::hd182649926e2b713
                               at /rustc/0ef0dd24510b52da980889546fcd15254dc56a23/library/std/src/sys/pal/unix/thread.rs:108:17
  52:     0x738fae8a6ded - <unknown>
  53:     0x738fae92a0dc - <unknown>
  54:                0x0 - <unknown>

error: the compiler unexpectedly panicked. this is a bug.

note: we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new?labels=C-bug%2C+I-ICE%2C+T-compiler&template=ice.md

note: please make sure that you have updated to the latest nightly

note: rustc 1.81.0-nightly (0ef0dd245 2024-06-14) running on x86_64-unknown-linux-gnu

query stack during panic:
#0 [evaluate_obligation] evaluating trait selection obligation `(): core::mem::transmutability::BikeshedIntrinsicFrom<distant_void::DistantVoid, core::mem::transmutability::Assume { alignment: false, lifetimes: false, safety: false, validity: false }>`
#1 [typeck] type-checking `distant_void`
end of query stack
error: aborting due to 4 previous errors; 1 warning emitted

Some errors have detailed explanations: E0601, E0658.
For more information about an error, try `rustc --explain E0601`.

@rustbot label +F-transmutability

@matthiaskrgr matthiaskrgr added I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. C-bug Category: This is a bug. labels Jun 14, 2024
@rustbot rustbot added needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. F-transmutability `#![feature(transmutability)]` labels Jun 14, 2024
@matthiaskrgr matthiaskrgr changed the title ICE: layout: 🌲 : `Size != Size? ICE: layout: 🌲 : Size != Size Jun 14, 2024
@matthiaskrgr
Copy link
Member Author

#126358

@compiler-errors
Copy link
Member

cc @jswrenn

@jswrenn
Copy link
Member

jswrenn commented Jun 14, 2024

Ah, it's an uninhabited non-ZST!

@jswrenn
Copy link
Member

jswrenn commented Jun 14, 2024

@rustbot claim

jswrenn added a commit to jswrenn/rust that referenced this issue Jun 14, 2024
Previously, `Tree::from_enum`'s implementation branched into three disjoint
cases:

 1. enums that uninhabited
 2. enums for which all but one variant is uninhabited
 3. enums with multiple inhabited variants

This branching (incorrectly) did not differentiate between variantful and
variantless uninhabited enums. In both cases, we assumed (and asserted) that
uninhabited enums are zero-sized types. This assumption is false for enums like:

   enum Uninhabited { A(!, u128) }

...which, currently, has the same size as `u128`. This faulty assumption
manifested as the ICE reported in rust-lang#126460.

In this PR, we revise the first case of `Tree::from_enum` to consider only the
narrower category of "enums that are variantless". These enums, whose layouts
are described with `Variants::Single { index }`, are special in that they do not
have a variant at `index`.

The second case is revised to consider the broader category of "enums that defer
their layout to one of their variants"; i.e., enums whose layouts are described
with `Variants::Single { index }` but that do have a variant at `index`.

This PR also adds a comment requested by @RalfJung in his review of rust-lang#126358 to
`compiler/rustc_const_eval/src/interpret/discriminant.rs`.

Fixes rust-lang#126460
jswrenn added a commit to jswrenn/rust that referenced this issue Jun 14, 2024
Previously, `Tree::from_enum`'s implementation branched into three disjoint
cases:

 1. enums that uninhabited
 2. enums for which all but one variant is uninhabited
 3. enums with multiple inhabited variants

This branching (incorrectly) did not differentiate between variantful and
variantless uninhabited enums. In both cases, we assumed (and asserted) that
uninhabited enums are zero-sized types. This assumption is false for enums like:

    enum Uninhabited { A(!, u128) }

...which, currently, has the same size as `u128`. This faulty assumption
manifested as the ICE reported in rust-lang#126460.

In this PR, we revise the first case of `Tree::from_enum` to consider only the
narrower category of "enums that are variantless". These enums, whose layouts
are described with `Variants::Single { index }`, are special in that they do not
have a variant at `index`.

The second case is revised to consider the broader category of "enums that defer
their layout to one of their variants"; i.e., enums whose layouts are described
with `Variants::Single { index }` but that do have a variant at `index`.

This PR also adds a comment requested by @RalfJung in his review of rust-lang#126358 to
`compiler/rustc_const_eval/src/interpret/discriminant.rs`.

Fixes rust-lang#126460
jswrenn added a commit to jswrenn/rust that referenced this issue Jun 14, 2024
Previously, `Tree::from_enum`'s implementation branched into three disjoint
cases:

 1. enums that uninhabited
 2. enums for which all but one variant is uninhabited
 3. enums with multiple inhabited variants

This branching (incorrectly) did not differentiate between variantful and
variantless uninhabited enums. In both cases, we assumed (and asserted) that
uninhabited enums are zero-sized types. This assumption is false for enums like:

    enum Uninhabited { A(!, u128) }

...which, currently, has the same size as `u128`. This faulty assumption
manifested as the ICE reported in rust-lang#126460.

In this PR, we revise the first case of `Tree::from_enum` to consider only the
narrow category of "enums that are uninhabited ZSTs". These enums, whose layouts
are described with `Variants::Single { index }`, are special in their layouts
otherwise resemble the `!` type and cannot be descended into like typical enums.
This first case captures uninhabited enums like:

    enum Uninhabited { A(!, !), B(!) }

The second case is revised to consider the broader category of "enums that defer
their layout to one of their variants"; i.e., enums whose layouts are described
with `Variants::Single { index }` and that do have a variant at `index`. This
second case captures uninhabited enums that are not ZSTs, like:

    enum Uninhabited { A(!, u128) }

This PR also adds a comment requested by @RalfJung in his review of rust-lang#126358 to
`compiler/rustc_const_eval/src/interpret/discriminant.rs`.

Fixes rust-lang#126460
jswrenn added a commit to jswrenn/rust that referenced this issue Jun 14, 2024
Previously, `Tree::from_enum`'s implementation branched into three disjoint
cases:

 1. enums that uninhabited
 2. enums for which all but one variant is uninhabited
 3. enums with multiple inhabited variants

This branching (incorrectly) did not differentiate between variantful and
variantless uninhabited enums. In both cases, we assumed (and asserted) that
uninhabited enums are zero-sized types. This assumption is false for enums like:

    enum Uninhabited { A(!, u128) }

...which, currently, has the same size as `u128`. This faulty assumption
manifested as the ICE reported in rust-lang#126460.

In this PR, we revise the first case of `Tree::from_enum` to consider only the
narrow category of "enums that are uninhabited ZSTs". These enums, whose layouts
are described with `Variants::Single { index }`, are special in their layouts
otherwise resemble the `!` type and cannot be descended into like typical enums.
This first case captures uninhabited enums like:

    enum Uninhabited { A(!, !), B(!) }

The second case is revised to consider the broader category of "enums that defer
their layout to one of their variants"; i.e., enums whose layouts are described
with `Variants::Single { index }` and that do have a variant at `index`. This
second case captures uninhabited enums that are not ZSTs, like:

    enum Uninhabited { A(!, u128) }

This PR also adds a comment requested by @RalfJung in his review of rust-lang#126358 to
`compiler/rustc_const_eval/src/interpret/discriminant.rs`.

Fixes rust-lang#126460
@RalfJung
Copy link
Member

RalfJung commented Jun 14, 2024

I guess that answers my question here ;)

jswrenn added a commit to jswrenn/rust that referenced this issue Jun 14, 2024
Previously, `Tree::from_enum`'s implementation branched into three disjoint
cases:

 1. enums that uninhabited
 2. enums for which all but one variant is uninhabited
 3. enums with multiple inhabited variants

This branching (incorrectly) did not differentiate between variantful and
variantless uninhabited enums. In both cases, we assumed (and asserted) that
uninhabited enums are zero-sized types. This assumption is false for enums like:

    enum Uninhabited { A(!, u128) }

...which, currently, has the same size as `u128`. This faulty assumption
manifested as the ICE reported in rust-lang#126460.

In this PR, we revise the first case of `Tree::from_enum` to consider only the
narrow category of "enums that are uninhabited ZSTs". These enums, whose layouts
are described with `Variants::Single { index }`, are special in their layouts
otherwise resemble the `!` type and cannot be descended into like typical enums.
This first case captures uninhabited enums like:

    enum Uninhabited { A(!, !), B(!) }

The second case is revised to consider the broader category of "enums that defer
their layout to one of their variants"; i.e., enums whose layouts are described
with `Variants::Single { index }` and that do have a variant at `index`. This
second case captures uninhabited enums that are not ZSTs, like:

    enum Uninhabited { A(!, u128) }

This PR also adds a comment requested by @RalfJung in his review of rust-lang#126358 to
`compiler/rustc_const_eval/src/interpret/discriminant.rs`.

Fixes rust-lang#126460
jswrenn added a commit to jswrenn/rust that referenced this issue Jun 14, 2024
Previously, `Tree::from_enum`'s implementation branched into three disjoint
cases:

 1. enums that uninhabited
 2. enums for which all but one variant is uninhabited
 3. enums with multiple inhabited variants

This branching (incorrectly) did not differentiate between variantful and
variantless uninhabited enums. In both cases, we assumed (and asserted) that
uninhabited enums are zero-sized types. This assumption is false for enums like:

    enum Uninhabited { A(!, u128) }

...which, currently, has the same size as `u128`. This faulty assumption
manifested as the ICE reported in rust-lang#126460.

In this PR, we revise the first case of `Tree::from_enum` to consider only the
narrow category of "enums that are uninhabited ZSTs". These enums, whose layouts
are described with `Variants::Single { index }`, are special in their layouts
otherwise resemble the `!` type and cannot be descended into like typical enums.
This first case captures uninhabited enums like:

    enum Uninhabited { A(!, !), B(!) }

The second case is revised to consider the broader category of "enums that defer
their layout to one of their variants"; i.e., enums whose layouts are described
with `Variants::Single { index }` and that do have a variant at `index`. This
second case captures uninhabited enums that are not ZSTs, like:

    enum Uninhabited { A(!, u128) }

Finally, the third case is revised to cover the broader category of "enums with
multiple variants", which captures uninhabited enums like:

    enum Uninhabited { A(u8, !), B(!, u32) }

This PR also adds a comment requested by @RalfJung in his review of rust-lang#126358 to
`compiler/rustc_const_eval/src/interpret/discriminant.rs`.

Fixes rust-lang#126460
jswrenn added a commit to jswrenn/rust that referenced this issue Jun 14, 2024
Previously, `Tree::from_enum`'s implementation branched into three disjoint
cases:

 1. enums that uninhabited
 2. enums for which all but one variant is uninhabited
 3. enums with multiple inhabited variants

This branching (incorrectly) did not differentiate between variantful and
variantless uninhabited enums. In both cases, we assumed (and asserted) that
uninhabited enums are zero-sized types. This assumption is false for enums like:

    enum Uninhabited { A(!, u128) }

...which, currently, has the same size as `u128`. This faulty assumption
manifested as the ICE reported in rust-lang#126460.

In this PR, we revise the first case of `Tree::from_enum` to consider only the
narrow category of "enums that are uninhabited ZSTs". These enums, whose layouts
are described with `Variants::Single { index }`, are special in their layouts
otherwise resemble the `!` type and cannot be descended into like typical enums.
This first case captures uninhabited enums like:

    enum Uninhabited { A(!, !), B(!) }

The second case is revised to consider the broader category of "enums that defer
their layout to one of their variants"; i.e., enums whose layouts are described
with `Variants::Single { index }` and that do have a variant at `index`. This
second case captures uninhabited enums that are not ZSTs, like:

    enum Uninhabited { A(!, u128) }

Finally, the third case is revised to cover the broader category of "enums with
multiple variants", which captures uninhabited enums like:

    enum Uninhabited { A(u8, !), B(!, u32) }

This PR also adds a comment requested by RalfJung in his review of rust-lang#126358 to
`compiler/rustc_const_eval/src/interpret/discriminant.rs`.

Fixes rust-lang#126460
jswrenn added a commit to jswrenn/rust that referenced this issue Jun 14, 2024
Previously, `Tree::from_enum`'s implementation branched into three disjoint
cases:

 1. enums that uninhabited
 2. enums for which all but one variant is uninhabited
 3. enums with multiple inhabited variants

This branching (incorrectly) did not differentiate between variantful and
variantless uninhabited enums. In both cases, we assumed (and asserted) that
uninhabited enums are zero-sized types. This assumption is false for enums like:

    enum Uninhabited { A(!, u128) }

...which, currently, has the same size as `u128`. This faulty assumption
manifested as the ICE reported in rust-lang#126460.

In this PR, we revise the first case of `Tree::from_enum` to consider only the
narrow category of "enums that are uninhabited ZSTs". These enums, whose layouts
are described with `Variants::Single { index }`, are special in their layouts
otherwise resemble the `!` type and cannot be descended into like typical enums.
This first case captures uninhabited enums like:

    enum Uninhabited { A(!, !), B(!) }

The second case is revised to consider the broader category of "enums that defer
their layout to one of their variants"; i.e., enums whose layouts are described
with `Variants::Single { index }` and that do have a variant at `index`. This
second case captures uninhabited enums that are not ZSTs, like:

    enum Uninhabited { A(!, u128) }

...which represent their variants with `Variants::Single`.

Finally, the third case is revised to cover the broader category of "enums with
multiple variants", which captures uninhabited, non-ZST enums like:

    enum Uninhabited { A(u8, !), B(!, u32) }

...which represent their variants with `Variants::Multiple`.

This PR also adds a comment requested by RalfJung in his review of rust-lang#126358 to
`compiler/rustc_const_eval/src/interpret/discriminant.rs`.

Fixes rust-lang#126460
GuillaumeGomez added a commit to GuillaumeGomez/rust that referenced this issue Jun 18, 2024
safe transmute: support non-ZST, variantful, uninhabited enums

Previously, `Tree::from_enum`'s implementation branched into three disjoint cases:

 1. enums that uninhabited
 2. enums for which all but one variant is uninhabited
 3. enums with multiple variants

This branching (incorrectly) did not differentiate between variantful and variantless uninhabited enums. In both cases, we assumed (and asserted) that uninhabited enums are zero-sized types. This assumption is false for enums like:

    enum Uninhabited { A(!, u128) }

...which, currently, has the same size as `u128`. This faulty assumption manifested as the ICE reported in rust-lang#126460.

In this PR, we revise the first case of `Tree::from_enum` to consider only the narrow category of "enums that are uninhabited ZSTs". These enums, whose layouts are described with `Variants::Single { index }`, are special in their layouts otherwise resemble the `!` type and cannot be descended into like typical enums. This first case captures uninhabited enums like:

    enum Uninhabited { A(!, !), B(!) }

The second case is revised to consider the broader category of "enums that defer their layout to one of their variants"; i.e., enums whose layouts are described with `Variants::Single { index }` and that do have a variant at `index`. This second case captures uninhabited enums that are not ZSTs, like:

    enum Uninhabited { A(!, u128) }

...which represent their variants with `Variants::Single`.

Finally, the third case is revised to cover the broader category of "enums with multiple variants", which captures uninhabited enums like:

    enum Uninhabited { A(u8, !), B(!, u32) }

...which represent their variants with `Variants::Multiple`.

This PR also adds a comment requested by `@RalfJung` in his review of rust-lang#126358 to `compiler/rustc_const_eval/src/interpret/discriminant.rs`.

Fixes rust-lang#126460

r? `@compiler-errors`
GuillaumeGomez added a commit to GuillaumeGomez/rust that referenced this issue Jun 18, 2024
safe transmute: support non-ZST, variantful, uninhabited enums

Previously, `Tree::from_enum`'s implementation branched into three disjoint cases:

 1. enums that uninhabited
 2. enums for which all but one variant is uninhabited
 3. enums with multiple variants

This branching (incorrectly) did not differentiate between variantful and variantless uninhabited enums. In both cases, we assumed (and asserted) that uninhabited enums are zero-sized types. This assumption is false for enums like:

    enum Uninhabited { A(!, u128) }

...which, currently, has the same size as `u128`. This faulty assumption manifested as the ICE reported in rust-lang#126460.

In this PR, we revise the first case of `Tree::from_enum` to consider only the narrow category of "enums that are uninhabited ZSTs". These enums, whose layouts are described with `Variants::Single { index }`, are special in their layouts otherwise resemble the `!` type and cannot be descended into like typical enums. This first case captures uninhabited enums like:

    enum Uninhabited { A(!, !), B(!) }

The second case is revised to consider the broader category of "enums that defer their layout to one of their variants"; i.e., enums whose layouts are described with `Variants::Single { index }` and that do have a variant at `index`. This second case captures uninhabited enums that are not ZSTs, like:

    enum Uninhabited { A(!, u128) }

...which represent their variants with `Variants::Single`.

Finally, the third case is revised to cover the broader category of "enums with multiple variants", which captures uninhabited enums like:

    enum Uninhabited { A(u8, !), B(!, u32) }

...which represent their variants with `Variants::Multiple`.

This PR also adds a comment requested by ``@RalfJung`` in his review of rust-lang#126358 to `compiler/rustc_const_eval/src/interpret/discriminant.rs`.

Fixes rust-lang#126460

r? ``@compiler-errors``
jieyouxu added a commit to jieyouxu/rust that referenced this issue Jun 19, 2024
safe transmute: support non-ZST, variantful, uninhabited enums

Previously, `Tree::from_enum`'s implementation branched into three disjoint cases:

 1. enums that uninhabited
 2. enums for which all but one variant is uninhabited
 3. enums with multiple variants

This branching (incorrectly) did not differentiate between variantful and variantless uninhabited enums. In both cases, we assumed (and asserted) that uninhabited enums are zero-sized types. This assumption is false for enums like:

    enum Uninhabited { A(!, u128) }

...which, currently, has the same size as `u128`. This faulty assumption manifested as the ICE reported in rust-lang#126460.

In this PR, we revise the first case of `Tree::from_enum` to consider only the narrow category of "enums that are uninhabited ZSTs". These enums, whose layouts are described with `Variants::Single { index }`, are special in their layouts otherwise resemble the `!` type and cannot be descended into like typical enums. This first case captures uninhabited enums like:

    enum Uninhabited { A(!, !), B(!) }

The second case is revised to consider the broader category of "enums that defer their layout to one of their variants"; i.e., enums whose layouts are described with `Variants::Single { index }` and that do have a variant at `index`. This second case captures uninhabited enums that are not ZSTs, like:

    enum Uninhabited { A(!, u128) }

...which represent their variants with `Variants::Single`.

Finally, the third case is revised to cover the broader category of "enums with multiple variants", which captures uninhabited enums like:

    enum Uninhabited { A(u8, !), B(!, u32) }

...which represent their variants with `Variants::Multiple`.

This PR also adds a comment requested by ```@RalfJung``` in his review of rust-lang#126358 to `compiler/rustc_const_eval/src/interpret/discriminant.rs`.

Fixes rust-lang#126460

r? ```@compiler-errors```
jieyouxu added a commit to jieyouxu/rust that referenced this issue Jun 19, 2024
safe transmute: support non-ZST, variantful, uninhabited enums

Previously, `Tree::from_enum`'s implementation branched into three disjoint cases:

 1. enums that uninhabited
 2. enums for which all but one variant is uninhabited
 3. enums with multiple variants

This branching (incorrectly) did not differentiate between variantful and variantless uninhabited enums. In both cases, we assumed (and asserted) that uninhabited enums are zero-sized types. This assumption is false for enums like:

    enum Uninhabited { A(!, u128) }

...which, currently, has the same size as `u128`. This faulty assumption manifested as the ICE reported in rust-lang#126460.

In this PR, we revise the first case of `Tree::from_enum` to consider only the narrow category of "enums that are uninhabited ZSTs". These enums, whose layouts are described with `Variants::Single { index }`, are special in their layouts otherwise resemble the `!` type and cannot be descended into like typical enums. This first case captures uninhabited enums like:

    enum Uninhabited { A(!, !), B(!) }

The second case is revised to consider the broader category of "enums that defer their layout to one of their variants"; i.e., enums whose layouts are described with `Variants::Single { index }` and that do have a variant at `index`. This second case captures uninhabited enums that are not ZSTs, like:

    enum Uninhabited { A(!, u128) }

...which represent their variants with `Variants::Single`.

Finally, the third case is revised to cover the broader category of "enums with multiple variants", which captures uninhabited enums like:

    enum Uninhabited { A(u8, !), B(!, u32) }

...which represent their variants with `Variants::Multiple`.

This PR also adds a comment requested by ````@RalfJung```` in his review of rust-lang#126358 to `compiler/rustc_const_eval/src/interpret/discriminant.rs`.

Fixes rust-lang#126460

r? ````@compiler-errors````
@bors bors closed this as completed in df1d616 Jun 19, 2024
rust-timer added a commit to rust-lang-ci/rust that referenced this issue Jun 19, 2024
Rollup merge of rust-lang#126493 - jswrenn:fix-126460, r=compiler-errors

safe transmute: support non-ZST, variantful, uninhabited enums

Previously, `Tree::from_enum`'s implementation branched into three disjoint cases:

 1. enums that uninhabited
 2. enums for which all but one variant is uninhabited
 3. enums with multiple variants

This branching (incorrectly) did not differentiate between variantful and variantless uninhabited enums. In both cases, we assumed (and asserted) that uninhabited enums are zero-sized types. This assumption is false for enums like:

    enum Uninhabited { A(!, u128) }

...which, currently, has the same size as `u128`. This faulty assumption manifested as the ICE reported in rust-lang#126460.

In this PR, we revise the first case of `Tree::from_enum` to consider only the narrow category of "enums that are uninhabited ZSTs". These enums, whose layouts are described with `Variants::Single { index }`, are special in their layouts otherwise resemble the `!` type and cannot be descended into like typical enums. This first case captures uninhabited enums like:

    enum Uninhabited { A(!, !), B(!) }

The second case is revised to consider the broader category of "enums that defer their layout to one of their variants"; i.e., enums whose layouts are described with `Variants::Single { index }` and that do have a variant at `index`. This second case captures uninhabited enums that are not ZSTs, like:

    enum Uninhabited { A(!, u128) }

...which represent their variants with `Variants::Single`.

Finally, the third case is revised to cover the broader category of "enums with multiple variants", which captures uninhabited enums like:

    enum Uninhabited { A(u8, !), B(!, u32) }

...which represent their variants with `Variants::Multiple`.

This PR also adds a comment requested by ````@RalfJung```` in his review of rust-lang#126358 to `compiler/rustc_const_eval/src/interpret/discriminant.rs`.

Fixes rust-lang#126460

r? ````@compiler-errors````
@saethlin saethlin removed the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Jun 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug. F-transmutability `#![feature(transmutability)]` I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants