You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: text/0000-import-trait-methods.md
+21-6Lines changed: 21 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -13,7 +13,7 @@ Allow importing methods from traits and then using them like regular functions.
13
13
14
14
There has for a long time been a desire to shorten the duplication needed to access certain methods, such as `Default::default`. Codebases like [Bevy](https://github.com/bevyengine/bevy/blob/7c7d1e8a6442a4258896b6c605beb1bf50399396/crates/bevy_utils/src/default.rs#L27) provide wrapper methods to shorten this call, and a previous, now-rejected, [RFC](https://github.com/rust-lang/rust/pull/73001) aimed to provide this method as part of the standard library. This RFC was rejected with a note that there is a desire for a more general capability to import any trait method.
15
15
16
-
Additionally, if you pull in a crate like [num_traits](https://docs.rs/num-traits/latest/num_traits/), then this feature will allow access to numeric methods such as `sin` using the infix syntax that is more common in mathematics. More generally, it will make infix calls to a trait method shorter without having to write a wrapper function.
16
+
Additionally, if you pull in a crate like [num_traits](https://docs.rs/num-traits/latest/num_traits/), then this feature will allow access to numeric methods such as `sin` using the `sin(x)` syntax that is more common in mathematics. More generally, it will make calls to trait methods shorter without having to write a wrapper function.
occurs, we first find the supertrait in which `method` occurs.
120
-
A new item `m` is made available in the function namespace of the current module. Any attempts to call this item are treated calling the (super-)trait method explicitly qualified. As always, the `as` qualifier is optional, in which case the name of the new item is identical with the name of the method in the trait. In other words, the example:
119
+
occurs, we first find the supertrait in which `method` occurs. If it occurs in multiple supertraits, or in the trait and in a supertrait, then error.
120
+
A new item `m` is made available in the function namespace of the current module. Any attempts to call this item are treated calling the (super-)trait method explicitly qualified. As always, the `as` qualifier is optional, in which case the name of the new item is identical with the name of the method in the trait.
121
+
122
+
In other words, the example:
121
123
122
124
```rust
123
125
useDefault::default;
@@ -191,7 +193,14 @@ Super::f();
191
193
# Drawbacks
192
194
[drawbacks]: #drawbacks
193
195
194
-
Calls to `default` are less explicit than calls to `Default::default`, likewise for any other trait.
196
+
Calls to `default` are less explicit than calls to `Default::default` or to `T::default`, likewise for any other trait. Some users may see this lack of explicitness as bad style.
197
+
198
+
To expand on this, [the book](https://doc.rust-lang.org/book/ch07-04-bringing-paths-into-scope-with-the-use-keyword.html#creating-idiomatic-use-paths) currently recommends that methods should be called using their parent module's name:
199
+
> Although both Listing 7-11 and 7-13 accomplish the same task, Listing 7-11 is the idiomatic way to bring a function into scope with use. Bringing the function’s parent module into scope with use means we have to specify the parent module when calling the function. Specifying the parent module when calling the function makes it clear that the function isn’t locally defined while still minimizing repetition of the full path.
200
+
201
+
This recommendation makes the most sense when there is a possibility of ambiguity in the mind of the reader. For example, a function like `sin` is unlikely to be ambiguous, because there is only one mathematical function of that name. If a codebase is likely to be making use of multiple different implementations of `sin`, then it makes more sense to require specifically naming the one you are going to use. Similar considerations apply to traits like `Default::default`, or more generally in cases like `Frobnicator::frobnicate`.
202
+
203
+
Because of this context sensitivity, we should allow developers to choose when removing the extra context makes sense for their codebase.
@@ -214,11 +223,17 @@ An earlier version of this RFC proposed not allowing `use Trait::super_trait_met
214
223
215
224
## What is the impact of not doing this?
216
225
217
-
Users of the language continue to create helper methods to access trait methods with infix syntax.
226
+
Users of the language continue to create helper methods to access trait methods with regular function syntax. More specifically, each such instance requires a minimum of three lines when using normal rust formatting, corresponding to the following example:
227
+
```rust
228
+
fnmy_trait_method<T:MyTrait>(args) ->ret {
229
+
MyTrait::my_trait_method(args)
230
+
}
231
+
```
232
+
Such code is boilerplate that serves nobody's time to have to write repeatedly.
218
233
219
234
## If this is a language proposal, could this be done in a library or macro instead? Does the proposed change make Rust code easier or harder to read, understand, and maintain?
220
235
221
-
A library solution has already been rejected for this. This solves the same problem as a library solution in a much more general way, that doesn't require adding new library methods every time we want infix/shorthand access to trait method names.
236
+
A library solution has already been rejected for this. This solves the same problem as a library solution in a much more general way, that doesn't require adding new library methods every time we want shorthand access to trait method names.
0 commit comments