about summary refs log tree commit diff
path: root/compiler/rustc_resolve
diff options
context:
space:
mode:
authorAlex Macleod <alex@macleod.io>2024-03-05 18:31:32 +0000
committerAlex Macleod <alex@macleod.io>2024-03-05 18:31:32 +0000
commit6120de99f7be901f94e55c2cdf09b6fb98f93409 (patch)
treee5cf498fdb10a1c84d8115d04c76ad8f62f52967 /compiler/rustc_resolve
parentc7beecf3e3cef7a8226a99aec4e4f6bfc114ba8e (diff)
downloadrust-6120de99f7be901f94e55c2cdf09b6fb98f93409.tar.gz
rust-6120de99f7be901f94e55c2cdf09b6fb98f93409.zip
Fix linting paths with qself in `unused_qualifications`
Diffstat (limited to 'compiler/rustc_resolve')
-rw-r--r--compiler/rustc_resolve/src/late.rs70
1 files changed, 37 insertions, 33 deletions
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index de6e121c79b..36279de83d3 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -3953,6 +3953,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
             // Avoid recording definition of `A::B` in `<T as A>::B::C`.
             self.r.record_partial_res(node_id, partial_res);
             self.resolve_elided_lifetimes_in_path(partial_res, path, source, path_span);
+            self.lint_unused_qualifications(path, ns, finalize);
         }
 
         partial_res
@@ -4145,39 +4146,6 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
             PathResult::Indeterminate => bug!("indeterminate path result in resolve_qpath"),
         };
 
-        if path.iter().all(|seg| !seg.ident.span.from_expansion()) {
-            let end_pos =
-                path.iter().position(|seg| seg.has_generic_args).map_or(path.len(), |pos| pos + 1);
-            let unqualified =
-                path[..end_pos].iter().enumerate().skip(1).rev().find_map(|(i, seg)| {
-                    // Preserve the current namespace for the final path segment, but use the type
-                    // namespace for all preceding segments
-                    //
-                    // e.g. for `std::env::args` check the `ValueNS` for `args` but the `TypeNS` for
-                    // `std` and `env`
-                    //
-                    // If the final path segment is beyond `end_pos` all the segments to check will
-                    // use the type namespace
-                    let ns = if i + 1 == path.len() { ns } else { TypeNS };
-                    let res = self.r.partial_res_map.get(&seg.id?)?.full_res()?;
-                    let binding = self.resolve_ident_in_lexical_scope(seg.ident, ns, None, None)?;
-
-                    (res == binding.res()).then_some(seg)
-                });
-
-            if let Some(unqualified) = unqualified {
-                self.r.lint_buffer.buffer_lint_with_diagnostic(
-                    lint::builtin::UNUSED_QUALIFICATIONS,
-                    finalize.node_id,
-                    finalize.path_span,
-                    "unnecessary qualification",
-                    lint::BuiltinLintDiag::UnusedQualifications {
-                        removal_span: finalize.path_span.until(unqualified.ident.span),
-                    },
-                );
-            }
-        }
-
         Ok(Some(result))
     }
 
@@ -4656,6 +4624,42 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
             self.r.doc_link_traits_in_scope = doc_link_traits_in_scope;
         }
     }
+
+    fn lint_unused_qualifications(&mut self, path: &[Segment], ns: Namespace, finalize: Finalize) {
+        if path.iter().any(|seg| seg.ident.span.from_expansion()) {
+            return;
+        }
+
+        let end_pos =
+            path.iter().position(|seg| seg.has_generic_args).map_or(path.len(), |pos| pos + 1);
+        let unqualified = path[..end_pos].iter().enumerate().skip(1).rev().find_map(|(i, seg)| {
+            // Preserve the current namespace for the final path segment, but use the type
+            // namespace for all preceding segments
+            //
+            // e.g. for `std::env::args` check the `ValueNS` for `args` but the `TypeNS` for
+            // `std` and `env`
+            //
+            // If the final path segment is beyond `end_pos` all the segments to check will
+            // use the type namespace
+            let ns = if i + 1 == path.len() { ns } else { TypeNS };
+            let res = self.r.partial_res_map.get(&seg.id?)?.full_res()?;
+            let binding = self.resolve_ident_in_lexical_scope(seg.ident, ns, None, None)?;
+
+            (res == binding.res()).then_some(seg)
+        });
+
+        if let Some(unqualified) = unqualified {
+            self.r.lint_buffer.buffer_lint_with_diagnostic(
+                lint::builtin::UNUSED_QUALIFICATIONS,
+                finalize.node_id,
+                finalize.path_span,
+                "unnecessary qualification",
+                lint::BuiltinLintDiag::UnusedQualifications {
+                    removal_span: path[0].ident.span.until(unqualified.ident.span),
+                },
+            );
+        }
+    }
 }
 
 /// Walks the whole crate in DFS order, visiting each item, counting the declared number of