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

use some::Trait as _; #1311

Closed
arcnmx opened this issue Oct 8, 2015 · 20 comments
Closed

use some::Trait as _; #1311

arcnmx opened this issue Oct 8, 2015 · 20 comments
Labels
T-lang Relevant to the language team, which will review and decide on the RFC.

Comments

@arcnmx
Copy link

arcnmx commented Oct 8, 2015

mini/pre RFC

use some::Trait as _;

This would allow importing a trait into scope for resolution reasons, without being able to reference it by ident directly.

Motivation

I've found a need for use some::Trait as __Trait; in order to avoid conflicts with another type in scope. It tends to come up when dealing with abstractions and wrappers that have similar type names.

Alternatives

  • Some other syntax? I feel like this choice meshes well with Rust in general.
  • Not doing this at all. Is it necessary/useful enough to warrant the minor language change?
  • Workarounds in current rust:
    • use some::Trait as __Trait;
    • UFCS: use some; some::Trait::method(etc);
    • Using names like TraitImp for your concrete types instead.

Unresolved Questions

Wildcard version? use some::* as _ could work well for importing preludes.

Allow use with pub to make them available for constructing preludes?

Actual design? A simple approach might be to simply implement this as sugar for mangling the trait name in some way (ideally with the full path of the module to accomodate for pub exporting). A real implementation would make them truly hidden as identifiers, but otherwise usable for deciding whether a trait is applicable.

Would this be valid for non-trait types such as structures, type aliases, etc? I'd imagine the wildcard case would simply ignore them, but the explicit syntax would be weird and useless.

@pnkfelix
Copy link
Member

yes yes yes!

@wthrowe
Copy link

wthrowe commented Oct 16, 2015

If these can be public and glob imports match them they would be nice for preludes. I imagine they would have been used for std::prelude::v1::SliceConcatExt, for example.

@arcnmx
Copy link
Author

arcnmx commented Oct 17, 2015

@wthrowe good point, I like that suggestion.

@nrc nrc added the T-lang Relevant to the language team, which will review and decide on the RFC. label Aug 22, 2016
@nrc
Copy link
Member

nrc commented Aug 22, 2016

+1, this would be nice to have.

cc @jseyfried, @petrochenkov, @nikomatsakis

@jseyfried
Copy link

Also +1, I like this idea.

One potential downside is extra complexity for rustdoc when displaying reexported unnameable traits, but otherwise I think this would be straightforward to implement (I'd be happy to prototype it).

@petrochenkov
Copy link
Contributor

Looks reasonable.

@strega-nil
Copy link

cc me

@nikomatsakis
Copy link
Contributor

nikomatsakis commented Aug 23, 2016

Yeah, I am 👍 on this basic idea.

@pwoolcoc
Copy link

I was just looking into this today, glad someone beat me to it

@briansmith
Copy link

I feel like this doesn't work well for the use xxx:prelude::* style that is common. I think it might be better to add a hiding {names} syntax like Haskell has instead. Then you could do use xxx::prelude::* hiding TraitName.

@jseyfried
Copy link

jseyfried commented Aug 24, 2016

@briansmith
If you hid a trait using a Haskell-like hiding, I would expect the trait not to be "in scope" for method resolution purposes. A major motivation of as _ is that the trait's name would not be in scope, but the trait would still be in scope for method resolution.

n.b. After #1560 is done (c.f. rust-lang/rust#35894), we won't need hiding.
With #1560, if a glob-imported name conflicts with an item or an explicit import, the glob-imported name is shadowed. If a glob-imported name conflicts with another glob-imported name, the user can add an explicit import to disambiguate (which the compiler will prompt):

mod a { pub fn f() {} }
mod b { pub fn f() {} }
fn main() {
    use a::*;
    use b::*;
    f(); // This is an error, since `f` could be `a::f` or `b::f`.
    // use a::f; // uncommenting this fixes the error.
    //^ Adding this is analogous to appending `hiding {f}` to `use b::*;`.
}

@petrochenkov
Copy link
Contributor

the trait's name would not be in scope, but the trait would still be in scope for method resolution

I wonder if the opposite behavior is ever useful - the trait's name is in scope, but the trait doesn't participate in method/ufcs-path resolution.

@nikomatsakis
Copy link
Contributor

I have never actually wanted this behavior, but I can imagine
wanting it. For example, I might want to mostly use methods from trait
A, but a few methods from trait B -- I can import trait B and use its
methods via UFCS form, while avoiding conflicts with trait A.

On Wed, Aug 24, 2016 at 02:09:24AM -0700, Vadim Petrochenkov wrote:

the trait's name would not be in scope, but the trait would still be in scope for method resolution

I wonder if the opposite behavior is ever useful - the trait's name is in scope, but the trait doesn't participate in method/ufcs-path resolution.

You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub:
#1311 (comment)

@nikomatsakis
Copy link
Contributor

Definitely a way to omit specific names from glob would be useful.

On Tue, Aug 23, 2016 at 07:01:18PM -0700, Brian Smith wrote:

I feel like this doesn't work well for the use xxx:prelude::* style that is common. I think it might be better to add a hiding {names} syntax like Haskell has instead. Then you could do use xxx::prelude::* hiding TraitName.

You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub:
#1311 (comment)

@Ericson2314
Copy link
Contributor

Can use some::Trait::* work? It would import static methods too.

@petrochenkov
Copy link
Contributor

Can use Trait as _; declarations be reexported?

mod m {
    pub use a::b::Trait as _; // `Trait` is available in `m` for method resolution
}

use m::*; // Is `Trait` available in this module for method resolution?

@jseyfried
Copy link

Can use Trait as _; declarations be reexported?

I think so -- it seems more consistent and could be useful.

@petrochenkov
Copy link
Contributor

In this case use Trait as _ can simply be desugared into use Trait as gensym and no other import logic is affected.

@ordovicia
Copy link
Contributor

RFC is proposed. #2166

@arcnmx arcnmx mentioned this issue Oct 24, 2017
@Centril
Copy link
Contributor

Centril commented Oct 7, 2018

Closing in favor of rust-lang/rust#48216.

@Centril Centril closed this as completed Oct 7, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T-lang Relevant to the language team, which will review and decide on the RFC.
Projects
None yet
Development

No branches or pull requests