rust-lang / lang-team

Home of the Rust lang team
http://lang-team.rust-lang.org/
Apache License 2.0
202 stars 48 forks source link

Add a `NOOP_METHOD_CALL` lint for methods which should never be directly called #67

Closed Aaron1011 closed 3 years ago

Aaron1011 commented 3 years ago

Proposal

Summary and problem statement

Some types have trivial implementations of particular traits - for example, <&T as Clone>::clone and <&T as Borrow>::borrow. These methods are useful in generic contexts, since they allow things like passing a reference to a function with a T: Clone parameter. However, directly calling one of these methods (e.g. (&NonCloneStruct).clone()) is useless. This can also lead to confusing error messages - for example, calling some_ref.to_owned() may return either a &Foo or a Foo, depending on whether the call to to_owned resolves to <&Foo as ToOwned>::to_owned or <Foo as ToOwned::to_owned

Motivation, use-cases, and solution sketches

I propose introducing a lint NOOP_METHOD_CALL (name bikesheddable), which will fire on direct calls to any 'useless' methods. Initially, it will fire on direct calls to the following methods:

Note that we will intentionally not perform any kind of post-monomorphization checks. This lint will only fire on calls that are known to have the proper receiver (&T) at the call site (where the user could just remove the call).

For example

struct Foo;

fn clone_it<T: Clone>(val: T) -> T {
    val.clone() // No warning - we don't know if `T` is `&T`
}

fn main() {
    let val = &Foo;
    val.clone(); // WARNING: noop method call
    clone_it(val);
}

For now, this lint will only work for types and traits in the standard library. In the future, this could be extended to third-party code via some mechanism, allowing crates to mark methods as only being useful in generic contexts.

However, more design work will be required for such a mechanism. Method calls like <&T as ToOwned>::to_owned go through a blanket impl, so applying an attributes to a method in an impl block is not sufficient to cover all use cases. For the standard library, we can simply hard-code the desired paths, or use some other perma-unstable mechanism.

Prioritization

I believe this fits into the 'Targeted ergonomic wins and extensions' lang team priority. Anecdotally, I've seen users on the Rust discord servers accidentally call some of these methods, and get confused by the resulting error messages. A lint would point users in the right direction.

Links and related work

This was initially proposed as the compiler-team MCP https://github.com/rust-lang/compiler-team/issues/375, then reworded and re-opened here.

Initial people involved

I'm planning to implement this

What happens now?

This issue is part of the experimental MCP process described in RFC 2936. Once this issue is filed, a Zulip topic will be opened for discussion, and the lang-team will review open MCPs in its weekly triage meetings. You should receive feedback within a week or two.

This issue is not meant to be used for technical discussion. There is a Zulip stream for that. Use this issue to leave procedural comments, such as volunteering to review, indicating that you second the proposal (or third, etc), or raising a concern that you would like to be addressed.

rustbot commented 3 years ago

This issue is not meant to be used for technical discussion. There is a Zulip stream for that. Use this issue to leave procedural comments, such as volunteering to review, indicating that you second the proposal (or third, etc), or raising a concern that you would like to be addressed.

nikomatsakis commented 3 years ago

@rustbot second

I'm a bit torn on this one. I'd like it if we developed and published clearer criteria for what sort of lints belong in rustc -- I remember that @oli-obk actually took a stab at that. I don't know that this could be a common source of bugs but certainly confusing compilation errors (I've experienced that myself on occasion...). In any case, I'd be ok seeing a PR go up, and I'd expect an FCP on that PR.

nikomatsakis commented 3 years ago

Discussed in meeting on 2020-11-10:

Aaron1011 commented 3 years ago

@nikomatsakis It looks like the FCP didn't complete after 10 days

nikomatsakis commented 3 years ago

This FCP completed, I'm going to mark this as accepted and close. The expectation @Aaron1011 is that you'll go ahead and do the work to write the PR and then cc lang team before it is merged.

rylev commented 3 years ago

I talked with @Aaron1011, and I'm going to try to implement this.