Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Misc. rustc_resolve cleanups #135826

Merged
merged 5 commits into from
Jan 23, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 26 additions & 28 deletions compiler/rustc_resolve/src/build_reduced_graph.rs
Original file line number Diff line number Diff line change
@@ -645,10 +645,10 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
let self_spans = items
.iter()
.filter_map(|(use_tree, _)| {
if let ast::UseTreeKind::Simple(..) = use_tree.kind {
if use_tree.ident().name == kw::SelfLower {
return Some(use_tree.span);
}
if let ast::UseTreeKind::Simple(..) = use_tree.kind
&& use_tree.ident().name == kw::SelfLower
{
return Some(use_tree.span);
}

None
@@ -947,19 +947,19 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
let imported_binding = self.r.import(binding, import);
if parent == self.r.graph_root {
let ident = ident.normalize_to_macros_2_0();
if let Some(entry) = self.r.extern_prelude.get(&ident) {
if expansion != LocalExpnId::ROOT && orig_name.is_some() && !entry.is_import() {
self.r.dcx().emit_err(
errors::MacroExpandedExternCrateCannotShadowExternArguments {
span: item.span,
},
);
// `return` is intended to discard this binding because it's an
// unregistered ambiguity error which would result in a panic
// caused by inconsistency `path_res`
// more details: https://github.com/rust-lang/rust/pull/111761
return;
}
if let Some(entry) = self.r.extern_prelude.get(&ident)
&& expansion != LocalExpnId::ROOT
&& orig_name.is_some()
&& !entry.is_import()
{
self.r.dcx().emit_err(
errors::MacroExpandedExternCrateCannotShadowExternArguments { span: item.span },
);
// `return` is intended to discard this binding because it's an
// unregistered ambiguity error which would result in a panic
// caused by inconsistency `path_res`
// more details: https://github.com/rust-lang/rust/pull/111761
return;
}
let entry = self
.r
@@ -1040,10 +1040,10 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
span: item.span,
});
}
if let ItemKind::ExternCrate(Some(orig_name)) = item.kind {
if orig_name == kw::SelfLower {
self.r.dcx().emit_err(errors::MacroUseExternCrateSelf { span: attr.span });
}
if let ItemKind::ExternCrate(Some(orig_name)) = item.kind
&& orig_name == kw::SelfLower
{
self.r.dcx().emit_err(errors::MacroUseExternCrateSelf { span: attr.span });
}
let ill_formed = |span| {
self.r.dcx().emit_err(errors::BadMacroImport { span });
@@ -1179,14 +1179,12 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
return Some((MacroKind::Bang, item.ident, item.span));
} else if ast::attr::contains_name(&item.attrs, sym::proc_macro_attribute) {
return Some((MacroKind::Attr, item.ident, item.span));
} else if let Some(attr) = ast::attr::find_by_name(&item.attrs, sym::proc_macro_derive) {
if let Some(meta_item_inner) =
} else if let Some(attr) = ast::attr::find_by_name(&item.attrs, sym::proc_macro_derive)
&& let Some(meta_item_inner) =
attr.meta_item_list().and_then(|list| list.get(0).cloned())
{
if let Some(ident) = meta_item_inner.ident() {
return Some((MacroKind::Derive, ident, ident.span));
}
}
&& let Some(ident) = meta_item_inner.ident()
{
return Some((MacroKind::Derive, ident, ident.span));
}
None
}
476 changes: 232 additions & 244 deletions compiler/rustc_resolve/src/diagnostics.rs

Large diffs are not rendered by default.

59 changes: 30 additions & 29 deletions compiler/rustc_resolve/src/effective_visibilities.rs
Original file line number Diff line number Diff line change
@@ -118,37 +118,38 @@ impl<'a, 'ra, 'tcx> EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> {
let resolutions = self.r.resolutions(module);

for (_, name_resolution) in resolutions.borrow().iter() {
if let Some(mut binding) = name_resolution.borrow().binding() {
// Set the given effective visibility level to `Level::Direct` and
// sets the rest of the `use` chain to `Level::Reexported` until
// we hit the actual exported item.
//
// If the binding is ambiguous, put the root ambiguity binding and all reexports
// leading to it into the table. They are used by the `ambiguous_glob_reexports`
// lint. For all bindings added to the table this way `is_ambiguity` returns true.
let is_ambiguity =
|binding: NameBinding<'ra>, warn: bool| binding.ambiguity.is_some() && !warn;
let mut parent_id = ParentId::Def(module_id);
let mut warn_ambiguity = binding.warn_ambiguity;
while let NameBindingKind::Import { binding: nested_binding, .. } = binding.kind {
self.update_import(binding, parent_id);
let Some(mut binding) = name_resolution.borrow().binding() else {
continue;
};
// Set the given effective visibility level to `Level::Direct` and
// sets the rest of the `use` chain to `Level::Reexported` until
// we hit the actual exported item.
//
// If the binding is ambiguous, put the root ambiguity binding and all reexports
// leading to it into the table. They are used by the `ambiguous_glob_reexports`
// lint. For all bindings added to the table this way `is_ambiguity` returns true.
let is_ambiguity =
|binding: NameBinding<'ra>, warn: bool| binding.ambiguity.is_some() && !warn;
let mut parent_id = ParentId::Def(module_id);
let mut warn_ambiguity = binding.warn_ambiguity;
while let NameBindingKind::Import { binding: nested_binding, .. } = binding.kind {
self.update_import(binding, parent_id);

if is_ambiguity(binding, warn_ambiguity) {
// Stop at the root ambiguity, further bindings in the chain should not
// be reexported because the root ambiguity blocks any access to them.
// (Those further bindings are most likely not ambiguities themselves.)
break;
}

parent_id = ParentId::Import(binding);
binding = nested_binding;
warn_ambiguity |= nested_binding.warn_ambiguity;
}
if !is_ambiguity(binding, warn_ambiguity)
&& let Some(def_id) = binding.res().opt_def_id().and_then(|id| id.as_local())
{
self.update_def(def_id, binding.vis.expect_local(), parent_id);
if is_ambiguity(binding, warn_ambiguity) {
// Stop at the root ambiguity, further bindings in the chain should not
// be reexported because the root ambiguity blocks any access to them.
// (Those further bindings are most likely not ambiguities themselves.)
break;
}

parent_id = ParentId::Import(binding);
binding = nested_binding;
warn_ambiguity |= nested_binding.warn_ambiguity;
}
if !is_ambiguity(binding, warn_ambiguity)
&& let Some(def_id) = binding.res().opt_def_id().and_then(|id| id.as_local())
{
self.update_def(def_id, binding.vis.expect_local(), parent_id);
}
}
}
98 changes: 47 additions & 51 deletions compiler/rustc_resolve/src/ident.rs
Original file line number Diff line number Diff line change
@@ -246,23 +246,21 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
// ---- end
// ```
// 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 let Some(parent) = module.parent {
// Inner module is inside the macro, parent module is outside of the macro.
if module.expansion != parent.expansion
&& module.expansion.is_descendant_of(parent.expansion)
{
// The macro is a proc macro derive
if let Some(def_id) = module.expansion.expn_data().macro_def_id {
let ext = &self.get_macro_by_def_id(def_id).ext;
if ext.builtin_name.is_none()
&& ext.macro_kind() == MacroKind::Derive
&& parent.expansion.outer_expn_is_descendant_of(*ctxt)
{
return Some((parent, derive_fallback_lint_id));
}
}
}
if derive_fallback_lint_id.is_some()
&& let Some(parent) = module.parent
// Inner module is inside the macro
&& module.expansion != parent.expansion
// Parent module is outside of the macro
&& module.expansion.is_descendant_of(parent.expansion)
// The macro is a proc macro derive
&& let Some(def_id) = module.expansion.expn_data().macro_def_id
{
let ext = &self.get_macro_by_def_id(def_id).ext;
if ext.builtin_name.is_none()
&& ext.macro_kind() == MacroKind::Derive
&& parent.expansion.outer_expn_is_descendant_of(*ctxt)
{
return Some((parent, derive_fallback_lint_id));
}
}

@@ -593,8 +591,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
},
Scope::StdLibPrelude => {
let mut result = Err(Determinacy::Determined);
if let Some(prelude) = this.prelude {
if let Ok(binding) = this.resolve_ident_in_module_unadjusted(
if let Some(prelude) = this.prelude
&& let Ok(binding) = this.resolve_ident_in_module_unadjusted(
ModuleOrUniformRoot::Module(prelude),
ident,
ns,
@@ -603,14 +601,13 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
None,
ignore_binding,
ignore_import,
) {
if matches!(use_prelude, UsePrelude::Yes)
|| this.is_builtin_macro(binding.res())
{
result = Ok((binding, Flags::MISC_FROM_PRELUDE));
}
}
)
&& (matches!(use_prelude, UsePrelude::Yes)
|| this.is_builtin_macro(binding.res()))
{
result = Ok((binding, Flags::MISC_FROM_PRELUDE));
}

result
}
Scope::BuiltinTypes => match this.builtin_types_bindings.get(&ident.name) {
@@ -939,10 +936,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
};

// Items and single imports are not shadowable, if we have one, then it's determined.
if let Some(binding) = binding {
if !binding.is_glob_import() {
return check_usable(self, binding);
}
if let Some(binding) = binding
&& !binding.is_glob_import()
{
return check_usable(self, binding);
}

// --- From now on we either have a glob resolution or no resolution. ---
@@ -1437,13 +1434,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
for (segment_idx, &Segment { ident, id, .. }) in path.iter().enumerate() {
debug!("resolve_path ident {} {:?} {:?}", segment_idx, ident, id);
let record_segment_res = |this: &mut Self, res| {
if finalize.is_some() {
if let Some(id) = id {
if !this.partial_res_map.contains_key(&id) {
assert!(id != ast::DUMMY_NODE_ID, "Trying to resolve dummy id");
this.record_partial_res(id, PartialRes::new(res));
}
}
if finalize.is_some()
&& let Some(id) = id
&& !this.partial_res_map.contains_key(&id)
{
assert!(id != ast::DUMMY_NODE_ID, "Trying to resolve dummy id");
this.record_partial_res(id, PartialRes::new(res));
}
};

@@ -1463,13 +1459,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
_ => None,
},
};
if let Some(self_module) = self_module {
if let Some(parent) = self_module.parent {
module = Some(ModuleOrUniformRoot::Module(
self.resolve_self(&mut ctxt, parent),
));
continue;
}
if let Some(self_module) = self_module
&& let Some(parent) = self_module.parent
{
module =
Some(ModuleOrUniformRoot::Module(self.resolve_self(&mut ctxt, parent)));
continue;
}
return PathResult::failed(
ident,
@@ -1644,13 +1639,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
}
Err(Undetermined) => return PathResult::Indeterminate,
Err(Determined) => {
if let Some(ModuleOrUniformRoot::Module(module)) = module {
if opt_ns.is_some() && !module.is_normal() {
return PathResult::NonModule(PartialRes::with_unresolved_segments(
module.res().unwrap(),
path.len() - segment_idx,
));
}
if let Some(ModuleOrUniformRoot::Module(module)) = module
&& opt_ns.is_some()
&& !module.is_normal()
{
return PathResult::NonModule(PartialRes::with_unresolved_segments(
module.res().unwrap(),
path.len() - segment_idx,
));
}

return PathResult::failed(
261 changes: 128 additions & 133 deletions compiler/rustc_resolve/src/imports.rs
Original file line number Diff line number Diff line change
@@ -287,12 +287,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
binding.vis
};

if let ImportKind::Glob { ref max_vis, .. } = import.kind {
if vis == import_vis
|| max_vis.get().is_none_or(|max_vis| vis.is_at_least(max_vis, self.tcx))
{
max_vis.set(Some(vis.expect_local()))
}
if let ImportKind::Glob { ref max_vis, .. } = import.kind
&& (vis == import_vis
|| max_vis.get().is_none_or(|max_vis| vis.is_at_least(max_vis, self.tcx)))
{
max_vis.set(Some(vis.expect_local()))
}

self.arenas.alloc_name_binding(NameBindingData {
@@ -543,31 +542,28 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
// resolution for it so that later resolve stages won't complain.
self.import_dummy_binding(*import, is_indeterminate);

if let Some(err) = unresolved_import_error {
glob_error |= import.is_glob();
let Some(err) = unresolved_import_error else { continue };

if let ImportKind::Single { source, ref source_bindings, .. } = import.kind {
if source.name == kw::SelfLower {
// Silence `unresolved import` error if E0429 is already emitted
if let Err(Determined) = source_bindings.value_ns.get() {
continue;
}
}
}
glob_error |= import.is_glob();

if prev_root_id != NodeId::ZERO
&& prev_root_id != import.root_id
&& !errors.is_empty()
{
// In the case of a new import line, throw a diagnostic message
// for the previous line.
self.throw_unresolved_import_error(errors, glob_error);
errors = vec![];
}
if seen_spans.insert(err.span) {
errors.push((*import, err));
prev_root_id = import.root_id;
}
if let ImportKind::Single { source, ref source_bindings, .. } = import.kind
&& source.name == kw::SelfLower
// Silence `unresolved import` error if E0429 is already emitted
&& let Err(Determined) = source_bindings.value_ns.get()
{
continue;
}

if prev_root_id != NodeId::ZERO && prev_root_id != import.root_id && !errors.is_empty()
{
// In the case of a new import line, throw a diagnostic message
// for the previous line.
self.throw_unresolved_import_error(errors, glob_error);
errors = vec![];
}
if seen_spans.insert(err.span) {
errors.push((*import, err));
prev_root_id = import.root_id;
}
}

@@ -609,60 +605,60 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
for (key, resolution) in self.resolutions(*module).borrow().iter() {
let resolution = resolution.borrow();

if let Some(binding) = resolution.binding {
if let NameBindingKind::Import { import, .. } = binding.kind
&& let Some((amb_binding, _)) = binding.ambiguity
&& binding.res() != Res::Err
&& exported_ambiguities.contains(&binding)
let Some(binding) = resolution.binding else { continue };

if let NameBindingKind::Import { import, .. } = binding.kind
&& let Some((amb_binding, _)) = binding.ambiguity
&& binding.res() != Res::Err
&& exported_ambiguities.contains(&binding)
{
self.lint_buffer.buffer_lint(
AMBIGUOUS_GLOB_REEXPORTS,
import.root_id,
import.root_span,
BuiltinLintDiag::AmbiguousGlobReexports {
name: key.ident.to_string(),
namespace: key.ns.descr().to_string(),
first_reexport_span: import.root_span,
duplicate_reexport_span: amb_binding.span,
},
);
}

if let Some(glob_binding) = resolution.shadowed_glob {
let binding_id = match binding.kind {
NameBindingKind::Res(res) => {
Some(self.def_id_to_node_id[res.def_id().expect_local()])
}
NameBindingKind::Module(module) => {
Some(self.def_id_to_node_id[module.def_id().expect_local()])
}
NameBindingKind::Import { import, .. } => import.id(),
};

if binding.res() != Res::Err
&& glob_binding.res() != Res::Err
&& let NameBindingKind::Import { import: glob_import, .. } =
glob_binding.kind
&& let Some(binding_id) = binding_id
&& let Some(glob_import_id) = glob_import.id()
&& let glob_import_def_id = self.local_def_id(glob_import_id)
&& self.effective_visibilities.is_exported(glob_import_def_id)
&& glob_binding.vis.is_public()
&& !binding.vis.is_public()
{
self.lint_buffer.buffer_lint(
AMBIGUOUS_GLOB_REEXPORTS,
import.root_id,
import.root_span,
BuiltinLintDiag::AmbiguousGlobReexports {
name: key.ident.to_string(),
namespace: key.ns.descr().to_string(),
first_reexport_span: import.root_span,
duplicate_reexport_span: amb_binding.span,
HIDDEN_GLOB_REEXPORTS,
binding_id,
binding.span,
BuiltinLintDiag::HiddenGlobReexports {
name: key.ident.name.to_string(),
namespace: key.ns.descr().to_owned(),
glob_reexport_span: glob_binding.span,
private_item_span: binding.span,
},
);
}

if let Some(glob_binding) = resolution.shadowed_glob {
let binding_id = match binding.kind {
NameBindingKind::Res(res) => {
Some(self.def_id_to_node_id[res.def_id().expect_local()])
}
NameBindingKind::Module(module) => {
Some(self.def_id_to_node_id[module.def_id().expect_local()])
}
NameBindingKind::Import { import, .. } => import.id(),
};

if binding.res() != Res::Err
&& glob_binding.res() != Res::Err
&& let NameBindingKind::Import { import: glob_import, .. } =
glob_binding.kind
&& let Some(binding_id) = binding_id
&& let Some(glob_import_id) = glob_import.id()
&& let glob_import_def_id = self.local_def_id(glob_import_id)
&& self.effective_visibilities.is_exported(glob_import_def_id)
&& glob_binding.vis.is_public()
&& !binding.vis.is_public()
{
self.lint_buffer.buffer_lint(
HIDDEN_GLOB_REEXPORTS,
binding_id,
binding.span,
BuiltinLintDiag::HiddenGlobReexports {
name: key.ident.name.to_string(),
namespace: key.ns.descr().to_owned(),
glob_reexport_span: glob_binding.span,
private_item_span: binding.span,
},
);
}
}
}
}
}
@@ -1006,21 +1002,19 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
self.lint_if_path_starts_with_module(Some(finalize), &full_path, None);
}

if let ModuleOrUniformRoot::Module(module) = module {
if module == import.parent_scope.module {
// Importing a module into itself is not allowed.
return Some(UnresolvedImportError {
span: import.span,
label: Some(String::from(
"cannot glob-import a module into itself",
)),
note: None,
suggestion: None,
candidates: None,
segment: None,
module: None,
});
}
if let ModuleOrUniformRoot::Module(module) = module
&& module == import.parent_scope.module
{
// Importing a module into itself is not allowed.
return Some(UnresolvedImportError {
span: import.span,
label: Some(String::from("cannot glob-import a module into itself")),
note: None,
suggestion: None,
candidates: None,
segment: None,
module: None,
});
}
if !is_prelude
&& let Some(max_vis) = max_vis.get()
@@ -1081,18 +1075,17 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
// Consistency checks, analogous to `finalize_macro_resolutions`.
let initial_res = source_bindings[ns].get().map(|initial_binding| {
all_ns_err = false;
if let Some(target_binding) = target_bindings[ns].get() {
if target.name == kw::Underscore
&& initial_binding.is_extern_crate()
&& !initial_binding.is_import()
{
let used = if import.module_path.is_empty() {
Used::Scope
} else {
Used::Other
};
this.record_use(ident, target_binding, used);
}
if let Some(target_binding) = target_bindings[ns].get()
&& target.name == kw::Underscore
&& initial_binding.is_extern_crate()
&& !initial_binding.is_import()
{
let used = if import.module_path.is_empty() {
Used::Scope
} else {
Used::Other
};
this.record_use(ident, target_binding, used);
}
initial_binding.res()
});
@@ -1247,17 +1240,19 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
let mut any_successful_reexport = false;
let mut crate_private_reexport = false;
self.per_ns(|this, ns| {
if let Ok(binding) = source_bindings[ns].get() {
if !binding.vis.is_at_least(import.vis, this.tcx) {
reexport_error = Some((ns, binding));
if let ty::Visibility::Restricted(binding_def_id) = binding.vis {
if binding_def_id.is_top_level_module() {
crate_private_reexport = true;
}
}
} else {
any_successful_reexport = true;
let Ok(binding) = source_bindings[ns].get() else {
return;
};

if !binding.vis.is_at_least(import.vis, this.tcx) {
reexport_error = Some((ns, binding));
if let ty::Visibility::Restricted(binding_def_id) = binding.vis
&& binding_def_id.is_top_level_module()
{
crate_private_reexport = true;
}
} else {
any_successful_reexport = true;
}
});

@@ -1474,28 +1469,28 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
// Since import resolution is finished, globs will not define any more names.
*module.globs.borrow_mut() = Vec::new();

if let Some(def_id) = module.opt_def_id() {
let mut children = Vec::new();

module.for_each_child(self, |this, ident, _, binding| {
let res = binding.res().expect_non_local();
let error_ambiguity = binding.is_ambiguity_recursive() && !binding.warn_ambiguity;
if res != def::Res::Err && !error_ambiguity {
let mut reexport_chain = SmallVec::new();
let mut next_binding = binding;
while let NameBindingKind::Import { binding, import, .. } = next_binding.kind {
reexport_chain.push(import.simplify(this));
next_binding = binding;
}
let Some(def_id) = module.opt_def_id() else { return };

let mut children = Vec::new();

children.push(ModChild { ident, res, vis: binding.vis, reexport_chain });
module.for_each_child(self, |this, ident, _, binding| {
let res = binding.res().expect_non_local();
let error_ambiguity = binding.is_ambiguity_recursive() && !binding.warn_ambiguity;
if res != def::Res::Err && !error_ambiguity {
let mut reexport_chain = SmallVec::new();
let mut next_binding = binding;
while let NameBindingKind::Import { binding, import, .. } = next_binding.kind {
reexport_chain.push(import.simplify(this));
next_binding = binding;
}
});

if !children.is_empty() {
// Should be fine because this code is only called for local modules.
self.module_children.insert(def_id.expect_local(), children);
children.push(ModChild { ident, res, vis: binding.vis, reexport_chain });
}
});

if !children.is_empty() {
// Should be fine because this code is only called for local modules.
self.module_children.insert(def_id.expect_local(), children);
}
}
}
220 changes: 99 additions & 121 deletions compiler/rustc_resolve/src/late.rs
Original file line number Diff line number Diff line change
@@ -468,16 +468,12 @@ impl<'a> PathSource<'a> {
{
"external crate"
}
ExprKind::Path(_, path) => {
let mut msg = "function";
if let Some(segment) = path.segments.iter().last() {
if let Some(c) = segment.ident.to_string().chars().next() {
if c.is_uppercase() {
msg = "function, tuple struct or tuple variant";
}
}
}
msg
ExprKind::Path(_, path)
if let Some(segment) = path.segments.last()
&& let Some(c) = segment.ident.to_string().chars().next()
&& c.is_uppercase() =>
{
"function, tuple struct or tuple variant"
}
_ => "function",
},
@@ -1182,32 +1178,27 @@ 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
// resolution in the value namespace succeeds, we have an generic const argument on
// 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
// checking.
if path.is_potential_trivial_const_arg() {
let mut check_ns = |ns| {
self.maybe_resolve_ident_in_lexical_scope(path.segments[0].ident, ns)
.is_some()
};
if !check_ns(TypeNS) && check_ns(ValueNS) {
self.resolve_anon_const_manual(
true,
AnonConstKind::ConstArg(IsRepeatExpr::No),
|this| {
this.smart_resolve_path(
ty.id,
&None,
path,
PathSource::Expr(None),
);
this.visit_path(path, ty.id);
},
);
&& path.is_potential_trivial_const_arg()
{
let mut check_ns = |ns| {
self.maybe_resolve_ident_in_lexical_scope(path.segments[0].ident, ns)
.is_some()
};
if !check_ns(TypeNS) && check_ns(ValueNS) {
self.resolve_anon_const_manual(
true,
AnonConstKind::ConstArg(IsRepeatExpr::No),
|this| {
this.smart_resolve_path(ty.id, &None, path, PathSource::Expr(None));
this.visit_path(path, ty.id);
},
);

self.diag_metadata.currently_processing_generic_args = prev;
return;
}
self.diag_metadata.currently_processing_generic_args = prev;
return;
}
}

@@ -1243,54 +1234,56 @@ impl<'ra: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'r
}

fn visit_path_segment(&mut self, path_segment: &'ast PathSegment) {
if let Some(ref args) = path_segment.args {
match &**args {
GenericArgs::AngleBracketed(..) => visit::walk_generic_args(self, args),
GenericArgs::Parenthesized(p_args) => {
// Probe the lifetime ribs to know how to behave.
for rib in self.lifetime_ribs.iter().rev() {
match rib.kind {
// We are inside a `PolyTraitRef`. The lifetimes are
// to be introduced in that (maybe implicit) `for<>` binder.
LifetimeRibKind::Generics {
binder,
kind: LifetimeBinderKind::PolyTrait,
..
} => {
self.with_lifetime_rib(
LifetimeRibKind::AnonymousCreateParameter {
let Some(ref args) = path_segment.args else {
return;
};

match &**args {
GenericArgs::AngleBracketed(..) => visit::walk_generic_args(self, args),
GenericArgs::Parenthesized(p_args) => {
// Probe the lifetime ribs to know how to behave.
for rib in self.lifetime_ribs.iter().rev() {
match rib.kind {
// We are inside a `PolyTraitRef`. The lifetimes are
// to be introduced in that (maybe implicit) `for<>` binder.
LifetimeRibKind::Generics {
binder,
kind: LifetimeBinderKind::PolyTrait,
..
} => {
self.with_lifetime_rib(
LifetimeRibKind::AnonymousCreateParameter {
binder,
report_in_path: false,
},
|this| {
this.resolve_fn_signature(
binder,
report_in_path: false,
},
|this| {
this.resolve_fn_signature(
binder,
false,
p_args.inputs.iter().map(|ty| (None, &**ty)),
&p_args.output,
)
},
);
break;
}
// We have nowhere to introduce generics. Code is malformed,
// so use regular lifetime resolution to avoid spurious errors.
LifetimeRibKind::Item | LifetimeRibKind::Generics { .. } => {
visit::walk_generic_args(self, args);
break;
}
LifetimeRibKind::AnonymousCreateParameter { .. }
| LifetimeRibKind::AnonymousReportError
| LifetimeRibKind::StaticIfNoLifetimeInScope { .. }
| LifetimeRibKind::Elided(_)
| LifetimeRibKind::ElisionFailure
| LifetimeRibKind::ConcreteAnonConst(_)
| LifetimeRibKind::ConstParamTy => {}
false,
p_args.inputs.iter().map(|ty| (None, &**ty)),
&p_args.output,
)
},
);
break;
}
// We have nowhere to introduce generics. Code is malformed,
// so use regular lifetime resolution to avoid spurious errors.
LifetimeRibKind::Item | LifetimeRibKind::Generics { .. } => {
visit::walk_generic_args(self, args);
break;
}
LifetimeRibKind::AnonymousCreateParameter { .. }
| LifetimeRibKind::AnonymousReportError
| LifetimeRibKind::StaticIfNoLifetimeInScope { .. }
| LifetimeRibKind::Elided(_)
| LifetimeRibKind::ElisionFailure
| LifetimeRibKind::ConcreteAnonConst(_)
| LifetimeRibKind::ConstParamTy => {}
}
}
GenericArgs::ParenthesizedElided(_) => {}
}
GenericArgs::ParenthesizedElided(_) => {}
}
}

@@ -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 mut outer_res = None;
for rib in lifetime_rib_iter {
if let Some((&outer, _)) = rib.bindings.get_key_value(&normalized_ident) {
outer_res = Some(outer);
break;
}
}
let outer_res = lifetime_rib_iter
.find_map(|rib| rib.bindings.get_key_value(&normalized_ident).map(|(&outer, _)| outer));

self.emit_undeclared_lifetime_error(lifetime, outer_res);
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 => {
if elided {
let mut suggestion = None;
for rib in self.lifetime_ribs[i..].iter().rev() {
let suggestion = self.lifetime_ribs[i..].iter().rev().find_map(|rib| {
if let LifetimeRibKind::Generics {
span,
kind: LifetimeBinderKind::PolyTrait | LifetimeBinderKind::WhereBound,
..
} = &rib.kind
} = rib.kind
{
suggestion =
Some(errors::ElidedAnonymousLivetimeReportErrorSuggestion {
lo: span.shrink_to_lo(),
hi: lifetime.ident.span.shrink_to_hi(),
});
break;
Some(errors::ElidedAnonymousLivetimeReportErrorSuggestion {
lo: span.shrink_to_lo(),
hi: lifetime.ident.span.shrink_to_hi(),
})
} else {
None
}
}

});
// are we trying to use an anonymous lifetime
// on a non GAT associated trait type?
if !self.in_func_body
@@ -2460,12 +2446,12 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
for i in (0..self.label_ribs.len()).rev() {
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`
// and switch to `ident`'s source from the macro definition.
if def == self.r.macro_def(label.span.ctxt()) {
label.span.remove_mark();
}
&& def == self.r.macro_def(label.span.ctxt())
{
label.span.remove_mark();
}

let ident = label.normalize_to_macro_rules();
@@ -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.
fn is_label_valid_from_rib(&self, rib_index: usize) -> bool {
let ribs = &self.label_ribs[rib_index + 1..];

for rib in ribs {
if rib.kind.is_label_barrier() {
return false;
}
}

true
ribs.iter().all(|rib| !rib.kind.is_label_barrier())
}

fn resolve_adt(&mut self, item: &'ast Item, generics: &'ast Generics) {
@@ -3505,21 +3484,20 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
self.visit_ty(&qself.ty);
}
self.visit_path(&delegation.path, delegation.id);
if let Some(body) = &delegation.body {
self.with_rib(ValueNS, RibKind::FnOrCoroutine, |this| {
// `PatBoundCtx` is not necessary in this context
let mut bindings = smallvec![(PatBoundCtx::Product, Default::default())];

let span = delegation.path.segments.last().unwrap().ident.span;
this.fresh_binding(
Ident::new(kw::SelfLower, span),
delegation.id,
PatternSource::FnParam,
&mut bindings,
);
this.visit_block(body);
});
}
let Some(body) = &delegation.body else { return };
self.with_rib(ValueNS, RibKind::FnOrCoroutine, |this| {
// `PatBoundCtx` is not necessary in this context
let mut bindings = smallvec![(PatBoundCtx::Product, Default::default())];

let span = delegation.path.segments.last().unwrap().ident.span;
this.fresh_binding(
Ident::new(kw::SelfLower, span),
delegation.id,
PatternSource::FnParam,
&mut bindings,
);
this.visit_block(body);
});
}

fn resolve_params(&mut self, params: &'ast [Param]) {