]> git.lizzy.rs Git - rust.git/blobdiff - compiler/rustc_resolve/src/diagnostics.rs
Rollup merge of #101644 - Timmmm:file_permissions_docs, r=thomcc
[rust.git] / compiler / rustc_resolve / src / diagnostics.rs
index 83aae286402996c5b1860f8c4a174b744532f7bd..5d868ebec94482d0fdfef0d50dc700c41b56f2b4 100644 (file)
@@ -24,7 +24,7 @@
 use rustc_span::lev_distance::find_best_match_for_name;
 use rustc_span::source_map::SourceMap;
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
-use rustc_span::{BytePos, Span};
+use rustc_span::{BytePos, Span, SyntaxContext};
 
 use crate::imports::{Import, ImportKind, ImportResolver};
 use crate::late::{PatternSource, Rib};
@@ -47,6 +47,7 @@
 /// similarly named label and whether or not it is reachable.
 pub(crate) type LabelSuggestion = (Ident, bool);
 
+#[derive(Debug)]
 pub(crate) enum SuggestionTarget {
     /// The target has a similar name as the name used by the programmer (probably a typo)
     SimilarlyNamed,
@@ -54,6 +55,7 @@ pub(crate) enum SuggestionTarget {
     SingleItem,
 }
 
+#[derive(Debug)]
 pub(crate) struct TypoSuggestion {
     pub candidate: Symbol,
     pub res: Res,
@@ -139,8 +141,7 @@ fn report_with_use_injections(&mut self, krate: &Crate) {
                     &candidates,
                     if instead { Instead::Yes } else { Instead::No },
                     found_use,
-                    IsPattern::No,
-                    IsImport::No,
+                    DiagnosticMode::Normal,
                     path,
                 );
                 err.emit();
@@ -483,11 +484,12 @@ pub(crate) fn add_module_candidates(
         module: Module<'a>,
         names: &mut Vec<TypoSuggestion>,
         filter_fn: &impl Fn(Res) -> bool,
+        ctxt: Option<SyntaxContext>,
     ) {
         for (key, resolution) in self.resolutions(module).borrow().iter() {
             if let Some(binding) = resolution.borrow().binding {
                 let res = binding.res();
-                if filter_fn(res) {
+                if filter_fn(res) && ctxt.map_or(true, |ctxt| ctxt == key.ident.span.ctxt()) {
                     names.push(TypoSuggestion::typo_from_res(key.ident.name, res));
                 }
             }
@@ -699,8 +701,7 @@ pub(crate) fn into_struct_error(
                         &import_suggestions,
                         Instead::No,
                         FoundUse::Yes,
-                        IsPattern::Yes,
-                        IsImport::No,
+                        DiagnosticMode::Pattern,
                         vec![],
                     );
                 }
@@ -1183,10 +1184,10 @@ fn early_lookup_typo_candidate(
                 Scope::CrateRoot => {
                     let root_ident = Ident::new(kw::PathRoot, ident.span);
                     let root_module = this.resolve_crate_root(root_ident);
-                    this.add_module_candidates(root_module, &mut suggestions, filter_fn);
+                    this.add_module_candidates(root_module, &mut suggestions, filter_fn, None);
                 }
                 Scope::Module(module, _) => {
-                    this.add_module_candidates(module, &mut suggestions, filter_fn);
+                    this.add_module_candidates(module, &mut suggestions, filter_fn, None);
                 }
                 Scope::MacroUsePrelude => {
                     suggestions.extend(this.macro_use_prelude.iter().filter_map(
@@ -1223,7 +1224,7 @@ fn early_lookup_typo_candidate(
                 Scope::StdLibPrelude => {
                     if let Some(prelude) = this.prelude {
                         let mut tmp_suggestions = Vec::new();
-                        this.add_module_candidates(prelude, &mut tmp_suggestions, filter_fn);
+                        this.add_module_candidates(prelude, &mut tmp_suggestions, filter_fn, None);
                         suggestions.extend(
                             tmp_suggestions
                                 .into_iter()
@@ -1496,8 +1497,7 @@ pub(crate) fn unresolved_macro_suggestions(
             &import_suggestions,
             Instead::No,
             FoundUse::Yes,
-            IsPattern::No,
-            IsImport::No,
+            DiagnosticMode::Normal,
             vec![],
         );
 
@@ -2458,18 +2458,13 @@ enum FoundUse {
     No,
 }
 
-/// Whether a binding is part of a pattern or an expression. Used for diagnostics.
-enum IsPattern {
+/// Whether a binding is part of a pattern or a use statement. Used for diagnostics.
+enum DiagnosticMode {
+    Normal,
     /// The binding is part of a pattern
-    Yes,
-    /// The binding is part of an expression
-    No,
-}
-
-/// Whether a binding is part of a use statement. Used for diagnostics.
-enum IsImport {
-    Yes,
-    No,
+    Pattern,
+    /// The binding is part of a use statement
+    Import,
 }
 
 pub(crate) fn import_candidates(
@@ -2488,8 +2483,7 @@ pub(crate) fn import_candidates(
         candidates,
         Instead::Yes,
         FoundUse::Yes,
-        IsPattern::No,
-        IsImport::Yes,
+        DiagnosticMode::Import,
         vec![],
     );
 }
@@ -2506,8 +2500,7 @@ fn show_candidates(
     candidates: &[ImportSuggestion],
     instead: Instead,
     found_use: FoundUse,
-    is_pattern: IsPattern,
-    is_import: IsImport,
+    mode: DiagnosticMode,
     path: Vec<Segment>,
 ) {
     if candidates.is_empty() {
@@ -2542,7 +2535,7 @@ fn show_candidates(
         };
 
         let instead = if let Instead::Yes = instead { " instead" } else { "" };
-        let mut msg = if let IsPattern::Yes = is_pattern {
+        let mut msg = if let DiagnosticMode::Pattern = mode {
             format!(
                 "if you meant to match on {}{}{}, use the full path in the pattern",
                 kind, instead, name
@@ -2555,19 +2548,24 @@ fn show_candidates(
             err.note(note);
         }
 
-        if let (IsPattern::Yes, Some(span)) = (is_pattern, use_placement_span) {
-            err.span_suggestions(
-                span,
-                &msg,
-                accessible_path_strings.into_iter().map(|a| a.0),
-                Applicability::MaybeIncorrect,
-            );
-        } else if let Some(span) = use_placement_span {
+        if let Some(span) = use_placement_span {
+            let add_use = match mode {
+                DiagnosticMode::Pattern => {
+                    err.span_suggestions(
+                        span,
+                        &msg,
+                        accessible_path_strings.into_iter().map(|a| a.0),
+                        Applicability::MaybeIncorrect,
+                    );
+                    return;
+                }
+                DiagnosticMode::Import => "",
+                DiagnosticMode::Normal => "use ",
+            };
             for candidate in &mut accessible_path_strings {
                 // produce an additional newline to separate the new use statement
                 // from the directly following item.
                 let additional_newline = if let FoundUse::Yes = found_use { "" } else { "\n" };
-                let add_use = if let IsImport::Yes = is_import { "" } else { "use " };
                 candidate.0 = format!("{}{};\n{}", add_use, &candidate.0, additional_newline);
             }
 
@@ -2598,11 +2596,14 @@ fn show_candidates(
 
             err.note(&msg);
         }
-    } else if matches!(is_import, IsImport::No) {
+    } else if !matches!(mode, DiagnosticMode::Import) {
         assert!(!inaccessible_path_strings.is_empty());
 
-        let prefix =
-            if let IsPattern::Yes = is_pattern { "you might have meant to match on " } else { "" };
+        let prefix = if let DiagnosticMode::Pattern = mode {
+            "you might have meant to match on "
+        } else {
+            ""
+        };
         if inaccessible_path_strings.len() == 1 {
             let (name, descr, def_id, note) = &inaccessible_path_strings[0];
             let msg = format!(
@@ -2610,7 +2611,7 @@ fn show_candidates(
                 prefix,
                 descr,
                 name,
-                if let IsPattern::Yes = is_pattern { ", which" } else { "" }
+                if let DiagnosticMode::Pattern = mode { ", which" } else { "" }
             );
 
             if let Some(local_def_id) = def_id.and_then(|did| did.as_local()) {