Skip to content

Something's broken in sized/unsized traits #20550

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

Closed
stepancheg opened this issue Jan 5, 2015 · 5 comments
Closed

Something's broken in sized/unsized traits #20550

stepancheg opened this issue Jan 5, 2015 · 5 comments
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-DSTs Area: Dynamically-sized types (DSTs) A-trait-system Area: Trait system

Comments

@stepancheg
Copy link
Contributor

Code:

fn bar(foo: &Foo) {}

fn baz(foo: &Foo) {
    // this call works
    bar(foo);
}

trait Foo {
    fn qux(&self) {
        // this doesn't, and error is
        // error: the trait `core::kinds::Sized` is not implemented for the type `Self`
        bar(self);
    }
} 

Calls to bar seems to be identical from baz and qux functions, however, first call works and second doesn't. I don't understand how sized/unsized types work, please, close if it is not a bug.

@nrc
Copy link
Member

nrc commented Jan 5, 2015

This is a feature, not a bug, but I agree it looks pretty weird in this example.

The logic is that the Self type does not have the Sized bound by default, whereas other types do. To 'fix' this you could write trait Foo: Sized. However, that would then mean the &Foos are illegal, because Sized traits cannot be used to make trait objects.

cc @nikomatsakis to double check this is expected behaviour.

@kmcallister kmcallister added A-DSTs Area: Dynamically-sized types (DSTs) A-trait-system Area: Trait system A-diagnostics Area: Messages for errors, warnings, and lints labels Jan 5, 2015
@shadowmint
Copy link

If this is intended behavior, its certainly very strange.

fn foo(f:&Foo) {
  f.huh();
}

trait Foo {
  fn bar(&self, self_:&Foo) {
    let self_:&Foo = self_;
    // let self_:&Foo = self; // Doesn't work
    foo(self_);
  }

  fn huh(&self) {
    println!("huh");
  }
}

struct IsFoo;
impl Foo for IsFoo {}

fn main() {
  let is_foo = IsFoo;
  let foo:&Foo = &is_foo;
  foo.bar(foo);
}

@huonw
Copy link
Member

huonw commented Jan 7, 2015

It isn't just intended, but effectively required by the semantics implied by RFC 546 and #20341.

I'm writing up something more on your question and am actually part way through a few blog posts that go into this sort of stuff in more detail. (I'm aiming to get them published before the alpha, they'll appear on /r/rust when they're done.)

@huonw huonw closed this as completed Jan 7, 2015
@huonw
Copy link
Member

huonw commented Jan 7, 2015

@stepancheg
Copy link
Contributor Author

My brain hurts. Thanks for the explanation!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-DSTs Area: Dynamically-sized types (DSTs) A-trait-system Area: Trait system
Projects
None yet
Development

No branches or pull requests

5 participants