Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upDeref and method shadowing #42021
Comments
This comment has been minimized.
This comment has been minimized.
|
New lints (as this proposes) need to go through the RFC process. You can also suggest a lint to Clippy (https://github.com/Manishearth/rust-clippy). If you or someone else wants to pursue this, please follow the RFC process here (or go through clippy) https://github.com/rust-lang/rfcs#before-creating-an-rfc. |
Mark-Simulacrum
closed this
Jun 22, 2017
This comment has been minimized.
This comment has been minimized.
|
Thanks, I was thinking about going through Clippy (and will ask for directions in an issue there). |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
gavento commentedMay 16, 2017
Types implementing
Deref, e.g.Rc<T>, can shadow methods of their target types. This can happen in two ways:implof both types defining the same method (case A)While this is according to the intended
Derefdesign, it can easily lead to confusion or bugs. It is also one case where addingimpls or importing traits can silently change behavior (see below) or break the code (see e.g. #41906 and the original #41865).We should be able to detect it and at least issue a warning.
Details and illustration
To illustrate, consider this code excerpt (full playpen). (The types here are abstract on purpose, but see #41906 and case C below for examples with
Borrow.)Case A is triggered by adding
impl<T> A<T> { fn method(&self) { } }. While here the behavior is least confusing of the three, it still a bad design we might be able to detect and warn about. (This is the reasonDereftypes such asstd::rc::Rcgenerally only have type-associated methods.)Case B is triggered by implementing a trait with
methodonA<T>as below. This is harder to both avoid (trait methods are not associated) and notice.Case C is triggered similarly to B, by the code below. The difference is that the trait is implemented in another module and only gets activated by an
use.For this last case, I have a slightly more realistic example with
use std::borrow::Borrow;triggering a different behavior with no warnings. See the playpen.Solution
On a method call, we could inspect the entire
Derefchain of types for methods of the same name and issue a warning if we find a method of the same name.Users could resolve this with:
(*a).method()A::method(&a)#[allow(deref_shadowing)]pragmaI would see this as an important warning: activating any two of the cases A, B or C at once is a compiler error (as it should be) and the
Derefcoercion is very close to that from user point of view but gives no warning.This would also resolve #41906 in a general way (are there any other related issues?)