Skip to content

default method ICE #3563

New issue

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

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

Already on GitHub? # to your account

Closed
jesse99 opened this issue Sep 23, 2012 · 6 comments
Closed

default method ICE #3563

jesse99 opened this issue Sep 23, 2012 · 6 comments
Labels
A-trait-system Area: Trait system I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️
Milestone

Comments

@jesse99
Copy link
Contributor

jesse99 commented Sep 23, 2012

Working on an example app and got an ICE as soon as I added a default method (add_points).

// ASCII art shape renderer.
// Demonstrates traits, impls, operator overloading, non-copyable struct, unit testing.
// To run execute: rustc --test shapes.rs && ./shapes

// Rust's core library is tightly bound to the language itself so it is automatically linked in.
// However the std library is designed to be optional (for code that must run on constrained
//  environments like embedded devices or special environments like kernel code) so it must
// be explicitly linked in.
extern mod std;

// Extern mod controls linkage. Use controls the visibility of names to modules that are
// already linked in. Using WriterUtil allows us to use the write_line method.
use io::WriterUtil;

// Represents a position on a canvas.
struct Point
{
    x: int,
    y: int,
}

// Represents an offset on a canvas. (This has the same structure as a Point.
// but different semantics).
struct Size
{
    width: int,
    height: int,
}

struct Rect
{
    top_left: Point,
    size: Size,
}

// TODO: operators

// Contains the information needed to do shape rendering via ASCII art.
struct AsciiArt
{
    width: uint,
    height: uint,
    priv fill: char,
    priv lines: ~[~[mut char]],

    // This struct can be quite large so we'll disable copying: developers need
    // to either pass these structs around via borrowed pointers or move them.
    drop {}
}

// It's common to define a constructor sort of function to create struct instances.
// If there is a canonical constructor it is typically named the same as the type.
// Other constructor sort of functions are typically named from_foo, from_bar, etc. 
fn AsciiArt(width: uint, height: uint, fill: char) -> AsciiArt
{
    // Use an anonymous function to build a vector of vectors containing
    // blank characters for each position in our canvas.
    let lines = do vec::build_sized(height)
        |push|
        {
            for height.times
            {
                let mut line = ~[mut];    
                vec::grow_set(line, width-1, '.', '.');
                push(line);
            }
        };

    // Rust code often returns values by omitting the trailing semi-colon
    // instead of using an explicit return statement.
    AsciiArt {width: width, height: height, fill: fill, lines: lines}
}

// Methods particular to the AsciiArt struct.
impl AsciiArt
{
    fn add_pt(x: int, y: int)
    {
        if x >= 0 && x < self.width as int
        {
            if y >= 0 && y < self.height as int
            {
                // Note that numeric types don't implicitly convert to each other.
                let v = y as uint;
                let h = x as uint;

                // Vector subscripting will normally copy the element, but &v[i]
                // will return a reference which is what we need because the
                // element is:
                // 1) potentially large
                // 2) needs to be modified
                let row = &self.lines[v];
                row[h] = self.fill;
            }
        }
    }
}

// Allows AsciiArt to be converted to a string using the libcore ToStr trait.
// Note that the %s fmt! specifier will not call this automatically.
impl AsciiArt : ToStr
{
    fn to_str() -> ~str
    {
        // Convert each line into a string.
        let lines = do self.lines.map |line| {str::from_chars(line)};

        // Concatenate the lines together using a new-line.
        str::connect(lines, "\n")
    }
}

// This is similar to an interface in other languages: it defines a protocol which
// developers can implement for arbitrary concrete types.
trait Canvas
{
    fn add_point(shape: Point);
    fn add_rect(shape: Rect);

    // Unlike interfaces traits support default implementations.
    // Got an ICE as soon as I added this method.
    fn add_points(shapes: &[Point])
    {
        for shapes.each |pt| {self.add_point(pt)};
    }
}

// Here we provide an implementation of the Canvas methods for AsciiArt.
// Other implementations could also be provided (e.g. for PDF or Apple's Quartz)
// and code can use them polymorphically via the Canvas trait.
impl AsciiArt : Canvas
{
    fn add_point(shape: Point)
    {
        self.add_pt(shape.x, shape.y);
    }

    fn add_rect(shape: Rect)
    {
        // Add the top and bottom lines.
        for int::range(shape.top_left.x, shape.top_left.x + shape.size.width)
        |x|
        {
            self.add_pt(x, shape.top_left.y);
            self.add_pt(x, shape.top_left.y + shape.size.height - 1);
        }

        // Add the left and right lines.
        for int::range(shape.top_left.y, shape.top_left.y + shape.size.height)
        |y|
        {
            self.add_pt(shape.top_left.x, y);
            self.add_pt(shape.top_left.x + shape.size.width - 1, y);
        }
    }
}

