Add RFC for deprecating method call syntax on traits#2611
Conversation
|
I am against this. A benefit of traits is the seamless usage of a trait by its type. This is a large change to the Rust language that will be removed by such a seemingly simple RFC. |
| - `Ord::clamp` was rejected completely because it caused similar breakage. | ||
| https://github.com/rust-lang/rust/pull/44438 | ||
| - `failure` broke on 2018-12-11 due to newly introduced ambiguous trait calls: | ||
| https://github.com/rust-lang-nursery/failure/issues/280 |
There was a problem hiding this comment.
Iterator::flatten broke Itertools::flatten too.
|
@sinistersnare then I take it you would be in favor the alternative I wrote here? |
|
So traits that utilize builder patterns go from this: my_impl.with_foo(foo)
.with_bar(bar)
.with_baz(baz);to this: ? |
|
As I understand it, Rust does not actually require SemVer in its crate ecosystem. So, even if it is a breaking change, it should not be a 'required' breaking change. Of course, adding a default method is a breaking change, so maybe it is important that we educate that. However, there needn't be anything changed in the Rust language. |
|
@m-hilgendorf oof, yeah I suppose they would. |
|
@Xaeroxe I don't know how it would affect the compiler but is it possible to use type annotation for method calls instead? Something like: my_impl.foo::<TraitA>();
my_impl.foo::<TraitB>(); |
|
I'd suggest adding this as an automatic lightbulb action for the VSCode extension (and IntelliJ plugin) that automatically rewrites method call syntax to UFCS for you. |
|
As some people have brought up on Reddit this would pretty much completely break the |
|
While I'm personally against this specific solution to the problem, I do think that there's a large problem worth solving here, and it's preventing api-breakages from being published to crate patch versions, including "providing new trait functions with default implementations, or adding new traits to an existing struct" as an api breakage. I have not personally seen any work regarding this but what would be incredible is if the rust toolchain could check the equality of the type-level api between two crates, and if this check was enforced on patch publishing on both the client and server side of cargo. |
|
There's a lot to say here, and most important is that this is far too huge of a breaking change for too little benefit to be considered seriously even with epochs, but I think my main reaction is bafflement that trait method syntax is being singled out. The examples in the RFC are just a subset of "expected inference breakage". You can get plenty of similar situations with other kinds of type inference that aren't unique to trait methods (which is why I say "little" benefit; we can't categorically eliminate this problem without going to even greater extremes and nuking type inference entirely). The whole reason "expected inference breakage" is a phrase that exists is because the Rust community already agreed that having type inference in the language and allowing trait/type authors to add defaulted methods/new impls in a minor version were valuable enough to offset the cost of dealing with the breakage that implies. As that RFC put it:
But I do agree that we could do better at mitigating this sort of thing. There should probably be a clippy lint for preferring |
Yeah after further consideration I agree, this might be the worst idea I've ever had.
In my experience it's a very common variety of this kind of breakage, but noted. |
|
I'll go ahead and close this now as I think the RFC process served its purpose. To summarize:
|
|
I haven't seen it mentioned here, but I recall seeing a proposal that code could be automatically re-written into UFCS form when generating a package (not an RFC, I think it was just a side-note on i.rl.o at some point). That would mean that any package uploaded to a registry would avoid the breakage from newly introduced trait methods, but would still retain the benefits of method call syntax while developing the code. |
Probably shouldn't be merged as is...
Rendered