Skip to content
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

Trait object coercion to borrowed trait does not work with methods on &self #9950

Closed
Kimundi opened this issue Oct 19, 2013 · 5 comments
Closed
Labels
A-dst Area: Dynamically Sized Types

Comments

@Kimundi
Copy link
Member

Kimundi commented Oct 19, 2013

This might not be a bug, but while writing extension traits for a trait object I discovered that calling a &self method of a trait implemented on a &Trait does not work if it needs to borrow from a ~Trait or @Trait first. This complicates things, because you need to explicit borrow to a &Trait prior to making the call.

As comparison, these three combinations work:

trait Bar{} 
impl Bar for uint {} 

// self by value
trait Foo { fn baz(self); }  
impl<'self> Foo for &'self Bar { fn baz(self) { println("baz"); } }; 

// borrowed trait object
let x = &5u as &Bar; 

x.baz();
> baz
trait Bar{}
impl Bar for uint {}

// self by value
trait Foo {fn baz(self);}
impl<'self> Foo for &'self Bar { fn baz(self) { println("baz"); } };

// owned trait object
let x = ~5u as ~Bar; 

x.baz();
> baz
trait Bar{}
impl Bar for uint {}

// self by reference
trait Foo {fn baz(&self);} 
impl<'self> Foo for &'self Bar { fn baz(&self) { println("baz"); } };

// borrowed trait object
let x = &5u as &Bar; 

x.baz();
> baz

While this one fails to compile:

trait Bar{}
impl Bar for uint {} 

// self by reference
trait Foo {fn baz(&self);} 
impl<'self> Foo for &'self Bar { fn baz(&self) { println("baz"); } };

// owned trait object
let x = ~5u as ~Bar; 

x.baz();
> error: type `~main::Bar:Send` does not implement any method in scope named `baz`

And this one is the workaround necessary to make it work:

trait Bar{}
impl Bar for uint {} 

// self by reference
trait Foo {fn baz(&self);} 
impl<'self> Foo for &'self Bar { fn baz(&self) { println("baz"); } };

// owned trait object
let x = ~5u as ~Bar; 

{let tmp: &Bar = x; tmp}.baz();
> baz
@nikomatsakis
Copy link
Contributor

I think this will improve with DST, in that it would be possible to implement:

impl<'self> Foo for Bar { ... }

and then the required type of self would not be & & Bar but rather &Bar. I believe this would address the issue. Incidentally, the reason that this works for slices is that we added a special hack to address this scenario -- we could do the same for traits but I'd rather do DST.

@nikomatsakis
Copy link
Contributor

cc #6308

@reem
Copy link
Contributor

reem commented Aug 12, 2014

Triage: No change. Third example still fails to compile in the same way, this is symptomatic of larger issues around trait objects until DST lands.

@steveklabnik
Copy link
Member

Triage: I am bad at DST, and so couldn't update the code sample. What's the state of this now?

@steveklabnik steveklabnik added the A-dst Area: Dynamically Sized Types label Jan 23, 2015
@steveklabnik
Copy link
Member

Triage: with no response in a year, and no real comments since 2013, and with tons of changes, I'm just going to close this one.

flip1995 pushed a commit to flip1995/rust that referenced this issue Dec 1, 2022
Improve `EXIT` lint docs

Super simple change, hopefully fast and fun to review. Have a great start to the weekend!

changelog: none
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-dst Area: Dynamically Sized Types
Projects
None yet
Development

No branches or pull requests

4 participants