about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDylan DPC <dylan.dpc@gmail.com>2020-04-27 03:26:15 +0200
committerGitHub <noreply@github.com>2020-04-27 03:26:15 +0200
commit94ac0ac59fc4203b4d57a56e2b4eb46004b2a603 (patch)
tree1d9cacb46dad0e2ecac324c0d0d3715e73ca1c08
parentc95bcbc9d5db498b572909bdcc56e684ceece68a (diff)
parenteb8a7031ef1ecd9b44a929f0b93f0e41c78fda25 (diff)
downloadrust-94ac0ac59fc4203b4d57a56e2b4eb46004b2a603.tar.gz
rust-94ac0ac59fc4203b4d57a56e2b4eb46004b2a603.zip
Rollup merge of #71419 - contrun:wrong-namespace-rustc-resolve, r=petrochenkov
add message for resolution failure because wrong namespace

closes https://github.com/rust-lang/rust/issues/71406
-rw-r--r--src/librustc_resolve/lib.rs128
-rw-r--r--src/test/ui/issues/issue-71406.rs6
-rw-r--r--src/test/ui/issues/issue-71406.stderr9
3 files changed, 98 insertions, 45 deletions
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 26ea75ad7ef..d84edbe3ad7 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -2066,52 +2066,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 {
@@ -2201,7 +2213,33 @@ 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 || ns == ValueNS {
+                            let ns_to_try = if ns == TypeNS { ValueNS } else { TypeNS };
+                            if let FindBindingResult::Binding(Ok(binding)) =
+                                find_binding_in_ns(self, ns_to_try)
+                            {
+                                let mut found = |what| {
+                                    msg = format!(
+                                        "expected {}, found {} `{}` in `{}`",
+                                        ns.descr(),
+                                        what,
+                                        ident,
+                                        path[i - 1].ident
+                                    )
+                                };
+                                if binding.module().is_some() {
+                                    found("module")
+                                } else {
+                                    match binding.res() {
+                                        def::Res::<NodeId>::Def(kind, id) => found(kind.descr(id)),
+                                        _ => found(ns_to_try.descr()),
+                                    }
+                                }
+                            };
+                        }
+                        (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..6266112c3a8
--- /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 expected type, found function `channel` in `mpsc`
+}
diff --git a/src/test/ui/issues/issue-71406.stderr b/src/test/ui/issues/issue-71406.stderr
new file mode 100644
index 00000000000..918163b6094
--- /dev/null
+++ b/src/test/ui/issues/issue-71406.stderr
@@ -0,0 +1,9 @@
+error[E0433]: failed to resolve: expected type, found function `channel` in `mpsc`
+  --> $DIR/issue-71406.rs:4:26
+   |
+LL |     let (tx, rx) = mpsc::channel::new(1);
+   |                          ^^^^^^^ expected type, found function `channel` in `mpsc`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0433`.