Skip to content

Panic with Layout mismatch when copying! from macro #61663

Closed
@mickvangelderen

Description

@mickvangelderen

The following code has the compiler (correctly) emit an error about how explicit enum tags with the default representation need to be of type isize. The compiler panics afterwards.

use std::convert::TryFrom;

pub trait Symbol<T> {
    const VALUE: T;
}

pub struct FALSE;

impl Symbol<i32> for FALSE {
    const VALUE: i32 = 0;
}

pub struct TRUE;

impl Symbol<i32> for TRUE {
    const VALUE: i32 = 1;
}

macro_rules! impl_symbol_enum {
    (
        $Raw: ident,
        $Enum: ident,
        $Error: ident { $(
            $Variant: ident = $Symbol: ident,
        )* }
    ) => {
        #[derive(Debug)]
        pub struct $Error($Raw);

        #[derive(Debug, Copy, Clone, Eq, PartialEq)]
        pub enum $Enum {
            $(
                $Variant = <$Symbol as Symbol<$Raw>>::VALUE,
            )*
        }

        impl TryFrom<$Raw> for $Enum {
            type Error = $Error;

            fn try_from(value: $Raw) -> Result<Self, Self::Error> {
                match value {
                    $(
                        valid if valid == <$Symbol as Symbol<$Raw>>::VALUE => Ok($Enum::$Variant),
                    )*
                    invalid => Err($Error(invalid)),
                }
            }
        }
    }
}

impl_symbol_enum! {
    i32,
    InvalidLinkStatus,
    LinkStatus {
        Unlinked = FALSE,
        Linked = TRUE,
    }
}

Output:

error[E0308]: mismatched types
  --> glw/src/glw.rs:35:28
   |
35 |                   $Variant = <$Symbol as Symbol<$Raw>>::VALUE,
   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected isize, found i32
...
54 | / impl_symbol_enum! {
55 | |     i32,
56 | |     InvalidLinkStatus,
57 | |     LinkStatus {
...  |
60 | |     }
61 | | }
   | |_- in this macro invocation
help: you can convert an `i32` to `isize` and panic if the converted value wouldn't fit
   |
35 |                 $Variant = <$Symbol as Symbol<$Raw>>::VALUE.try_into().unwrap(),
   |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

thread 'rustc' panicked at 'Layout mismatch when copying!
src: OpTy {
    op: Indirect(
        MemPlace {
            ptr: AllocId(1).0x0,
            align: Align {
                pow2: 2,
            },
            meta: None,
        },
    ),
    layout: TyLayout {
        ty: i32,
        details: LayoutDetails {
            variants: Single {
                index: 0,
            },
            fields: Union(
                0,
            ),
            abi: Scalar(
                Scalar {
                    value: Int(
                        I32,
                        true,
                    ),
                    valid_range: 0..=4294967295,
                },
            ),
            align: AbiAndPrefAlign {
                abi: Align {
                    pow2: 2,
                },
                pref: Align {
                    pow2: 2,
                },
            },
            size: Size {
                raw: 4,
            },
        },
    },
}
dest: PlaceTy {
    place: Ptr(
        MemPlace {
            ptr: AllocId(0).0x0,
            align: Align {
                pow2: 3,
            },
            meta: None,
        },
    ),
    layout: TyLayout {
        ty: isize,
        details: LayoutDetails {
            variants: Single {
                index: 0,
            },
            fields: Union(
                0,
            ),
            abi: Scalar(
                Scalar {
                    value: Int(
                        I64,
                        true,
                    ),
                    valid_range: 0..=18446744073709551615,
                },
            ),
            align: AbiAndPrefAlign {
                abi: Align {
                    pow2: 3,
                },
                pref: Align {
                    pow2: 3,
                },
            },
            size: Size {
                raw: 8,
            },
        },
    },
}', src/librustc_mir/interpret/place.rs:826:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
error: aborting due to previous error

For more information about this error, try `rustc --explain E0308`.

error: internal compiler error: unexpected panic

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

note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports

note: rustc 1.37.0-nightly (d132f544f 2019-06-07) running on x86_64-unknown-linux-gnu

note: compiler flags: -C debuginfo=2 -C incremental --crate-type lib

