diff options
Diffstat (limited to 'compiler/rustc_resolve/src/late/diagnostics.rs')
| -rw-r--r-- | compiler/rustc_resolve/src/late/diagnostics.rs | 118 |
1 files changed, 50 insertions, 68 deletions
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 0807142a7c3..80b2095d8cc 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -19,14 +19,13 @@ use rustc_errors::{ }; use rustc_hir as hir; use rustc_hir::def::Namespace::{self, *}; -use rustc_hir::def::{self, CtorKind, CtorOf, DefKind}; +use rustc_hir::def::{self, CtorKind, CtorOf, DefKind, MacroKinds}; use rustc_hir::def_id::{CRATE_DEF_ID, DefId}; use rustc_hir::{MissingLifetimeKind, PrimTy}; use rustc_middle::ty; use rustc_session::{Session, lint}; use rustc_span::edit_distance::{edit_distance, find_best_match_for_name}; use rustc_span::edition::Edition; -use rustc_span::hygiene::MacroKind; use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym}; use thin_vec::ThinVec; use tracing::debug; @@ -39,8 +38,8 @@ use crate::late::{ }; use crate::ty::fast_reject::SimplifiedType; use crate::{ - Module, ModuleKind, ModuleOrUniformRoot, PathResult, PathSource, Resolver, Segment, errors, - path_names_to_string, + Module, ModuleKind, ModuleOrUniformRoot, ParentScope, PathResult, PathSource, Resolver, + ScopeSet, Segment, errors, path_names_to_string, }; type Res = def::Res<ast::NodeId>; @@ -174,7 +173,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { &mut self, path: &[Segment], span: Span, - source: PathSource<'_, '_, '_>, + source: PathSource<'_, 'ast, 'ra>, res: Option<Res>, ) -> BaseError { // Make the base error. @@ -318,7 +317,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { (String::new(), "the crate root".to_string(), Some(CRATE_DEF_ID.to_def_id()), None) } else { let mod_path = &path[..path.len() - 1]; - let mod_res = self.resolve_path(mod_path, Some(TypeNS), None); + let mod_res = self.resolve_path(mod_path, Some(TypeNS), None, source); let mod_prefix = match mod_res { PathResult::Module(ModuleOrUniformRoot::Module(module)) => module.res(), _ => None, @@ -419,7 +418,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { path: &[Segment], following_seg: Option<&Segment>, span: Span, - source: PathSource<'_, '_, '_>, + source: PathSource<'_, 'ast, 'ra>, res: Option<Res>, qself: Option<&QSelf>, ) -> (Diag<'tcx>, Vec<ImportSuggestion>) { @@ -850,9 +849,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { } // Try to find in last block rib - if let Some(rib) = &self.last_block_rib - && let RibKind::Normal = rib.kind - { + if let Some(rib) = &self.last_block_rib { for (ident, &res) in &rib.bindings { if let Res::Local(_) = res && path.len() == 1 @@ -901,7 +898,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { if path.len() == 1 { for rib in self.ribs[ns].iter().rev() { let item = path[0].ident; - if let RibKind::Module(module) = rib.kind + if let RibKind::Module(module) | RibKind::Block(Some(module)) = rib.kind && let Some(did) = find_doc_alias_name(self.r, module, item.name) { return Some((did, item)); @@ -1014,7 +1011,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { fn suggest_typo( &mut self, err: &mut Diag<'_>, - source: PathSource<'_, '_, '_>, + source: PathSource<'_, 'ast, 'ra>, path: &[Segment], following_seg: Option<&Segment>, span: Span, @@ -1333,7 +1330,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { fn suggest_swapping_misplaced_self_ty_and_trait( &mut self, err: &mut Diag<'_>, - source: PathSource<'_, '_, '_>, + source: PathSource<'_, 'ast, 'ra>, res: Option<Res>, span: Span, ) { @@ -1341,7 +1338,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { self.diag_metadata.currently_processing_impl_trait.clone() && let TyKind::Path(_, self_ty_path) = &self_ty.kind && let PathResult::Module(ModuleOrUniformRoot::Module(module)) = - self.resolve_path(&Segment::from_path(self_ty_path), Some(TypeNS), None) + self.resolve_path(&Segment::from_path(self_ty_path), Some(TypeNS), None, source) && let ModuleKind::Def(DefKind::Trait, ..) = module.kind && trait_ref.path.span == span && let PathSource::Trait(_) = source @@ -1449,13 +1446,13 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { fn get_single_associated_item( &mut self, path: &[Segment], - source: &PathSource<'_, '_, '_>, + source: &PathSource<'_, 'ast, 'ra>, filter_fn: &impl Fn(Res) -> bool, ) -> Option<TypoSuggestion> { if let crate::PathSource::TraitItem(_, _) = source { let mod_path = &path[..path.len() - 1]; if let PathResult::Module(ModuleOrUniformRoot::Module(module)) = - self.resolve_path(mod_path, None, None) + self.resolve_path(mod_path, None, None, *source) { let targets: Vec<_> = self .r @@ -1850,12 +1847,12 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { match (res, source) { ( - Res::Def(DefKind::Macro(MacroKind::Bang), def_id), + Res::Def(DefKind::Macro(kinds), def_id), PathSource::Expr(Some(Expr { kind: ExprKind::Index(..) | ExprKind::Call(..), .. })) - | PathSource::Struct, - ) => { + | PathSource::Struct(_), + ) if kinds.contains(MacroKinds::BANG) => { // Don't suggest macro if it's unstable. let suggestable = def_id.is_local() || self.r.tcx.lookup_stability(def_id).is_none_or(|s| s.is_stable()); @@ -1880,7 +1877,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { err.note("if you want the `try` keyword, you need Rust 2018 or later"); } } - (Res::Def(DefKind::Macro(MacroKind::Bang), _), _) => { + (Res::Def(DefKind::Macro(kinds), _), _) if kinds.contains(MacroKinds::BANG) => { err.span_label(span, fallback_label.to_string()); } (Res::Def(DefKind::TyAlias, def_id), PathSource::Trait(_)) => { @@ -2459,50 +2456,34 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { } } + if let RibKind::Block(Some(module)) = rib.kind { + self.r.add_module_candidates(module, &mut names, &filter_fn, Some(ctxt)); + } else if let RibKind::Module(module) = rib.kind { + // Encountered a module item, abandon ribs and look into that module and preludes. + let parent_scope = &ParentScope { module, ..self.parent_scope }; + self.r.add_scope_set_candidates( + &mut names, + ScopeSet::All(ns), + parent_scope, + ctxt, + filter_fn, + ); + break; + } + if let RibKind::MacroDefinition(def) = rib.kind && def == self.r.macro_def(ctxt) { // If an invocation of this macro created `ident`, give up on `ident` // and switch to `ident`'s source from the macro definition. ctxt.remove_mark(); - continue; - } - - // Items in scope - if let RibKind::Module(module) = rib.kind { - // Items from this module - self.r.add_module_candidates(module, &mut names, &filter_fn, Some(ctxt)); - - if let ModuleKind::Block = module.kind { - // We can see through blocks - } else { - // Items from the prelude - if !module.no_implicit_prelude { - names.extend(self.r.extern_prelude.keys().flat_map(|ident| { - let res = Res::Def(DefKind::Mod, CRATE_DEF_ID.to_def_id()); - filter_fn(res) - .then_some(TypoSuggestion::typo_from_ident(ident.0, res)) - })); - - if let Some(prelude) = self.r.prelude { - self.r.add_module_candidates(prelude, &mut names, &filter_fn, None); - } - } - break; - } } } - // Add primitive types to the mix - if filter_fn(Res::PrimTy(PrimTy::Bool)) { - names.extend(PrimTy::ALL.iter().map(|prim_ty| { - TypoSuggestion::typo_from_name(prim_ty.name(), Res::PrimTy(*prim_ty)) - })) - } } else { // Search in module. let mod_path = &path[..path.len() - 1]; if let PathResult::Module(ModuleOrUniformRoot::Module(module)) = - self.resolve_path(mod_path, Some(TypeNS), None) + self.resolve_path(mod_path, Some(TypeNS), None, PathSource::Type) { self.r.add_module_candidates(module, &mut names, &filter_fn, None); } @@ -3114,7 +3095,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { } else { self.suggest_introducing_lifetime( &mut err, - Some(lifetime_ref.ident.name.as_str()), + Some(lifetime_ref.ident), |err, _, span, message, suggestion, span_suggs| { err.multipart_suggestion_verbose( message, @@ -3132,7 +3113,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { fn suggest_introducing_lifetime( &self, err: &mut Diag<'_>, - name: Option<&str>, + name: Option<Ident>, suggest: impl Fn( &mut Diag<'_>, bool, @@ -3179,7 +3160,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { let mut rm_inner_binders: FxIndexSet<Span> = Default::default(); let (span, sugg) = if span.is_empty() { let mut binder_idents: FxIndexSet<Ident> = Default::default(); - binder_idents.insert(Ident::from_str(name.unwrap_or("'a"))); + binder_idents.insert(name.unwrap_or(Ident::from_str("'a"))); // We need to special case binders in the following situation: // Change `T: for<'a> Trait<T> + 'b` to `for<'a, 'b> T: Trait<T> + 'b` @@ -3209,16 +3190,11 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { } } - let binders_sugg = binder_idents.into_iter().enumerate().fold( - "".to_string(), - |mut binders, (i, x)| { - if i != 0 { - binders += ", "; - } - binders += x.as_str(); - binders - }, - ); + let binders_sugg: String = binder_idents + .into_iter() + .map(|ident| ident.to_string()) + .intersperse(", ".to_owned()) + .collect(); let sugg = format!( "{}<{}>{}", if higher_ranked { "for" } else { "" }, @@ -3234,7 +3210,8 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { .source_map() .span_through_char(span, '<') .shrink_to_hi(); - let sugg = format!("{}, ", name.unwrap_or("'a")); + let sugg = + format!("{}, ", name.map(|i| i.to_string()).as_deref().unwrap_or("'a")); (span, sugg) }; @@ -3242,7 +3219,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { let message = Cow::from(format!( "consider making the {} lifetime-generic with a new `{}` lifetime", kind.descr(), - name.unwrap_or("'a"), + name.map(|i| i.to_string()).as_deref().unwrap_or("'a"), )); should_continue = suggest( err, @@ -3673,7 +3650,12 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { if let TyKind::Path(None, path) = &ty.kind { // Check if the path being borrowed is likely to be owned. let path: Vec<_> = Segment::from_path(path); - match self.resolve_path(&path, Some(TypeNS), None) { + match self.resolve_path( + &path, + Some(TypeNS), + None, + PathSource::Type, + ) { PathResult::Module(ModuleOrUniformRoot::Module(module)) => { match module.res() { Some(Res::PrimTy(PrimTy::Str)) => { |
