-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Add RFC for deprecating method call syntax on traits #2611
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
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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