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

Comments

Projects
None yet
@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

This comment has been minimized.

Copy link
Member

pnkfelix commented Oct 15, 2015

yes yes yes!

@wthrowe

This comment has been minimized.

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

This comment has been minimized.

Copy link
Author

arcnmx commented Oct 17, 2015

@wthrowe good point, I like that suggestion.

@nrc nrc added the T-lang label Aug 22, 2016

@nrc

This comment has been minimized.

Copy link
Member

nrc commented Aug 22, 2016

+1, this would be nice to have.

cc @jseyfried, @petrochenkov, @nikomatsakis

@jseyfried

This comment has been minimized.

Copy link

jseyfried commented Aug 22, 2016

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

This comment has been minimized.

Copy link
Contributor

petrochenkov commented Aug 22, 2016

Looks reasonable.

@ubsan

This comment has been minimized.

Copy link
Contributor

ubsan commented Aug 23, 2016

cc me

@nikomatsakis

This comment has been minimized.

Copy link
Contributor

nikomatsakis commented Aug 23, 2016

Yeah, I am 👍 on this basic idea.

@pwoolcoc

This comment has been minimized.

Copy link

pwoolcoc commented Aug 24, 2016

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

@briansmith

This comment has been minimized.

Copy link

briansmith commented Aug 24, 2016

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

This comment has been minimized.

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

This comment has been minimized.

Copy link
Contributor

petrochenkov commented Aug 24, 2016

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

This comment has been minimized.

Copy link
Contributor

nikomatsakis commented Aug 24, 2016

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

This comment has been minimized.

Copy link
Contributor

nikomatsakis commented Aug 24, 2016

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

This comment has been minimized.

Copy link
Contributor

Ericson2314 commented Aug 25, 2016

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

@petrochenkov

This comment has been minimized.

Copy link
Contributor

petrochenkov commented Oct 30, 2016

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

This comment has been minimized.

Copy link

jseyfried commented Oct 31, 2016

Can use Trait as _; declarations be reexported?

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

@petrochenkov

This comment has been minimized.

Copy link
Contributor

petrochenkov commented Oct 31, 2016

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

@ordovicia

This comment has been minimized.

Copy link
Contributor

ordovicia commented Oct 24, 2017

RFC is proposed. #2166

@arcnmx arcnmx referenced this issue Oct 24, 2017

Merged

impl-only-use #2166

@Centril

This comment has been minimized.

Copy link
Contributor

Centril commented Oct 7, 2018

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

@Centril Centril closed this Oct 7, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.