diff options
| author | Alex Macleod <alex@macleod.io> | 2024-03-05 18:31:32 +0000 |
|---|---|---|
| committer | Alex Macleod <alex@macleod.io> | 2024-03-05 18:31:32 +0000 |
| commit | 6120de99f7be901f94e55c2cdf09b6fb98f93409 (patch) | |
| tree | e5cf498fdb10a1c84d8115d04c76ad8f62f52967 /compiler/rustc_resolve | |
| parent | c7beecf3e3cef7a8226a99aec4e4f6bfc114ba8e (diff) | |
| download | rust-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.rs | 70 |
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 |
