1
Fork 0

Rollup merge of #135826 - yotamofek:resolve-cleanups4, r=petrochenkov

Misc. `rustc_resolve` cleanups

Hopefully this PR should make `rustc_resolve` a bit cleaner.
Each commit here stands on its own. I tried to only include changes that are easy to review, and are a clear improvement. (but I'll be happy to revert any changes that turn out to be more controversial than I'd thought)

Best viewed with whitespace ignored 😁 (especially [these two commits](a93616acf3..ae87d005bc?diff=unified&w=1))
This commit is contained in:
Matthias Krüger 2025-01-22 20:37:27 +01:00 committed by GitHub
commit 41885a4858
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 564 additions and 608 deletions

View file

@ -645,11 +645,11 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
let self_spans = items let self_spans = items
.iter() .iter()
.filter_map(|(use_tree, _)| { .filter_map(|(use_tree, _)| {
if let ast::UseTreeKind::Simple(..) = use_tree.kind { if let ast::UseTreeKind::Simple(..) = use_tree.kind
if use_tree.ident().name == kw::SelfLower { && use_tree.ident().name == kw::SelfLower
{
return Some(use_tree.span); return Some(use_tree.span);
} }
}
None None
}) })
@ -947,12 +947,13 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
let imported_binding = self.r.import(binding, import); let imported_binding = self.r.import(binding, import);
if parent == self.r.graph_root { if parent == self.r.graph_root {
let ident = ident.normalize_to_macros_2_0(); let ident = ident.normalize_to_macros_2_0();
if let Some(entry) = self.r.extern_prelude.get(&ident) { if let Some(entry) = self.r.extern_prelude.get(&ident)
if expansion != LocalExpnId::ROOT && orig_name.is_some() && !entry.is_import() { && expansion != LocalExpnId::ROOT
&& orig_name.is_some()
&& !entry.is_import()
{
self.r.dcx().emit_err( self.r.dcx().emit_err(
errors::MacroExpandedExternCrateCannotShadowExternArguments { errors::MacroExpandedExternCrateCannotShadowExternArguments { span: item.span },
span: item.span,
},
); );
// `return` is intended to discard this binding because it's an // `return` is intended to discard this binding because it's an
// unregistered ambiguity error which would result in a panic // unregistered ambiguity error which would result in a panic
@ -960,7 +961,6 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
// more details: https://github.com/rust-lang/rust/pull/111761 // more details: https://github.com/rust-lang/rust/pull/111761
return; return;
} }
}
let entry = self let entry = self
.r .r
.extern_prelude .extern_prelude
@ -1040,11 +1040,11 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
span: item.span, span: item.span,
}); });
} }
if let ItemKind::ExternCrate(Some(orig_name)) = item.kind { if let ItemKind::ExternCrate(Some(orig_name)) = item.kind
if orig_name == kw::SelfLower { && orig_name == kw::SelfLower
{
self.r.dcx().emit_err(errors::MacroUseExternCrateSelf { span: attr.span }); self.r.dcx().emit_err(errors::MacroUseExternCrateSelf { span: attr.span });
} }
}
let ill_formed = |span| { let ill_formed = |span| {
self.r.dcx().emit_err(errors::BadMacroImport { span }); self.r.dcx().emit_err(errors::BadMacroImport { span });
}; };
@ -1179,15 +1179,13 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
return Some((MacroKind::Bang, item.ident, item.span)); return Some((MacroKind::Bang, item.ident, item.span));
} else if ast::attr::contains_name(&item.attrs, sym::proc_macro_attribute) { } else if ast::attr::contains_name(&item.attrs, sym::proc_macro_attribute) {
return Some((MacroKind::Attr, item.ident, item.span)); return Some((MacroKind::Attr, item.ident, item.span));
} else if let Some(attr) = ast::attr::find_by_name(&item.attrs, sym::proc_macro_derive) { } else if let Some(attr) = ast::attr::find_by_name(&item.attrs, sym::proc_macro_derive)
if let Some(meta_item_inner) = && let Some(meta_item_inner) =
attr.meta_item_list().and_then(|list| list.get(0).cloned()) attr.meta_item_list().and_then(|list| list.get(0).cloned())
&& let Some(ident) = meta_item_inner.ident()
{ {
if let Some(ident) = meta_item_inner.ident() {
return Some((MacroKind::Derive, ident, ident.span)); return Some((MacroKind::Derive, ident, ident.span));
} }
}
}
None None
} }

View file

