Skip to content

Commit 51ee8c1

Browse files
authored
Merge pull request #2166 from phaazon/impl-only-use
impl-only-use
2 parents 2431a9a + 1b9950f commit 51ee8c1

File tree

1 file changed

+130
-0
lines changed

1 file changed

+130
-0
lines changed

text/2166-impl-only-use.md

+130
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
- Feature Name: impl-only-use
2+
- Start Date: 2017-10-01
3+
- RFC PR: https://github.com/rust-lang/rfcs/pull/2166
4+
- Rust Issue: https://github.com/rust-lang/rust/issues/48216
5+
6+
# Summary
7+
[summary]: #summary
8+
9+
The `use …::{… as …}` syntax can now accept `_` as alias to a trait to only import the
10+
implementations of such a trait.
11+
12+
# Motivation
13+
[motivation]: #motivation
14+
15+
Sometimes, we might need to `use` a trait to be able to use its methods on a type in our code.
16+
However, we might also not want to import the trait symbol (because we redefine it, for instance):
17+
18+
```rust
19+
// in zoo.rs
20+
pub trait Zoo {
21+
fn zoo(&self) -> u32;
22+
}
23+
24+
// several impls here
25+
//
26+
```
27+
28+
```rust
29+
// in main.rs
30+
struct Zoo {
31+
//
32+
}
33+
34+
fn main() {
35+
let x = "foo";
36+
let y = x.zoo(); // won’t compile because `zoo::Zoo` not in scope
37+
}
38+
```
39+
40+
To solve this, we need to import the trait:
41+
42+
```rust
43+
// in main.rs
44+
use zoo::Zoo;
45+
46+
struct Zoo { // wait, what happens here?
47+
//
48+
}
49+
50+
fn main() {
51+
let x = "foo";
52+
let y = x.zoo();
53+
}
54+
```
55+
56+
However, you can see that we’ll hit a problem here, because we define an ambiguous symbol. We have
57+
two solutions:
58+
59+
- Change the name of the `struct` to something else.
60+
- Qualify the `use`.
61+
62+
The problem is that if we qualify the `use`, what name do we give the trait? We’re not even
63+
referring to it directly.
64+
65+
```rust
66+
use zoo::Zoo as ZooTrait;
67+
```
68+
69+
This will work but seems a bit like a hack because rustc forces us to give a name to something we
70+
won’t use in our types.
71+
72+
This RFC suggests to solve this by adding the possibility to explictly state that we won’t directly
73+
refer to that trait, but we want the impls:
74+
75+
```rust
76+
use zoo::Zoo as _;
77+
```
78+
79+
# Guide-level explanation
80+
[guide-level-explanation]: #guide-level-explanation
81+
82+
Qualifying a `use` with `_` on a trait imports the trait’s `impl`s but not the symbol directly. It’s
83+
handy if you don’t use the trait’s symbol in your type and if you redefine the symbol to something
84+
else.
85+
86+
The `_` means that you “don’t care about the name rustc will use for that qualified `use`“.
87+
88+
# Reference-level explanation
89+
[reference-level-explanation]: #reference-level-explanation
90+
91+
`use Trait as _` needs to desugar into `use Trait as SomeGenSym`. With this scheme, global imports
92+
and exports can work properly with such items, i.e. import / re-export them.
93+
94+
```rust
95+
mod m {
96+
pub use Trait as _;
97+
98+
// `Trait` is in scope
99+
}
100+
101+
use m::*;
102+
103+
// `Trait` is in scope too
104+
```
105+
106+
In the case where the symbol is not a *trait*, it works the exact same way. However, a warning must
107+
be emitted by the compiler to state the unused import (as types don’t have `impl`!).
108+
109+
In the same way, it’s possible to use the same mechanism with `extern crate` for linking-only
110+
crates:
111+
112+
```rust
113+
extern crate my_crate as _;
114+
```
115+
116+
# Drawbacks
117+
[drawbacks]: #drawbacks
118+
119+
This RFC tries to solve a very specific problem (when you *must* alias a trait use). It’s just a
120+
nit to make the syntax more *“rust-ish”* (it’s very easy to think such a thing would work given the
121+
way `_` works pretty much everywhere else).
122+
123+
# Rationale and alternatives
124+
[alternatives]: #alternatives
125+
126+
The simple alternative is to let the programmer give a name to the qualified import, which is not a
127+
big deal, but is a bit ugly.
128+
129+
# Unresolved questions
130+
[unresolved]: #unresolved-questions

0 commit comments

Comments
 (0)