Skip to content

librustc: Permit by-value-self methods to be invoked on objects referenced by boxes. #15242

New issue

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

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

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 1, 2014

Conversation

pcwalton
Copy link
Contributor

I can't believe this worked! I believe that the way the ABI and
immediates work mean that this Just Works.

Closes #10672.

r? @alexcrichton

@alexcrichton
Copy link
Member

We chatted on IRC about this, just wanted to write a few things down:

  • Can you make sure this is valgrind-clean?
  • Can you add a test which unwinds over a fn foo(self) call and ensure that it's valgrind clean?
  • Can you add some more assertions in the test to make sure things are as we expect?

referenced by boxes.

This is done by creating a shim function that handles the cleanup of the
box properly.

Closes rust-lang#10672.
@pcwalton
Copy link
Contributor Author

pcwalton commented Jul 1, 2014

Issues addressed. The box is now freed. re-r? @alexcrichton

bors added a commit that referenced this pull request Jul 1, 2014
…chton

I can't believe this worked! I believe that the way the ABI and
immediates work mean that this Just Works.

Closes #10672.

r? @alexcrichton
@bors bors closed this Jul 1, 2014
@bors bors merged commit 68ead46 into rust-lang:master Jul 1, 2014
@pcwalton pcwalton deleted the self-in-trait-methods branch July 1, 2014 06:17
@huonw
Copy link
Member

huonw commented Jul 1, 2014

Some people may encounter breakage due to this change (cargo did), if they have trait structure like

trait Foo {
    fn bar(self);
}

impl Foo for Box<Foo> { fn bar(self) { /* ... */ } }

Previously

let a: T = ...;
(box a as Box<Foo>).bar();

would be calling the bar from the Box<Foo> impl (i.e. self: Box<Foo>), but now it will be calling the one from the vtable (i.e. self: T). If bar is generic fn bar<U>(self, ...) then the compiler will complain "cannot call a generic method through an object".

I believe a work around (for both) is defining a function like

fn call_bar<T: Foo>(x: T) { x.bar() }

then call_bar(some_box_foo) should use the Box<Foo> impl.

@alexcrichton
Copy link
Member

This has caused even more problems for cargo as the tests are currently ICEing due to a problem in trans_unboxing_shim. To make @huonw's example concrete:

trait Foo {
    fn foo(self) { println!("default") }
}

impl Foo for Box<Foo> {
    fn foo(self) { println!("overridden") }
}

impl Foo for int {
    fn foo(self) { println!("int") }
}

fn main() {
    let f = box 1i as Box<Foo>;
    f.foo();
}

This prints int, not overridden.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Permit fn(self) methods to be invoked on object types
4 participants