rust-lang / rust

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

Internal compile error when adding sized constain with assoicated type #24682

Closed magast-io closed 9 years ago

magast-io commented 9 years ago

Adding a sized constraint to a trait caused an internal compile error.

I tried this code:

trait A: Sized {
    type N:One;
    fn new(x:Self::N) -> Self;

    fn x() -> Self<N=Self::N> {
        Self::new(Self::N::one())
    }
}

trait One {
    fn one() -> Self;
}

impl One for i32 {
    fn one() -> i32 {
        1i32
    }
}

impl A for B {
    type N = i32;
     fn new(x:i32) -> B {
        B { x: x }
    }
}

struct B {
    x:i32
}

fn main() {
    let b = B::new(5i32);
    println!("b.x: {}", b.x )
}

Removing the sized constraint from A no longer as a internal compile error, and fails to compile with the error

sized_trait.rs:5:15: 5:30 error: the trait `core::marker::Sized` is not implemented for the type `Self` [E0277]
sized_trait.rs:5     fn x() -> Self<N=Self::N> {
^
sized_trait.rs:5:15: 5:30 note: `Self` does not have a constant size known at compile-time
sized_trait.rs:5     fn x() -> Self<N=Self::N> {
^
error: aborting due to previous error

Removing fn x() -> Self<N=Self::N> from trait A causes a successful compile.

Meta

rustc --version --verbose: rustc 1.0.0-beta.2 (e9080ec39 2015-04-16) (built 2015-04-16) binary: rustc commit-hash: e9080ec39d9a44eb0773d648b348575b19f655e5 commit-date: 2015-04-16 build-date: 2015-04-16 host: x86_64-unknown-linux-gnu release: 1.0.0-beta.2

Backtrace:

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: run with `RUST_BACKTRACE=1` for a backtrace
thread 'rustc' panicked at 'path not fully resolved: PathResolution { base_def: DefSelfTy(Some(DefId { krate: 0, node: 4 }), None), last_private: LastMod(AllPublic), depth: 1 }', /home/rustbuild/src/rust-buildbot/slave/beta-dist-rustc-linux/build/src/librustc/middle/def.rs:80

stack backtrace: 1: 0x7f4ce4435439 - sys::backtrace::write::he2e34ba2c33dc0e30Us 2: 0x7f4ce443d0f6 - panicking::on_panic::hc9625174f6ab8ee8fix 3: 0x7f4ce43fb182 - rt::unwind::begin_unwind_inner::h3ab4e1f5d89ab81bpXw 4: 0x7f4ce43fb44c - rt::unwind::begin_unwind_fmt::haff11c8aa28ec8b23Vw 5: 0x7f4ce2271db6 - middle::def::PathResolution::full_def::h74a01ccebde3cb12mZl 6: 0x7f4ce3897e4e - PrivacyVisitor<'a, 'tcx>::check_path::h7dab5d16c75af8c4X4a 7: 0x7f4ce3898ed7 - PrivacyVisitor<'a, 'tcx>.Visitor<'v>::visit_path::hb9a2f24773dbb8d9ctb 8: 0x7f4ce3899022 - visit::walk_path::h7066235731909768411 9: 0x7f4ce389aa99 - visit::Visitor::visit_fn::h17785043978168098476 10: 0x7f4ce389b5da - visit::walk_trait_item::h1977003431506782162 11: 0x7f4ce3898d7f - PrivacyVisitor<'a, 'tcx>.Visitor<'v>::visit_item::hf1bd234520341cbexdb 12: 0x7f4ce389f7fb - check_crate::hb8e3f1bb5ec19bf6EVb 13: 0x7f4ce499bfc3 - driver::phase_3_run_analysis_passes::h5a432074c589df71nGa 14: 0x7f4ce497ccf5 - driver::compile_input::h534dde66bedcbe27Qba 15: 0x7f4ce4a3d561 - run_compiler::hcc529c6d73620eadz4b 16: 0x7f4ce4a3b1b2 - boxed::F.FnBox::call_box::h8768627190356120502 17: 0x7f4ce4a3a6e9 - rt::unwind::try::try_fn::h4698797487832078877 18: 0x7f4ce44b4018 - rust_try_inner 19: 0x7f4ce44b4005 - rust_try 20: 0x7f4ce4a3a998 - boxed::F.FnBox::call_box::h562643224173615142 21: 0x7f4ce443bfe1 - sys::thread::create::thread_start::he373f01c0b872a8fwgw 22: 0x7f4cdeccc181 - start_thread 23: 0x7f4ce407547c - __clone 24: 0x0 -

TimNN commented 9 years ago

I think the following minimal test case produces the same ICE:

trait T {
    type A;
    type B = Self::A;
}
apasel422 commented 9 years ago

Removing the nonsensical declaration Self<N=Self::N> from the original snippet allows the code to compile and run successfully, though obviously that shouldn't have caused an ICE:

trait A: Sized {
    type N:One;
    fn new(x:Self::N) -> Self;

    fn x() -> Self {
        Self::new(Self::N::one())
    }
}

trait One {
    fn one() -> Self;
}

impl One for i32 {
    fn one() -> i32 {
        1i32
    }
}

impl A for B {
    type N = i32;
    fn new(x:i32) -> B {
        B { x: x }
    }
}

struct B {
    x:i32
}

fn main() {
    let b = B::new(5i32);
    println!("b.x: {}", b.x )
}