diff options
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_resolve/src/late.rs | 46 |
1 files changed, 24 insertions, 22 deletions
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 2f4da29133f..87aa3bed2ca 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -4150,34 +4150,36 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { PathResult::Indeterminate => bug!("indeterminate path result in resolve_qpath"), }; - if path.len() > 1 - && let Some(res) = result.full_res() - && let Some((&last_segment, prev_segs)) = path.split_last() - && prev_segs.iter().all(|seg| !seg.has_generic_args) - && res != Res::Err - && path[0].ident.name != kw::PathRoot - && path[0].ident.name != kw::DollarCrate - { - let unqualified_result = { - match self.resolve_path(&[last_segment], Some(ns), None) { - PathResult::NonModule(path_res) => path_res.expect_full_res(), - PathResult::Module(ModuleOrUniformRoot::Module(module)) => { - module.res().unwrap() - } - _ => return Ok(Some(result)), - } - }; - if res == unqualified_result { - let lint = lint::builtin::UNUSED_QUALIFICATIONS; + 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, + lint::builtin::UNUSED_QUALIFICATIONS, finalize.node_id, finalize.path_span, "unnecessary qualification", lint::BuiltinLintDiagnostics::UnusedQualifications { - removal_span: finalize.path_span.until(last_segment.ident.span), + removal_span: finalize.path_span.until(unqualified.ident.span), }, - ) + ); } } |
