diff options
Diffstat (limited to 'compiler/rustc_resolve/src')
| -rw-r--r-- | compiler/rustc_resolve/src/build_reduced_graph.rs | 69 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/def_collector.rs | 25 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/diagnostics.rs | 526 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/effective_visibilities.rs | 59 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/errors.rs | 16 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/ident.rs | 155 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/imports.rs | 280 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/late.rs | 303 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/late/diagnostics.rs | 51 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/lib.rs | 68 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/macros.rs | 31 |
11 files changed, 809 insertions, 774 deletions
diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 3fe1eed243f..c6781ecc566 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -6,6 +6,7 @@ //! Imports are also considered items and placed into modules here, but not resolved yet. use std::cell::Cell; +use std::sync::Arc; use rustc_ast::visit::{self, AssocCtxt, Visitor, WalkItemKind}; use rustc_ast::{ @@ -13,7 +14,6 @@ use rustc_ast::{ ItemKind, MetaItemKind, NodeId, StmtKind, }; use rustc_attr_parsing as attr; -use rustc_data_structures::sync::Lrc; use rustc_expand::base::ResolverExpand; use rustc_expand::expand::AstFragment; use rustc_hir::def::{self, *}; @@ -179,7 +179,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { LoadedMacro::MacroDef { def, ident, attrs, span, edition } => { self.compile_macro(&def, ident, &attrs, span, ast::DUMMY_NODE_ID, edition) } - LoadedMacro::ProcMacro(ext) => MacroData::new(Lrc::new(ext)), + LoadedMacro::ProcMacro(ext) => MacroData::new(Arc::new(ext)), }; self.macro_map.entry(def_id).or_insert(macro_data) @@ -567,10 +567,13 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { Some(rename) => source.ident.span.to(rename.span), None => source.ident.span, }; - self.r.report_error(span, ResolutionError::SelfImportsOnlyAllowedWithin { - root: parent.is_none(), - span_with_rename, - }); + self.r.report_error( + span, + ResolutionError::SelfImportsOnlyAllowedWithin { + root: parent.is_none(), + span_with_rename, + }, + ); // Error recovery: replace `use foo::self;` with `use foo;` if let Some(parent) = module_path.pop() { @@ -645,10 +648,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 +950,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 +1043,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 +1182,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 } diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index 87024c487df..5eb8e420fa4 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -95,11 +95,14 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> { fn visit_macro_invoc(&mut self, id: NodeId) { let id = id.placeholder_to_expn_id(); - let old_parent = self.resolver.invocation_parents.insert(id, InvocationParent { - parent_def: self.parent_def, - impl_trait_context: self.impl_trait_context, - in_attr: self.in_attr, - }); + let old_parent = self.resolver.invocation_parents.insert( + id, + InvocationParent { + parent_def: self.parent_def, + impl_trait_context: self.impl_trait_context, + in_attr: self.in_attr, + }, + ); assert!(old_parent.is_none(), "parent `LocalDefId` is reset for an invocation"); } } @@ -170,11 +173,17 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { fn visit_fn(&mut self, fn_kind: FnKind<'a>, span: Span, _: NodeId) { match fn_kind { - FnKind::Fn(_ctxt, _ident, FnSig { header, decl, span: _ }, _vis, generics, body) - if let Some(coroutine_kind) = header.coroutine_kind => - { + FnKind::Fn( + _ctxt, + _ident, + _vis, + Fn { sig: FnSig { header, decl, span: _ }, generics, contract, body, .. }, + ) if let Some(coroutine_kind) = header.coroutine_kind => { self.visit_fn_header(header); self.visit_generics(generics); + if let Some(contract) = contract { + self.visit_contract(contract); + } // For async functions, we need to create their inner defs inside of a // closure to match their desugared representation. Besides that, diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 0da27a9c071..5db6f83f3ee 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -24,6 +24,7 @@ use rustc_session::lint::builtin::{ MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS, }; use rustc_session::lint::{AmbiguityErrorDiag, BuiltinLintDiag}; +use rustc_session::utils::was_invoked_from_cargo; use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::edition::Edition; use rustc_span::hygiene::MacroKind; @@ -225,10 +226,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let (name, 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 s == &span { - return; - } + if self.name_already_seen.get(&name) == Some(&span) { + return; } let old_kind = match (ns, old_binding.module()) { @@ -380,20 +379,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { suggestion = Some(format!("self as {suggested_name}")) } ImportKind::Single { source, .. } => { - if let Some(pos) = - source.span.hi().0.checked_sub(binding_span.lo().0).map(|pos| pos as usize) + if let Some(pos) = source.span.hi().0.checked_sub(binding_span.lo().0) + && 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) { - if pos <= snippet.len() { - 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}")); - } - } + span = binding_span.with_lo(binding_span.lo() + BytePos(pos)).with_hi( + binding_span.hi() - BytePos(if snippet.ends_with(';') { 1 } else { 0 }), + ); + suggestion = Some(format!(" as {suggested_name}")); } } ImportKind::ExternCrate { source, target, .. } => { @@ -510,13 +503,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // If the first element of our path was actually resolved to an // `ExternCrate` (also used for `crate::...`) then no need to issue a // warning, this looks all good! - if let Some(binding) = second_binding { - if let NameBindingKind::Import { import, .. } = binding.kind { - // Careful: we still want to rewrite paths from renamed extern crates. - if let ImportKind::ExternCrate { source: None, .. } = import.kind { - return; - } - } + if let Some(binding) = second_binding + && let NameBindingKind::Import { import, .. } = binding.kind + // Careful: we still want to rewrite paths from renamed extern crates. + && let ImportKind::ExternCrate { source: None, .. } = import.kind + { + return; } let diag = BuiltinLintDiag::AbsPathWithModule(root_span); @@ -685,7 +677,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } if could_be_path { let import_suggestions = self.lookup_import_candidates( - Ident::with_dummy_span(name), + name, Namespace::ValueNS, &parent_scope, &|res: Res| { @@ -809,7 +801,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } err.multipart_suggestion(msg, suggestions, applicability); } - if let Some(ModuleOrUniformRoot::Module(module)) = module && let Some(module) = module.opt_def_id() && let Some(segment) = segment @@ -999,14 +990,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { VisResolutionError::AncestorOnly(span) => { self.dcx().create_err(errs::AncestorOnly(span)) } - VisResolutionError::FailedToResolve(span, label, suggestion) => { - self.into_struct_error(span, ResolutionError::FailedToResolve { - segment: None, - label, - suggestion, - module: None, - }) - } + VisResolutionError::FailedToResolve(span, label, suggestion) => self.into_struct_error( + span, + ResolutionError::FailedToResolve { segment: None, label, suggestion, module: None }, + ), VisResolutionError::ExpectedFound(span, path_str, res) => { self.dcx().create_err(errs::ExpectedModuleFound { span, res, path_str }) } @@ -1047,20 +1034,21 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { if filter_fn(res) { for derive in parent_scope.derives { 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, Some(MacroKind::Derive), parent_scope, false, false, None, - ) { - suggestions.extend( - ext.helper_attrs - .iter() - .map(|name| TypoSuggestion::typo_from_name(*name, res)), - ); - } + ) else { + continue; + }; + suggestions.extend( + ext.helper_attrs + .iter() + .map(|name| TypoSuggestion::typo_from_name(*name, res)), + ); } } } @@ -1215,12 +1203,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } // #90113: Do not count an inaccessible reexported item as a candidate. - if let NameBindingKind::Import { binding, .. } = name_binding.kind { - if this.is_accessible_from(binding.vis, parent_scope.module) - && !this.is_accessible_from(name_binding.vis, parent_scope.module) - { - return; - } + if let NameBindingKind::Import { binding, .. } = name_binding.kind + && this.is_accessible_from(binding.vis, parent_scope.module) + && !this.is_accessible_from(name_binding.vis, parent_scope.module) + { + return; } let res = name_binding.res(); @@ -1253,14 +1240,13 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { segms.push(ast::PathSegment::from_ident(ident)); let path = Path { span: name_binding.span, segments: segms, tokens: None }; - if child_accessible { + if child_accessible // Remove invisible match if exists - if let Some(idx) = candidates + && let Some(idx) = candidates .iter() .position(|v: &ImportSuggestion| v.did == did && !v.accessible) - { - candidates.remove(idx); - } + { + candidates.remove(idx); } if candidates.iter().all(|v: &ImportSuggestion| v.did != did) { @@ -1373,48 +1359,50 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // otherwise cause duplicate suggestions. continue; } - let crate_id = self.crate_loader(|c| c.maybe_process_path_extern(ident.name)); - if let Some(crate_id) = crate_id { - let crate_def_id = crate_id.as_def_id(); - let crate_root = self.expect_module(crate_def_id); - - // Check if there's already an item in scope with the same name as the crate. - // If so, we have to disambiguate the potential import suggestions by making - // the paths *global* (i.e., by prefixing them with `::`). - let needs_disambiguation = - self.resolutions(parent_scope.module).borrow().iter().any( - |(key, name_resolution)| { - if key.ns == TypeNS - && key.ident == ident - && let Some(binding) = name_resolution.borrow().binding - { - match binding.res() { - // No disambiguation needed if the identically named item we - // found in scope actually refers to the crate in question. - Res::Def(_, def_id) => def_id != crate_def_id, - Res::PrimTy(_) => true, - _ => false, - } - } else { - false - } - }, - ); - let mut crate_path = ThinVec::new(); - if needs_disambiguation { - crate_path.push(ast::PathSegment::path_root(rustc_span::DUMMY_SP)); - } - crate_path.push(ast::PathSegment::from_ident(ident)); + let Some(crate_id) = self.crate_loader(|c| c.maybe_process_path_extern(ident.name)) + else { + continue; + }; - suggestions.extend(self.lookup_import_candidates_from_module( - lookup_ident, - namespace, - parent_scope, - crate_root, - crate_path, - &filter_fn, - )); + let crate_def_id = crate_id.as_def_id(); + let crate_root = self.expect_module(crate_def_id); + + // Check if there's already an item in scope with the same name as the crate. + // If so, we have to disambiguate the potential import suggestions by making + // the paths *global* (i.e., by prefixing them with `::`). + let needs_disambiguation = + self.resolutions(parent_scope.module).borrow().iter().any( + |(key, name_resolution)| { + if key.ns == TypeNS + && key.ident == ident + && let Some(binding) = name_resolution.borrow().binding + { + match binding.res() { + // No disambiguation needed if the identically named item we + // found in scope actually refers to the crate in question. + Res::Def(_, def_id) => def_id != crate_def_id, + Res::PrimTy(_) => true, + _ => false, + } + } else { + false + } + }, + ); + let mut crate_path = ThinVec::new(); + if needs_disambiguation { + crate_path.push(ast::PathSegment::path_root(rustc_span::DUMMY_SP)); } + crate_path.push(ast::PathSegment::from_ident(ident)); + + suggestions.extend(self.lookup_import_candidates_from_module( + lookup_ident, + namespace, + parent_scope, + crate_root, + crate_path, + &filter_fn, + )); } } @@ -1511,7 +1499,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { }); } 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, ScopeSet::All(ns), parent_scope, @@ -1519,53 +1507,53 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { false, None, None, - ) { - let desc = match binding.res() { - Res::Def(DefKind::Macro(MacroKind::Bang), _) => { - "a function-like macro".to_string() - } - Res::Def(DefKind::Macro(MacroKind::Attr), _) | Res::NonMacroAttr(..) => { - format!("an attribute: `#[{ident}]`") - } - Res::Def(DefKind::Macro(MacroKind::Derive), _) => { - format!("a derive macro: `#[derive({ident})]`") - } - Res::ToolMod => { - // Don't confuse the user with tool modules. - continue; - } - Res::Def(DefKind::Trait, _) if macro_kind == MacroKind::Derive => { - "only a trait, without a derive macro".to_string() - } - res => format!( - "{} {}, not {} {}", - res.article(), - res.descr(), - macro_kind.article(), - macro_kind.descr_expected(), - ), - }; - if let crate::NameBindingKind::Import { import, .. } = binding.kind { - if !import.span.is_dummy() { - let note = errors::IdentImporterHereButItIsDesc { - span: import.span, - imported_ident: ident, - imported_ident_desc: &desc, - }; - err.subdiagnostic(note); - // Silence the 'unused import' warning we might get, - // since this diagnostic already covers that import. - self.record_use(ident, binding, Used::Other); - return; - } + ) else { + continue; + }; + + let desc = match binding.res() { + Res::Def(DefKind::Macro(MacroKind::Bang), _) => "a function-like macro".to_string(), + Res::Def(DefKind::Macro(MacroKind::Attr), _) | Res::NonMacroAttr(..) => { + format!("an attribute: `#[{ident}]`") + } + Res::Def(DefKind::Macro(MacroKind::Derive), _) => { + format!("a derive macro: `#[derive({ident})]`") } - let note = errors::IdentInScopeButItIsDesc { + Res::ToolMod => { + // Don't confuse the user with tool modules. + continue; + } + Res::Def(DefKind::Trait, _) if macro_kind == MacroKind::Derive => { + "only a trait, without a derive macro".to_string() + } + res => format!( + "{} {}, not {} {}", + res.article(), + res.descr(), + macro_kind.article(), + macro_kind.descr_expected(), + ), + }; + if let crate::NameBindingKind::Import { import, .. } = binding.kind + && !import.span.is_dummy() + { + let note = errors::IdentImporterHereButItIsDesc { + span: import.span, imported_ident: ident, imported_ident_desc: &desc, }; err.subdiagnostic(note); + // Silence the 'unused import' warning we might get, + // since this diagnostic already covers that import. + self.record_use(ident, binding, Used::Other); return; } + let note = errors::IdentInScopeButItIsDesc { + imported_ident: ident, + imported_ident_desc: &desc, + }; + err.subdiagnostic(note); + return; } } @@ -1749,15 +1737,16 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { /// If the binding refers to a tuple struct constructor with fields, /// returns the span of its fields. 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), ctor_def_id, )) = binding.kind - { - 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()` - } - None + else { + return None; + }; + + let def_id = self.tcx.parent(ctor_def_id); + self.field_idents(def_id)?.iter().map(|&f| f.span).reduce(Span::to) // None for `struct Foo()` } fn report_privacy_error(&mut self, privacy_error: &PrivacyError<'ra>) { @@ -1983,10 +1972,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { .collect::<Vec<_>>(); candidates.sort(); candidates.dedup(); - match find_best_match_for_name(&candidates, ident, None) { - Some(sugg) if sugg == ident => None, - sugg => sugg, - } + find_best_match_for_name(&candidates, ident, None).filter(|sugg| *sugg != ident) } pub(crate) fn report_path_resolution_error( @@ -2044,13 +2030,23 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { (format!("`_` is not a valid crate or module name"), None) } else if self.tcx.sess.is_rust_2015() { ( - format!("you might be missing crate `{ident}`"), + format!("use of unresolved module or unlinked crate `{ident}`"), Some(( vec![( self.current_crate_outer_attr_insert_span, format!("extern crate {ident};\n"), )], - format!("consider importing the `{ident}` crate"), + if was_invoked_from_cargo() { + format!( + "if you wanted to use a crate named `{ident}`, use `cargo add {ident}` \ + to add it to your `Cargo.toml` and import it in your code", + ) + } else { + format!( + "you might be missing a crate named `{ident}`, add it to your \ + project and import it in your code", + ) + }, Applicability::MaybeIncorrect, )), ) @@ -2229,7 +2225,25 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let descr = binding.res().descr(); (format!("{descr} `{ident}` is not a crate or module"), suggestion) } else { - (format!("use of undeclared crate or module `{ident}`"), suggestion) + let suggestion = if suggestion.is_some() { + suggestion + } else if was_invoked_from_cargo() { + Some(( + vec![], + format!( + "if you wanted to use a crate named `{ident}`, use `cargo add {ident}` \ + to add it to your `Cargo.toml`", + ), + Applicability::MaybeIncorrect, + )) + } else { + Some(( + vec![], + format!("you might be missing a crate named `{ident}`",), + Applicability::MaybeIncorrect, + )) + }; + (format!("use of unresolved module or unlinked crate `{ident}`"), suggestion) } } } @@ -2411,115 +2425,115 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let binding_key = BindingKey::new(ident, MacroNS); let resolution = resolutions.get(&binding_key)?; let binding = resolution.borrow().binding()?; - if let Res::Def(DefKind::Macro(MacroKind::Bang), _) = binding.res() { - let module_name = crate_module.kind.name().unwrap(); - let import_snippet = match import.kind { - ImportKind::Single { source, target, .. } if source != target => { - format!("{source} as {target}") - } - _ => format!("{ident}"), - }; + let Res::Def(DefKind::Macro(MacroKind::Bang), _) = binding.res() else { + return None; + }; + let module_name = crate_module.kind.name().unwrap(); + let import_snippet = match import.kind { + ImportKind::Single { source, target, .. } if source != target => { + format!("{source} as {target}") + } + _ => format!("{ident}"), + }; - let mut corrections: Vec<(Span, String)> = Vec::new(); - if !import.is_nested() { - // Assume this is the easy case of `use issue_59764::foo::makro;` and just remove - // intermediate segments. - corrections.push((import.span, format!("{module_name}::{import_snippet}"))); - } else { - // Find the binding span (and any trailing commas and spaces). - // ie. `use a::b::{c, d, e};` - // ^^^ - let (found_closing_brace, binding_span) = find_span_of_binding_until_next_binding( - self.tcx.sess, - import.span, - import.use_span, - ); - debug!(found_closing_brace, ?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: - // ie. `use a::b::{c, d};` - // ^ - // Then expand the span of characters to remove to include the previous - // binding's trailing comma. - // ie. `use a::b::{c, d};` - // ^^^ - if let Some(previous_span) = - extend_span_to_previous_binding(self.tcx.sess, binding_span) - { - debug!(?previous_span); - removal_span = removal_span.with_lo(previous_span.lo()); - } - } - debug!(?removal_span); - - // Remove the `removal_span`. - corrections.push((removal_span, "".to_string())); - - // Find the span after the crate name and if it has nested imports immediately - // after the crate name already. - // ie. `use a::b::{c, d};` - // ^^^^^^^^^ - // or `use a::{b, c, d}};` - // ^^^^^^^^^^^ - let (has_nested, after_crate_name) = find_span_immediately_after_crate_name( - self.tcx.sess, - module_name, - import.use_span, - ); - debug!(has_nested, ?after_crate_name); + let mut corrections: Vec<(Span, String)> = Vec::new(); + if !import.is_nested() { + // Assume this is the easy case of `use issue_59764::foo::makro;` and just remove + // intermediate segments. + corrections.push((import.span, format!("{module_name}::{import_snippet}"))); + } else { + // Find the binding span (and any trailing commas and spaces). + // ie. `use a::b::{c, d, e};` + // ^^^ + let (found_closing_brace, binding_span) = find_span_of_binding_until_next_binding( + self.tcx.sess, + import.span, + import.use_span, + ); + debug!(found_closing_brace, ?binding_span); + + let mut removal_span = binding_span; + + // If the binding span ended with a closing brace, as in the below example: + // ie. `use a::b::{c, d};` + // ^ + // Then expand the span of characters to remove to include the previous + // binding's trailing comma. + // ie. `use a::b::{c, d};` + // ^^^ + if found_closing_brace + && let Some(previous_span) = + extend_span_to_previous_binding(self.tcx.sess, binding_span) + { + debug!(?previous_span); + removal_span = removal_span.with_lo(previous_span.lo()); + } + debug!(?removal_span); - let source_map = self.tcx.sess.source_map(); + // Remove the `removal_span`. + corrections.push((removal_span, "".to_string())); - // Make sure this is actually crate-relative. - let is_definitely_crate = import - .module_path - .first() - .is_some_and(|f| f.ident.name != kw::SelfLower && f.ident.name != kw::Super); + // Find the span after the crate name and if it has nested imports immediately + // after the crate name already. + // ie. `use a::b::{c, d};` + // ^^^^^^^^^ + // or `use a::{b, c, d}};` + // ^^^^^^^^^^^ + let (has_nested, after_crate_name) = + find_span_immediately_after_crate_name(self.tcx.sess, module_name, import.use_span); + debug!(has_nested, ?after_crate_name); - // Add the import to the start, with a `{` if required. - let start_point = source_map.start_point(after_crate_name); - if is_definitely_crate - && let Ok(start_snippet) = source_map.span_to_snippet(start_point) - { - corrections.push(( - start_point, - if has_nested { - // In this case, `start_snippet` must equal '{'. - format!("{start_snippet}{import_snippet}, ") - } else { - // In this case, add a `{`, then the moved import, then whatever - // was there before. - format!("{{{import_snippet}, {start_snippet}") - }, - )); + let source_map = self.tcx.sess.source_map(); - // Add a `};` to the end if nested, matching the `{` added at the start. - if !has_nested { - corrections - .push((source_map.end_point(after_crate_name), "};".to_string())); - } - } else { - // If the root import is module-relative, add the import separately - corrections.push(( - import.use_span.shrink_to_lo(), - format!("use {module_name}::{import_snippet};\n"), - )); + // Make sure this is actually crate-relative. + let is_definitely_crate = import + .module_path + .first() + .is_some_and(|f| f.ident.name != kw::SelfLower && f.ident.name != kw::Super); + + // Add the import to the start, with a `{` if required. + let start_point = source_map.start_point(after_crate_name); + if is_definitely_crate + && let Ok(start_snippet) = source_map.span_to_snippet(start_point) + { + corrections.push(( + start_point, + if has_nested { + // In this case, `start_snippet` must equal '{'. + format!("{start_snippet}{import_snippet}, ") + } else { + // In this case, add a `{`, then the moved import, then whatever + // was there before. + format!("{{{import_snippet}, {start_snippet}") + }, + )); + + // Add a `};` to the end if nested, matching the `{` added at the start. + if !has_nested { + corrections.push((source_map.end_point(after_crate_name), "};".to_string())); } + } else { + // If the root import is module-relative, add the import separately + corrections.push(( + import.use_span.shrink_to_lo(), + format!("use {module_name}::{import_snippet};\n"), + )); } + } - let suggestion = Some(( - corrections, - String::from("a macro with this name exists at the root of the crate"), - Applicability::MaybeIncorrect, - )); - Some((suggestion, Some("this could be because a macro annotated with `#[macro_export]` will be exported \ + let suggestion = Some(( + corrections, + String::from("a macro with this name exists at the root of the crate"), + Applicability::MaybeIncorrect, + )); + 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" - .to_string()))) - } else { - None - } + .to_string(), + ), + )) } /// Finds a cfg-ed out item inside `module` with the matching name. @@ -3043,7 +3057,6 @@ impl<'tcx> visit::Visitor<'tcx> for UsePlacementFinder { self.first_legal_span = Some(inject); } self.first_use_span = search_for_any_use_in_items(&c.items); - return; } else { visit::walk_crate(self, c); } @@ -3057,7 +3070,6 @@ impl<'tcx> visit::Visitor<'tcx> for UsePlacementFinder { self.first_legal_span = Some(inject); } self.first_use_span = search_for_any_use_in_items(items); - return; } } else { visit::walk_item(self, item); @@ -3067,16 +3079,16 @@ impl<'tcx> visit::Visitor<'tcx> for UsePlacementFinder { fn search_for_any_use_in_items(items: &[P<ast::Item>]) -> Option<Span> { for item in items { - if let ItemKind::Use(..) = item.kind { - if is_span_suitable_for_use_injection(item.span) { - let mut lo = item.span.lo(); - for attr in &item.attrs { - if attr.span.eq_ctxt(item.span) { - lo = std::cmp::min(lo, attr.span.lo()); - } + if let ItemKind::Use(..) = item.kind + && is_span_suitable_for_use_injection(item.span) + { + let mut lo = item.span.lo(); + for attr in &item.attrs { + if attr.span.eq_ctxt(item.span) { + lo = std::cmp::min(lo, attr.span.lo()); } - 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 diff --git a/compiler/rustc_resolve/src/effective_visibilities.rs b/compiler/rustc_resolve/src/effective_visibilities.rs index e279d14704e..6ef4aa40725 100644 --- a/compiler/rustc_resolve/src/effective_visibilities.rs +++ b/compiler/rustc_resolve/src/effective_visibilities.rs @@ -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); } } } diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs index 3bfe98f7091..7eb795034b0 100644 --- a/compiler/rustc_resolve/src/errors.rs +++ b/compiler/rustc_resolve/src/errors.rs @@ -59,7 +59,7 @@ pub(crate) struct NameAlreadyUsedInParameterList { pub(crate) span: Span, #[label(resolve_first_use_of_name)] pub(crate) first_use_span: Span, - pub(crate) name: Symbol, + pub(crate) name: Ident, } #[derive(Diagnostic)] @@ -142,7 +142,7 @@ pub(crate) struct VariableBoundWithDifferentMode { pub(crate) span: Span, #[label(resolve_first_binding_span)] pub(crate) first_binding_span: Span, - pub(crate) variable_name: Symbol, + pub(crate) variable_name: Ident, } #[derive(Diagnostic)] @@ -151,7 +151,7 @@ pub(crate) struct IdentifierBoundMoreThanOnceInParameterList { #[primary_span] #[label] pub(crate) span: Span, - pub(crate) identifier: Symbol, + pub(crate) identifier: Ident, } #[derive(Diagnostic)] @@ -160,7 +160,7 @@ pub(crate) struct IdentifierBoundMoreThanOnceInSamePattern { #[primary_span] #[label] pub(crate) span: Span, - pub(crate) identifier: Symbol, + pub(crate) identifier: Ident, } #[derive(Diagnostic)] @@ -478,7 +478,7 @@ pub(crate) struct TraitImplDuplicate { pub(crate) old_span: Span, #[label(resolve_trait_item_span)] pub(crate) trait_item_span: Span, - pub(crate) name: Symbol, + pub(crate) name: Ident, } #[derive(Diagnostic)] @@ -976,7 +976,7 @@ pub(crate) struct AttemptToDefineBuiltinMacroTwice { pub(crate) struct VariableIsNotBoundInAllPatterns { #[primary_span] pub(crate) multispan: MultiSpan, - pub(crate) name: Symbol, + pub(crate) name: Ident, } #[derive(Subdiagnostic, Debug, Clone)] @@ -984,7 +984,7 @@ pub(crate) struct VariableIsNotBoundInAllPatterns { pub(crate) struct PatternDoesntBindName { #[primary_span] pub(crate) span: Span, - pub(crate) name: Symbol, + pub(crate) name: Ident, } #[derive(Subdiagnostic, Debug, Clone)] @@ -1260,7 +1260,7 @@ pub(crate) struct TraitImplMismatch { #[primary_span] #[label] pub(crate) span: Span, - pub(crate) name: Symbol, + pub(crate) name: Ident, pub(crate) kind: &'static str, pub(crate) trait_path: String, #[label(resolve_trait_impl_mismatch_label_item)] diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index 45e87edc53e..499b9bca4d2 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -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. --- @@ -1184,21 +1181,25 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } Some(_) => None, }; - (rib_ident.span, AttemptToUseNonConstantValueInConstant { - ident: original_rib_ident_def, - suggestion: "const", - current: "let", - type_span, - }) + ( + rib_ident.span, + AttemptToUseNonConstantValueInConstant { + ident: original_rib_ident_def, + suggestion: "const", + current: "let", + type_span, + }, + ) } - Some((ident, kind)) => { - (span, AttemptToUseNonConstantValueInConstant { + Some((ident, kind)) => ( + span, + AttemptToUseNonConstantValueInConstant { ident, suggestion: "let", current: kind.as_str(), type_span: None, - }) - } + }, + ), }; self.report_error(span, resolution_error); } @@ -1206,10 +1207,13 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } RibKind::ConstParamTy => { if let Some(span) = finalize { - self.report_error(span, ParamInTyOfConstParam { - name: rib_ident.name, - param_kind: None, - }); + self.report_error( + span, + ParamInTyOfConstParam { + name: rib_ident.name, + param_kind: None, + }, + ); } return Res::Err; } @@ -1290,10 +1294,13 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } RibKind::ConstParamTy => { if let Some(span) = finalize { - self.report_error(span, ResolutionError::ParamInTyOfConstParam { - name: rib_ident.name, - param_kind: Some(errors::ParamKindInTyOfConstParam::Type), - }); + self.report_error( + span, + ResolutionError::ParamInTyOfConstParam { + name: rib_ident.name, + param_kind: Some(errors::ParamKindInTyOfConstParam::Type), + }, + ); } return Res::Err; } @@ -1356,10 +1363,13 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } RibKind::ConstParamTy => { if let Some(span) = finalize { - self.report_error(span, ResolutionError::ParamInTyOfConstParam { - name: rib_ident.name, - param_kind: Some(errors::ParamKindInTyOfConstParam::Const), - }); + self.report_error( + span, + ResolutionError::ParamInTyOfConstParam { + name: rib_ident.name, + param_kind: Some(errors::ParamKindInTyOfConstParam::Const), + }, + ); } return Res::Err; } @@ -1437,13 +1447,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 +1472,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 +1652,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( diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 29b4d913c82..b1b234eb757 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -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, - }, - ); - } - } } } } @@ -918,12 +914,15 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } => { if no_ambiguity { assert!(import.imported_module.get().is_none()); - self.report_error(span, ResolutionError::FailedToResolve { - segment: Some(segment_name), - label, - suggestion, - module, - }); + self.report_error( + span, + ResolutionError::FailedToResolve { + segment: Some(segment_name), + label, + suggestion, + module, + }, + ); } return None; } @@ -1006,21 +1005,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 +1078,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 +1243,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 +1472,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); } } } @@ -1505,7 +1503,7 @@ fn import_path_to_string(names: &[Ident], import_kind: &ImportKind<'_>, span: Sp let global = !names.is_empty() && names[0].name == kw::PathRoot; if let Some(pos) = pos { let names = if global { &names[1..pos + 1] } else { &names[..pos + 1] }; - names_to_string(&names.iter().map(|ident| ident.name).collect::<Vec<_>>()) + names_to_string(names.iter().map(|ident| ident.name)) } else { let names = if global { &names[1..] } else { names }; if names.is_empty() { @@ -1513,7 +1511,7 @@ fn import_path_to_string(names: &[Ident], import_kind: &ImportKind<'_>, span: Sp } else { format!( "{}::{}", - names_to_string(&names.iter().map(|ident| ident.name).collect::<Vec<_>>()), + names_to_string(names.iter().map(|ident| ident.name)), import_kind_to_string(import_kind), ) } diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index bbcbb5d1ce4..508bd831ccb 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -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", }, @@ -990,8 +986,8 @@ impl<'ra: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'r match fn_kind { // Bail if the function is foreign, and thus cannot validly have // a body, or if there's no body for some other reason. - FnKind::Fn(FnCtxt::Foreign, _, sig, _, generics, _) - | FnKind::Fn(_, _, sig, _, generics, None) => { + FnKind::Fn(FnCtxt::Foreign, _, _, Fn { sig, generics, .. }) + | FnKind::Fn(_, _, _, Fn { sig, generics, body: None, .. }) => { self.visit_fn_header(&sig.header); self.visit_generics(generics); self.with_lifetime_rib( @@ -1023,7 +1019,7 @@ impl<'ra: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'r // Create a label rib for the function. this.with_label_rib(RibKind::FnOrCoroutine, |this| { match fn_kind { - FnKind::Fn(_, _, sig, _, generics, body) => { + FnKind::Fn(_, _, _, Fn { sig, generics, contract, body, .. }) => { this.visit_generics(generics); let declaration = &sig.decl; @@ -1050,6 +1046,10 @@ impl<'ra: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'r }, ); + if let Some(contract) = contract { + this.visit_contract(contract); + } + if let Some(body) = body { // Ignore errors in function bodies if this is rustdoc // Be sure not to set this until the function signature has been resolved. @@ -1182,32 +1182,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 +1238,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 +1732,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 +1800,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 @@ -1833,9 +1823,11 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { && Some(true) == self.diag_metadata.in_non_gat_assoc_type && let crate::ModuleKind::Def(DefKind::Trait, trait_id, _) = module.kind { - if def_id_matches_path(self.r.tcx, trait_id, &[ - "core", "iter", "traits", "iterator", "Iterator", - ]) { + if def_id_matches_path( + self.r.tcx, + trait_id, + &["core", "iter", "traits", "iterator", "Iterator"], + ) { self.r.dcx().emit_err(errors::LendingIteratorReportError { lifetime: lifetime.ident.span, ty: ty.span, @@ -2460,12 +2452,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 +2485,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) { @@ -2856,7 +2841,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { match seen_bindings.entry(ident) { Entry::Occupied(entry) => { let span = *entry.get(); - let err = ResolutionError::NameAlreadyUsedInParameterList(ident.name, span); + let err = ResolutionError::NameAlreadyUsedInParameterList(ident, span); self.report_error(param.ident.span, err); let rib = match param.kind { GenericParamKind::Lifetime => { @@ -3442,11 +3427,14 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { match seen_trait_items.entry(id_in_trait) { Entry::Occupied(entry) => { - self.report_error(span, ResolutionError::TraitImplDuplicate { - name: ident.name, - old_span: *entry.get(), - trait_item_span: binding.span, - }); + self.report_error( + span, + ResolutionError::TraitImplDuplicate { + name: ident, + old_span: *entry.get(), + trait_item_span: binding.span, + }, + ); return; } Entry::Vacant(entry) => { @@ -3477,13 +3465,16 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { } }; let trait_path = path_names_to_string(path); - self.report_error(span, ResolutionError::TraitImplMismatch { - name: ident.name, - kind, - code, - trait_path, - trait_item_span: binding.span, - }); + self.report_error( + span, + ResolutionError::TraitImplMismatch { + name: ident, + kind, + code, + trait_path, + trait_item_span: binding.span, + }, + ); } fn resolve_const_body(&mut self, expr: &'ast Expr, item: Option<(Ident, ConstantItemKind)>) { @@ -3505,21 +3496,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]) { @@ -3662,9 +3652,8 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { .filter(|(_, pat)| pat.id != pat_outer.id) .flat_map(|(map, _)| map); - for (key, binding_inner) in inners { - let name = key.name; - match map_outer.get(key) { + for (&name, binding_inner) in inners { + match map_outer.get(&name) { None => { // The inner binding is missing in the outer. let binding_error = @@ -3864,10 +3853,13 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { .patterns_with_skipped_bindings .entry(def_id) .or_default() - .push((pat.span, match rest { - ast::PatFieldsRest::Recovered(guar) => Err(*guar), - _ => Ok(()), - })); + .push(( + pat.span, + match rest { + ast::PatFieldsRest::Recovered(guar) => Err(*guar), + _ => Ok(()), + }, + )); } } ast::PatFieldsRest::None => {} @@ -3902,7 +3894,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { // `Variant(a, a)`: _ => IdentifierBoundMoreThanOnceInSamePattern, }; - self.report_error(ident.span, error(ident.name)); + self.report_error(ident.span, error(ident)); } // Record as bound if it's valid: @@ -4504,12 +4496,15 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { segment_name, error_implied_by_parse_error: _, } => { - return Err(respan(span, ResolutionError::FailedToResolve { - segment: Some(segment_name), - label, - suggestion, - module, - })); + return Err(respan( + span, + ResolutionError::FailedToResolve { + segment: Some(segment_name), + label, + suggestion, + module, + }, + )); } PathResult::Module(..) | PathResult::Failed { .. } => return Ok(None), PathResult::Indeterminate => bug!("indeterminate path result in resolve_qpath"), diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 17c92c7b501..a80b68d9773 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -224,7 +224,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { let suggestion = if self.current_trait_ref.is_none() && let Some((fn_kind, _)) = self.diag_metadata.current_function && let Some(FnCtxt::Assoc(_)) = fn_kind.ctxt() - && let FnKind::Fn(_, _, sig, ..) = fn_kind + && let FnKind::Fn(_, _, _, ast::Fn { sig, .. }) = fn_kind && let Some(items) = self.diag_metadata.current_impl_items && let Some(item) = items.iter().find(|i| { i.ident.name == item_str.name @@ -560,7 +560,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { Applicability::MaybeIncorrect, ); if !self.self_value_is_available(path[0].ident.span) { - if let Some((FnKind::Fn(_, _, sig, ..), fn_span)) = + if let Some((FnKind::Fn(_, _, _, ast::Fn { sig, .. }), fn_span)) = &self.diag_metadata.current_function { let (span, sugg) = if let Some(param) = sig.decl.inputs.get(0) { @@ -1048,12 +1048,15 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { debug!("smart_resolve_path_fragment: E0424, source={:?}", source); err.code(E0424); - err.span_label(span, match source { - PathSource::Pat => { - "`self` value is a keyword and may not be bound to variables or shadowed" - } - _ => "`self` value is a keyword only available in methods with a `self` parameter", - }); + err.span_label( + span, + match source { + PathSource::Pat => { + "`self` value is a keyword and may not be bound to variables or shadowed" + } + _ => "`self` value is a keyword only available in methods with a `self` parameter", + }, + ); let is_assoc_fn = self.self_type_is_available(); let self_from_macro = "a `self` parameter, but a macro invocation can only \ access identifiers it receives from parameters"; @@ -1636,13 +1639,12 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { .enumerate() .map(|(idx, new)| (new, old_fields.get(idx))) .map(|(new, old)| { - let new = new.name.to_ident_string(); if let Some(Some(old)) = old - && new != *old + && new.as_str() != old { format!("{new}: {old}") } else { - new + new.to_string() } }) .collect::<Vec<String>>() @@ -2400,15 +2402,18 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { if module_def_id == def_id { let path = Path { span: name_binding.span, segments: path_segments, tokens: None }; - result = Some((module, ImportSuggestion { - did: Some(def_id), - descr: "module", - path, - accessible: true, - doc_visible, - note: None, - via_import: false, - })); + result = Some(( + module, + ImportSuggestion { + did: Some(def_id), + descr: "module", + path, + accessible: true, + doc_visible, + note: None, + via_import: false, + }, + )); } else { // add the module to the lookup if seen_modules.insert(module_def_id) { @@ -3250,7 +3255,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { { let pre = if lt.kind == MissingLifetimeKind::Ampersand && let Some((kind, _span)) = self.diag_metadata.current_function - && let FnKind::Fn(_, _, sig, _, _, _) = kind + && let FnKind::Fn(_, _, _, ast::Fn { sig, .. }) = kind && !sig.decl.inputs.is_empty() && let sugg = sig .decl @@ -3291,7 +3296,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { } else if (lt.kind == MissingLifetimeKind::Ampersand || lt.kind == MissingLifetimeKind::Underscore) && let Some((kind, _span)) = self.diag_metadata.current_function - && let FnKind::Fn(_, _, sig, _, _, _) = kind + && let FnKind::Fn(_, _, _, ast::Fn { sig, .. }) = kind && let ast::FnRetTy::Ty(ret_ty) = &sig.decl.output && !sig.decl.inputs.is_empty() && let arg_refs = sig @@ -3351,7 +3356,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { let mut owned_sugg = lt.kind == MissingLifetimeKind::Ampersand; let mut sugg = vec![(lt.span, String::new())]; if let Some((kind, _span)) = self.diag_metadata.current_function - && let FnKind::Fn(_, _, sig, _, _, _) = kind + && let FnKind::Fn(_, _, _, ast::Fn { sig, .. }) = kind && let ast::FnRetTy::Ty(ty) = &sig.decl.output { let mut lt_finder = diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 3b18e480be4..90191b7776f 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -27,6 +27,7 @@ use std::cell::{Cell, RefCell}; use std::collections::BTreeSet; use std::fmt; +use std::sync::Arc; use diagnostics::{ImportSuggestion, LabelSuggestion, Suggestion}; use effective_visibilities::EffectiveVisibilitiesVisitor; @@ -46,7 +47,7 @@ use rustc_ast::{ use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet}; use rustc_data_structures::intern::Interned; use rustc_data_structures::steal::Steal; -use rustc_data_structures::sync::{FreezeReadGuard, Lrc}; +use rustc_data_structures::sync::FreezeReadGuard; use rustc_errors::{Applicability, Diag, ErrCode, ErrorGuaranteed}; use rustc_expand::base::{DeriveResolution, SyntaxExtension, SyntaxExtensionKind}; use rustc_feature::BUILTIN_ATTRIBUTES; @@ -214,7 +215,7 @@ enum Used { #[derive(Debug)] struct BindingError { - name: Symbol, + name: Ident, origin: BTreeSet<Span>, target: BTreeSet<Span>, could_be_path: bool, @@ -226,7 +227,7 @@ enum ResolutionError<'ra> { GenericParamsFromOuterItem(Res, HasGenericParams, DefKind), /// Error E0403: the name is already used for a type or const parameter in this generic /// parameter list. - NameAlreadyUsedInParameterList(Symbol, Span), + NameAlreadyUsedInParameterList(Ident, Span), /// Error E0407: method is not a member of trait. MethodNotMemberOfTrait(Ident, String, Option<Symbol>), /// Error E0437: type is not a member of trait. @@ -236,11 +237,11 @@ enum ResolutionError<'ra> { /// Error E0408: variable `{}` is not bound in all patterns. VariableNotBoundInPattern(BindingError, ParentScope<'ra>), /// Error E0409: variable `{}` is bound in inconsistent ways within the same match arm. - VariableBoundWithDifferentMode(Symbol, Span), + VariableBoundWithDifferentMode(Ident, Span), /// Error E0415: identifier is bound more than once in this parameter list. - IdentifierBoundMoreThanOnceInParameterList(Symbol), + IdentifierBoundMoreThanOnceInParameterList(Ident), /// Error E0416: identifier is bound more than once in the same pattern. - IdentifierBoundMoreThanOnceInSamePattern(Symbol), + IdentifierBoundMoreThanOnceInSamePattern(Ident), /// Error E0426: use of undeclared label. UndeclaredLabel { name: Symbol, suggestion: Option<LabelSuggestion> }, /// Error E0429: `self` imports are only allowed within a `{ }` list. @@ -292,14 +293,14 @@ enum ResolutionError<'ra> { UnreachableLabel { name: Symbol, definition_span: Span, suggestion: Option<LabelSuggestion> }, /// Error E0323, E0324, E0325: mismatch between trait item and impl item. TraitImplMismatch { - name: Symbol, + name: Ident, kind: &'static str, trait_path: String, trait_item_span: Span, code: ErrCode, }, /// Error E0201: multiple impl items for the same trait item. - TraitImplDuplicate { name: Symbol, trait_item_span: Span, old_span: Span }, + TraitImplDuplicate { name: Ident, trait_item_span: Span, old_span: Span }, /// Inline asm `sym` operand must refer to a `fn` or `static`. InvalidAsmSym, /// `self` used instead of `Self` in a generic parameter @@ -357,7 +358,7 @@ impl Segment { } fn names_to_string(segments: &[Segment]) -> String { - names_to_string(&segments.iter().map(|seg| seg.ident.name).collect::<Vec<_>>()) + names_to_string(segments.iter().map(|seg| seg.ident.name)) } } @@ -995,13 +996,13 @@ struct DeriveData { } struct MacroData { - ext: Lrc<SyntaxExtension>, + ext: Arc<SyntaxExtension>, rule_spans: Vec<(usize, Span)>, macro_rules: bool, } impl MacroData { - fn new(ext: Lrc<SyntaxExtension>) -> MacroData { + fn new(ext: Arc<SyntaxExtension>) -> MacroData { MacroData { ext, rule_spans: Vec::new(), macro_rules: false } } } @@ -1110,8 +1111,8 @@ pub struct Resolver<'ra, 'tcx> { registered_tools: &'tcx RegisteredTools, macro_use_prelude: FxHashMap<Symbol, NameBinding<'ra>>, macro_map: FxHashMap<DefId, MacroData>, - dummy_ext_bang: Lrc<SyntaxExtension>, - dummy_ext_derive: Lrc<SyntaxExtension>, + dummy_ext_bang: Arc<SyntaxExtension>, + dummy_ext_derive: Arc<SyntaxExtension>, non_macro_attr: MacroData, local_macro_def_scopes: FxHashMap<LocalDefId, Module<'ra>>, ast_transform_scopes: FxHashMap<LocalExpnId, Module<'ra>>, @@ -1510,9 +1511,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { registered_tools, macro_use_prelude: FxHashMap::default(), macro_map: FxHashMap::default(), - dummy_ext_bang: Lrc::new(SyntaxExtension::dummy_bang(edition)), - dummy_ext_derive: Lrc::new(SyntaxExtension::dummy_derive(edition)), - non_macro_attr: MacroData::new(Lrc::new(SyntaxExtension::non_macro_attr(edition))), + dummy_ext_bang: Arc::new(SyntaxExtension::dummy_bang(edition)), + dummy_ext_derive: Arc::new(SyntaxExtension::dummy_derive(edition)), + non_macro_attr: MacroData::new(Arc::new(SyntaxExtension::non_macro_attr(edition))), invocation_parent_scopes: Default::default(), output_macro_rules_scopes: Default::default(), macro_rules_scopes: Default::default(), @@ -1688,11 +1689,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { CStore::from_tcx(self.tcx) } - fn dummy_ext(&self, macro_kind: MacroKind) -> Lrc<SyntaxExtension> { + fn dummy_ext(&self, macro_kind: MacroKind) -> Arc<SyntaxExtension> { match macro_kind { - MacroKind::Bang => Lrc::clone(&self.dummy_ext_bang), - MacroKind::Derive => Lrc::clone(&self.dummy_ext_derive), - MacroKind::Attr => Lrc::clone(&self.non_macro_attr.ext), + MacroKind::Bang => Arc::clone(&self.dummy_ext_bang), + MacroKind::Derive => Arc::clone(&self.dummy_ext_derive), + MacroKind::Attr => Arc::clone(&self.non_macro_attr.ext), } } @@ -2240,13 +2241,13 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } } -fn names_to_string(names: &[Symbol]) -> String { +fn names_to_string(names: impl Iterator<Item = Symbol>) -> String { let mut result = String::new(); - for (i, name) in names.iter().filter(|name| **name != kw::PathRoot).enumerate() { + for (i, name) in names.filter(|name| *name != kw::PathRoot).enumerate() { if i > 0 { result.push_str("::"); } - if Ident::with_dummy_span(*name).is_raw_guess() { + if Ident::with_dummy_span(name).is_raw_guess() { result.push_str("r#"); } result.push_str(name.as_str()); @@ -2255,31 +2256,32 @@ fn names_to_string(names: &[Symbol]) -> String { } fn path_names_to_string(path: &Path) -> String { - names_to_string(&path.segments.iter().map(|seg| seg.ident.name).collect::<Vec<_>>()) + names_to_string(path.segments.iter().map(|seg| seg.ident.name)) } /// A somewhat inefficient routine to obtain the name of a module. -fn module_to_string(module: Module<'_>) -> Option<String> { +fn module_to_string(mut module: Module<'_>) -> Option<String> { let mut names = Vec::new(); - - fn collect_mod(names: &mut Vec<Symbol>, module: Module<'_>) { + loop { if let ModuleKind::Def(.., name) = module.kind { if let Some(parent) = module.parent { names.push(name); - collect_mod(names, parent); + module = parent + } else { + break; } } else { names.push(sym::opaque_module_name_placeholder); - collect_mod(names, module.parent.unwrap()); + let Some(parent) = module.parent else { + return None; + }; + module = parent; } } - collect_mod(&mut names, module); - if names.is_empty() { return None; } - names.reverse(); - Some(names_to_string(&names)) + Some(names_to_string(names.iter().rev().copied())) } #[derive(Copy, Clone, Debug)] diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 4ff54f47435..cca01a01e98 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -3,6 +3,7 @@ use std::cell::Cell; use std::mem; +use std::sync::Arc; use rustc_ast::attr::AttributeExt; use rustc_ast::expand::StrippedCfgItem; @@ -10,7 +11,6 @@ use rustc_ast::{self as ast, Crate, NodeId, attr}; use rustc_ast_pretty::pprust; use rustc_attr_parsing::StabilityLevel; use rustc_data_structures::intern::Interned; -use rustc_data_structures::sync::Lrc; use rustc_errors::{Applicability, StashKey}; use rustc_expand::base::{ DeriveResolution, Indeterminate, ResolverExpand, SyntaxExtension, SyntaxExtensionKind, @@ -239,7 +239,7 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> { invoc: &Invocation, eager_expansion_root: LocalExpnId, force: bool, - ) -> Result<Lrc<SyntaxExtension>, Indeterminate> { + ) -> Result<Arc<SyntaxExtension>, Indeterminate> { let invoc_id = invoc.expansion_data.id; let parent_scope = match self.invocation_parent_scopes.get(&invoc_id) { Some(parent_scope) => *parent_scope, @@ -529,7 +529,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { force: bool, deleg_impl: Option<LocalDefId>, invoc_in_mod_inert_attr: Option<LocalDefId>, - ) -> Result<(Lrc<SyntaxExtension>, Res), Indeterminate> { + ) -> Result<(Arc<SyntaxExtension>, Res), Indeterminate> { let (ext, res) = match self.resolve_macro_or_delegation_path( path, Some(kind), @@ -682,7 +682,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { trace: bool, force: bool, ignore_import: Option<Import<'ra>>, - ) -> Result<(Option<Lrc<SyntaxExtension>>, Res), Determinacy> { + ) -> Result<(Option<Arc<SyntaxExtension>>, Res), Determinacy> { self.resolve_macro_or_delegation_path( path, kind, @@ -705,7 +705,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { deleg_impl: Option<LocalDefId>, invoc_in_mod_inert_attr: Option<(LocalDefId, NodeId)>, ignore_import: Option<Import<'ra>>, - ) -> Result<(Option<Lrc<SyntaxExtension>>, Res), Determinacy> { + ) -> Result<(Option<Arc<SyntaxExtension>>, Res), Determinacy> { let path_span = ast_path.span; let mut path = Segment::from_path(ast_path); @@ -788,11 +788,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { Some(impl_def_id) => match res { def::Res::Def(DefKind::Trait, def_id) => { let edition = self.tcx.sess.edition(); - Some(Lrc::new(SyntaxExtension::glob_delegation(def_id, impl_def_id, edition))) + Some(Arc::new(SyntaxExtension::glob_delegation(def_id, impl_def_id, edition))) } _ => None, }, - None => self.get_macro(res).map(|macro_data| Lrc::clone(¯o_data.ext)), + None => self.get_macro(res).map(|macro_data| Arc::clone(¯o_data.ext)), }; Ok((ext, res)) } @@ -888,12 +888,15 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { None, ) }; - self.report_error(span, ResolutionError::FailedToResolve { - segment: path.last().map(|segment| segment.ident.name), - label, - suggestion, - module, - }); + self.report_error( + span, + ResolutionError::FailedToResolve { + segment: path.last().map(|segment| segment.ident.name), + label, + suggestion, + module, + }, + ); } PathResult::Module(..) | PathResult::Indeterminate => unreachable!(), } @@ -1130,7 +1133,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } } - MacroData { ext: Lrc::new(ext), rule_spans, macro_rules: macro_def.macro_rules } + MacroData { ext: Arc::new(ext), rule_spans, macro_rules: macro_def.macro_rules } } fn path_accessible( |
