]> git.lizzy.rs Git - rust.git/commitdiff
resolve: Unify reporting of ambiguity errors for macro paths
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>
Mon, 20 Aug 2018 21:34:30 +0000 (00:34 +0300)
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>
Mon, 20 Aug 2018 22:01:50 +0000 (01:01 +0300)
src/librustc_resolve/lib.rs
src/librustc_resolve/macros.rs
src/test/ui/imports/issue-53269.stderr
src/test/ui/imports/macros.stderr
src/test/ui/imports/shadow_builtin_macros.stderr

index 0614e8714583f21b208677faf44caab78ed65024..9bfa17615ff9a3979cf88053f6bd0e8731f1de79 100644 (file)
@@ -4431,6 +4431,42 @@ fn is_accessible_from(&self, vis: ty::Visibility, module: Module<'a>) -> bool {
         vis.is_accessible_from(module.normal_ancestor_id, self)
     }
 
+    fn report_ambiguity_error(
+        &self, name: Name, span: Span, _lexical: bool,
+        def1: Def, is_import1: bool, is_glob1: bool, from_expansion1: bool, span1: Span,
+        def2: Def, is_import2: bool, _is_glob2: bool, _from_expansion2: bool, span2: Span,
+    ) {
+        let participle = |is_import: bool| if is_import { "imported" } else { "defined" };
+        let msg1 = format!("`{}` could refer to the name {} here", name, participle(is_import1));
+        let msg2 =
+            format!("`{}` could also refer to the name {} here", name, participle(is_import2));
+        let note = if from_expansion1 {
+            Some(if let Def::Macro(..) = def1 {
+                format!("macro-expanded {} do not shadow",
+                        if is_import1 { "macro imports" } else { "macros" })
+            } else {
+                format!("macro-expanded {} do not shadow when used in a macro invocation path",
+                        if is_import1 { "imports" } else { "items" })
+            })
+        } else if is_glob1 {
+            Some(format!("consider adding an explicit import of `{}` to disambiguate", name))
+        } else {
+            None
+        };
+
+        let mut err = struct_span_err!(self.session, span, E0659, "`{}` is ambiguous", name);
+        err.span_note(span1, &msg1);
+        match def2 {
+            Def::Macro(..) if span2.is_dummy() =>
+                err.note(&format!("`{}` is also a builtin macro", name)),
+            _ => err.span_note(span2, &msg2),
+        };
+        if let Some(note) = note {
+            err.note(&note);
+        }
+        err.emit();
+    }
+
     fn report_errors(&mut self, krate: &Crate) {
         self.report_shadowing_errors();
         self.report_with_use_injections(krate);
@@ -4446,30 +4482,15 @@ fn report_errors(&mut self, krate: &Crate) {
         }
 
         for &AmbiguityError { span, name, b1, b2, lexical } in &self.ambiguity_errors {
-            if !reported_spans.insert(span) { continue }
-            let participle = |binding: &NameBinding| {
-                if binding.is_import() { "imported" } else { "defined" }
-            };
-            let msg1 = format!("`{}` could refer to the name {} here", name, participle(b1));
-            let msg2 = format!("`{}` could also refer to the name {} here", name, participle(b2));
-            let note = if b1.expansion == Mark::root() || !lexical && b1.is_glob_import() {
-                format!("consider adding an explicit import of `{}` to disambiguate", name)
-            } else if let Def::Macro(..) = b1.def() {
-                format!("macro-expanded {} do not shadow",
-                        if b1.is_import() { "macro imports" } else { "macros" })
-            } else {
-                format!("macro-expanded {} do not shadow when used in a macro invocation path",
-                        if b1.is_import() { "imports" } else { "items" })
-            };
-
-            let mut err = struct_span_err!(self.session, span, E0659, "`{}` is ambiguous", name);
-            err.span_note(b1.span, &msg1);
-            match b2.def() {
-                Def::Macro(..) if b2.span.is_dummy() =>
-                    err.note(&format!("`{}` is also a builtin macro", name)),
-                _ => err.span_note(b2.span, &msg2),
-            };
-            err.note(&note).emit();
+            if reported_spans.insert(span) {
+                self.report_ambiguity_error(
+                    name, span, lexical,
+                    b1.def(), b1.is_import(), b1.is_glob_import(),
+                    b1.expansion != Mark::root(), b1.span,
+                    b2.def(), b2.is_import(), b2.is_glob_import(),
+                    b2.expansion != Mark::root(), b2.span,
+                );
+            }
         }
 
         for &PrivacyError(span, name, binding) in &self.privacy_errors {
index bab98fb91da02ad37399ffbfda2968a007a660af..1161d57417b1890865c4590a6da8f698c96bea7e 100644 (file)
@@ -871,16 +871,18 @@ pub fn finalize_current_module_macro_resolutions(&mut self) {
                     self.suggest_macro_name(&ident.as_str(), kind, &mut err, span);
                     err.emit();
                 },
-                (Some((legacy_binding, _)), Ok((binding, FromPrelude(false)))) |
-                (Some((legacy_binding, FromExpansion(true))), Ok((binding, FromPrelude(true)))) => {
+                (Some((legacy_binding, FromExpansion(from_expansion))),
+                 Ok((binding, FromPrelude(false)))) |
+                (Some((legacy_binding, FromExpansion(from_expansion @ true))),
+                 Ok((binding, FromPrelude(true)))) => {
                     if legacy_binding.def() != binding.def_ignoring_ambiguity() {
-                        let msg1 = format!("`{}` could refer to the macro defined here", ident);
-                        let msg2 =
-                            format!("`{}` could also refer to the macro imported here", ident);
-                        self.session.struct_span_err(span, &format!("`{}` is ambiguous", ident))
-                            .span_note(legacy_binding.span, &msg1)
-                            .span_note(binding.span, &msg2)
-                            .emit();
+                        self.report_ambiguity_error(
+                            ident.name, span, true,
+                            legacy_binding.def(), false, false,
+                            from_expansion, legacy_binding.span,
+                            binding.def(), binding.is_import(), binding.is_glob_import(),
+                            binding.expansion != Mark::root(), binding.span,
+                        );
                     }
                 },
                 // OK, non-macro-expanded legacy wins over macro prelude even if defs are different
index 183cf925954390e2eba25fc34d2ad77662ae4835..0036d71107a95f57d8b024a86d6bcb158fcfaf1c 100644 (file)
@@ -4,18 +4,18 @@ error[E0432]: unresolved import `nonexistent_module`
 LL |     use nonexistent_module::mac; //~ ERROR unresolved import `nonexistent_module`
    |         ^^^^^^^^^^^^^^^^^^ Maybe a missing `extern crate nonexistent_module;`?
 
-error: `mac` is ambiguous
+error[E0659]: `mac` is ambiguous
   --> $DIR/issue-53269.rs:18:5
    |
 LL |     mac!(); //~ ERROR `mac` is ambiguous
    |     ^^^
    |
-note: `mac` could refer to the macro defined here
+note: `mac` could refer to the name defined here
   --> $DIR/issue-53269.rs:13:1
    |
 LL | macro_rules! mac { () => () }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-note: `mac` could also refer to the macro imported here
+note: `mac` could also refer to the name imported here
   --> $DIR/issue-53269.rs:16:9
    |
 LL |     use nonexistent_module::mac; //~ ERROR unresolved import `nonexistent_module`
@@ -23,4 +23,5 @@ LL |     use nonexistent_module::mac; //~ ERROR unresolved import `nonexistent_m
 
 error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0432`.
+Some errors occurred: E0432, E0659.
+For more information about an error, try `rustc --explain E0432`.
index 01d1f4fdfad03df261080be2fa31a4b06a28b30c..2c0c4642067ac5f3dc4bb77815d130f1cd91736c 100644 (file)
@@ -1,15 +1,15 @@
-error: `m` is ambiguous
+error[E0659]: `m` is ambiguous
   --> $DIR/macros.rs:48:5
    |
 LL |     m!(); //~ ERROR ambiguous
    |     ^
    |
-note: `m` could refer to the macro defined here
+note: `m` could refer to the name defined here
   --> $DIR/macros.rs:46:5
    |
 LL |     macro_rules! m { () => {} }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
-note: `m` could also refer to the macro imported here
+note: `m` could also refer to the name imported here
   --> $DIR/macros.rs:47:9
    |
 LL |     use two_macros::m;
index 263e24baff4d3693d892a9dec9910dfd0fb50f7f..5c7f15b6fe26f898e4b65f66a4884970e9a54abe 100644 (file)
@@ -1,10 +1,10 @@
-error: `panic` is ambiguous
+error[E0659]: `panic` is ambiguous
   --> $DIR/shadow_builtin_macros.rs:43:5
    |
 LL |     panic!(); //~ ERROR `panic` is ambiguous
    |     ^^^^^
    |
-note: `panic` could refer to the macro defined here
+note: `panic` could refer to the name defined here
   --> $DIR/shadow_builtin_macros.rs:40:9
    |
 LL |         macro_rules! panic { () => {} }
@@ -12,7 +12,8 @@ LL |         macro_rules! panic { () => {} }
 LL |     } }
 LL |     m!();
    |     ----- in this macro invocation
-note: `panic` could also refer to the macro imported here
+   = note: `panic` is also a builtin macro
+   = note: macro-expanded macros do not shadow
 
 error[E0659]: `panic` is ambiguous
   --> $DIR/shadow_builtin_macros.rs:25:14