diff options
| author | bors <bors@rust-lang.org> | 2023-02-26 17:17:25 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2023-02-26 17:17:25 +0000 |
| commit | 56ac6bfc87cce22feffc079c0540c8774b00a5ca (patch) | |
| tree | e430c91fb4e29070945f79df7a47639e5cf4f9b1 /compiler/rustc_resolve | |
| parent | ffd12f67cfa28891bbd1fa81d5e80a128f346ace (diff) | |
| parent | cb45103358c0fef99d7659e0949b3c65b3eabdd6 (diff) | |
| download | rust-56ac6bfc87cce22feffc079c0540c8774b00a5ca.tar.gz rust-56ac6bfc87cce22feffc079c0540c8774b00a5ca.zip | |
Auto merge of #2803 - RalfJung:rustup, r=RalfJung
Rustup
Diffstat (limited to 'compiler/rustc_resolve')
| -rw-r--r-- | compiler/rustc_resolve/Cargo.toml | 2 | ||||
| -rw-r--r-- | compiler/rustc_resolve/locales/en-US.ftl | 211 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/diagnostics.rs | 75 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/errors.rs | 14 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/imports.rs | 143 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/lib.rs | 15 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/macros.rs | 3 |
7 files changed, 327 insertions, 136 deletions
diff --git a/compiler/rustc_resolve/Cargo.toml b/compiler/rustc_resolve/Cargo.toml index d4935b52b10..5c4ec44d2b8 100644 --- a/compiler/rustc_resolve/Cargo.toml +++ b/compiler/rustc_resolve/Cargo.toml @@ -25,5 +25,5 @@ rustc_query_system = { path = "../rustc_query_system" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } -thin-vec = "0.2.8" +thin-vec = "0.2.12" tracing = "0.1" diff --git a/compiler/rustc_resolve/locales/en-US.ftl b/compiler/rustc_resolve/locales/en-US.ftl new file mode 100644 index 00000000000..817bb83ed78 --- /dev/null +++ b/compiler/rustc_resolve/locales/en-US.ftl @@ -0,0 +1,211 @@ +resolve_parent_module_reset_for_binding = + parent module is reset for binding + +resolve_ampersand_used_without_explicit_lifetime_name = + `&` without an explicit lifetime name cannot be used here + .note = explicit lifetime name needed here + +resolve_underscore_lifetime_name_cannot_be_used_here = + `'_` cannot be used here + .note = `'_` is a reserved lifetime name + +resolve_crate_may_not_be_imported = + `$crate` may not be imported + +resolve_crate_root_imports_must_be_named_explicitly = + crate root imports need to be explicitly named: `use crate as name;` + +resolve_generic_params_from_outer_function = + can't use generic parameters from outer function + .label = use of generic parameter from outer function + .suggestion = try using a local generic parameter instead + +resolve_self_type_implicitly_declared_by_impl = + `Self` type implicitly declared here, by this `impl` + +resolve_cannot_use_self_type_here = + can't use `Self` here + +resolve_use_a_type_here_instead = + use a type here instead + +resolve_type_param_from_outer_fn = + type parameter from outer function + +resolve_const_param_from_outer_fn = + const parameter from outer function + +resolve_try_using_local_generic_parameter = + try using a local generic parameter instead + +resolve_try_adding_local_generic_param_on_method = + try adding a local generic parameter in this method instead + +resolve_help_try_using_local_generic_param = + try using a local generic paramter instead + +resolve_name_is_already_used_as_generic_parameter = + the name `{$name}` is already used for a generic parameter in this item's generic parameters + .label = already used + .first_use_of_name = first use of `{$name}` + +resolve_method_not_member_of_trait = + method `{$method}` is not a member of trait `{$trait_}` + .label = not a member of trait `{$trait_}` + +resolve_associated_fn_with_similar_name_exists = + there is an associated function with a similar name + +resolve_type_not_member_of_trait = + type `{$type_}` is not a member of trait `{$trait_}` + .label = not a member of trait `{$trait_}` + +resolve_associated_type_with_similar_name_exists = + there is an associated type with a similar name + +resolve_const_not_member_of_trait = + const `{$const_}` is not a member of trait `{$trait_}` + .label = not a member of trait `{$trait_}` + +resolve_associated_const_with_similar_name_exists = + there is an associated constant with a similar name + +resolve_variable_bound_with_different_mode = + variable `{$variable_name}` is bound inconsistently across alternatives separated by `|` + .label = bound in different ways + .first_binding_span = first binding + +resolve_ident_bound_more_than_once_in_parameter_list = + identifier `{$identifier}` is bound more than once in this parameter list + .label = used as parameter more than once + +resolve_ident_bound_more_than_once_in_same_pattern = + identifier `{$identifier}` is bound more than once in the same pattern + .label = used in a pattern more than once + +resolve_undeclared_label = + use of undeclared label `{$name}` + .label = undeclared label `{$name}` + +resolve_label_with_similar_name_reachable = + a label with a similar name is reachable + +resolve_try_using_similarly_named_label = + try using similarly named label + +resolve_unreachable_label_with_similar_name_exists = + a label with a similar name exists but is unreachable + +resolve_self_import_can_only_appear_once_in_the_list = + `self` import can only appear once in an import list + .label = can only appear once in an import list + +resolve_self_import_only_in_import_list_with_non_empty_prefix = + `self` import can only appear in an import list with a non-empty prefix + .label = can only appear in an import list with a non-empty prefix + +resolve_cannot_capture_dynamic_environment_in_fn_item = + can't capture dynamic environment in a fn item + .help = use the `|| {"{"} ... {"}"}` closure form instead + +resolve_attempt_to_use_non_constant_value_in_constant = + attempt to use a non-constant value in a constant + +resolve_attempt_to_use_non_constant_value_in_constant_with_suggestion = + consider using `{$suggestion}` instead of `{$current}` + +resolve_attempt_to_use_non_constant_value_in_constant_label_with_suggestion = + non-constant value + +resolve_attempt_to_use_non_constant_value_in_constant_without_suggestion = + this would need to be a `{$suggestion}` + +resolve_self_imports_only_allowed_within = + `self` imports are only allowed within a {"{"} {"}"} list + +resolve_self_imports_only_allowed_within_suggestion = + consider importing the module directly + +resolve_self_imports_only_allowed_within_multipart_suggestion = + alternatively, use the multi-path `use` syntax to import `self` + +resolve_binding_shadows_something_unacceptable = + {$shadowing_binding}s cannot shadow {$shadowed_binding}s + .label = cannot be named the same as {$article} {$shadowed_binding} + .label_shadowed_binding = the {$shadowed_binding} `{$name}` is {$participle} here + +resolve_binding_shadows_something_unacceptable_suggestion = + try specify the pattern arguments + +resolve_forward_declared_generic_param = + generic parameters with a default cannot use forward declared identifiers + .label = defaulted generic parameters cannot be forward declared + +resolve_param_in_ty_of_const_param = + the type of const parameters must not depend on other generic parameters + .label = the type must not depend on the parameter `{$name}` + +resolve_self_in_generic_param_default = + generic parameters cannot use `Self` in their defaults + .label = `Self` in generic parameter default + +resolve_param_in_non_trivial_anon_const = + generic parameters may not be used in const operations + .label = cannot perform const operation using `{$name}` + +resolve_param_in_non_trivial_anon_const_help = + use `#![feature(generic_const_exprs)]` to allow generic const expressions + +resolve_param_in_non_trivial_anon_const_sub_type = + type parameters may not be used in const expressions + +resolve_param_in_non_trivial_anon_const_sub_non_type = + const parameters may only be used as standalone arguments, i.e. `{$name}` + +resolve_unreachable_label = + use of unreachable label `{$name}` + .label = unreachable label `{$name}` + .label_definition_span = unreachable label defined here + .note = labels are unreachable through functions, closures, async blocks and modules + +resolve_unreachable_label_suggestion_use_similarly_named = + try using similarly named label + +resolve_unreachable_label_similar_name_reachable = + a label with a similar name is reachable + +resolve_unreachable_label_similar_name_unreachable = + a label with a similar name exists but is also unreachable + +resolve_trait_impl_mismatch = + item `{$name}` is an associated {$kind}, which doesn't match its trait `{$trait_path}` + .label = does not match trait + .label_trait_item = item in trait + +resolve_invalid_asm_sym = + invalid `sym` operand + .label = is a local variable + .help = `sym` operands must refer to either a function or a static + +resolve_trait_impl_duplicate = + duplicate definitions with name `{$name}`: + .label = duplicate definition + .old_span_label = previous definition here + .trait_item_span = item in trait + +resolve_relative_2018 = + relative paths are not supported in visibilities in 2018 edition or later + .suggestion = try + +resolve_ancestor_only = + visibilities can only be restricted to ancestor modules + +resolve_expected_found = + expected module, found {$res} `{$path_str}` + .label = not a module + +resolve_indeterminate = + cannot determine resolution for the visibility + +resolve_module_only = + visibility must resolve to a module diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 9aec25fff0b..ee2d2301399 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -12,11 +12,10 @@ use rustc_errors::{struct_span_err, SuggestionStyle}; use rustc_feature::BUILTIN_ATTRIBUTES; use rustc_hir::def::Namespace::{self, *}; use rustc_hir::def::{self, CtorKind, CtorOf, DefKind, NonMacroAttrKind, PerNS}; -use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, LOCAL_CRATE}; +use rustc_hir::def_id::{DefId, CRATE_DEF_ID, LOCAL_CRATE}; use rustc_hir::PrimTy; -use rustc_index::vec::IndexVec; use rustc_middle::bug; -use rustc_middle::ty::DefIdTree; +use rustc_middle::ty::{DefIdTree, TyCtxt}; use rustc_session::lint::builtin::ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE; use rustc_session::lint::builtin::MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS; use rustc_session::lint::BuiltinLintDiagnostics; @@ -30,7 +29,7 @@ use rustc_span::{BytePos, Span, SyntaxContext}; use thin_vec::ThinVec; use crate::errors as errs; -use crate::imports::{Import, ImportKind, ImportResolver}; +use crate::imports::{Import, ImportKind}; use crate::late::{PatternSource, Rib}; use crate::path_names_to_string; use crate::{AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, BindingError, Finalize}; @@ -154,8 +153,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { if !candidates.is_empty() { show_candidates( - &self.tcx.sess, - &self.tcx.untracked().source_span.read(), + self.tcx, &mut err, span, &candidates, @@ -191,7 +189,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } let container = match parent.kind { - ModuleKind::Def(kind, _, _) => kind.descr(parent.def_id()), + ModuleKind::Def(kind, _, _) => self.tcx.def_kind_descr(kind, parent.def_id()), ModuleKind::Block => "block", }; @@ -687,8 +685,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { err.span_help(span, &help_msg); } show_candidates( - &self.tcx.sess, - &self.tcx.untracked().source_span.read(), + self.tcx, &mut err, Some(span), &import_suggestions, @@ -1352,8 +1349,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let import_suggestions = self.lookup_import_candidates(ident, Namespace::MacroNS, parent_scope, is_expected); show_candidates( - &self.tcx.sess, - &self.tcx.untracked().source_span.read(), + self.tcx, err, None, &import_suggestions, @@ -1808,7 +1804,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { found("module") } else { match binding.res() { - Res::Def(kind, id) => found(kind.descr(id)), + Res::Def(kind, id) => found(self.tcx.def_kind_descr(kind, id)), _ => found(ns_to_try.descr()), } } @@ -1892,15 +1888,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { (format!("use of undeclared crate or module `{}`", ident), suggestion) } } -} -impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { /// Adds suggestions for a path that cannot be resolved. pub(crate) fn make_path_suggestion( &mut self, span: Span, mut path: Vec<Segment>, - parent_scope: &ParentScope<'b>, + parent_scope: &ParentScope<'a>, ) -> Option<(Vec<Segment>, Option<String>)> { debug!("make_path_suggestion: span={:?} path={:?}", span, path); @@ -1935,11 +1929,11 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { fn make_missing_self_suggestion( &mut self, mut path: Vec<Segment>, - parent_scope: &ParentScope<'b>, + parent_scope: &ParentScope<'a>, ) -> Option<(Vec<Segment>, Option<String>)> { // Replace first ident with `self` and check if that is valid. path[0].ident.name = kw::SelfLower; - let result = self.r.maybe_resolve_path(&path, None, parent_scope); + let result = self.maybe_resolve_path(&path, None, parent_scope); debug!("make_missing_self_suggestion: path={:?} result={:?}", path, result); if let PathResult::Module(..) = result { Some((path, None)) } else { None } } @@ -1954,11 +1948,11 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { fn make_missing_crate_suggestion( &mut self, mut path: Vec<Segment>, - parent_scope: &ParentScope<'b>, + parent_scope: &ParentScope<'a>, ) -> Option<(Vec<Segment>, Option<String>)> { // Replace first ident with `crate` and check if that is valid. path[0].ident.name = kw::Crate; - let result = self.r.maybe_resolve_path(&path, None, parent_scope); + let result = self.maybe_resolve_path(&path, None, parent_scope); debug!("make_missing_crate_suggestion: path={:?} result={:?}", path, result); if let PathResult::Module(..) = result { Some(( @@ -1985,11 +1979,11 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { fn make_missing_super_suggestion( &mut self, mut path: Vec<Segment>, - parent_scope: &ParentScope<'b>, + parent_scope: &ParentScope<'a>, ) -> Option<(Vec<Segment>, Option<String>)> { // Replace first ident with `crate` and check if that is valid. path[0].ident.name = kw::Super; - let result = self.r.maybe_resolve_path(&path, None, parent_scope); + let result = self.maybe_resolve_path(&path, None, parent_scope); debug!("make_missing_super_suggestion: path={:?} result={:?}", path, result); if let PathResult::Module(..) = result { Some((path, None)) } else { None } } @@ -2007,7 +2001,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { fn make_external_crate_suggestion( &mut self, mut path: Vec<Segment>, - parent_scope: &ParentScope<'b>, + parent_scope: &ParentScope<'a>, ) -> Option<(Vec<Segment>, Option<String>)> { if path[1].ident.span.is_rust_2015() { return None; @@ -2017,13 +2011,13 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { // 1) some consistent ordering for emitted diagnostics, and // 2) `std` suggestions before `core` suggestions. let mut extern_crate_names = - self.r.extern_prelude.iter().map(|(ident, _)| ident.name).collect::<Vec<_>>(); + self.extern_prelude.iter().map(|(ident, _)| ident.name).collect::<Vec<_>>(); extern_crate_names.sort_by(|a, b| b.as_str().partial_cmp(a.as_str()).unwrap()); for name in extern_crate_names.into_iter() { // Replace first ident with a crate name and check if that is valid. path[0].ident.name = name; - let result = self.r.maybe_resolve_path(&path, None, parent_scope); + let result = self.maybe_resolve_path(&path, None, parent_scope); debug!( "make_external_crate_suggestion: name={:?} path={:?} result={:?}", name, path, result @@ -2050,8 +2044,8 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { /// ``` pub(crate) fn check_for_module_export_macro( &mut self, - import: &'b Import<'b>, - module: ModuleOrUniformRoot<'b>, + import: &'a Import<'a>, + module: ModuleOrUniformRoot<'a>, ident: Ident, ) -> Option<(Option<Suggestion>, Option<String>)> { let ModuleOrUniformRoot::Module(mut crate_module) = module else { @@ -2068,8 +2062,8 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { return None; } - let resolutions = self.r.resolutions(crate_module).borrow(); - let resolution = resolutions.get(&self.r.new_key(ident, MacroNS))?; + let resolutions = self.resolutions(crate_module).borrow(); + let resolution = resolutions.get(&self.new_key(ident, MacroNS))?; let binding = resolution.borrow().binding()?; if let Res::Def(DefKind::Macro(MacroKind::Bang), _) = binding.res() { let module_name = crate_module.kind.name().unwrap(); @@ -2090,7 +2084,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { // ie. `use a::b::{c, d, e};` // ^^^ let (found_closing_brace, binding_span) = find_span_of_binding_until_next_binding( - self.r.tcx.sess, + self.tcx.sess, import.span, import.use_span, ); @@ -2109,7 +2103,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { // ie. `use a::b::{c, d};` // ^^^ if let Some(previous_span) = - extend_span_to_previous_binding(self.r.tcx.sess, binding_span) + extend_span_to_previous_binding(self.tcx.sess, binding_span) { debug!("check_for_module_export_macro: previous_span={:?}", previous_span); removal_span = removal_span.with_lo(previous_span.lo()); @@ -2127,7 +2121,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { // or `use a::{b, c, d}};` // ^^^^^^^^^^^ let (has_nested, after_crate_name) = find_span_immediately_after_crate_name( - self.r.tcx.sess, + self.tcx.sess, module_name, import.use_span, ); @@ -2136,7 +2130,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { has_nested, after_crate_name ); - let source_map = self.r.tcx.sess.source_map(); + let source_map = self.tcx.sess.source_map(); // Make sure this is actually crate-relative. let is_definitely_crate = import @@ -2358,8 +2352,7 @@ pub(crate) enum DiagnosticMode { } pub(crate) fn import_candidates( - session: &Session, - source_span: &IndexVec<LocalDefId, Span>, + tcx: TyCtxt<'_>, err: &mut Diagnostic, // This is `None` if all placement locations are inside expansions use_placement_span: Option<Span>, @@ -2368,8 +2361,7 @@ pub(crate) fn import_candidates( append: &str, ) { show_candidates( - session, - source_span, + tcx, err, use_placement_span, candidates, @@ -2385,8 +2377,7 @@ pub(crate) fn import_candidates( /// entities with that name in all crates. This method allows outputting the /// results of this search in a programmer-friendly way fn show_candidates( - session: &Session, - source_span: &IndexVec<LocalDefId, Span>, + tcx: TyCtxt<'_>, err: &mut Diagnostic, // This is `None` if all placement locations are inside expansions use_placement_span: Option<Span>, @@ -2511,8 +2502,8 @@ fn show_candidates( ); if let Some(local_def_id) = def_id.and_then(|did| did.as_local()) { - let span = source_span[local_def_id]; - let span = session.source_map().guess_head_span(span); + let span = tcx.source_span(local_def_id); + let span = tcx.sess.source_map().guess_head_span(span); let mut multi_span = MultiSpan::from_span(span); multi_span.push_span_label(span, "not accessible"); err.span_note(multi_span, &msg); @@ -2542,8 +2533,8 @@ fn show_candidates( let mut spans = Vec::new(); for (name, _, def_id, _) in &inaccessible_path_strings { if let Some(local_def_id) = def_id.and_then(|did| did.as_local()) { - let span = source_span[local_def_id]; - let span = session.source_map().guess_head_span(span); + let span = tcx.source_span(local_def_id); + let span = tcx.sess.source_map().guess_head_span(span); spans.push((name, span)); } else { if !has_colon { diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs index 2c442774667..867363f4246 100644 --- a/compiler/rustc_resolve/src/errors.rs +++ b/compiler/rustc_resolve/src/errors.rs @@ -38,7 +38,7 @@ pub(crate) struct NameAlreadyUsedInParameterList { #[primary_span] #[label] pub(crate) span: Span, - #[label(first_use_of_name)] + #[label(resolve_first_use_of_name)] pub(crate) first_use_span: Span, pub(crate) name: Symbol, } @@ -121,7 +121,7 @@ pub(crate) struct VariableBoundWithDifferentMode { #[primary_span] #[label] pub(crate) span: Span, - #[label(first_binding_span)] + #[label(resolve_first_binding_span)] pub(crate) first_binding_span: Span, pub(crate) variable_name: Symbol, } @@ -293,7 +293,7 @@ pub(crate) struct BindingShadowsSomethingUnacceptable<'a> { pub(crate) article: &'a str, #[subdiagnostic] pub(crate) sub_suggestion: Option<BindingShadowsSomethingUnacceptableSuggestion>, - #[label(label_shadowed_binding)] + #[label(resolve_label_shadowed_binding)] pub(crate) shadowed_binding_span: Span, pub(crate) participle: &'a str, pub(crate) name: Symbol, @@ -369,7 +369,7 @@ pub(crate) struct UnreachableLabel { #[label] pub(crate) span: Span, pub(crate) name: Symbol, - #[label(label_definition_span)] + #[label(resolve_label_definition_span)] pub(crate) definition_span: Span, #[subdiagnostic] pub(crate) sub_suggestion: Option<UnreachableLabelSubSuggestion>, @@ -413,7 +413,7 @@ pub(crate) struct TraitImplMismatch { pub(crate) span: Span, pub(crate) name: Symbol, pub(crate) kind: String, - #[label(label_trait_item)] + #[label(resolve_label_trait_item)] pub(crate) trait_item_span: Span, pub(crate) trait_path: String, pub(crate) code: String, @@ -434,9 +434,9 @@ pub(crate) struct TraitImplDuplicate { #[primary_span] #[label] pub(crate) span: Span, - #[label(old_span_label)] + #[label(resolve_old_span_label)] pub(crate) old_span: Span, - #[label(trait_item_span)] + #[label(resolve_trait_item_span)] pub(crate) trait_item_span: Span, pub(crate) name: Symbol, } diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 449d8094bd6..4dab0836d28 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -210,6 +210,17 @@ impl<'a> NameResolution<'a> { } } +/// An error that may be transformed into a diagnostic later. Used to combine multiple unresolved +/// import errors within the same use tree into a single diagnostic. +#[derive(Debug, Clone)] +struct UnresolvedImportError { + span: Span, + label: Option<String>, + note: Option<String>, + suggestion: Option<Suggestion>, + candidates: Option<Vec<ImportSuggestion>>, +} + // Reexports of the form `pub use foo as bar;` where `foo` is `extern crate foo;` // are permitted for backward-compatibility under a deprecation lint. fn pub_use_of_private_extern_crate_hack(import: &Import<'_>, binding: &NameBinding<'_>) -> bool { @@ -392,24 +403,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } } } -} - -/// An error that may be transformed into a diagnostic later. Used to combine multiple unresolved -/// import errors within the same use tree into a single diagnostic. -#[derive(Debug, Clone)] -struct UnresolvedImportError { - span: Span, - label: Option<String>, - note: Option<String>, - suggestion: Option<Suggestion>, - candidates: Option<Vec<ImportSuggestion>>, -} - -pub(crate) struct ImportResolver<'a, 'b, 'tcx> { - pub r: &'a mut Resolver<'b, 'tcx>, -} -impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { // Import resolution // // This is a fixed-point algorithm. We resolve imports until our efforts @@ -421,28 +415,28 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { /// Resolves all imports for the crate. This method performs the fixed- /// point iteration. pub(crate) fn resolve_imports(&mut self) { - let mut prev_num_indeterminates = self.r.indeterminate_imports.len() + 1; - while self.r.indeterminate_imports.len() < prev_num_indeterminates { - prev_num_indeterminates = self.r.indeterminate_imports.len(); - for import in mem::take(&mut self.r.indeterminate_imports) { + let mut prev_num_indeterminates = self.indeterminate_imports.len() + 1; + while self.indeterminate_imports.len() < prev_num_indeterminates { + prev_num_indeterminates = self.indeterminate_imports.len(); + for import in mem::take(&mut self.indeterminate_imports) { match self.resolve_import(&import) { - true => self.r.determined_imports.push(import), - false => self.r.indeterminate_imports.push(import), + true => self.determined_imports.push(import), + false => self.indeterminate_imports.push(import), } } } } pub(crate) fn finalize_imports(&mut self) { - for module in self.r.arenas.local_modules().iter() { + for module in self.arenas.local_modules().iter() { self.finalize_resolutions_in(module); } let mut seen_spans = FxHashSet::default(); let mut errors = vec![]; let mut prev_root_id: NodeId = NodeId::from_u32(0); - let determined_imports = mem::take(&mut self.r.determined_imports); - let indeterminate_imports = mem::take(&mut self.r.indeterminate_imports); + let determined_imports = mem::take(&mut self.determined_imports); + let indeterminate_imports = mem::take(&mut self.indeterminate_imports); for (is_indeterminate, import) in determined_imports .into_iter() @@ -453,7 +447,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { // If this import is unresolved then create a dummy import // resolution for it so that later resolve stages won't complain. - self.r.import_dummy_binding(import); + self.import_dummy_binding(import); if let Some(err) = unresolved_import_error { if let ImportKind::Single { source, ref source_bindings, .. } = import.kind { @@ -526,7 +520,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { .collect::<Vec<_>>(); let msg = format!("unresolved import{} {}", pluralize!(paths.len()), paths.join(", "),); - let mut diag = struct_span_err!(self.r.tcx.sess, span, E0432, "{}", &msg); + let mut diag = struct_span_err!(self.tcx.sess, span, E0432, "{}", &msg); if let Some((_, UnresolvedImportError { note: Some(note), .. })) = errors.iter().last() { diag.note(note); @@ -548,8 +542,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { if let Some(candidates) = &err.candidates { match &import.kind { ImportKind::Single { nested: false, source, target, .. } => import_candidates( - self.r.tcx.sess, - &self.r.tcx.untracked().source_span.read(), + self.tcx, &mut diag, Some(err.span), &candidates, @@ -561,8 +554,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { ), ImportKind::Single { nested: true, source, target, .. } => { import_candidates( - self.r.tcx.sess, - &self.r.tcx.untracked().source_span.read(), + self.tcx, &mut diag, None, &candidates, @@ -583,7 +575,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { /// Attempts to resolve the given import, returning true if its resolution is determined. /// If successful, the resolved bindings are written into the module. - fn resolve_import(&mut self, import: &'b Import<'b>) -> bool { + fn resolve_import(&mut self, import: &'a Import<'a>) -> bool { debug!( "(resolving import for module) resolving import `{}::...` in `{}`", Segment::names_to_string(&import.module_path), @@ -596,8 +588,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { // For better failure detection, pretend that the import will // not define any names while resolving its module path. let orig_vis = import.vis.take(); - let path_res = - self.r.maybe_resolve_path(&import.module_path, None, &import.parent_scope); + let path_res = self.maybe_resolve_path(&import.module_path, None, &import.parent_scope); import.vis.set(orig_vis); match path_res { @@ -625,7 +616,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { }; let mut indeterminate = false; - self.r.per_ns(|this, ns| { + self.per_ns(|this, ns| { if !type_ns_only || ns == TypeNS { if let Err(Undetermined) = source_bindings[ns].get() { // For better failure detection, pretend that the import will @@ -678,15 +669,15 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { /// /// Optionally returns an unresolved import error. This error is buffered and used to /// consolidate multiple unresolved import errors into a single diagnostic. - fn finalize_import(&mut self, import: &'b Import<'b>) -> Option<UnresolvedImportError> { + fn finalize_import(&mut self, import: &'a Import<'a>) -> Option<UnresolvedImportError> { let orig_vis = import.vis.take(); let ignore_binding = match &import.kind { ImportKind::Single { target_bindings, .. } => target_bindings[TypeNS].get(), _ => None, }; - let prev_ambiguity_errors_len = self.r.ambiguity_errors.len(); + let prev_ambiguity_errors_len = self.ambiguity_errors.len(); let finalize = Finalize::with_root_span(import.root_id, import.span, import.root_span); - let path_res = self.r.resolve_path( + let path_res = self.resolve_path( &import.module_path, None, &import.parent_scope, @@ -694,7 +685,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { ignore_binding, ); - let no_ambiguity = self.r.ambiguity_errors.len() == prev_ambiguity_errors_len; + let no_ambiguity = self.ambiguity_errors.len() == prev_ambiguity_errors_len; import.vis.set(orig_vis); let module = match path_res { PathResult::Module(module) => { @@ -703,10 +694,10 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { if !ModuleOrUniformRoot::same_def(module, initial_module) && no_ambiguity { span_bug!(import.span, "inconsistent resolution for an import"); } - } else if self.r.privacy_errors.is_empty() { + } else if self.privacy_errors.is_empty() { let msg = "cannot determine resolution for the import"; let msg_note = "import resolution is stuck, try simplifying other imports"; - self.r.tcx.sess.struct_span_err(import.span, msg).note(msg_note).emit(); + self.tcx.sess.struct_span_err(import.span, msg).note(msg_note).emit(); } module @@ -714,8 +705,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { PathResult::Failed { is_error_from_last_segment: false, span, label, suggestion } => { if no_ambiguity { assert!(import.imported_module.get().is_none()); - self.r - .report_error(span, ResolutionError::FailedToResolve { label, suggestion }); + self.report_error(span, ResolutionError::FailedToResolve { label, suggestion }); } return None; } @@ -777,7 +767,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { // 2 segments, so the `resolve_path` above won't trigger it. let mut full_path = import.module_path.clone(); full_path.push(Segment::from_ident(Ident::empty())); - self.r.lint_if_path_starts_with_module(Some(finalize), &full_path, None); + self.lint_if_path_starts_with_module(Some(finalize), &full_path, None); } if let ModuleOrUniformRoot::Module(module) = module { @@ -796,10 +786,10 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { } if !is_prelude && let Some(max_vis) = max_vis.get() - && !max_vis.is_at_least(import.expect_vis(), &*self.r) + && !max_vis.is_at_least(import.expect_vis(), &*self) { let msg = "glob import doesn't reexport anything because no candidate is public enough"; - self.r.lint_buffer.buffer_lint(UNUSED_IMPORTS, id, import.span, msg); + self.lint_buffer.buffer_lint(UNUSED_IMPORTS, id, import.span, msg); } return None; } @@ -807,7 +797,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { }; let mut all_ns_err = true; - self.r.per_ns(|this, ns| { + self.per_ns(|this, ns| { if !type_ns_only || ns == TypeNS { let orig_vis = import.vis.take(); let binding = this.resolve_ident_in_module( @@ -876,7 +866,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { if all_ns_err { let mut all_ns_failed = true; - self.r.per_ns(|this, ns| { + self.per_ns(|this, ns| { if !type_ns_only || ns == TypeNS { let binding = this.resolve_ident_in_module( module, @@ -894,9 +884,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { return if all_ns_failed { let resolutions = match module { - ModuleOrUniformRoot::Module(module) => { - Some(self.r.resolutions(module).borrow()) - } + ModuleOrUniformRoot::Module(module) => Some(self.resolutions(module).borrow()), _ => None, }; let resolutions = resolutions.as_ref().into_iter().flat_map(|r| r.iter()); @@ -965,7 +953,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { }; let parent_suggestion = - self.r.lookup_import_candidates(ident, TypeNS, &import.parent_scope, |_| true); + self.lookup_import_candidates(ident, TypeNS, &import.parent_scope, |_| true); Some(UnresolvedImportError { span: import.span, @@ -987,7 +975,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { let mut reexport_error = None; let mut any_successful_reexport = false; let mut crate_private_reexport = false; - self.r.per_ns(|this, ns| { + self.per_ns(|this, ns| { if let Ok(binding) = source_bindings[ns].get() { if !binding.vis.is_at_least(import.expect_vis(), &*this) { reexport_error = Some((ns, binding)); @@ -1012,7 +1000,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { `pub`", ident ); - self.r.lint_buffer.buffer_lint( + self.lint_buffer.buffer_lint( PUB_USE_OF_PRIVATE_EXTERN_CRATE, import_id, import.span, @@ -1035,17 +1023,17 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { format!("re-export of private `{}`", ident) }; - struct_span_err!(self.r.tcx.sess, import.span, E0365, "{}", error_msg) + struct_span_err!(self.tcx.sess, import.span, E0365, "{}", error_msg) .span_label(import.span, label_msg) .note(&format!("consider declaring type or module `{}` with `pub`", ident)) .emit(); } else { let mut err = - struct_span_err!(self.r.tcx.sess, import.span, E0364, "{error_msg}"); + struct_span_err!(self.tcx.sess, import.span, E0364, "{error_msg}"); match binding.kind { NameBindingKind::Res(Res::Def(DefKind::Macro(_), def_id)) // exclude decl_macro - if self.r.get_macro_by_def_id(def_id).macro_rules => + if self.get_macro_by_def_id(def_id).macro_rules => { err.span_help( binding.span, @@ -1071,7 +1059,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { // 2 segments, so the `resolve_path` above won't trigger it. let mut full_path = import.module_path.clone(); full_path.push(Segment::from_ident(ident)); - self.r.per_ns(|this, ns| { + self.per_ns(|this, ns| { if let Ok(binding) = source_bindings[ns].get() { this.lint_if_path_starts_with_module(Some(finalize), &full_path, Some(binding)); } @@ -1081,7 +1069,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { // Record what this import resolves to for later uses in documentation, // this may resolve to either a value or a type, but for documentation // purposes it's good enough to just favor one over the other. - self.r.per_ns(|this, ns| { + self.per_ns(|this, ns| { if let Ok(binding) = source_bindings[ns].get() { this.import_res_map.entry(import_id).or_default()[ns] = Some(binding.res()); } @@ -1096,9 +1084,9 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { fn check_for_redundant_imports( &mut self, ident: Ident, - import: &'b Import<'b>, - source_bindings: &PerNS<Cell<Result<&'b NameBinding<'b>, Determinacy>>>, - target_bindings: &PerNS<Cell<Option<&'b NameBinding<'b>>>>, + import: &'a Import<'a>, + source_bindings: &PerNS<Cell<Result<&'a NameBinding<'a>, Determinacy>>>, + target_bindings: &PerNS<Cell<Option<&'a NameBinding<'a>>>>, target: Ident, ) { // This function is only called for single imports. @@ -1119,7 +1107,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { let mut redundant_span = PerNS { value_ns: None, type_ns: None, macro_ns: None }; - self.r.per_ns(|this, ns| { + self.per_ns(|this, ns| { if let Ok(binding) = source_bindings[ns].get() { if binding.res() == Res::Err { return; @@ -1149,7 +1137,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { let mut redundant_spans: Vec<_> = redundant_span.present_items().collect(); redundant_spans.sort(); redundant_spans.dedup(); - self.r.lint_buffer.buffer_lint_with_diagnostic( + self.lint_buffer.buffer_lint_with_diagnostic( UNUSED_IMPORTS, id, import.span, @@ -1159,22 +1147,22 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { } } - fn resolve_glob_import(&mut self, import: &'b Import<'b>) { + fn resolve_glob_import(&mut self, import: &'a Import<'a>) { // This function is only called for glob imports. let ImportKind::Glob { id, is_prelude, .. } = import.kind else { unreachable!() }; let ModuleOrUniformRoot::Module(module) = import.imported_module.get().unwrap() else { - self.r.tcx.sess.span_err(import.span, "cannot glob-import all possible crates"); + self.tcx.sess.span_err(import.span, "cannot glob-import all possible crates"); return; }; if module.is_trait() { - self.r.tcx.sess.span_err(import.span, "items in traits are not importable"); + self.tcx.sess.span_err(import.span, "items in traits are not importable"); return; } else if ptr::eq(module, import.parent_scope.module) { return; } else if is_prelude { - self.r.prelude = Some(module); + self.prelude = Some(module); return; } @@ -1184,7 +1172,6 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { // Ensure that `resolutions` isn't borrowed during `try_define`, // since it might get updated via a glob cycle. let bindings = self - .r .resolutions(module) .borrow() .iter() @@ -1194,30 +1181,30 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { .collect::<Vec<_>>(); for (mut key, binding) in bindings { let scope = match key.ident.span.reverse_glob_adjust(module.expansion, import.span) { - Some(Some(def)) => self.r.expn_def_scope(def), + Some(Some(def)) => self.expn_def_scope(def), Some(None) => import.parent_scope.module, None => continue, }; - if self.r.is_accessible_from(binding.vis, scope) { - let imported_binding = self.r.import(binding, import); - let _ = self.r.try_define(import.parent_scope.module, key, imported_binding); + if self.is_accessible_from(binding.vis, scope) { + let imported_binding = self.import(binding, import); + let _ = self.try_define(import.parent_scope.module, key, imported_binding); } } // Record the destination of this import - self.r.record_partial_res(id, PartialRes::new(module.res().unwrap())); + self.record_partial_res(id, PartialRes::new(module.res().unwrap())); } // Miscellaneous post-processing, including recording re-exports, // reporting conflicts, and reporting unresolved imports. - fn finalize_resolutions_in(&mut self, module: Module<'b>) { + fn finalize_resolutions_in(&mut self, module: Module<'a>) { // 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 reexports = Vec::new(); - module.for_each_child(self.r, |this, ident, _, binding| { + module.for_each_child(self, |this, ident, _, binding| { if let Some(res) = this.is_reexport(binding) { reexports.push(ModChild { ident, @@ -1232,7 +1219,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { if !reexports.is_empty() { // Call to `expect_local` should be fine because current // code is only called for local modules. - self.r.reexport_map.insert(def_id.expect_local(), reexports); + self.reexport_map.insert(def_id.expect_local(), reexports); } } } diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 66034baaa0b..7a1f14f71f2 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -28,7 +28,9 @@ use rustc_ast::{AngleBracketedArg, Crate, Expr, ExprKind, GenericArg, GenericArg use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet}; use rustc_data_structures::intern::Interned; use rustc_data_structures::sync::{Lrc, MappedReadGuard}; -use rustc_errors::{Applicability, DiagnosticBuilder, ErrorGuaranteed}; +use rustc_errors::{ + Applicability, DiagnosticBuilder, DiagnosticMessage, ErrorGuaranteed, SubdiagnosticMessage, +}; use rustc_expand::base::{DeriveResolutions, SyntaxExtension, SyntaxExtensionKind}; use rustc_hir::def::Namespace::{self, *}; use rustc_hir::def::{self, CtorOf, DefKind, DocLinkResMap, LifetimeRes, PartialRes, PerNS}; @@ -37,6 +39,7 @@ use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE}; use rustc_hir::definitions::DefPathData; use rustc_hir::TraitCandidate; use rustc_index::vec::IndexVec; +use rustc_macros::fluent_messages; use rustc_metadata::creader::{CStore, CrateLoader}; use rustc_middle::metadata::ModChild; use rustc_middle::middle::privacy::EffectiveVisibilities; @@ -57,7 +60,7 @@ use std::collections::BTreeSet; use std::{fmt, ptr}; use diagnostics::{ImportSuggestion, LabelSuggestion, Suggestion}; -use imports::{Import, ImportKind, ImportResolver, NameResolution}; +use imports::{Import, ImportKind, NameResolution}; use late::{HasGenericParams, PathSource, PatternSource}; use macros::{MacroRulesBinding, MacroRulesScope, MacroRulesScopeRef}; @@ -77,6 +80,8 @@ mod late; mod macros; pub mod rustdoc; +fluent_messages! { "../locales/en-US.ftl" } + enum Weak { Yes, No, @@ -1156,7 +1161,7 @@ impl<'tcx> Resolver<'_, 'tcx> { // A relative span's parent must be an absolute span. debug_assert_eq!(span.data_untracked().parent, None); - let _id = self.tcx.untracked().source_span.write().push(span); + let _id = self.tcx.untracked().source_span.push(span); debug_assert_eq!(_id, def_id); // Some things for which we allocate `LocalDefId`s don't correspond to @@ -1486,9 +1491,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { /// Entry point to crate resolution. pub fn resolve_crate(&mut self, krate: &Crate) { self.tcx.sess.time("resolve_crate", || { - self.tcx - .sess - .time("finalize_imports", || ImportResolver { r: self }.finalize_imports()); + self.tcx.sess.time("finalize_imports", || self.finalize_imports()); self.tcx.sess.time("compute_effective_visibilities", || { EffectiveVisibilitiesVisitor::compute_effective_visibilities(self, krate) }); diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 341db774b4d..b38c11e8bb8 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -1,7 +1,6 @@ //! A bunch of methods and structures more or less related to resolving macros and //! interface provided by `Resolver` to macro expander. -use crate::imports::ImportResolver; use crate::Namespace::*; use crate::{BuiltinMacroState, Determinacy}; use crate::{DeriveData, Finalize, ParentScope, ResolutionError, Resolver, ScopeSet}; @@ -233,7 +232,7 @@ impl<'a, 'tcx> ResolverExpand for Resolver<'a, 'tcx> { } fn resolve_imports(&mut self) { - ImportResolver { r: self }.resolve_imports() + self.resolve_imports() } fn resolve_macro_invocation( |
