rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
96.18k stars 12.44k forks source link

ICE: `expected wide pointer extra data (e.g. slice length or trait object vtable)` #127742

Open Naserume opened 1 month ago

Naserume commented 1 month ago

Code

#[derive(Copy, Clone)]
struct Wide<'a>(&'a Foo, &'static VTable);

trait Cap<'a> {}

struct VTable {
    bar: dyn Cap,
}

trait Bar {
    fn bar(&self) -> u32;
}

struct Foo {
    foo: u32,
    bar: bool,
}

impl Bar for Foo {
    fn bar(&self) -> u32 {}
}

#[repr(C)]
union Transmute<T: Copy, U: Copy> {
    t: T,
    u: U,
}

const FOO: &dyn Bar = &Foo {
    foo: 128,
    bar: false,
};

const G: Wide = Transmute { t: FOO }.u;

fn main() {}

Meta

rustc --version --verbose:

rustc 1.81.0-nightly (fcaa6fdfb 2024-07-13)
binary: rustc
commit-hash: fcaa6fdfbee1316184e7ad98c53241d52cd30a5f
commit-date: 2024-07-13
host: x86_64-apple-darwin
release: 1.81.0-nightly
LLVM version: 18.1.7

Error output

error[E0106]: missing lifetime specifier
 --> ./A6D34.rs:7:14
  |
7 |     bar: dyn Cap,
  |              ^^^ expected named lifetime parameter
  |
  = note: for more information on higher-ranked polymorphism, visit https://doc.rust-lang.org/nomicon/hrtb.html
help: consider making the bound lifetime-generic with a new `'a` lifetime
  |
7 |     bar: dyn for<'a> Cap<'a>,
  |              +++++++    ++++
help: consider introducing a named lifetime parameter
  |
6 ~ struct VTable<'a> {
7 ~     bar: dyn Cap<'a>,
  |
Backtrace

