diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 650a0dc82ce23..7485dd51863b7 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -298,7 +298,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { &segments, Some(TypeNS), parent_scope, - if finalize { Finalize::SimplePath(id, path.span) } else { Finalize::No }, + finalize.then(|| Finalize::new(id, path.span)), None, ) { PathResult::Module(ModuleOrUniformRoot::Module(module)) => { diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index e0a83ba8c0d4a..7d40ecb18b747 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -417,15 +417,12 @@ impl<'a> Resolver<'a> { crate fn lint_if_path_starts_with_module( &mut self, - finalize: Finalize, + finalize: Option, path: &[Segment], second_binding: Option<&NameBinding<'_>>, ) { - let (diag_id, diag_span) = match finalize { - Finalize::No => return, - Finalize::SimplePath(id, path_span) => (id, path_span), - Finalize::UsePath { root_id, root_span, .. } => (root_id, root_span), - Finalize::QPathTrait { qpath_id, qpath_span, .. } => (qpath_id, qpath_span), + let Some(Finalize { node_id, root_span, .. }) = finalize else { + return; }; let first_name = match path.get(0) { @@ -463,11 +460,11 @@ impl<'a> Resolver<'a> { } } - let diag = BuiltinLintDiagnostics::AbsPathWithModule(diag_span); + let diag = BuiltinLintDiagnostics::AbsPathWithModule(root_span); self.lint_buffer.buffer_lint_with_diagnostic( ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE, - diag_id, - diag_span, + node_id, + root_span, "absolute paths must start with `self`, `super`, \ `crate`, or an external crate name in the 2018 edition", diag, @@ -1503,7 +1500,6 @@ impl<'a> Resolver<'a> { &parent_scope, None, false, - false, None, ) { let desc = match binding.res() { @@ -1811,7 +1807,7 @@ impl<'a> Resolver<'a> { opt_ns: Option, // `None` indicates a module path in import parent_scope: &ParentScope<'a>, ribs: Option<&PerNS>>>, - unusable_binding: Option<&'a NameBinding<'a>>, + ignore_binding: Option<&'a NameBinding<'a>>, module: Option>, i: usize, ident: Ident, @@ -1863,8 +1859,7 @@ impl<'a> Resolver<'a> { ns_to_try, parent_scope, None, - false, - unusable_binding, + ignore_binding, ).ok() } else if let Some(ribs) = ribs && let Some(TypeNS | ValueNS) = opt_ns @@ -1873,9 +1868,9 @@ impl<'a> Resolver<'a> { ident, ns_to_try, parent_scope, - Finalize::No, + None, &ribs[ns_to_try], - unusable_binding, + ignore_binding, ) { // we found a locally-imported or available item/module Some(LexicalScopeBinding::Item(binding)) => Some(binding), @@ -1889,8 +1884,7 @@ impl<'a> Resolver<'a> { parent_scope, None, false, - false, - unusable_binding, + ignore_binding, ).ok() }; if let Some(binding) = binding { @@ -1921,9 +1915,9 @@ impl<'a> Resolver<'a> { ident, ValueNS, parent_scope, - Finalize::No, + None, &ribs[ValueNS], - unusable_binding, + ignore_binding, ) } else { None diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index 84fe0ec83d26c..18ce359524da2 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -279,9 +279,9 @@ impl<'a> Resolver<'a> { mut ident: Ident, ns: Namespace, parent_scope: &ParentScope<'a>, - finalize_full: Finalize, + finalize: Option, ribs: &[Rib<'a>], - unusable_binding: Option<&'a NameBinding<'a>>, + ignore_binding: Option<&'a NameBinding<'a>>, ) -> Option> { assert!(ns == TypeNS || ns == ValueNS); let orig_ident = ident; @@ -302,7 +302,6 @@ impl<'a> Resolver<'a> { let normalized_ident = Ident { span: normalized_span, ..ident }; // Walk backwards up the ribs in scope. - let finalize = finalize_full.path_span(); let mut module = self.graph_root; for i in (0..ribs.len()).rev() { debug!("walk rib\n{:?}", ribs[i].bindings); @@ -316,7 +315,7 @@ impl<'a> Resolver<'a> { i, rib_ident, *res, - finalize, + finalize.map(|finalize| finalize.path_span), *original_rib_ident_def, ribs, ))); @@ -344,8 +343,7 @@ impl<'a> Resolver<'a> { ns, parent_scope, finalize, - false, - unusable_binding, + ignore_binding, ); if let Ok(binding) = item { // The ident resolves to an item. @@ -354,12 +352,11 @@ impl<'a> Resolver<'a> { } self.early_resolve_ident_in_lexical_scope( orig_ident, - ScopeSet::Late(ns, module, finalize_full.node_id()), + ScopeSet::Late(ns, module, finalize.map(|finalize| finalize.node_id)), parent_scope, finalize, finalize.is_some(), - false, - unusable_binding, + ignore_binding, ) .ok() .map(LexicalScopeBinding::Item) @@ -376,10 +373,9 @@ impl<'a> Resolver<'a> { orig_ident: Ident, scope_set: ScopeSet<'a>, parent_scope: &ParentScope<'a>, - finalize: Option, + finalize: Option, force: bool, - last_import_segment: bool, - unusable_binding: Option<&'a NameBinding<'a>>, + ignore_binding: Option<&'a NameBinding<'a>>, ) -> Result<&'a NameBinding<'a>, Determinacy> { bitflags::bitflags! { struct Flags: u8 { @@ -499,8 +495,7 @@ impl<'a> Resolver<'a> { ns, parent_scope, finalize, - last_import_segment, - unusable_binding, + ignore_binding, ); match binding { Ok(binding) => Ok((binding, Flags::MODULE | Flags::MISC_SUGGEST_CRATE)), @@ -522,8 +517,7 @@ impl<'a> Resolver<'a> { adjusted_parent_scope, !matches!(scope_set, ScopeSet::Late(..)), finalize, - last_import_segment, - unusable_binding, + ignore_binding, ); match binding { Ok(binding) => { @@ -608,8 +602,7 @@ impl<'a> Resolver<'a> { ns, parent_scope, None, - last_import_segment, - unusable_binding, + ignore_binding, ) { if use_prelude || this.is_builtin_macro(binding.res()) { result = Ok((binding, Flags::MISC_FROM_PRELUDE)); @@ -731,7 +724,7 @@ impl<'a> Resolver<'a> { ns: Namespace, parent_scope: &ParentScope<'a>, ) -> Result<&'a NameBinding<'a>, Determinacy> { - self.resolve_ident_in_module_ext(module, ident, ns, parent_scope, None, false, None) + self.resolve_ident_in_module_ext(module, ident, ns, parent_scope, None, None) .map_err(|(determinacy, _)| determinacy) } @@ -742,23 +735,11 @@ impl<'a> Resolver<'a> { ident: Ident, ns: Namespace, parent_scope: &ParentScope<'a>, - finalize: Option, - // We are resolving a last import segment during import validation. - last_import_segment: bool, - // This binding should be ignored during in-module resolution, so that we don't get - // "self-confirming" import resolutions during import validation. - unusable_binding: Option<&'a NameBinding<'a>>, + finalize: Option, + ignore_binding: Option<&'a NameBinding<'a>>, ) -> Result<&'a NameBinding<'a>, Determinacy> { - self.resolve_ident_in_module_ext( - module, - ident, - ns, - parent_scope, - finalize, - last_import_segment, - unusable_binding, - ) - .map_err(|(determinacy, _)| determinacy) + self.resolve_ident_in_module_ext(module, ident, ns, parent_scope, finalize, ignore_binding) + .map_err(|(determinacy, _)| determinacy) } #[tracing::instrument(level = "debug", skip(self))] @@ -768,9 +749,8 @@ impl<'a> Resolver<'a> { mut ident: Ident, ns: Namespace, parent_scope: &ParentScope<'a>, - finalize: Option, - last_import_segment: bool, - unusable_binding: Option<&'a NameBinding<'a>>, + finalize: Option, + ignore_binding: Option<&'a NameBinding<'a>>, ) -> Result<&'a NameBinding<'a>, (Determinacy, Weak)> { let tmp_parent_scope; let mut adjusted_parent_scope = parent_scope; @@ -796,8 +776,7 @@ impl<'a> Resolver<'a> { adjusted_parent_scope, false, finalize, - last_import_segment, - unusable_binding, + ignore_binding, ) } @@ -808,9 +787,8 @@ impl<'a> Resolver<'a> { ident: Ident, ns: Namespace, parent_scope: &ParentScope<'a>, - finalize: Option, - last_import_segment: bool, - unusable_binding: Option<&'a NameBinding<'a>>, + finalize: Option, + ignore_binding: Option<&'a NameBinding<'a>>, ) -> Result<&'a NameBinding<'a>, Determinacy> { self.resolve_ident_in_module_unadjusted_ext( module, @@ -819,8 +797,7 @@ impl<'a> Resolver<'a> { parent_scope, false, finalize, - last_import_segment, - unusable_binding, + ignore_binding, ) .map_err(|(determinacy, _)| determinacy) } @@ -835,9 +812,10 @@ impl<'a> Resolver<'a> { ns: Namespace, parent_scope: &ParentScope<'a>, restricted_shadowing: bool, - finalize: Option, - last_import_segment: bool, - unusable_binding: Option<&'a NameBinding<'a>>, + finalize: Option, + // This binding should be ignored during in-module resolution, so that we don't get + // "self-confirming" import resolutions during import validation and checking. + ignore_binding: Option<&'a NameBinding<'a>>, ) -> Result<&'a NameBinding<'a>, (Determinacy, Weak)> { let module = match module { ModuleOrUniformRoot::Module(module) => module, @@ -849,8 +827,7 @@ impl<'a> Resolver<'a> { parent_scope, finalize, finalize.is_some(), - last_import_segment, - unusable_binding, + ignore_binding, ); return binding.map_err(|determinacy| (determinacy, Weak::No)); } @@ -890,8 +867,7 @@ impl<'a> Resolver<'a> { parent_scope, finalize, finalize.is_some(), - last_import_segment, - unusable_binding, + ignore_binding, ); return binding.map_err(|determinacy| (determinacy, Weak::No)); } @@ -901,19 +877,15 @@ impl<'a> Resolver<'a> { let resolution = self.resolution(module, key).try_borrow_mut().map_err(|_| (Determined, Weak::No))?; // This happens when there is a cycle of imports. - if let Some(path_span) = finalize { + if let Some(Finalize { path_span, report_private, .. }) = finalize { // If the primary binding is unusable, search further and return the shadowed glob // binding if it exists. What we really want here is having two separate scopes in // a module - one for non-globs and one for globs, but until that's done use this // hack to avoid inconsistent resolution ICEs during import validation. let binding = [resolution.binding, resolution.shadowed_glob] .into_iter() - .filter_map(|binding| match (binding, unusable_binding) { - (Some(binding), Some(unusable_binding)) - if ptr::eq(binding, unusable_binding) => - { - None - } + .filter_map(|binding| match (binding, ignore_binding) { + (Some(binding), Some(ignored)) if ptr::eq(binding, ignored) => None, _ => binding, }) .next(); @@ -922,14 +894,14 @@ impl<'a> Resolver<'a> { }; if !self.is_accessible_from(binding.vis, parent_scope.module) { - if last_import_segment { - return Err((Determined, Weak::No)); - } else { + if report_private { self.privacy_errors.push(PrivacyError { ident, binding, dedup_span: path_span, }); + } else { + return Err((Determined, Weak::No)); } } @@ -960,10 +932,8 @@ impl<'a> Resolver<'a> { } let check_usable = |this: &mut Self, binding: &'a NameBinding<'a>| { - if let Some(unusable_binding) = unusable_binding { - if ptr::eq(binding, unusable_binding) { - return Err((Determined, Weak::No)); - } + if let Some(ignored) = ignore_binding && ptr::eq(binding, ignored) { + return Err((Determined, Weak::No)); } let usable = this.is_accessible_from(binding.vis, parent_scope.module); if usable { Ok(binding) } else { Err((Determined, Weak::No)) } @@ -996,8 +966,7 @@ impl<'a> Resolver<'a> { ns, &single_import.parent_scope, None, - last_import_segment, - unusable_binding, + ignore_binding, ) { Err(Determined) => continue, Ok(binding) @@ -1073,8 +1042,7 @@ impl<'a> Resolver<'a> { ns, adjusted_parent_scope, None, - last_import_segment, - unusable_binding, + ignore_binding, ); match result { @@ -1371,7 +1339,7 @@ impl<'a> Resolver<'a> { opt_ns: Option, // `None` indicates a module path in import parent_scope: &ParentScope<'a>, ) -> PathResult<'a> { - self.resolve_path_with_ribs(path, opt_ns, parent_scope, Finalize::No, None, None) + self.resolve_path_with_ribs(path, opt_ns, parent_scope, None, None, None) } #[tracing::instrument(level = "debug", skip(self))] @@ -1380,10 +1348,10 @@ impl<'a> Resolver<'a> { path: &[Segment], opt_ns: Option, // `None` indicates a module path in import parent_scope: &ParentScope<'a>, - finalize: Finalize, - unusable_binding: Option<&'a NameBinding<'a>>, + finalize: Option, + ignore_binding: Option<&'a NameBinding<'a>>, ) -> PathResult<'a> { - self.resolve_path_with_ribs(path, opt_ns, parent_scope, finalize, None, unusable_binding) + self.resolve_path_with_ribs(path, opt_ns, parent_scope, finalize, None, ignore_binding) } crate fn resolve_path_with_ribs( @@ -1391,13 +1359,12 @@ impl<'a> Resolver<'a> { path: &[Segment], opt_ns: Option, // `None` indicates a module path in import parent_scope: &ParentScope<'a>, - finalize_full: Finalize, + finalize: Option, ribs: Option<&PerNS>>>, - unusable_binding: Option<&'a NameBinding<'a>>, + ignore_binding: Option<&'a NameBinding<'a>>, ) -> PathResult<'a> { - debug!("resolve_path(path={:?}, opt_ns={:?}, finalize={:?})", path, opt_ns, finalize_full); + debug!("resolve_path(path={:?}, opt_ns={:?}, finalize={:?})", path, opt_ns, finalize); - let finalize = finalize_full.path_span(); let mut module = None; let mut allow_super = true; let mut second_binding = None; @@ -1497,8 +1464,7 @@ impl<'a> Resolver<'a> { ns, parent_scope, finalize, - false, - unusable_binding, + ignore_binding, ) } else if let Some(ribs) = ribs && let Some(TypeNS | ValueNS) = opt_ns @@ -1507,9 +1473,9 @@ impl<'a> Resolver<'a> { ident, ns, parent_scope, - finalize_full, + finalize, &ribs[ns], - unusable_binding, + ignore_binding, ) { // we found a locally-imported or available item/module Some(LexicalScopeBinding::Item(binding)) => Ok(binding), @@ -1525,8 +1491,7 @@ impl<'a> Resolver<'a> { parent_scope, finalize, finalize.is_some(), - false, - unusable_binding, + ignore_binding, ) }; FindBindingResult::Binding(binding) @@ -1566,7 +1531,7 @@ impl<'a> Resolver<'a> { } else if res == Res::Err { return PathResult::NonModule(PartialRes::new(Res::Err)); } else if opt_ns.is_some() && (is_last || maybe_assoc) { - self.lint_if_path_starts_with_module(finalize_full, path, second_binding); + self.lint_if_path_starts_with_module(finalize, path, second_binding); return PathResult::NonModule(PartialRes::with_unresolved_segments( res, path.len() - i - 1, @@ -1599,7 +1564,7 @@ impl<'a> Resolver<'a> { opt_ns, parent_scope, ribs, - unusable_binding, + ignore_binding, module, i, ident, @@ -1609,7 +1574,7 @@ impl<'a> Resolver<'a> { } } - self.lint_if_path_starts_with_module(finalize_full, path, second_binding); + self.lint_if_path_starts_with_module(finalize, path, second_binding); PathResult::Module(match module { Some(module) => module, diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 01dc727737a5a..ef06ec356bd68 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -545,7 +545,6 @@ impl<'a, 'b> ImportResolver<'a, 'b> { ns, &import.parent_scope, None, - false, None, ); import.vis.set(orig_vis); @@ -589,22 +588,18 @@ impl<'a, 'b> ImportResolver<'a, 'b> { /// consolidate multiple unresolved import errors into a single diagnostic. fn finalize_import(&mut self, import: &'b Import<'b>) -> Option { let orig_vis = import.vis.replace(ty::Visibility::Invisible); - let unusable_binding = match &import.kind { + let ignore_binding = match &import.kind { ImportKind::Single { target_bindings, .. } => target_bindings[TypeNS].get(), _ => None, }; let prev_ambiguity_errors_len = self.r.ambiguity_errors.len(); - let finalize = Finalize::UsePath { - root_id: import.root_id, - root_span: import.root_span, - path_span: import.span, - }; + let finalize = Finalize::with_root_span(import.root_id, import.span, import.root_span); let path_res = self.r.resolve_path( &import.module_path, None, &import.parent_scope, - finalize, - unusable_binding, + Some(finalize), + ignore_binding, ); let no_ambiguity = self.r.ambiguity_errors.len() == prev_ambiguity_errors_len; import.vis.set(orig_vis); @@ -685,7 +680,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { // 2 segments, so the `resolve_path` above won't trigger it. let mut full_path = import.module_path.clone(); full_path.push(Segment::from_ident(Ident::empty())); - self.r.lint_if_path_starts_with_module(finalize, &full_path, None); + self.r.lint_if_path_starts_with_module(Some(finalize), &full_path, None); } if let ModuleOrUniformRoot::Module(module) = module { @@ -720,8 +715,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { ident, ns, &import.parent_scope, - Some(import.span), - true, + Some(Finalize { report_private: false, ..finalize }), target_bindings[ns].get(), ); import.vis.set(orig_vis); @@ -781,8 +775,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { ident, ns, &import.parent_scope, - Some(import.span), - false, + Some(finalize), None, ); if binding.is_ok() { @@ -948,7 +941,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { full_path.push(Segment::from_ident(ident)); self.r.per_ns(|this, ns| { if let Ok(binding) = source_bindings[ns].get() { - this.lint_if_path_starts_with_module(finalize, &full_path, Some(binding)); + this.lint_if_path_starts_with_module(Some(finalize), &full_path, Some(binding)); } }); } @@ -1003,7 +996,6 @@ impl<'a, 'b> ImportResolver<'a, 'b> { &import.parent_scope, None, false, - false, target_bindings[ns].get(), ) { Ok(other_binding) => { diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 53bd589fdcde1..ca89f61032221 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -578,7 +578,7 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> { .resolve_ident_in_lexical_scope( self_ty, TypeNS, - Finalize::SimplePath(ty.id, ty.span), + Some(Finalize::new(ty.id, ty.span)), None, ) .map_or(Res::Err, |d| d.res()); @@ -958,7 +958,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { ident, ns, &self.parent_scope, - Finalize::No, + None, &self.ribs[ns], None, ) @@ -968,8 +968,8 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { &mut self, ident: Ident, ns: Namespace, - finalize: Finalize, - unusable_binding: Option<&'a NameBinding<'a>>, + finalize: Option, + ignore_binding: Option<&'a NameBinding<'a>>, ) -> Option> { self.r.resolve_ident_in_lexical_scope( ident, @@ -977,7 +977,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { &self.parent_scope, finalize, &self.ribs[ns], - unusable_binding, + ignore_binding, ) } @@ -985,7 +985,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { &mut self, path: &[Segment], opt_ns: Option, // `None` indicates a module path in import - finalize: Finalize, + finalize: Option, ) -> PathResult<'a> { self.r.resolve_path_with_ribs( path, @@ -1299,11 +1299,8 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { partial_res: PartialRes, path: &[Segment], source: PathSource<'_>, - finalize: Finalize, + path_span: Span, ) { - let Some(path_span) = finalize.path_span() else { - return; - }; let proj_start = path.len() - partial_res.unresolved_segments(); for (i, segment) in path.iter().enumerate() { if segment.has_lifetime_args { @@ -1576,8 +1573,8 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { report_error(self, ns); } Some(LexicalScopeBinding::Item(binding)) => { - if let Some(LexicalScopeBinding::Res(..)) = self - .resolve_ident_in_lexical_scope(ident, ns, Finalize::No, Some(binding)) + if let Some(LexicalScopeBinding::Res(..)) = + self.resolve_ident_in_lexical_scope(ident, ns, None, Some(binding)) { report_error(self, ns); } @@ -1979,7 +1976,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { None, &path, PathSource::Trait(AliasPossibility::No), - Finalize::SimplePath(trait_ref.ref_id, trait_ref.path.span), + Finalize::new(trait_ref.ref_id, trait_ref.path.span), ); if let Some(def_id) = res.base_res().opt_def_id() { new_id = Some(def_id); @@ -2653,7 +2650,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { qself, &Segment::from_path(path), source, - Finalize::SimplePath(id, path.span), + Finalize::new(id, path.span), ); } @@ -2672,8 +2669,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { ); let ns = source.namespace(); - let (id, path_span) = - finalize.node_id_and_path_span().expect("unexpected speculative resolution"); + let Finalize { node_id, path_span, .. } = finalize; let report_errors = |this: &mut Self, res: Option| { if this.should_report_errs() { let (err, candidates) = @@ -2787,7 +2783,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { if ns == ValueNS { let item_name = path.last().unwrap().ident; let traits = self.traits_in_scope(item_name, ns); - self.r.trait_map.insert(id, traits); + self.r.trait_map.insert(node_id, traits); } if PrimTy::from_name(path[0].ident.name).is_some() { @@ -2796,7 +2792,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { std_path.push(Segment::from_ident(Ident::with_dummy_span(sym::std))); std_path.extend(path); if let PathResult::Module(_) | PathResult::NonModule(_) = - self.resolve_path(&std_path, Some(ns), Finalize::No) + self.resolve_path(&std_path, Some(ns), None) { // Check if we wrote `str::from_utf8` instead of `std::str::from_utf8` let item_span = @@ -2823,8 +2819,8 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { if !matches!(source, PathSource::TraitItem(..)) { // Avoid recording definition of `A::B` in `::B::C`. - self.r.record_partial_res(id, partial_res); - self.resolve_elided_lifetimes_in_path(id, partial_res, path, source, finalize); + self.r.record_partial_res(node_id, partial_res); + self.resolve_elided_lifetimes_in_path(node_id, partial_res, path, source, path_span); } partial_res @@ -2932,21 +2928,12 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { // the trait (the slice upto and including // `qself.position`). And then we recursively resolve that, // but with `qself` set to `None`. - // - // However, setting `qself` to none (but not changing the - // span) loses the information about where this path - // *actually* appears, so for the purposes of the crate - // lint we pass along information that this is the trait - // name from a fully qualified path, and this also - // contains the full span (the `Finalize::QPathTrait`). let ns = if qself.position + 1 == path.len() { ns } else { TypeNS }; let partial_res = self.smart_resolve_path_fragment( None, &path[..=qself.position], PathSource::TraitItem(ns), - finalize.node_id_and_path_span().map_or(Finalize::No, |(qpath_id, path_span)| { - Finalize::QPathTrait { qpath_id, qpath_span: qself.path_span, path_span } - }), + Finalize::with_root_span(finalize.node_id, finalize.path_span, qself.path_span), ); // The remaining segments (the `C` in our example) will @@ -2958,7 +2945,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { ))); } - let result = match self.resolve_path(&path, Some(ns), finalize) { + let result = match self.resolve_path(&path, Some(ns), Some(finalize)) { PathResult::NonModule(path_res) => path_res, PathResult::Module(ModuleOrUniformRoot::Module(module)) if !module.is_normal() => { PartialRes::new(module.res().unwrap()) @@ -2996,10 +2983,9 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { && result.base_res() != Res::Err && path[0].ident.name != kw::PathRoot && path[0].ident.name != kw::DollarCrate - && let Some((id, path_span)) = finalize.node_id_and_path_span() { let unqualified_result = { - match self.resolve_path(&[*path.last().unwrap()], Some(ns), Finalize::No) { + match self.resolve_path(&[*path.last().unwrap()], Some(ns), None) { PathResult::NonModule(path_res) => path_res.base_res(), PathResult::Module(ModuleOrUniformRoot::Module(module)) => { module.res().unwrap() @@ -3009,7 +2995,12 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { }; if result.base_res() == unqualified_result { let lint = lint::builtin::UNUSED_QUALIFICATIONS; - self.r.lint_buffer.buffer_lint(lint, id, path_span, "unnecessary qualification") + self.r.lint_buffer.buffer_lint( + lint, + finalize.node_id, + finalize.path_span, + "unnecessary qualification", + ) } } diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index a5243bf8ac3f8..3076cc1131700 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -3,7 +3,7 @@ use crate::late::lifetimes::{ElisionFailureInfo, LifetimeContext}; use crate::late::{AliasPossibility, LateResolutionVisitor, RibKind}; use crate::late::{LifetimeBinderKind, LifetimeRibKind}; use crate::path_names_to_string; -use crate::{Finalize, Module, ModuleKind, ModuleOrUniformRoot}; +use crate::{Module, ModuleKind, ModuleOrUniformRoot}; use crate::{PathResult, PathSource, Segment}; use rustc_ast::visit::FnKind; @@ -189,7 +189,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { (String::new(), "the crate root".to_string()) } else { let mod_path = &path[..path.len() - 1]; - let mod_prefix = match self.resolve_path(mod_path, Some(TypeNS), Finalize::No) { + let mod_prefix = match self.resolve_path(mod_path, Some(TypeNS), None) { PathResult::Module(ModuleOrUniformRoot::Module(module)) => module.res(), _ => None, } @@ -648,7 +648,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { if let crate::PathSource::TraitItem(_) = source { let mod_path = &path[..path.len() - 1]; if let PathResult::Module(ModuleOrUniformRoot::Module(module)) = - self.resolve_path(mod_path, None, Finalize::No) + self.resolve_path(mod_path, None, None) { let resolutions = self.r.resolutions(module).borrow(); let targets: Vec<_> = @@ -1362,7 +1362,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { // Search in module. let mod_path = &path[..path.len() - 1]; if let PathResult::Module(ModuleOrUniformRoot::Module(module)) = - self.resolve_path(mod_path, Some(TypeNS), Finalize::No) + self.resolve_path(mod_path, Some(TypeNS), None) { self.r.add_module_candidates(module, &mut names, &filter_fn); } diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index dbc4f337ad3b5..2e625fc1b4f7b 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -2044,42 +2044,27 @@ fn module_to_string(module: Module<'_>) -> Option { } #[derive(Copy, Clone, Debug)] -enum Finalize { - /// Do not issue the lint. - No, - - /// This lint applies to some arbitrary path; e.g., `impl ::foo::Bar`. - /// In this case, we can take the span of that path. - SimplePath(NodeId, Span), - - /// This lint comes from a `use` statement. In this case, what we - /// care about really is the *root* `use` statement; e.g., if we - /// have nested things like `use a::{b, c}`, we care about the - /// `use a` part. - UsePath { root_id: NodeId, root_span: Span, path_span: Span }, - - /// This is the "trait item" from a fully qualified path. For example, - /// we might be resolving `X::Y::Z` from a path like `::Z`. - /// The `path_span` is the span of the to the trait itself (`X::Y`). - QPathTrait { qpath_id: NodeId, qpath_span: Span, path_span: Span }, +struct Finalize { + /// Node ID for linting. + node_id: NodeId, + /// Span of the whole path or some its characteristic fragment. + /// E.g. span of `b` in `foo::{a, b, c}`, or full span for regular paths. + path_span: Span, + /// Span of the path start, suitable for prepending something to to it. + /// E.g. span of `foo` in `foo::{a, b, c}`, or full span for regular paths. + root_span: Span, + /// Whether to report privacy errors or silently return "no resolution" for them, + /// similarly to speculative resolution. + report_private: bool, } impl Finalize { - fn node_id_and_path_span(&self) -> Option<(NodeId, Span)> { - match *self { - Finalize::No => None, - Finalize::SimplePath(id, path_span) - | Finalize::UsePath { root_id: id, path_span, .. } - | Finalize::QPathTrait { qpath_id: id, path_span, .. } => Some((id, path_span)), - } - } - - fn node_id(&self) -> Option { - self.node_id_and_path_span().map(|(id, _)| id) + fn new(node_id: NodeId, path_span: Span) -> Finalize { + Finalize::with_root_span(node_id, path_span, path_span) } - fn path_span(&self) -> Option { - self.node_id_and_path_span().map(|(_, path_span)| path_span) + fn with_root_span(node_id: NodeId, path_span: Span, root_span: Span) -> Finalize { + Finalize { node_id, path_span, root_span, report_private: true } } } diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 01f0b11f1ac3b..19a9c1b99fc47 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -604,7 +604,6 @@ impl<'a> Resolver<'a> { parent_scope, None, force, - false, None, ); if let Err(Determinacy::Undetermined) = binding { @@ -673,7 +672,7 @@ impl<'a> Resolver<'a> { &path, Some(MacroNS), &parent_scope, - Finalize::SimplePath(ast::CRATE_NODE_ID, path_span), + Some(Finalize::new(ast::CRATE_NODE_ID, path_span)), None, ) { PathResult::NonModule(path_res) if path_res.unresolved_segments() == 0 => { @@ -708,9 +707,8 @@ impl<'a> Resolver<'a> { ident, ScopeSet::Macro(kind), &parent_scope, - Some(ident.span), + Some(Finalize::new(ast::CRATE_NODE_ID, ident.span)), true, - false, None, ) { Ok(binding) => { @@ -751,9 +749,8 @@ impl<'a> Resolver<'a> { ident, ScopeSet::Macro(MacroKind::Attr), &parent_scope, - Some(ident.span), + Some(Finalize::new(ast::CRATE_NODE_ID, ident.span)), true, - false, None, ); }