// Rust's unit testing framework is currently a bit under-developed so we'll use
// this little helper.
pub fn check_strs(actual: &str, expected: &str) -> bool
{
    if actual != expected
    {
        io::stderr().write_line(fmt!("Found:\n%s\nbut expected\n%s", actual, expected));
        return false;
    }
    return true;
}

#[test]
fn test_ascii_art_ctor()
{
    let art = AsciiArt(3, 3, '*');
    assert check_strs(art.to_str(), "...\n...\n...");
}

#[test]
fn test_add_pt()
{
    let art = AsciiArt(3, 3, '*');
    art.add_pt(0, 0);
    art.add_pt(0, -10);
    art.add_pt(1, 2);
    assert check_strs(art.to_str(), "*..\n...\n.*.");
}

#[test]
fn test_shapes()
{
    let art = AsciiArt(4, 4, '*');
    art.add_rect(Rect {top_left: Point {x: 0, y: 0}, size: Size {width: 4, height: 4}});
    art.add_point(Point {x: 2, y: 2});
    assert check_strs(art.to_str(), "****\n*..*\n*.**\n****");
}

This is with rust from Sep 22, 2012.

@Dretch
Copy link
Contributor

Dretch commented Nov 24, 2012

This still seems to be an issue.

Here is a smaller test case:

trait Canvas {

    fn add_point(point: &int);

    fn add_points(shapes: &[int]) {
        for shapes.each |pt| {
            self.add_point(pt)
        }
    }

}

Produces:

error: internal compiler error: unexpected failure
note: the compiler hit an unexpected failure path. this is a bug
note: try running with RUST_LOG=rustc=1,::rt::backtrace to get further details and report the results to github.com/mozilla/rust/issues

@rntz
Copy link
Contributor

rntz commented Dec 4, 2012

Here's an even smaller test case:

trait A {
  fn a(&self) {
    || self.b()
  }
}

The resulting error:

error: internal compiler error: unexpected failure
note: the compiler hit an unexpected failure path. this is a bug
note: try running with RUST_LOG=rustc=1,::rt::backtrace to get further details and report the results to github.com/mozilla/rust/issues

With backtrace:

