The compiler panics when there's a std::mem::size_of call for a struct with repr(packed) that contains a matrix type from nalgebra. I'm fairly new to rust and I'm not sure how to isolate what within the nalgebra crate might be causing this.
src/main.rs:
use nalgebra as na;
#[repr(packed)]
struct Foo(na::Vector3<f32>);
fn main() {
std::mem::size_of::<Foo>();
}
Cargo.toml
[package]
name = "test"
version = "0.1.0"
authors = ["Robert Grindeland <[email protected]>"]
edition = "2018"
[dependencies]
nalgebra = "0.16.13"
Result of RUST_BACKTRACE=1 cargo build --verbose
$ RUST_BACKTRACE=1 cargo build --verbose
Fresh rand_core v0.4.0
Fresh libm v0.1.2
Fresh rawpointer v0.1.0
Fresh rand_core v0.3.1
Fresh num-traits v0.2.6
Fresh winapi v0.3.6
Fresh typenum v1.10.0
Fresh matrixmultiply v0.1.15
Fresh num-complex v0.2.1
Fresh approx v0.3.1
Fresh rand v0.5.6
Fresh generic-array v0.11.1
Fresh alga v0.7.2
Fresh nalgebra v0.16.13
Compiling test v0.1.0 (C:\Users\Rob\Documents\Programming\cpp\compiler-bug)
Running `rustc --edition=2018 --crate-name test 'src\main.rs' --color always --crate-type bin --emit=dep-info,link -C debuginfo=2 -C metadata=9be42db9345f3907 -C extra-filename=-9be42db9345f3907 --out-dir 'C:\Users\Rob\Documents\Programming\cpp\compiler-bug\target\debug\deps' -C 'incremental=C:\Users\Rob\Documents\Programming\cpp\compiler-bug\target\debug\incremental' -L 'dependency=C:\Users\Rob\Documents\Programming\cpp\compiler-bug\target\debug\deps' --extern 'nalgebra=C:\Users\Rob\Documents\Programming\cpp\compiler-bug\target\debug\deps\libnalgebra-4080678600ea4cae.rlib'`
error: internal compiler error: librustc_typeck\check\wfcheck.rs:261: inference variables in nalgebra::base::matrix::Matrix<f32, nalgebra::base::dimension::U3, nalgebra::base::dimension::U1, nalgebra::base::array_storage::ArrayStorage<_, _, _>>
--> src\main.rs:4:1
|
4 | struct Foo(na::Vector3<f32>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
thread 'main' panicked at 'Box<Any>', librustc_errors\lib.rs:538:9
stack backtrace:
0: <std::sync::mpsc::select::Select as core::fmt::Debug>::fmt
1: std::path::<impl core::convert::From<std::path::PathBuf> for std::ffi::os_str::OsString>::from
2: std::panicking::take_hook
3: std::panicking::take_hook
4: <rustc::ty::sty::Binder<rustc::ty::ProjectionPredicate<'tcx>> as rustc::ty::ToPredicate<'tcx>>::to_predicate
5: std::panicking::rust_panic_with_hook
6: rustc_typeck::collect::early_bound_lifetimes_from_generics
7: rustc_typeck::collect::early_bound_lifetimes_from_generics
8: <rustc_typeck::outlives::explicit::ExplicitPredicatesMap<'tcx> as core::fmt::Debug>::fmt
9: <rustc_typeck::outlives::explicit::ExplicitPredicatesMap<'tcx> as core::fmt::Debug>::fmt
10: <rustc_typeck::outlives::explicit::ExplicitPredicatesMap<'tcx> as core::fmt::Debug>::fmt
11: <rustc_typeck::outlives::explicit::ExplicitPredicatesMap<'tcx> as core::fmt::Debug>::fmt
12: <rustc_typeck::outlives::explicit::ExplicitPredicatesMap<'tcx> as core::fmt::Debug>::fmt
13: <rustc_typeck::outlives::explicit::ExplicitPredicatesMap<'tcx> as core::fmt::Debug>::fmt
14: <rustc_typeck::outlives::explicit::ExplicitPredicatesMap<'tcx> as core::fmt::Debug>::fmt
15: <rustc_typeck::outlives::explicit::ExplicitPredicatesMap<'tcx> as core::fmt::Debug>::fmt
16: <rustc_typeck::check::method::probe::ProbeScope as core::fmt::Debug>::fmt
17: <rustc_typeck::check::upvar::InferBorrowKind<'a, 'gcx, 'tcx> as rustc::middle::expr_use_visitor::Delegate<'tcx>>::mutate
18: <rustc::traits::query::outlives_bounds::OutlivesBound<'a> as rustc::ty::context::Lift<'tcx>>::lift_to_tcx
19: rustc::ty::context::tls::track_diagnostic
20: rustc::dep_graph::graph::DepGraph::assert_ignored
21: rustc::ty::adjustment::<impl core::convert::From<rustc::ty::adjustment::AutoBorrowMutability> for rustc::hir::Mutability>::from
22: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::try_print_query_stack
23: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::try_print_query_stack
24: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::try_print_query_stack
25: <rustc_typeck::outlives::implicit_infer::IgnoreSelfTy as core::fmt::Debug>::fmt
26: <rustc_typeck::check::regionck::RegionCtxt<'a, 'gcx, 'tcx> as rustc::hir::intravisit::Visitor<'gcx>>::nested_visit_map
27: rustc_typeck::check_crate
28: <humantime::date::Error as std::error::Error>::cause
29: <rustc_driver::pretty::NoAnn<'hir> as rustc_driver::pretty::HirPrinterSupport<'hir>>::sess
30: <humantime::date::Error as std::error::Error>::cause
31: rustc_driver::driver::compile_input
32: rustc_driver::run_compiler
33: <rustc_driver::profile::trace::Query as core::fmt::Debug>::fmt
34: rustc_driver::run_compiler
35: <rustc_driver::profile::trace::Query as core::fmt::Debug>::fmt
36: _rust_maybe_catch_panic
37: <unknown>
38: rustc_driver::main
39: <unknown>
40: std::panicking::update_panic_count
41: _rust_maybe_catch_panic
42: std::rt::lang_start_internal
43: <unknown>
44: <unknown>
45: BaseThreadInitThunk
46: RtlUserThreadStart
query stack during panic:
#0 [check_item_well_formed] processing `Foo`
end of query stack
error: aborting due to previous error
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.31.1 (b6c32da9b 2018-12-18) running on x86_64-pc-windows-msvc
note: compiler flags: -C debuginfo=2 -C incremental --crate-type bin
note: some of the compiler flags provided by cargo are hidden
error: Could not compile `test`.
Caused by:
process didn't exit successfully: `rustc --edition=2018 --crate-name test 'src\main.rs' --color always --crate-type bin --emit=dep-info,link -C debuginfo=2 -C metadata=9be42db9345f3907 -C extra-filename=-9be42db9345f3907 --out-dir 'C:\Users\Rob\Documents\Programming\cpp\compiler-bug\target\debug\deps' -C 'incremental=C:\Users\Rob\Documents\Programming\cpp\compiler-bug\target\debug\incremental' -L 'dependency=C:\Users\Rob\Documents\Programming\cpp\compiler-bug\target\debug\deps' --extern 'nalgebra=C:\Users\Rob\Documents\Programming\cpp\compiler-bug\target\debug\deps\libnalgebra-4080678600ea4cae.rlib'` (exit code: 101)
Slightly minimized (this can be reduced _much_ more); the ICE in the following also occurs with std::mem::size_of commented out
use std::any::Any;
use std::fmt::Debug;
use std::marker::PhantomData;
#[repr(packed)]
struct Foo(Vector3<f32>);
fn main() {
// std::mem::size_of::<Foo>();
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct Matrix<N: Scalar, R: Dim, C: Dim, S> {
pub data: S,
_phantoms: PhantomData<(N, R, C)>,
}
type MatrixMN<N, R, C> = Matrix<N, R, C, Owned<N, R, C>>;
type VectorN<N, D> = MatrixMN<N, D, U1>;
type Vector3<N> = VectorN<N, U3>;
pub trait Dim: Any + Debug + Copy + PartialEq + Send + Sync {}
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub struct U1;
impl Dim for U1 {}
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub struct U3;
impl Dim for U3 {}
pub trait Scalar: Copy + PartialEq + Debug + Any {}
impl<T: Copy + PartialEq + Debug + Any> Scalar for T {}
pub unsafe trait Storage<N: Scalar, R: Dim, C: Dim = U1>: Debug + Sized {
type RStride: Dim;
type CStride: Dim;
}
pub unsafe trait StorageMut<N: Scalar, R: Dim, C: Dim = U1>: Storage<N, R, C> {}
pub unsafe trait ContiguousStorage<N: Scalar, R: Dim, C: Dim = U1>:
Storage<N, R, C>
{
}
pub unsafe trait ContiguousStorageMut<N: Scalar, R: Dim, C: Dim = U1>:
ContiguousStorage<N, R, C> + StorageMut<N, R, C>
{
}
pub trait Allocator<N: Scalar, R: Dim, C: Dim = U1>: Any + Sized {
type Buffer: ContiguousStorageMut<N, R, C> + Clone;
}
pub struct DefaultAllocator;
pub type Owned<N, R, C = U1> = <DefaultAllocator as Allocator<N, R, C>>::Buffer;
error: internal compiler error: src/librustc_typeck/check/wfcheck.rs:255: inference variables in Matrix<f32, U3, U1, _>
--> src/main.rs:6:1
|
6 | struct Foo(Vector3<f32>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^
thread 'rustc' panicked at 'Box<Any>', src/librustc_errors/lib.rs:543:9
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
stack backtrace:
0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
at src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:39
1: std::sys_common::backtrace::_print
at src/libstd/sys_common/backtrace.rs:70
2: std::panicking::default_hook::{{closure}}
at src/libstd/sys_common/backtrace.rs:58
at src/libstd/panicking.rs:200
3: std::panicking::default_hook
at src/libstd/panicking.rs:215
4: rustc::util::common::panic_hook
5: std::panicking::rust_panic_with_hook
at src/libstd/panicking.rs:482
6: std::panicking::begin_panic
7: rustc_errors::Handler::span_bug
8: rustc::util::bug::opt_span_bug_fmt::{{closure}}
9: rustc::ty::context::tls::with_opt::{{closure}}
10: rustc::ty::context::tls::with_context_opt
11: rustc::ty::context::tls::with_opt
12: rustc::util::bug::opt_span_bug_fmt
13: rustc::util::bug::span_bug_fmt
14: rustc_typeck::check::wfcheck::check_type_defn::{{closure}}::{{closure}}::{{closure}}
15: rustc::ty::context::GlobalCtxt::enter_local
16: rustc_typeck::check::wfcheck::check_item_well_formed
17: rustc::ty::query::__query_compute::check_item_well_formed
18: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors<'tcx> for rustc::ty::query::queries::check_item_well_formed<'tcx>>::compute
19: rustc::dep_graph::graph::DepGraph::with_task_impl
20: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::try_get_with
21: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::ensure_query
22: rustc::hir::Crate::visit_all_item_likes
23: rustc::util::common::time
24: rustc_typeck::check_crate
25: <std::thread::local::LocalKey<T>>::with
26: rustc::ty::context::TyCtxt::create_and_enter
27: rustc_driver::driver::compile_input
28: rustc_driver::run_compiler_with_pool
29: <scoped_tls::ScopedKey<T>>::set
30: rustc_driver::run_compiler
31: <scoped_tls::ScopedKey<T>>::set
query stack during panic:
#0 [check_item_well_formed] processing `Foo`
end of query stack
error: aborting due to previous error
note: rustc 1.34.0-nightly (f6fac4225 2019-02-03) running on x86_64-unknown-linux-gnu
note: compiler flags: -C codegen-units=1 -C debuginfo=2 --crate-type bin
rustc 1.34.0-nightly (f6fac4225 2019-02-03)
Minimized further:
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=e1c3725bd288e50631a4cf100538469f
pub struct Matrix<S> {}
pub struct DefaultAllocator;
pub trait Allocator {
type Buffer;
}
#[repr(packed)]
struct Foo(Matrix<<DefaultAllocator as Allocator>::Buffer>);
Even more:
#[repr(packed)]
pub struct Foo(<Vec<u32> as IntoIterator>::Item);
The ICE does not happen without the #[repr(packed)] attribute (also neat: this code would compile without warning when used as a testcase)
Also note, that this "never worked" (I went back to nightly-2018-03-01, and even there it panics).
triage. Marking P-high mostly because 1. it is an ICE and 2. I want to ensure it is at the front of the T-compiler queue for next week's meeting.
(also neat: this code would compile without warning when used as a testcase)
@hellow554 can you clarify what you meant by this parenthetical? Are you saying if I add #[test] somewhere to the file it compiles without any error or warning?
triage: assigning to self.
There's other variations up above, but I thought this one was particularly illuminating:
struct DefaultAllocator;
trait Allocator { type Buffer; }
// impl Allocator for DefaultAllocator { type Buffer = (); }
#[repr(packed)]
struct Foo(<DefaultAllocator as Allocator>::Buffer);
note in particular that, at least in this variation, the concrete type here does not implement the trait in question. So its impossible to actually resolve the associated type when doing the repr(packed) analysis.
(If you add back in the impl commented-out above, then the code compiles. And if you leave it out but remove repr(packed), then the code gets rejected since the concrete type does not implement the trait.)
(also neat: this code would compile without warning when used as a testcase)
@hellow554 can you clarify what you meant by this parenthetical? Are you saying if I add
#[test]somewhere to the file it compiles without any error or warning?
when you use it as a regression test in https://github.com/rust-lang/rust/tree/master/src/test
when you use it as a regression test in https://github.com/rust-lang/rust/tree/master/src/test
i find that ... surprising. Will investigate.
Sorry @pnkfelix ! I don't mean that it doesn't crash when used as test, but if this issue will be fixed my code can be used as testcode because it doesn't emit any warnings or errors.
@hellow554 ah, okay yes that makes more sense to me!
Most helpful comment
Minimized further:
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=e1c3725bd288e50631a4cf100538469f