Skip to content

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

Closed

Description

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:

  • <&T as Clone>::clone
  • <&T as Borrow>::borrow
  • <&T as Deref>::deref
  • <&T as ToOwned>::to_owned

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 rust-lang/compiler-team#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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions