-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Add lint for multiple associated types #50682
Conversation
(rust_highfive has picked a reviewer for you, use r? to override) |
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
src/librustc_lint/builtin.rs
Outdated
fn check_bindings(&self, ctxt: &EarlyContext, bindings: &[ast::TypeBinding]) { | ||
let mut dup_binds = HashMap::with_capacity(bindings.len()); | ||
for b in bindings { | ||
dup_binds.entry(b.ident.name).or_insert(vec![]).push(b.ident.span); |
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.
So the lint doesn't allocate for every path it checks, I think it'd be better just to do a nested loop search for any duplicates and push their spans to a Vec
.
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.
Well, using a HashMap<Name, Vec> to collect all the spans with the same associate type name can avoid the inner loop.
What do you mean by "the lint doesn't allocate for every path it checks"?
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.
Your approach is fine, actually, I just think it shouldn't allocate until a duplicate is found, so use HashMap::new()
. That way we're not allocating when we don't end up using it.
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.
Thanks. If we want to avoid allocation every time, how about keeping the HashMap
as a member of struct struct DupAssocTypeBinding
?
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.
I don't think that's quite necessary, I was just concerned about allocating every time this function is called.
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.
I think you are right. I have updated this function. Thanks.
r? @nikomatsakis for re-assignment |
Everybody forgets about hygiene :( |
@petrochenkov It's probably my mistake. This and #50763 were both started from my mentoring instructions and I was purely looking at the AST types since anything further in-depth would probably not be a good starting ticket. |
☔ The latest upstream changes (presumably #48557) made this pull request unmergeable. Please resolve the merge conflicts. |
I will fix this when I have time in the next two days. Thanks very much! |
@F001 do you think you know what to do from @petrochenkov's notes? |
r? @petrochenkov — since you seem to have a pretty specific idea for what you want, can you take on the review? (let me know if that's a problem) |
@petrochenkov This lint is re-implemented. Please help to review. Thanks! |
src/librustc/lint/builtin.rs
Outdated
@@ -279,6 +279,12 @@ declare_lint! { | |||
"detects name collision with an existing but unstable method" | |||
} | |||
|
|||
declare_lint! { | |||
pub DUPLICATE_ASSOCIATED_TYPE_BINDING, |
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.
Could you add this lint to the list of deprecation lints?
(See e.g. PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES
as an example.)
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.
Also duplicate_associated_type_binding
-> duplicate_associated_type_bindings
(see https://github.com/rust-lang/rfcs/blob/master/text/0344-conventions-galore.md#lints).
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.
Fixed.
src/librustc_typeck/astconv.rs
Outdated
@@ -565,6 +577,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { | |||
tcx.sess.span_err(binding.span, &msg); | |||
} | |||
tcx.check_stability(assoc_ty.def_id, Some(ref_id), binding.span); | |||
dup_bindings.entry(assoc_ty.def_id).or_insert(Vec::new()).push(binding.span); |
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.
Could we model this error after duplicated fields:
error[E0062]: field `a` specified more than once
--> src/main.rs:4:23
|
4 | let s = S { a: 0, a: 1 };
| ---- ^ used more than once
| |
| first use of `a`
We keep FxHashMap<DefId, Span>
instead of FxHashMap<DefId, Vec<Span>>
and if the inserted DefId
was already in the table, report an error pointing to the first use right here.
I'd even reuse all the wording for fields (except for replacing "field a
" with "associated type binding a
", of course).
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.
(You can attach labels and notes to the object returned by struct_span_lint_node
, there are plenty of examples in the codebase.)
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.
Fixed.
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! | ||
= note: for more information, see issue #50589 <https://github.com/rust-lang/rust/issues/50589> | ||
|
||
warning: associated type binding `Item` specified more than once |
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.
Hmm, the warning is reported twice.
I suspect it needs to be reported only when speculative
is false.
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.
It seems the warning is reported twice when speculative
is false. I don't know why.
☔ The latest upstream changes (presumably #50763) made this pull request unmergeable. Please resolve the merge conflicts. |
src/librustc_typeck/astconv.rs
Outdated
@@ -566,6 +568,23 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { | |||
} | |||
tcx.check_stability(assoc_ty.def_id, Some(ref_id), binding.span); | |||
|
|||
if speculative { |
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.
if speculative
-> if !speculative
r=me after inverting the |
✌️ @F001 can now approve this pull request |
@petrochenkov Thank you for your detailed mentoring. As I mentioned in the previous comment, when I use |
Weird. I'll look what happens. |
Ok, this may look logically impossible unless you know that fully identical diagnostics are merged! This happens because |
@bors: r=petrochenkov |
📌 Commit 88f810f has been approved by |
Add lint for multiple associated types Fix #50589. cc @abonander
☀️ Test successful - status-appveyor, status-travis |
Do not deduplicate diagnostics in UI tests Error reporting infrastructure deduplicates identical diagnostics with identical spans. While it's preferable to do this in "release"/"user-facing" mode, it sometimes brings [confusion](rust-lang#50682 (comment)) and hides details that may be important during development. Do we run some passes multiple times when we could do it once? How many times we run them exactly? Can this number be large? Can the multiplied error construction be expensive? Can speculative checks be made cheaper if they don't report errors? *Relying* on this mechanism to deduplicate some specific error never looks like a proper solution to me personally. In this PR I attempt to disable this deduplication by applying `-Z deduplicate-diagnostics=no` to UI tests.
Do not deduplicate diagnostics in UI tests Error reporting infrastructure deduplicates identical diagnostics with identical spans. While it's preferable to do this in "release"/"user-facing" mode, it sometimes brings [confusion](rust-lang#50682 (comment)) and hides details that may be important during development. Do we run some passes multiple times when we could do it once? How many times we run them exactly? Can this number be large? Can the multiplied error construction be expensive? Can speculative checks be made cheaper if they don't report errors? *Relying* on this mechanism to deduplicate some specific error never looks like a proper solution to me personally. In this PR I attempt to disable this deduplication by applying `-Z deduplicate-diagnostics=no` to UI tests.
Fix #50589. cc @abonander