rust: task failed at 'unexpected `none` for self_impl_def_id', /home/rntz/s/rust/src/librustc/rustc.rc:1
/home/rntz/p/bin/../lib/librustrt.so(_ZN9rust_task13begin_failureEPKcS1_m+0x4b)[0x7f7424566ebb]
/home/rntz/p/bin/../lib/librustrt.so(+0x2e629)[0x7f742457a629]
/home/rntz/p/bin/../lib/librustrt.so(upcall_fail+0x1b0)[0x7f7424569670]
/home/rntz/p/bin/../lib/libcore-c3ca5d77d81b46c1-0.5.so(+0x3f5cb)[0x7f7425c1f5cb]
/home/rntz/p/bin/../lib/librustc-c84825241471686d-0.5.so(+0x3a938c)[0x7f7424b5238c]
/home/rntz/p/bin/../lib/librustc-c84825241471686d-0.5.so(_ZN6middle6typeck5check6method14__extensions__10meth_4812924push_inherent_candidates17_23b4d847dfe35cac3_05E+0x249)[0x7f7424b4ddb9]
/home/rntz/p/bin/../lib/librustc-c84825241471686d-0.5.so(_ZN6middle6typeck5check6method14__extensions__10meth_480879do_lookup16_e5d83e90897abbb3_05E+0x479)[0x7f7424b4c8b9]
/home/rntz/p/bin/../lib/librustc-c84825241471686d-0.5.so(_ZN6middle6typeck5check6method6lookup17_40828bfe237e6cb73_05E+0x179)[0x7f7424b4bb09]
/home/rntz/p/bin/../lib/librustc-c84825241471686d-0.5.so(+0x3ff948)[0x7f7424ba8948]
/home/rntz/p/bin/../lib/librustc-c84825241471686d-0.5.so(_ZN6middle6typeck5check23check_expr_with_unifier17_c3c2675515e0a6df3_05E+0x2143)[0x7f7424b94fc3]
/home/rntz/p/bin/../lib/librustc-c84825241471686d-0.5.so(_ZN6middle6typeck5check11check_block15_bfb867382ad3f43_05E+0x338)[0x7f7424b0a618]
/home/rntz/p/bin/../lib/librustc-c84825241471686d-0.5.so(_ZN6middle6typeck5check8check_fn16_705fbbd8b97e7f43_05E+0x18f3)[0x7f7424b61e83]
/home/rntz/p/bin/../lib/librustc-c84825241471686d-0.5.so(+0x6f66bc)[0x7f7424e9f6bc]
/home/rntz/p/bin/../lib/librustc-c84825241471686d-0.5.so(+0x40464b)[0x7f7424bad64b]
/home/rntz/p/bin/../lib/librustc-c84825241471686d-0.5.so(_ZN6middle6typeck5check23check_expr_with_unifier17_c3c2675515e0a6df3_05E+0x3917)[0x7f7424b96797]
/home/rntz/p/bin/../lib/librustc-c84825241471686d-0.5.so(+0x6f66bc)[0x7f7424e9f6bc]
/home/rntz/p/bin/../lib/librustc-c84825241471686d-0.5.so(_ZN6middle6typeck5check11check_block15_bfb867382ad3f43_05E+0x338)[0x7f7424b0a618]
/home/rntz/p/bin/../lib/librustc-c84825241471686d-0.5.so(_ZN6middle6typeck5check8check_fn16_705fbbd8b97e7f43_05E+0x18f3)[0x7f7424b61e83]
/home/rntz/p/bin/../lib/librustc-c84825241471686d-0.5.so(_ZN6middle6typeck5check13check_bare_fn16_7f1c69418c3fa2f3_05E+0xc2)[0x7f7424b604e2]
/home/rntz/p/bin/../lib/librustc-c84825241471686d-0.5.so(_ZN6middle6typeck5check12check_method17_c12e93cfdccf10163_05E+0x108)[0x7f7424b66f48]
/home/rntz/p/bin/../lib/librustc-c84825241471686d-0.5.so(_ZN6middle6typeck5check10check_item16_5c3ab521738fac33_05E+0xe29)[0x7f7424b5faf9]
/home/rntz/p/bin/../lib/libsyntax-84efebcb12c867a2-0.5.so(+0xb67dd)[0x7f742534c7dd]
/home/rntz/p/bin/../lib/libsyntax-84efebcb12c867a2-0.5.so(+0xb6624)[0x7f742534c624]
/home/rntz/p/bin/../lib/librustc-c84825241471686d-0.5.so(_ZN6middle6typeck5check16check_item_types16_32b77d65f37c2d43_05E+0x447)[0x7f7424b5ea77]
/home/rntz/p/bin/../lib/librustc-c84825241471686d-0.5.so(_ZN6middle6typeck11check_crate17_a7fd31a82852c0da3_05E+0x81d)[0x7f7424c53a0d]
/home/rntz/p/bin/../lib/librustc-c84825241471686d-0.5.so(+0x6f66bc)[0x7f7424e9f6bc]
/home/rntz/p/bin/../lib/librustc-c84825241471686d-0.5.so(_ZN6driver6driver12compile_upto17_6954e9f73b6043fc3_05E+0x16e7)[0x7f7424e66af7]
/home/rntz/p/bin/../lib/librustc-c84825241471686d-0.5.so(+0x6f66bc)[0x7f7424e9f6bc]
/home/rntz/p/bin/../lib/librustc-c84825241471686d-0.5.so(_ZN6driver6driver13compile_input16_188f29a75d855053_05E+0xbb)[0x7f7424e69ccb]
/home/rntz/p/bin/../lib/librustc-c84825241471686d-0.5.so(_ZN12run_compiler17_ce607359f9b399923_05E+0x241a)[0x7f7424e9838a]
/home/rntz/p/bin/../lib/librustc-c84825241471686d-0.5.so(+0x6f66bc)[0x7f7424e9f6bc]
/home/rntz/p/bin/../lib/librustc-c84825241471686d-0.5.so(+0x6f53d3)[0x7f7424e9e3d3]
/home/rntz/p/bin/../lib/librustc-c84825241471686d-0.5.so(+0x6f442c)[0x7f7424e9d42c]
/home/rntz/p/bin/../lib/libcore-c3ca5d77d81b46c1-0.5.so(+0x8064f)[0x7f7425c6064f]
/home/rntz/p/bin/../lib/libcore-c3ca5d77d81b46c1-0.5.so(+0xb7d50)[0x7f7425c97d50]
/home/rntz/p/bin/../lib/librustrt.so(_Z18task_start_wrapperP10spawn_args+0x24)[0x7f7424567724]
error: internal compiler error: unexpected failure
note: the compiler hit an unexpected failure path. this is a bug
note: try running with RUST_LOG=rustc=1,::rt::backtrace to get further details and report the results to github.com/mozilla/rust/issues
rust: task failed at 'explicit failure', /home/rntz/s/rust/src/librustc/rustc.rc:471
/home/rntz/p/bin/../lib/librustrt.so(_ZN9rust_task13begin_failureEPKcS1_m+0x4b)[0x7f7424566ebb]
/home/rntz/p/bin/../lib/librustrt.so(+0x2e629)[0x7f742457a629]
/home/rntz/p/bin/../lib/librustrt.so(upcall_fail+0x1b0)[0x7f7424569670]
/home/rntz/p/bin/../lib/libcore-c3ca5d77d81b46c1-0.5.so(+0x3f5cb)[0x7f7425c1f5cb]
/home/rntz/p/bin/../lib/libcore-c3ca5d77d81b46c1-0.5.so(+0xb7d50)[0x7f7425c97d50]
/home/rntz/p/bin/../lib/librustc-c84825241471686d-0.5.so(_ZN7monitor17_966bb99e13f97cd53_05E+0x2a48)[0x7f7424e9c3e8]
/home/rntz/p/bin/../lib/librustc-c84825241471686d-0.5.so(+0x6f66bc)[0x7f7424e9f6bc]
/home/rntz/p/bin/../lib/librustc-c84825241471686d-0.5.so(_ZN4main16_2fb85b4a659c4103_05E+0x86)[0x7f7424e9f2c6]
/home/rntz/p/bin/../lib/librustrt.so(_Z18task_start_wrapperP10spawn_args+0x24)[0x7f7424567724]
rust: domain main @0x14a8200 root task failed
rust: task failed at 'killed', /home/rntz/s/rust/src/libcore/task/mod.rs:620
/home/rntz/p/bin/../lib/librustrt.so(_ZN9rust_task13begin_failureEPKcS1_m+0x4b)[0x7f7424566ebb]
/home/rntz/p/bin/../lib/librustrt.so(+0x2e629)[0x7f742457a629]
/home/rntz/p/bin/../lib/librustrt.so(upcall_fail+0x1b0)[0x7f7424569670]
/home/rntz/p/bin/../lib/libcore-c3ca5d77d81b46c1-0.5.so(+0x3f5cb)[0x7f7425c1f5cb]
/home/rntz/p/bin/../lib/libcore-c3ca5d77d81b46c1-0.5.so(_ZN4task5yield17_56812fae66173efd3_05E+0xbd)[0x7f7425c496ed]
/home/rntz/p/bin/../lib/libcore-c3ca5d77d81b46c1-0.5.so(+0x91e36)[0x7f7425c71e36]
/home/rntz/p/bin/../lib/libcore-c3ca5d77d81b46c1-0.5.so(_ZN7private11weaken_task14_1904ec97c49c23_05E+0xd9)[0x7f7425c71c79]
/home/rntz/p/bin/../lib/libcore-c3ca5d77d81b46c1-0.5.so(+0x91b6b)[0x7f7425c71b6b]
/home/rntz/p/bin/../lib/libcore-c3ca5d77d81b46c1-0.5.so(+0xb7d50)[0x7f7425c97d50]
/home/rntz/p/bin/../lib/libcore-c3ca5d77d81b46c1-0.5.so(+0x90e72)[0x7f7425c70e72]
/home/rntz/p/bin/../lib/libcore-c3ca5d77d81b46c1-0.5.so(+0x907c2)[0x7f7425c707c2]
/home/rntz/p/bin/../lib/libcore-c3ca5d77d81b46c1-0.5.so(+0x8fdd6)[0x7f7425c6fdd6]
/home/rntz/p/bin/../lib/libcore-c3ca5d77d81b46c1-0.5.so(+0x8064f)[0x7f7425c6064f]
/home/rntz/p/bin/../lib/libcore-c3ca5d77d81b46c1-0.5.so(+0xb7d50)[0x7f7425c97d50]
/home/rntz/p/bin/../lib/librustrt.so(_Z18task_start_wrapperP10spawn_args+0x24)[0x7f7424567724]

@catamorphism
Copy link
Contributor

The smallest test case above still ICEs, as of d2ad028

@catamorphism
Copy link
Contributor

@pcwalton said that pending pull requests might fix this -- I'll wait for those before testing it again.

@catamorphism
Copy link
Contributor

I rebased just now, and tested the last test case; it still ICEs. This is with 6742c98

@ghost ghost assigned catamorphism Dec 23, 2012
catamorphism added a commit that referenced this issue Jan 8, 2013
That is, treat `self` as if it has dynamic scope. This seems to
be harmless, and prevents an ICE as per #3563
catamorphism added a commit to catamorphism/rust that referenced this issue Jan 8, 2013
…unctions

Necessary to allow supertrait methods to be called in default functions.

As per rust-lang#3563
@catamorphism
Copy link
Contributor

Fixed in 80435ad

RalfJung pushed a commit to RalfJung/rust that referenced this issue May 4, 2024
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
A-trait-system Area: Trait system I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️
Projects
None yet
Development

No branches or pull requests

4 participants