@@ -3953,6 +3953,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
3953
3953
// Avoid recording definition of `A::B` in `<T as A>::B::C`.
3954
3954
self.r.record_partial_res(node_id, partial_res);
3955
3955
self.resolve_elided_lifetimes_in_path(partial_res, path, source, path_span);
3956
+ self.lint_unused_qualifications(path, ns, finalize);
3956
3957
}
3957
3958
3958
3959
partial_res
@@ -4145,39 +4146,6 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
4145
4146
PathResult::Indeterminate => bug!("indeterminate path result in resolve_qpath"),
4146
4147
};
4147
4148
4148
- if path.iter().all(|seg| !seg.ident.span.from_expansion()) {
4149
- let end_pos =
4150
- path.iter().position(|seg| seg.has_generic_args).map_or(path.len(), |pos| pos + 1);
4151
- let unqualified =
4152
- path[..end_pos].iter().enumerate().skip(1).rev().find_map(|(i, seg)| {
4153
- // Preserve the current namespace for the final path segment, but use the type
4154
- // namespace for all preceding segments
4155
- //
4156
- // e.g. for `std::env::args` check the `ValueNS` for `args` but the `TypeNS` for
4157
- // `std` and `env`
4158
- //
4159
- // If the final path segment is beyond `end_pos` all the segments to check will
4160
- // use the type namespace
4161
- let ns = if i + 1 == path.len() { ns } else { TypeNS };
4162
- let res = self.r.partial_res_map.get(&seg.id?)?.full_res()?;
4163
- let binding = self.resolve_ident_in_lexical_scope(seg.ident, ns, None, None)?;
4164
-
4165
- (res == binding.res()).then_some(seg)
4166
- });
4167
-
4168
- if let Some(unqualified) = unqualified {
4169
- self.r.lint_buffer.buffer_lint_with_diagnostic(
4170
- lint::builtin::UNUSED_QUALIFICATIONS,
4171
- finalize.node_id,
4172
- finalize.path_span,
4173
- "unnecessary qualification",
4174
- lint::BuiltinLintDiag::UnusedQualifications {
4175
- removal_span: finalize.path_span.until(unqualified.ident.span),
4176
- },
4177
- );
4178
- }
4179
- }
4180
-
4181
4149
Ok(Some(result))
4182
4150
}
4183
4151
@@ -4656,6 +4624,42 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
4656
4624
self.r.doc_link_traits_in_scope = doc_link_traits_in_scope;
4657
4625
}
4658
4626
}
4627
+
4628
+ fn lint_unused_qualifications(&mut self, path: &[Segment], ns: Namespace, finalize: Finalize) {
4629
+ if path.iter().any(|seg| seg.ident.span.from_expansion()) {
4630
+ return;
4631
+ }
4632
+
4633
+ let end_pos =
4634
+ path.iter().position(|seg| seg.has_generic_args).map_or(path.len(), |pos| pos + 1);
4635
+ let unqualified = path[..end_pos].iter().enumerate().skip(1).rev().find_map(|(i, seg)| {
4636
+ // Preserve the current namespace for the final path segment, but use the type
4637
+ // namespace for all preceding segments
4638
+ //
4639
+ // e.g. for `std::env::args` check the `ValueNS` for `args` but the `TypeNS` for
4640
+ // `std` and `env`
4641
+ //
4642
+ // If the final path segment is beyond `end_pos` all the segments to check will
4643
+ // use the type namespace
4644
+ let ns = if i + 1 == path.len() { ns } else { TypeNS };
4645
+ let res = self.r.partial_res_map.get(&seg.id?)?.full_res()?;
4646
+ let binding = self.resolve_ident_in_lexical_scope(seg.ident, ns, None, None)?;
4647
+
4648
+ (res == binding.res()).then_some(seg)
4649
+ });
4650
+
4651
+ if let Some(unqualified) = unqualified {
4652
+ self.r.lint_buffer.buffer_lint_with_diagnostic(
4653
+ lint::builtin::UNUSED_QUALIFICATIONS,
4654
+ finalize.node_id,
4655
+ finalize.path_span,
4656
+ "unnecessary qualification",
4657
+ lint::BuiltinLintDiag::UnusedQualifications {
4658
+ removal_span: path[0].ident.span.until(unqualified.ident.span),
4659
+ },
4660
+ );
4661
+ }
4662
+ }
4659
4663
}
4660
4664
4661
4665
/// Walks the whole crate in DFS order, visiting each item, counting the declared number of
0 commit comments