``` error: internal compiler error: compiler/rustc_const_eval/src/interpret/place.rs:39:17: expected wide pointer extra data (e.g. slice length or trait object vtable) thread 'rustc' panicked at compiler/rustc_const_eval/src/interpret/place.rs:39:17: Box stack backtrace: 0: 0x101ff6373 - ::fmt::h605d51fc858e32d3 1: 0x1020412fb - core::fmt::write::he70b1f5b242a09e4 2: 0x101fec0be - std::io::Write::write_fmt::hbfde528b9dfff91a 3: 0x101ff8c1a - std::panicking::default_hook::{{closure}}::hfdc91bfcaaf40c09 4: 0x101ff88ca - std::panicking::default_hook::h8673ceadddb8316e 5: 0x10b37d8dc - std[8bfe66706d3bd117]::panicking::update_hook::>::{closure#0} 6: 0x101ff9a09 - std::panicking::rust_panic_with_hook::h206b639ed4704bb1 7: 0x10b3f0bb7 - std[8bfe66706d3bd117]::panicking::begin_panic::::{closure#0} 8: 0x10b3dc9f9 - std[8bfe66706d3bd117]::sys::backtrace::__rust_end_short_backtrace::::{closure#0}, !> 9: 0x10fe57469 - std[8bfe66706d3bd117]::panicking::begin_panic:: 10: 0x10b402c06 - ::emit_producing_guarantee 11: 0x10c0c8b45 - rustc_middle[66eaac359ba8a608]::util::bug::opt_span_bug_fmt::::{closure#0} 12: 0x10c07f0b7 - rustc_middle[66eaac359ba8a608]::ty::context::tls::with_opt::::{closure#0}, !>::{closure#0} 13: 0x10c07ebf5 - rustc_middle[66eaac359ba8a608]::ty::context::tls::with_context_opt::::{closure#0}, !>::{closure#0}, !> 14: 0x10ff1ff9b - rustc_middle[66eaac359ba8a608]::util::bug::bug_fmt 15: 0x10b2f2c32 - >::check_wide_ptr_meta 16: 0x10b2f3141 - >::check_safe_pointer 17: 0x10b2f57d3 - as rustc_const_eval[b2dc86267216f489]::interpret::visitor::ValueVisitor>::visit_value 18: 0x10b2f629e - as rustc_const_eval[b2dc86267216f489]::interpret::visitor::ValueVisitor>::visit_value 19: 0x10b2f7e85 - >::validate_operand_internal 20: 0x10b303b5b - rustc_const_eval[b2dc86267216f489]::const_eval::eval_queries::eval_to_allocation_raw_provider 21: 0x10ca63d1c - rustc_query_impl[ab99e8e391ad42b2]::plumbing::__rust_begin_short_backtrace::> 22: 0x10ca173de - )>>::call_once 23: 0x10c84e42d - rustc_query_system[55587a8be6cb95b6]::query::plumbing::try_execute_query::, rustc_middle[66eaac359ba8a608]::query::erase::Erased<[u8; 24usize]>>, false, false, false>, rustc_query_impl[ab99e8e391ad42b2]::plumbing::QueryCtxt, false> 24: 0x10ca8ed1c - rustc_query_impl[ab99e8e391ad42b2]::query_impl::eval_to_allocation_raw::get_query_non_incr::__rust_end_short_backtrace 25: 0x10b22d5a2 - rustc_middle[66eaac359ba8a608]::query::plumbing::query_get_at::, rustc_middle[66eaac359ba8a608]::query::erase::Erased<[u8; 24usize]>>> 26: 0x10b2ffe40 - rustc_const_eval[b2dc86267216f489]::const_eval::eval_queries::eval_to_const_value_raw_provider 27: 0x10ca646bc - rustc_query_impl[ab99e8e391ad42b2]::plumbing::__rust_begin_short_backtrace::> 28: 0x10ca1cbae - )>>::call_once 29: 0x10c84e42d - rustc_query_system[55587a8be6cb95b6]::query::plumbing::try_execute_query::, rustc_middle[66eaac359ba8a608]::query::erase::Erased<[u8; 24usize]>>, false, false, false>, rustc_query_impl[ab99e8e391ad42b2]::plumbing::QueryCtxt, false> 30: 0x10ca8f5cc - rustc_query_impl[ab99e8e391ad42b2]::query_impl::eval_to_const_value_raw::get_query_non_incr::__rust_end_short_backtrace 31: 0x10b600c61 - ::par_body_owners::::{closure#0} 32: 0x10b74f4dc - rustc_hir_analysis[c06ca58d4f3a4935]::check_crate 33: 0x10bd0ce37 - rustc_interface[f3798eed8f7e14ff]::passes::run_required_analyses 34: 0x10bd0f2d3 - rustc_interface[f3798eed8f7e14ff]::passes::analysis 35: 0x10ca6671c - rustc_query_impl[ab99e8e391ad42b2]::plumbing::__rust_begin_short_backtrace::> 36: 0x10c83ebfe - rustc_query_system[55587a8be6cb95b6]::query::plumbing::try_execute_query::>, false, false, false>, rustc_query_impl[ab99e8e391ad42b2]::plumbing::QueryCtxt, false> 37: 0x10ca70c77 - rustc_query_impl[ab99e8e391ad42b2]::query_impl::analysis::get_query_non_incr::__rust_end_short_backtrace 38: 0x10b323537 - >::enter::, rustc_driver_impl[d8a49a9463f03e6]::run_compiler::{closure#0}::{closure#1}::{closure#5}> 39: 0x10b384c1b - rustc_interface[f3798eed8f7e14ff]::interface::run_compiler::, rustc_driver_impl[d8a49a9463f03e6]::run_compiler::{closure#0}>::{closure#1} 40: 0x10b36ffc1 - std[8bfe66706d3bd117]::sys::backtrace::__rust_begin_short_backtrace::, rustc_driver_impl[d8a49a9463f03e6]::run_compiler::{closure#0}>::{closure#1}, core[84f3396b7379d157]::result::Result<(), rustc_span[9df13b32b3ae4eb2]::ErrorGuaranteed>>::{closure#0}, core[84f3396b7379d157]::result::Result<(), rustc_span[9df13b32b3ae4eb2]::ErrorGuaranteed>>::{closure#0}::{closure#0}, core[84f3396b7379d157]::result::Result<(), rustc_span[9df13b32b3ae4eb2]::ErrorGuaranteed>> 41: 0x10b38b5e6 - <::spawn_unchecked_, rustc_driver_impl[d8a49a9463f03e6]::run_compiler::{closure#0}>::{closure#1}, core[84f3396b7379d157]::result::Result<(), rustc_span[9df13b32b3ae4eb2]::ErrorGuaranteed>>::{closure#0}, core[84f3396b7379d157]::result::Result<(), rustc_span[9df13b32b3ae4eb2]::ErrorGuaranteed>>::{closure#0}::{closure#0}, core[84f3396b7379d157]::result::Result<(), rustc_span[9df13b32b3ae4eb2]::ErrorGuaranteed>>::{closure#2} as core[84f3396b7379d157]::ops::function::FnOnce<()>>::call_once::{shim:vtable#0} 42: 0x1020029bb - std::sys::pal::unix::thread::Thread::new::thread_start::hff8a09cc296b9c2d 43: 0x7ff801f5318b - __pthread_start 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: please attach the file at `/Users/sal/Documents/240714(240712-nightly)/rustc-ice-2024-07-15T00_43_16-58375.txt` to your bug report query stack during panic: #0 [eval_to_allocation_raw] const-evaluating + checking `G` #1 [eval_to_const_value_raw] simplifying constant for the type system `G` end of query stack error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0106`. ```

Note

ICE location https://github.com/rust-lang/rust/blob/fcaa6fdfbee1316184e7ad98c53241d52cd30a5f/compiler/rustc_const_eval/src/interpret/place.rs#L33-L42

theemathas commented 1 month ago

Minimized:

struct Vtable(dyn Cap);  // missing lifetime

trait Cap<'a> {}

union Transmute {
    t: u64,  // ICEs with u64, u128, or usize. Correctly errors with u32.
    u: &'static Vtable,
}

const G: &'static Vtable = unsafe { Transmute { t: 1 }.u };
GrigorenkoPV commented 1 month ago

searched nightlies: from nightly-2023-11-11 to nightly-2024-07-15 regressed nightly: nightly-2024-03-22 searched commit range: https://github.com/rust-lang/rust/compare/1388d7a069d872bcfe5e5dd97ef61fa0a586fac0...0ad927c0c07b65fc0dae37105e09c877c87c296a regressed commit: https://github.com/rust-lang/rust/commit/6a6cd6517dac28f9c3f0476e4ba436a2010e40d9 The PR introducing the regression in this rollup is #122749: make type_flags(ReError) & HAS_ERROR

(both the original and the minimized version)

adwinwhite commented 2 weeks ago

@rustbot claim

adwinwhite commented 2 weeks ago

The error originates from layout miscalculation of ill-formed type. It should return a ScalarPair for trait object reference but returned a Scalar here. https://github.com/rust-lang/rust/blob/176e5452095444815207be02c16de0b1487a1b53/compiler/rustc_ty_utils/src/layout.rs#L204-L205

adwinwhite commented 2 weeks ago

A more detailed analysis: The ICE happened when trying to validate resulting const value which had been interpreted. The result const is a trait object reference. As we can see from the backtrace, the ICE is due to the trait object reference having empty meta data, which should contain a vtable pointer under normal circumstance. Tracing down meta variable's origin, I found that it's directly split from the resulting const value. https://github.com/rust-lang/rust/blob/e57f3090aec33cdbf66063c866afaa5e1e78b9bb/compiler/rustc_const_eval/src/interpret/place.rs#L407-L414 https://github.com/rust-lang/rust/blob/e57f3090aec33cdbf66063c866afaa5e1e78b9bb/compiler/rustc_const_eval/src/interpret/operand.rs#L107-L110 Our resulting const value is a Scalar, allocated according to its layout. So its layout calculation must go wrong. As I mentioned in previous comment, it mistook the pointee(trait object wrapper) as sized. The cause is that our trait object type contains error, more specifically its region contains error. https://github.com/rust-lang/rust/blob/176e5452095444815207be02c16de0b1487a1b53/compiler/rustc_ty_utils/src/ty.rs#L97-L99 And is_trivially_sized thinks ty::Error is sized. https://github.com/rust-lang/rust/blob/176e5452095444815207be02c16de0b1487a1b53/compiler/rustc_middle/src/ty/sty.rs#L1805-L1806

adwinwhite commented 2 weeks ago

The analysis is based on the minimized code above and the trait object I'm talking about is dyn Cap.