I tried to reduce the code more but this code does not cause a panic:

macro_rules! happy_compiler {
    ($T: ident, $v: expr) => {
        trait C<T> {
            const V: T;
        }

        impl C<$T> for M {
            const V: $T = $v;
        }

        enum E {
            V = <M as C<$T>>::V,
        }
    };
}

happy_compiler!(i32, 42);

I will happily move on after correcting my mistake but I thought I'd at least report this panic.

Meta

rustc --version --verbose:

rustc 1.37.0-nightly (d132f544f 2019-06-07)
binary: rustc
commit-hash: d132f544f9d74e3cc047ef211e57eae60b78e5c5
commit-date: 2019-06-07
host: x86_64-unknown-linux-gnu
release: 1.37.0-nightly
LLVM version: 8.0

Backtrace:

stack backtrace:
   0: backtrace::backtrace::libunwind::trace
             at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.29/src/backtrace/libunwind.rs:88
   1: backtrace::backtrace::trace_unsynchronized
             at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.29/src/backtrace/mod.rs:66
   2: std::sys_common::backtrace::_print
             at src/libstd/sys_common/backtrace.rs:47
   3: std::sys_common::backtrace::print
             at src/libstd/sys_common/backtrace.rs:36
   4: std::panicking::default_hook::{{closure}}
             at src/libstd/panicking.rs:198
   5: std::panicking::default_hook
             at src/libstd/panicking.rs:212
   6: rustc::util::common::panic_hook
   7: std::panicking::rust_panic_with_hook
             at src/libstd/panicking.rs:479
   8: std::panicking::continue_panic_fmt
             at src/libstd/panicking.rs:382
   9: std::panicking::begin_panic_fmt
             at src/libstd/panicking.rs:337
  10: rustc_mir::interpret::place::<impl rustc_mir::interpret::eval_context::InterpretCx<M>>::copy_op_no_validate
  11: rustc_mir::interpret::step::<impl rustc_mir::interpret::eval_context::InterpretCx<M>>::run
  12: rustc_mir::const_eval::eval_body_using_ecx
  13: rustc_mir::const_eval::const_eval_raw_provider
  14: rustc::ty::query::__query_compute::const_eval_raw
  15: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors for rustc::ty::query::queries::const_eval_raw>::compute
  16: rustc::dep_graph::graph::DepGraph::with_task_impl
  17: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query
  18: rustc_mir::const_eval::const_eval_provider
  19: rustc::ty::query::__query_compute::const_eval
  20: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors for rustc::ty::query::queries::const_eval>::compute
  21: rustc::dep_graph::graph::DepGraph::with_task_impl
  22: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query
  23: <rustc_typeck::collect::CollectItemTypesVisitor as rustc::hir::intravisit::Visitor>::visit_item
  24: rustc::hir::map::Map::visit_item_likes_in_module
  25: rustc_typeck::collect::collect_mod_item_types
  26: rustc::ty::query::__query_compute::collect_mod_item_types
  27: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors for rustc::ty::query::queries::collect_mod_item_types>::compute
  28: rustc::dep_graph::graph::DepGraph::with_task_impl
  29: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query
  30: rustc_typeck::check_crate::{{closure}}::{{closure}}
  31: rustc::util::common::time
  32: rustc_typeck::check_crate
  33: rustc_interface::passes::analysis
  34: rustc::ty::query::__query_compute::analysis
  35: rustc::dep_graph::graph::DepGraph::with_task_impl
  36: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query
  37: rustc::ty::context::tls::enter_global
  38: rustc_interface::passes::BoxedGlobalCtxt::access::{{closure}}
  39: rustc_interface::passes::create_global_ctxt::{{closure}}
  40: rustc_interface::interface::run_compiler_in_existing_thread_pool
  41: std::thread::local::LocalKey<T>::with
  42: scoped_tls::ScopedKey<T>::set
  43: syntax::with_globals

Metadata

Metadata

Labels

A-const-evalArea: Constant evaluation, covers all const contexts (static, const fn, ...)C-bugCategory: This is a bug.I-ICEIssue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️P-highHigh priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.regression-from-stable-to-betaPerformance or correctness regression from stable to beta.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions