about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorYI <uuuuuu@protonmail.com>2020-04-22 15:33:34 +0800
committerYI <uuuuuu@protonmail.com>2020-04-22 16:05:17 +0800
commitbb1eedb026931853e2f37e752c45b7f3b59c5fa6 (patch)
treeb10c94f300b6c3a45d965c99ce0680800b8f6696 /src
parent25f070d1edf3d54d8933e00eeac95ce55ca8eabb (diff)
downloadrust-bb1eedb026931853e2f37e752c45b7f3b59c5fa6.tar.gz
rust-bb1eedb026931853e2f37e752c45b7f3b59c5fa6.zip
add message for resolution failure because wrong namespace
Diffstat (limited to 'src')
-rw-r--r--src/librustc_resolve/lib.rs125
-rw-r--r--src/test/ui/issues/issue-71406.rs6
-rw-r--r--src/test/ui/issues/issue-71406.stderr9
3 files changed, 95 insertions, 45 deletions
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index e94d7d6a85f..71fb8147793 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -2064,52 +2064,64 @@ impl<'a> Resolver<'a> {
                 };
             }
 
-            let binding = if let Some(module) = module {
-                self.resolve_ident_in_module(
-                    module,
-                    ident,
-                    ns,
-                    parent_scope,
-                    record_used,
-                    path_span,
-                )
-            } else if ribs.is_none() || opt_ns.is_none() || opt_ns == Some(MacroNS) {
-                let scopes = ScopeSet::All(ns, opt_ns.is_none());
-                self.early_resolve_ident_in_lexical_scope(
-                    ident,
-                    scopes,
-                    parent_scope,
-                    record_used,
-                    record_used,
-                    path_span,
-                )
-            } else {
-                let record_used_id =
-                    if record_used { crate_lint.node_id().or(Some(CRATE_NODE_ID)) } else { None };
-                match self.resolve_ident_in_lexical_scope(
-                    ident,
-                    ns,
-                    parent_scope,
-                    record_used_id,
-                    path_span,
-                    &ribs.unwrap()[ns],
-                ) {
-                    // we found a locally-imported or available item/module
-                    Some(LexicalScopeBinding::Item(binding)) => Ok(binding),
-                    // we found a local variable or type param
-                    Some(LexicalScopeBinding::Res(res))
-                        if opt_ns == Some(TypeNS) || opt_ns == Some(ValueNS) =>
-                    {
-                        record_segment_res(self, res);
-                        return PathResult::NonModule(PartialRes::with_unresolved_segments(
-                            res,
-                            path.len() - 1,
-                        ));
+            enum FindBindingResult<'a> {
+                Binding(Result<&'a NameBinding<'a>, Determinacy>),
+                PathResult(PathResult<'a>),
+            }
+            let find_binding_in_ns = |this: &mut Self, ns| {
+                let binding = if let Some(module) = module {
+                    this.resolve_ident_in_module(
+                        module,
+                        ident,
+                        ns,
+                        parent_scope,
+                        record_used,
+                        path_span,
+                    )
+                } else if ribs.is_none() || opt_ns.is_none() || opt_ns == Some(MacroNS) {
+                    let scopes = ScopeSet::All(ns, opt_ns.is_none());
+                    this.early_resolve_ident_in_lexical_scope(
+                        ident,
+                        scopes,
+                        parent_scope,
+                        record_used,
+                        record_used,
+                        path_span,
+                    )
+                } else {
+                    let record_used_id = if record_used {
+                        crate_lint.node_id().or(Some(CRATE_NODE_ID))
+                    } else {
+                        None
+                    };
+                    match this.resolve_ident_in_lexical_scope(
+                        ident,
+                        ns,
+                        parent_scope,
+                        record_used_id,
+                        path_span,
+                        &ribs.unwrap()[ns],
+                    ) {
+                        // we found a locally-imported or available item/module
+                        Some(LexicalScopeBinding::Item(binding)) => Ok(binding),
+                        // we found a local variable or type param
+                        Some(LexicalScopeBinding::Res(res))
+                            if opt_ns == Some(TypeNS) || opt_ns == Some(ValueNS) =>
+                        {
+                            record_segment_res(this, res);
+                            return FindBindingResult::PathResult(PathResult::NonModule(
+                                PartialRes::with_unresolved_segments(res, path.len() - 1),
+                            ));
+                        }
+                        _ => Err(Determinacy::determined(record_used)),
                     }
-                    _ => Err(Determinacy::determined(record_used)),
-                }
+                };
+                FindBindingResult::Binding(binding)
+            };
+            let binding = match find_binding_in_ns(self, ns) {
+                FindBindingResult::PathResult(x) => return x,
+                FindBindingResult::Binding(binding) => binding,
             };
-
             match binding {
                 Ok(binding) => {
                     if i == 1 {
@@ -2199,7 +2211,30 @@ impl<'a> Resolver<'a> {
                     } else if i == 0 {
                         (format!("use of undeclared type or module `{}`", ident), None)
                     } else {
-                        (format!("could not find `{}` in `{}`", ident, path[i - 1].ident), None)
+                        let mut msg =
+                            format!("could not find `{}` in `{}`", ident, path[i - 1].ident);
+                        if ns == TypeNS {
+                            if let FindBindingResult::Binding(Ok(_)) =
+                                find_binding_in_ns(self, ValueNS)
+                            {
+                                msg = format!(
+                                    "`{}` in `{}` is a concrete value, not a module or Struct you specified",
+                                    ident,
+                                    path[i - 1].ident
+                                );
+                            };
+                        } else if ns == ValueNS {
+                            if let FindBindingResult::Binding(Ok(_)) =
+                                find_binding_in_ns(self, TypeNS)
+                            {
+                                msg = format!(
+                                    "`{}` in `{}` is a type, not a concrete value you specified",
+                                    ident,
+                                    path[i - 1].ident
+                                );
+                            };
+                        }
+                        (msg, None)
                     };
                     return PathResult::Failed {
                         span: ident.span,
diff --git a/src/test/ui/issues/issue-71406.rs b/src/test/ui/issues/issue-71406.rs
new file mode 100644
index 00000000000..e3de30f9289
--- /dev/null
+++ b/src/test/ui/issues/issue-71406.rs
@@ -0,0 +1,6 @@
+use std::sync::mpsc;
+
+fn main() {
+    let (tx, rx) = mpsc::channel::new(1);
+    //~^ ERROR `channel` in `mpsc` is a concrete value, not a module or Struct you specified
+}
diff --git a/src/test/ui/issues/issue-71406.stderr b/src/test/ui/issues/issue-71406.stderr
new file mode 100644
index 00000000000..22a2ca4f3e2
--- /dev/null
+++ b/src/test/ui/issues/issue-71406.stderr
@@ -0,0 +1,9 @@
+error[E0433]: failed to resolve: `channel` in `mpsc` is a concrete value, not a module or Struct you specified
+  --> $DIR/issue-71406.rs:4:26
+   |
+LL |     let (tx, rx) = mpsc::channel::new(1);
+   |                          ^^^^^^^ `channel` in `mpsc` is a concrete value, not a module or Struct you specified
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0433`.