Skip to content

Overriding default ToStr impl for @A where A: ToStr #4851

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
pkgw opened this issue Feb 8, 2013 · 5 comments
Closed

Overriding default ToStr impl for @A where A: ToStr #4851

pkgw opened this issue Feb 8, 2013 · 5 comments

Comments

@pkgw
Copy link
Contributor

pkgw commented Feb 8, 2013

I'm running into an issue with an interaction between ToStr and pointers that I'm not sure how to handle. I have a struct with a ToStr, and I want to call that method on a @-pointer to the struct. However, to_str.rs provides a generic implementation:

impl<A: ToStr> @A: ToStr { ... }

that returns the to_str prefixed with "@". I do not want this behavior, but I can't figure out how to override it. My naive implementation is:

#[crate_type = "bin"];

pub struct Foo {
    v: uint,
}

impl Foo: to_str::ToStr {
    pure fn to_str (&self) -> ~str { ~"stacky" }
}

impl @Foo: to_str::ToStr {
    pure fn to_str (&self) -> ~str { ~"at-pointer" }
}

fn main () {
    let q = @Foo { v: 0 };
    io::print (q.to_str () + "\n");
}

But this gives a compile error about multiple implementations. Is there a way around this?

@nikomatsakis
Copy link
Contributor

No, you can't do this.

@nikomatsakis
Copy link
Contributor

One possible workaround is to make a "newtype" for your @Foo type, like this:

struct AtFoo(@Foo)

then use AtFoo everywhere.

Closing since this check is working as designed.

@pkgw
Copy link
Contributor Author

pkgw commented Feb 9, 2013

If there's no simple workaround on that end, I'd argue that the default ToStr implementations for pointers-to-ToStr should be removed. If I have some non-small data structure and I care about the to_str(), I'm probably going to also be passing around pointers to the structure. The way I see it, it's far more likely that I'll want

(@foo).to_str() = foo.to_str()

rather than

(@foo).to_str() = "@" + foo.to_str()

but more broadly, I will want control over the to_str result without having to resort to awkward hacks such as AtFoo. As evidence for the superfluity of the current @(ToStr) and ~(ToStr) implementations, if I comment them out, the whole system recompiles just fine.

@pkgw
Copy link
Contributor Author

pkgw commented Feb 9, 2013

Oh, and here's a variation that seems more like a genuine error in the impl-finder to me:

If I comment out both impls in my first example, unsurprisingly I get an error that there are no implementations for ToStr for <V7> which presumably corresponds to @Foo.

If I provide only the implementation for @Foo, but comment out the impl for plain Foo, I still get an error that there are two impls available: __extensions__::to_str and core::to_str::__extensions__::to_str. Looking at the set of impls in core.to_str; I think that the impl for @(ToStr) must be kicking in even though in this case only @Foo is ToStr, not Foo.

@catamorphism
Copy link
Contributor

Removing the default implementations here is a change worth considering -- @pkgw , please file a new issue with the RFC tag if you want to propose that. Thanks!

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

No branches or pull requests

3 participants