@ -225,11 +225,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
let (name, span) = let (name, span) =
(ident.name, self.tcx.sess.source_map().guess_head_span(new_binding.span)); (ident.name, self.tcx.sess.source_map().guess_head_span(new_binding.span));
if let Some(s) = self.name_already_seen.get(&name) { if self.name_already_seen.get(&name) == Some(&span) {
if s == &span {
return; return;
} }
}
let old_kind = match (ns, old_binding.module()) { let old_kind = match (ns, old_binding.module()) {
(ValueNS, _) => "value", (ValueNS, _) => "value",
@ -380,22 +378,16 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
suggestion = Some(format!("self as {suggested_name}")) suggestion = Some(format!("self as {suggested_name}"))
} }
ImportKind::Single { source, .. } => { ImportKind::Single { source, .. } => {
if let Some(pos) = if let Some(pos) = source.span.hi().0.checked_sub(binding_span.lo().0)
source.span.hi().0.checked_sub(binding_span.lo().0).map(|pos| pos as usize) && let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(binding_span)
&& pos as usize <= snippet.len()
{ {
if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(binding_span) { span = binding_span.with_lo(binding_span.lo() + BytePos(pos)).with_hi(
if pos <= snippet.len() { binding_span.hi() - BytePos(if snippet.ends_with(';') { 1 } else { 0 }),
span = binding_span
.with_lo(binding_span.lo() + BytePos(pos as u32))
.with_hi(
binding_span.hi()
- BytePos(if snippet.ends_with(';') { 1 } else { 0 }),
); );
suggestion = Some(format!(" as {suggested_name}")); suggestion = Some(format!(" as {suggested_name}"));
} }
} }
}
}
ImportKind::ExternCrate { source, target, .. } => { ImportKind::ExternCrate { source, target, .. } => {
suggestion = Some(format!( suggestion = Some(format!(
"extern crate {} as {};", "extern crate {} as {};",
@ -510,14 +502,13 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
// If the first element of our path was actually resolved to an // If the first element of our path was actually resolved to an
// `ExternCrate` (also used for `crate::...`) then no need to issue a // `ExternCrate` (also used for `crate::...`) then no need to issue a
// warning, this looks all good! // warning, this looks all good!
if let Some(binding) = second_binding { if let Some(binding) = second_binding
if let NameBindingKind::Import { import, .. } = binding.kind { && let NameBindingKind::Import { import, .. } = binding.kind
// Careful: we still want to rewrite paths from renamed extern crates. // Careful: we still want to rewrite paths from renamed extern crates.
if let ImportKind::ExternCrate { source: None, .. } = import.kind { && let ImportKind::ExternCrate { source: None, .. } = import.kind
{
return; return;
} }
}
}
let diag = BuiltinLintDiag::AbsPathWithModule(root_span); let diag = BuiltinLintDiag::AbsPathWithModule(root_span);
self.lint_buffer.buffer_lint( self.lint_buffer.buffer_lint(
@ -1047,14 +1038,16 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
if filter_fn(res) { if filter_fn(res) {
for derive in parent_scope.derives { for derive in parent_scope.derives {
let parent_scope = &ParentScope { derives: &[], ..*parent_scope }; let parent_scope = &ParentScope { derives: &[], ..*parent_scope };
if let Ok((Some(ext), _)) = this.resolve_macro_path( let Ok((Some(ext), _)) = this.resolve_macro_path(
derive, derive,
Some(MacroKind::Derive), Some(MacroKind::Derive),
parent_scope, parent_scope,
false, false,
false, false,
None, None,
) { ) else {
continue;
};
suggestions.extend( suggestions.extend(
ext.helper_attrs ext.helper_attrs
.iter() .iter()
@ -1063,7 +1056,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
} }
} }
} }
}
Scope::MacroRules(macro_rules_scope) => { Scope::MacroRules(macro_rules_scope) => {
if let MacroRulesScope::Binding(macro_rules_binding) = macro_rules_scope.get() { if let MacroRulesScope::Binding(macro_rules_binding) = macro_rules_scope.get() {
let res = macro_rules_binding.binding.res(); let res = macro_rules_binding.binding.res();
@ -1215,13 +1207,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
} }
// #90113: Do not count an inaccessible reexported item as a candidate. // #90113: Do not count an inaccessible reexported item as a candidate.
if let NameBindingKind::Import { binding, .. } = name_binding.kind { if let NameBindingKind::Import { binding, .. } = name_binding.kind
if this.is_accessible_from(binding.vis, parent_scope.module) && this.is_accessible_from(binding.vis, parent_scope.module)
&& !this.is_accessible_from(name_binding.vis, parent_scope.module) && !this.is_accessible_from(name_binding.vis, parent_scope.module)
{ {
return; return;
} }
}
let res = name_binding.res(); let res = name_binding.res();
let did = match res { let did = match res {
@ -1253,15 +1244,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
segms.push(ast::PathSegment::from_ident(ident)); segms.push(ast::PathSegment::from_ident(ident));
let path = Path { span: name_binding.span, segments: segms, tokens: None }; let path = Path { span: name_binding.span, segments: segms, tokens: None };
if child_accessible { if child_accessible
// Remove invisible match if exists // Remove invisible match if exists
if let Some(idx) = candidates && let Some(idx) = candidates
.iter() .iter()
.position(|v: &ImportSuggestion| v.did == did && !v.accessible) .position(|v: &ImportSuggestion| v.did == did && !v.accessible)
{ {
candidates.remove(idx); candidates.remove(idx);
} }
}
if candidates.iter().all(|v: &ImportSuggestion| v.did != did) { if candidates.iter().all(|v: &ImportSuggestion| v.did != did) {
// See if we're recommending TryFrom, TryInto, or FromIterator and add // See if we're recommending TryFrom, TryInto, or FromIterator and add
@ -1373,8 +1363,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
// otherwise cause duplicate suggestions. // otherwise cause duplicate suggestions.
continue; continue;
} }
let crate_id = self.crate_loader(|c| c.maybe_process_path_extern(ident.name)); let Some(crate_id) = self.crate_loader(|c| c.maybe_process_path_extern(ident.name))
if let Some(crate_id) = crate_id { else {
continue;
};
let crate_def_id = crate_id.as_def_id(); let crate_def_id = crate_id.as_def_id();
let crate_root = self.expect_module(crate_def_id); let crate_root = self.expect_module(crate_def_id);
@ -1416,7 +1409,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
)); ));
} }
} }
}
suggestions suggestions
} }
@ -1511,7 +1503,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
}); });
} }
for ns in [Namespace::MacroNS, Namespace::TypeNS, Namespace::ValueNS] { for ns in [Namespace::MacroNS, Namespace::TypeNS, Namespace::ValueNS] {
if let Ok(binding) = self.early_resolve_ident_in_lexical_scope( let Ok(binding) = self.early_resolve_ident_in_lexical_scope(
ident, ident,
ScopeSet::All(ns), ScopeSet::All(ns),
parent_scope, parent_scope,
@ -1519,11 +1511,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
false, false,
None, None,
None, None,
) { ) else {
continue;
};
let desc = match binding.res() { let desc = match binding.res() {
Res::Def(DefKind::Macro(MacroKind::Bang), _) => { Res::Def(DefKind::Macro(MacroKind::Bang), _) => "a function-like macro".to_string(),
"a function-like macro".to_string()
}
Res::Def(DefKind::Macro(MacroKind::Attr), _) | Res::NonMacroAttr(..) => { Res::Def(DefKind::Macro(MacroKind::Attr), _) | Res::NonMacroAttr(..) => {
format!("an attribute: `#[{ident}]`") format!("an attribute: `#[{ident}]`")
} }
@ -1545,8 +1538,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
macro_kind.descr_expected(), macro_kind.descr_expected(),
), ),
}; };
if let crate::NameBindingKind::Import { import, .. } = binding.kind { if let crate::NameBindingKind::Import { import, .. } = binding.kind
if !import.span.is_dummy() { && !import.span.is_dummy()
{
let note = errors::IdentImporterHereButItIsDesc { let note = errors::IdentImporterHereButItIsDesc {
span: import.span, span: import.span,
imported_ident: ident, imported_ident: ident,
@ -1558,7 +1552,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
self.record_use(ident, binding, Used::Other); self.record_use(ident, binding, Used::Other);
return; return;
} }
}
let note = errors::IdentInScopeButItIsDesc { let note = errors::IdentInScopeButItIsDesc {
imported_ident: ident, imported_ident: ident,
imported_ident_desc: &desc, imported_ident_desc: &desc,
@ -1567,7 +1560,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
return; return;
} }
} }
}
pub(crate) fn add_typo_suggestion( pub(crate) fn add_typo_suggestion(
&self, &self,
@ -1749,15 +1741,16 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
/// If the binding refers to a tuple struct constructor with fields, /// If the binding refers to a tuple struct constructor with fields,
/// returns the span of its fields. /// returns the span of its fields.
fn ctor_fields_span(&self, binding: NameBinding<'_>) -> Option<Span> { fn ctor_fields_span(&self, binding: NameBinding<'_>) -> Option<Span> {
if let NameBindingKind::Res(Res::Def( let NameBindingKind::Res(Res::Def(
DefKind::Ctor(CtorOf::Struct, CtorKind::Fn), DefKind::Ctor(CtorOf::Struct, CtorKind::Fn),
ctor_def_id, ctor_def_id,
)) = binding.kind )) = binding.kind
{ else {
return None;
};
let def_id = self.tcx.parent(ctor_def_id); let def_id = self.tcx.parent(ctor_def_id);
return self.field_idents(def_id)?.iter().map(|&f| f.span).reduce(Span::to); // None for `struct Foo()` self.field_idents(def_id)?.iter().map(|&f| f.span).reduce(Span::to) // None for `struct Foo()`
}
None
} }
fn report_privacy_error(&mut self, privacy_error: &PrivacyError<'ra>) { fn report_privacy_error(&mut self, privacy_error: &PrivacyError<'ra>) {
@ -1983,10 +1976,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
.collect::<Vec<_>>(); .collect::<Vec<_>>();
candidates.sort(); candidates.sort();
candidates.dedup(); candidates.dedup();
match find_best_match_for_name(&candidates, ident, None) { find_best_match_for_name(&candidates, ident, None).filter(|sugg| *sugg != ident)
Some(sugg) if sugg == ident => None,
sugg => sugg,
}
} }
pub(crate) fn report_path_resolution_error( pub(crate) fn report_path_resolution_error(
@ -2410,7 +2400,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
let binding_key = BindingKey::new(ident, MacroNS); let binding_key = BindingKey::new(ident, MacroNS);
let resolution = resolutions.get(&binding_key)?; let resolution = resolutions.get(&binding_key)?;
let binding = resolution.borrow().binding()?; let binding = resolution.borrow().binding()?;
if let Res::Def(DefKind::Macro(MacroKind::Bang), _) = binding.res() { let Res::Def(DefKind::Macro(MacroKind::Bang), _) = binding.res() else {
return None;
};
let module_name = crate_module.kind.name().unwrap(); let module_name = crate_module.kind.name().unwrap();
let import_snippet = match import.kind { let import_snippet = match import.kind {
ImportKind::Single { source, target, .. } if source != target => { ImportKind::Single { source, target, .. } if source != target => {
@ -2436,7 +2428,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
debug!(found_closing_brace, ?binding_span); debug!(found_closing_brace, ?binding_span);
let mut removal_span = binding_span; let mut removal_span = binding_span;
if found_closing_brace {
// If the binding span ended with a closing brace, as in the below example: // If the binding span ended with a closing brace, as in the below example:
// ie. `use a::b::{c, d};` // ie. `use a::b::{c, d};`
// ^ // ^
@ -2444,13 +2436,13 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
// binding's trailing comma. // binding's trailing comma.
// ie. `use a::b::{c, d};` // ie. `use a::b::{c, d};`
// ^^^ // ^^^
if let Some(previous_span) = if found_closing_brace
&& let Some(previous_span) =
extend_span_to_previous_binding(self.tcx.sess, binding_span) extend_span_to_previous_binding(self.tcx.sess, binding_span)
{ {
debug!(?previous_span); debug!(?previous_span);
removal_span = removal_span.with_lo(previous_span.lo()); removal_span = removal_span.with_lo(previous_span.lo());
} }
}
debug!(?removal_span); debug!(?removal_span);
// Remove the `removal_span`. // Remove the `removal_span`.
@ -2462,11 +2454,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
// ^^^^^^^^^ // ^^^^^^^^^
// or `use a::{b, c, d}};` // or `use a::{b, c, d}};`
// ^^^^^^^^^^^ // ^^^^^^^^^^^
let (has_nested, after_crate_name) = find_span_immediately_after_crate_name( let (has_nested, after_crate_name) =
self.tcx.sess, find_span_immediately_after_crate_name(self.tcx.sess, module_name, import.use_span);
module_name,
import.use_span,
);
debug!(has_nested, ?after_crate_name); debug!(has_nested, ?after_crate_name);
let source_map = self.tcx.sess.source_map(); let source_map = self.tcx.sess.source_map();
@ -2496,8 +2485,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
// Add a `};` to the end if nested, matching the `{` added at the start. // Add a `};` to the end if nested, matching the `{` added at the start.
if !has_nested { if !has_nested {
corrections corrections.push((source_map.end_point(after_crate_name), "};".to_string()));
.push((source_map.end_point(after_crate_name), "};".to_string()));
} }
} else { } else {
// If the root import is module-relative, add the import separately // If the root import is module-relative, add the import separately
@ -2513,12 +2501,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
String::from("a macro with this name exists at the root of the crate"), String::from("a macro with this name exists at the root of the crate"),
Applicability::MaybeIncorrect, Applicability::MaybeIncorrect,
)); ));
Some((suggestion, Some("this could be because a macro annotated with `#[macro_export]` will be exported \ Some((
suggestion,
Some(
"this could be because a macro annotated with `#[macro_export]` will be exported \
at the root of the crate instead of the module where it is defined" at the root of the crate instead of the module where it is defined"
.to_string()))) .to_string(),
} else { ),
None ))
}
} }
/// Finds a cfg-ed out item inside `module` with the matching name. /// Finds a cfg-ed out item inside `module` with the matching name.
@ -3042,7 +3032,6 @@ impl<'tcx> visit::Visitor<'tcx> for UsePlacementFinder {
self.first_legal_span = Some(inject); self.first_legal_span = Some(inject);
} }
self.first_use_span = search_for_any_use_in_items(&c.items); self.first_use_span = search_for_any_use_in_items(&c.items);
return;
} else { } else {
visit::walk_crate(self, c); visit::walk_crate(self, c);
} }
@ -3056,7 +3045,6 @@ impl<'tcx> visit::Visitor<'tcx> for UsePlacementFinder {
self.first_legal_span = Some(inject); self.first_legal_span = Some(inject);
} }
self.first_use_span = search_for_any_use_in_items(items); self.first_use_span = search_for_any_use_in_items(items);
return;
} }
} else { } else {
visit::walk_item(self, item); visit::walk_item(self, item);
@ -3066,8 +3054,9 @@ impl<'tcx> visit::Visitor<'tcx> for UsePlacementFinder {
fn search_for_any_use_in_items(items: &[P<ast::Item>]) -> Option<Span> { fn search_for_any_use_in_items(items: &[P<ast::Item>]) -> Option<Span> {
for item in items { for item in items {
if let ItemKind::Use(..) = item.kind { if let ItemKind::Use(..) = item.kind
if is_span_suitable_for_use_injection(item.span) { && is_span_suitable_for_use_injection(item.span)
{
let mut lo = item.span.lo(); let mut lo = item.span.lo();
for attr in &item.attrs { for attr in &item.attrs {
if attr.span.eq_ctxt(item.span) { if attr.span.eq_ctxt(item.span) {
@ -3077,7 +3066,6 @@ fn search_for_any_use_in_items(items: &[P<ast::Item>]) -> Option<Span> {
return Some(Span::new(lo, lo, item.span.ctxt(), item.span.parent())); return Some(Span::new(lo, lo, item.span.ctxt(), item.span.parent()));
} }
} }
}
None None
} }

View file

@ -118,7 +118,9 @@ impl<'a, 'ra, 'tcx> EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> {
let resolutions = self.r.resolutions(module); let resolutions = self.r.resolutions(module);
for (_, name_resolution) in resolutions.borrow().iter() { for (_, name_resolution) in resolutions.borrow().iter() {
if let Some(mut binding) = name_resolution.borrow().binding() { let Some(mut binding) = name_resolution.borrow().binding() else {
continue;
};
// Set the given effective visibility level to `Level::Direct` and // Set the given effective visibility level to `Level::Direct` and
// sets the rest of the `use` chain to `Level::Reexported` until // sets the rest of the `use` chain to `Level::Reexported` until
// we hit the actual exported item. // we hit the actual exported item.
@ -151,7 +153,6 @@ impl<'a, 'ra, 'tcx> EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> {
} }
} }
} }
}
fn effective_vis_or_private(&mut self, parent_id: ParentId<'ra>) -> EffectiveVisibility { fn effective_vis_or_private(&mut self, parent_id: ParentId<'ra>) -> EffectiveVisibility {
// Private nodes are only added to the table for caching, they could be added or removed at // Private nodes are only added to the table for caching, they could be added or removed at

View file

@ -246,14 +246,15 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
// ---- end // ---- end
// ``` // ```
// So we have to fall back to the module's parent during lexical resolution in this case. // So we have to fall back to the module's parent during lexical resolution in this case.
if derive_fallback_lint_id.is_some() { if derive_fallback_lint_id.is_some()
if let Some(parent) = module.parent { && let Some(parent) = module.parent
// Inner module is inside the macro, parent module is outside of the macro. // Inner module is inside the macro
if module.expansion != parent.expansion && module.expansion != parent.expansion
// Parent module is outside of the macro
&& module.expansion.is_descendant_of(parent.expansion) && module.expansion.is_descendant_of(parent.expansion)
{
// The macro is a proc macro derive // The macro is a proc macro derive
if let Some(def_id) = module.expansion.expn_data().macro_def_id { && let Some(def_id) = module.expansion.expn_data().macro_def_id
{
let ext = &self.get_macro_by_def_id(def_id).ext; let ext = &self.get_macro_by_def_id(def_id).ext;
if ext.builtin_name.is_none() if ext.builtin_name.is_none()
&& ext.macro_kind() == MacroKind::Derive && ext.macro_kind() == MacroKind::Derive
@ -262,9 +263,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
return Some((parent, derive_fallback_lint_id)); return Some((parent, derive_fallback_lint_id));
} }
} }
}
}
}
None None
} }
@ -593,8 +591,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
}, },
Scope::StdLibPrelude => { Scope::StdLibPrelude => {
let mut result = Err(Determinacy::Determined); let mut result = Err(Determinacy::Determined);
if let Some(prelude) = this.prelude { if let Some(prelude) = this.prelude
if let Ok(binding) = this.resolve_ident_in_module_unadjusted( && let Ok(binding) = this.resolve_ident_in_module_unadjusted(
ModuleOrUniformRoot::Module(prelude), ModuleOrUniformRoot::Module(prelude),
ident, ident,
ns, ns,
@ -603,14 +601,13 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
None, None,
ignore_binding, ignore_binding,
ignore_import, ignore_import,
) { )
if matches!(use_prelude, UsePrelude::Yes) && (matches!(use_prelude, UsePrelude::Yes)
|| this.is_builtin_macro(binding.res()) || this.is_builtin_macro(binding.res()))
{ {
result = Ok((binding, Flags::MISC_FROM_PRELUDE)); result = Ok((binding, Flags::MISC_FROM_PRELUDE));
} }
}
}
result result
} }
Scope::BuiltinTypes => match this.builtin_types_bindings.get(&ident.name) { Scope::BuiltinTypes => match this.builtin_types_bindings.get(&ident.name) {
@ -939,11 +936,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
}; };
// Items and single imports are not shadowable, if we have one, then it's determined. // Items and single imports are not shadowable, if we have one, then it's determined.
if let Some(binding) = binding { if let Some(binding) = binding
if !binding.is_glob_import() { && !binding.is_glob_import()
{
return check_usable(self, binding); return check_usable(self, binding);
} }
}
// --- From now on we either have a glob resolution or no resolution. --- // --- From now on we either have a glob resolution or no resolution. ---
@ -1437,14 +1434,13 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
for (segment_idx, &Segment { ident, id, .. }) in path.iter().enumerate() { for (segment_idx, &Segment { ident, id, .. }) in path.iter().enumerate() {
debug!("resolve_path ident {} {:?} {:?}", segment_idx, ident, id); debug!("resolve_path ident {} {:?} {:?}", segment_idx, ident, id);
let record_segment_res = |this: &mut Self, res| { let record_segment_res = |this: &mut Self, res| {
if finalize.is_some() { if finalize.is_some()
if let Some(id) = id { && let Some(id) = id
if !this.partial_res_map.contains_key(&id) { && !this.partial_res_map.contains_key(&id)
{
assert!(id != ast::DUMMY_NODE_ID, "Trying to resolve dummy id"); assert!(id != ast::DUMMY_NODE_ID, "Trying to resolve dummy id");
this.record_partial_res(id, PartialRes::new(res)); this.record_partial_res(id, PartialRes::new(res));
} }
}
}
}; };
let is_last = segment_idx + 1 == path.len(); let is_last = segment_idx + 1 == path.len();
@ -1463,14 +1459,13 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
_ => None, _ => None,
}, },
}; };
if let Some(self_module) = self_module { if let Some(self_module) = self_module
if let Some(parent) = self_module.parent { && let Some(parent) = self_module.parent
module = Some(ModuleOrUniformRoot::Module( {
self.resolve_self(&mut ctxt, parent), module =
)); Some(ModuleOrUniformRoot::Module(self.resolve_self(&mut ctxt, parent)));
continue; continue;
} }
}
return PathResult::failed( return PathResult::failed(
ident, ident,
false, false,
@ -1644,14 +1639,15 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
} }
Err(Undetermined) => return PathResult::Indeterminate, Err(Undetermined) => return PathResult::Indeterminate,
Err(Determined) => { Err(Determined) => {
if let Some(ModuleOrUniformRoot::Module(module)) = module { if let Some(ModuleOrUniformRoot::Module(module)) = module
if opt_ns.is_some() && !module.is_normal() { && opt_ns.is_some()
&& !module.is_normal()
{
return PathResult::NonModule(PartialRes::with_unresolved_segments( return PathResult::NonModule(PartialRes::with_unresolved_segments(
module.res().unwrap(), module.res().unwrap(),
path.len() - segment_idx, path.len() - segment_idx,
)); ));
} }
}
return PathResult::failed( return PathResult::failed(
ident, ident,

View file

@ -287,13 +287,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
binding.vis binding.vis
}; };
if let ImportKind::Glob { ref max_vis, .. } = import.kind { if let ImportKind::Glob { ref max_vis, .. } = import.kind
if vis == import_vis && (vis == import_vis
|| max_vis.get().is_none_or(|max_vis| vis.is_at_least(max_vis, self.tcx)) || max_vis.get().is_none_or(|max_vis| vis.is_at_least(max_vis, self.tcx)))
{ {
max_vis.set(Some(vis.expect_local())) max_vis.set(Some(vis.expect_local()))
} }
}
self.arenas.alloc_name_binding(NameBindingData { self.arenas.alloc_name_binding(NameBindingData {
kind: NameBindingKind::Import { binding, import }, kind: NameBindingKind::Import { binding, import },
@ -543,21 +542,19 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
// resolution for it so that later resolve stages won't complain. // resolution for it so that later resolve stages won't complain.
self.import_dummy_binding(*import, is_indeterminate); self.import_dummy_binding(*import, is_indeterminate);
if let Some(err) = unresolved_import_error { let Some(err) = unresolved_import_error else { continue };
glob_error |= import.is_glob(); glob_error |= import.is_glob();
if let ImportKind::Single { source, ref source_bindings, .. } = import.kind { if let ImportKind::Single { source, ref source_bindings, .. } = import.kind
if source.name == kw::SelfLower { && source.name == kw::SelfLower
// Silence `unresolved import` error if E0429 is already emitted // Silence `unresolved import` error if E0429 is already emitted
if let Err(Determined) = source_bindings.value_ns.get() { && let Err(Determined) = source_bindings.value_ns.get()
{
continue; continue;
} }
}
}
if prev_root_id != NodeId::ZERO if prev_root_id != NodeId::ZERO && prev_root_id != import.root_id && !errors.is_empty()
&& prev_root_id != import.root_id
&& !errors.is_empty()
{ {
// In the case of a new import line, throw a diagnostic message // In the case of a new import line, throw a diagnostic message
// for the previous line. // for the previous line.
@ -569,7 +566,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
prev_root_id = import.root_id; prev_root_id = import.root_id;
} }
} }
}
if !errors.is_empty() { if !errors.is_empty() {
self.throw_unresolved_import_error(errors, glob_error); self.throw_unresolved_import_error(errors, glob_error);
@ -609,7 +605,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
for (key, resolution) in self.resolutions(*module).borrow().iter() { for (key, resolution) in self.resolutions(*module).borrow().iter() {
let resolution = resolution.borrow(); let resolution = resolution.borrow();
if let Some(binding) = resolution.binding { let Some(binding) = resolution.binding else { continue };
if let NameBindingKind::Import { import, .. } = binding.kind if let NameBindingKind::Import { import, .. } = binding.kind
&& let Some((amb_binding, _)) = binding.ambiguity && let Some((amb_binding, _)) = binding.ambiguity
&& binding.res() != Res::Err && binding.res() != Res::Err
@ -666,7 +663,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
} }
} }
} }
}
fn throw_unresolved_import_error( fn throw_unresolved_import_error(
&mut self, &mut self,
@ -1006,14 +1002,13 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
self.lint_if_path_starts_with_module(Some(finalize), &full_path, None); self.lint_if_path_starts_with_module(Some(finalize), &full_path, None);
} }
if let ModuleOrUniformRoot::Module(module) = module { if let ModuleOrUniformRoot::Module(module) = module
if module == import.parent_scope.module { && module == import.parent_scope.module
{
// Importing a module into itself is not allowed. // Importing a module into itself is not allowed.
return Some(UnresolvedImportError { return Some(UnresolvedImportError {
span: import.span, span: import.span,
label: Some(String::from( label: Some(String::from("cannot glob-import a module into itself")),
"cannot glob-import a module into itself",
)),
note: None, note: None,
suggestion: None, suggestion: None,
candidates: None, candidates: None,
@ -1021,7 +1016,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
module: None, module: None,
}); });
} }
}
if !is_prelude if !is_prelude
&& let Some(max_vis) = max_vis.get() && let Some(max_vis) = max_vis.get()
&& !max_vis.is_at_least(import.vis, self.tcx) && !max_vis.is_at_least(import.vis, self.tcx)
@ -1081,8 +1075,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
// Consistency checks, analogous to `finalize_macro_resolutions`. // Consistency checks, analogous to `finalize_macro_resolutions`.
let initial_res = source_bindings[ns].get().map(|initial_binding| { let initial_res = source_bindings[ns].get().map(|initial_binding| {
all_ns_err = false; all_ns_err = false;
if let Some(target_binding) = target_bindings[ns].get() { if let Some(target_binding) = target_bindings[ns].get()
if target.name == kw::Underscore && target.name == kw::Underscore
&& initial_binding.is_extern_crate() && initial_binding.is_extern_crate()
&& !initial_binding.is_import() && !initial_binding.is_import()
{ {
@ -1093,7 +1087,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
}; };
this.record_use(ident, target_binding, used); this.record_use(ident, target_binding, used);
} }
}
initial_binding.res() initial_binding.res()
}); });
let res = binding.res(); let res = binding.res();
@ -1247,18 +1240,20 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
let mut any_successful_reexport = false; let mut any_successful_reexport = false;
let mut crate_private_reexport = false; let mut crate_private_reexport = false;
self.per_ns(|this, ns| { self.per_ns(|this, ns| {
if let Ok(binding) = source_bindings[ns].get() { let Ok(binding) = source_bindings[ns].get() else {
return;
};
if !binding.vis.is_at_least(import.vis, this.tcx) { if !binding.vis.is_at_least(import.vis, this.tcx) {
reexport_error = Some((ns, binding)); reexport_error = Some((ns, binding));
if let ty::Visibility::Restricted(binding_def_id) = binding.vis { if let ty::Visibility::Restricted(binding_def_id) = binding.vis
if binding_def_id.is_top_level_module() { && binding_def_id.is_top_level_module()
{
crate_private_reexport = true; crate_private_reexport = true;
} }
}
} else { } else {
any_successful_reexport = true; any_successful_reexport = true;
} }
}
}); });
// All namespaces must be re-exported with extra visibility for an error to occur. // All namespaces must be re-exported with extra visibility for an error to occur.
@ -1474,7 +1469,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
// Since import resolution is finished, globs will not define any more names. // Since import resolution is finished, globs will not define any more names.
*module.globs.borrow_mut() = Vec::new(); *module.globs.borrow_mut() = Vec::new();
if let Some(def_id) = module.opt_def_id() { let Some(def_id) = module.opt_def_id() else { return };
let mut children = Vec::new(); let mut children = Vec::new();
module.for_each_child(self, |this, ident, _, binding| { module.for_each_child(self, |this, ident, _, binding| {
@ -1497,7 +1493,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
self.module_children.insert(def_id.expect_local(), children); self.module_children.insert(def_id.expect_local(), children);
} }
} }
}
} }
fn import_path_to_string(names: &[Ident], import_kind: &ImportKind<'_>, span: Span) -> String { fn import_path_to_string(names: &[Ident], import_kind: &ImportKind<'_>, span: Span) -> String {

View file

@ -468,16 +468,12 @@ impl<'a> PathSource<'a> {
{ {
"external crate" "external crate"
} }
ExprKind::Path(_, path) => { ExprKind::Path(_, path)
let mut msg = "function"; if let Some(segment) = path.segments.last()
if let Some(segment) = path.segments.iter().last() { && let Some(c) = segment.ident.to_string().chars().next()
if let Some(c) = segment.ident.to_string().chars().next() { && c.is_uppercase() =>
if c.is_uppercase() { {
msg = "function, tuple struct or tuple variant"; "function, tuple struct or tuple variant"
}
}
}
msg
} }
_ => "function", _ => "function",
}, },
@ -1182,10 +1178,11 @@ impl<'ra: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'r
// namespace first, and if that fails we try again in the value namespace. If // namespace first, and if that fails we try again in the value namespace. If
// resolution in the value namespace succeeds, we have an generic const argument on // resolution in the value namespace succeeds, we have an generic const argument on
// our hands. // our hands.
if let TyKind::Path(None, ref path) = ty.kind { if let TyKind::Path(None, ref path) = ty.kind
// We cannot disambiguate multi-segment paths right now as that requires type // We cannot disambiguate multi-segment paths right now as that requires type
// checking. // checking.
if path.is_potential_trivial_const_arg() { && path.is_potential_trivial_const_arg()
{
let mut check_ns = |ns| { let mut check_ns = |ns| {
self.maybe_resolve_ident_in_lexical_scope(path.segments[0].ident, ns) self.maybe_resolve_ident_in_lexical_scope(path.segments[0].ident, ns)
.is_some() .is_some()
@ -1195,12 +1192,7 @@ impl<'ra: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'r
true, true,
AnonConstKind::ConstArg(IsRepeatExpr::No), AnonConstKind::ConstArg(IsRepeatExpr::No),
|this| { |this| {
this.smart_resolve_path( this.smart_resolve_path(ty.id, &None, path, PathSource::Expr(None));
ty.id,
&None,
path,
PathSource::Expr(None),
);
this.visit_path(path, ty.id); this.visit_path(path, ty.id);
}, },
); );
@ -1209,7 +1201,6 @@ impl<'ra: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'r
return; return;
} }
} }
}
self.visit_ty(ty); self.visit_ty(ty);
} }
@ -1243,7 +1234,10 @@ impl<'ra: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'r
} }
fn visit_path_segment(&mut self, path_segment: &'ast PathSegment) { fn visit_path_segment(&mut self, path_segment: &'ast PathSegment) {
if let Some(ref args) = path_segment.args { let Some(ref args) = path_segment.args else {
return;
};
match &**args { match &**args {
GenericArgs::AngleBracketed(..) => visit::walk_generic_args(self, args), GenericArgs::AngleBracketed(..) => visit::walk_generic_args(self, args),
GenericArgs::Parenthesized(p_args) => { GenericArgs::Parenthesized(p_args) => {
@ -1292,7 +1286,6 @@ impl<'ra: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'r
GenericArgs::ParenthesizedElided(_) => {} GenericArgs::ParenthesizedElided(_) => {}
} }
} }
}
fn visit_where_predicate(&mut self, p: &'ast WherePredicate) { fn visit_where_predicate(&mut self, p: &'ast WherePredicate) {
debug!("visit_where_predicate {:?}", p); debug!("visit_where_predicate {:?}", p);
@ -1735,13 +1728,8 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
} }
let normalized_ident = ident.normalize_to_macros_2_0(); let normalized_ident = ident.normalize_to_macros_2_0();
let mut outer_res = None; let outer_res = lifetime_rib_iter
for rib in lifetime_rib_iter { .find_map(|rib| rib.bindings.get_key_value(&normalized_ident).map(|(&outer, _)| outer));
if let Some((&outer, _)) = rib.bindings.get_key_value(&normalized_ident) {
outer_res = Some(outer);
break;
}
}
self.emit_undeclared_lifetime_error(lifetime, outer_res); self.emit_undeclared_lifetime_error(lifetime, outer_res);
self.record_lifetime_res(lifetime.id, LifetimeRes::Error, LifetimeElisionCandidate::Named); self.record_lifetime_res(lifetime.id, LifetimeRes::Error, LifetimeElisionCandidate::Named);
@ -1808,23 +1796,21 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
} }
LifetimeRibKind::AnonymousReportError => { LifetimeRibKind::AnonymousReportError => {
if elided { if elided {
let mut suggestion = None; let suggestion = self.lifetime_ribs[i..].iter().rev().find_map(|rib| {
for rib in self.lifetime_ribs[i..].iter().rev() {
if let LifetimeRibKind::Generics { if let LifetimeRibKind::Generics {
span, span,
kind: LifetimeBinderKind::PolyTrait | LifetimeBinderKind::WhereBound, kind: LifetimeBinderKind::PolyTrait | LifetimeBinderKind::WhereBound,
.. ..
} = &rib.kind } = rib.kind
{ {
suggestion =
Some(errors::ElidedAnonymousLivetimeReportErrorSuggestion { Some(errors::ElidedAnonymousLivetimeReportErrorSuggestion {
lo: span.shrink_to_lo(), lo: span.shrink_to_lo(),
hi: lifetime.ident.span.shrink_to_hi(), hi: lifetime.ident.span.shrink_to_hi(),
})
} else {
None
}
}); });
break;
}
}
// are we trying to use an anonymous lifetime // are we trying to use an anonymous lifetime
// on a non GAT associated trait type? // on a non GAT associated trait type?
if !self.in_func_body if !self.in_func_body
@ -2460,13 +2446,13 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
for i in (0..self.label_ribs.len()).rev() { for i in (0..self.label_ribs.len()).rev() {
let rib = &self.label_ribs[i]; let rib = &self.label_ribs[i];
if let RibKind::MacroDefinition(def) = rib.kind { if let RibKind::MacroDefinition(def) = rib.kind
// If an invocation of this macro created `ident`, give up on `ident` // If an invocation of this macro created `ident`, give up on `ident`
// and switch to `ident`'s source from the macro definition. // and switch to `ident`'s source from the macro definition.
if def == self.r.macro_def(label.span.ctxt()) { && def == self.r.macro_def(label.span.ctxt())
{
label.span.remove_mark(); label.span.remove_mark();
} }
}
let ident = label.normalize_to_macro_rules(); let ident = label.normalize_to_macro_rules();
if let Some((ident, id)) = rib.bindings.get_key_value(&ident) { if let Some((ident, id)) = rib.bindings.get_key_value(&ident) {
@ -2493,14 +2479,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
/// Determine whether or not a label from the `rib_index`th label rib is reachable. /// Determine whether or not a label from the `rib_index`th label rib is reachable.
fn is_label_valid_from_rib(&self, rib_index: usize) -> bool { fn is_label_valid_from_rib(&self, rib_index: usize) -> bool {
let ribs = &self.label_ribs[rib_index + 1..]; let ribs = &self.label_ribs[rib_index + 1..];
ribs.iter().all(|rib| !rib.kind.is_label_barrier())
for rib in ribs {
if rib.kind.is_label_barrier() {
return false;
}
}
true
} }
fn resolve_adt(&mut self, item: &'ast Item, generics: &'ast Generics) { fn resolve_adt(&mut self, item: &'ast Item, generics: &'ast Generics) {
@ -3505,7 +3484,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
self.visit_ty(&qself.ty); self.visit_ty(&qself.ty);
} }
self.visit_path(&delegation.path, delegation.id); self.visit_path(&delegation.path, delegation.id);
if let Some(body) = &delegation.body { let Some(body) = &delegation.body else { return };
self.with_rib(ValueNS, RibKind::FnOrCoroutine, |this| { self.with_rib(ValueNS, RibKind::FnOrCoroutine, |this| {
// `PatBoundCtx` is not necessary in this context // `PatBoundCtx` is not necessary in this context
let mut bindings = smallvec![(PatBoundCtx::Product, Default::default())]; let mut bindings = smallvec![(PatBoundCtx::Product, Default::default())];
@ -3520,7 +3499,6 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
this.visit_block(body); this.visit_block(body);
}); });
} }
}
fn resolve_params(&mut self, params: &'ast [Param]) { fn resolve_params(&mut self, params: &'ast [Param]) {
let mut bindings = smallvec![(PatBoundCtx::Product, Default::default())]; let mut bindings = smallvec![(PatBoundCtx::Product, Default::default())];