From bb1eedb026931853e2f37e752c45b7f3b59c5fa6 Mon Sep 17 00:00:00 2001 From: YI Date: Wed, 22 Apr 2020 15:33:34 +0800 Subject: [PATCH 1/2] add message for resolution failure because wrong namespace --- src/librustc_resolve/lib.rs | 125 ++++++++++++++++---------- src/test/ui/issues/issue-71406.rs | 6 ++ src/test/ui/issues/issue-71406.stderr | 9 ++ 3 files changed, 95 insertions(+), 45 deletions(-) create mode 100644 src/test/ui/issues/issue-71406.rs create mode 100644 src/test/ui/issues/issue-71406.stderr diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index e94d7d6a85fb4..71fb8147793a8 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 0000000000000..e3de30f92896e --- /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 0000000000000..22a2ca4f3e233 --- /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`. From eb8a7031ef1ecd9b44a929f0b93f0e41c78fda25 Mon Sep 17 00:00:00 2001 From: YI Date: Sun, 26 Apr 2020 10:28:33 +0800 Subject: [PATCH 2/2] use defkind.descr in wrong namespace resolve failure --- src/librustc_resolve/lib.rs | 39 ++++++++++++++------------- src/test/ui/issues/issue-71406.rs | 2 +- src/test/ui/issues/issue-71406.stderr | 4 +-- 3 files changed, 24 insertions(+), 21 deletions(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 71fb8147793a8..2d53b7553a156 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -2213,25 +2213,28 @@ impl<'a> Resolver<'a> { } else { 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) + 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) { - 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 - ); + 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::::Def(kind, id) => found(kind.descr(id)), + _ => found(ns_to_try.descr()), + } + } }; } (msg, None) diff --git a/src/test/ui/issues/issue-71406.rs b/src/test/ui/issues/issue-71406.rs index e3de30f92896e..6266112c3a86c 100644 --- a/src/test/ui/issues/issue-71406.rs +++ b/src/test/ui/issues/issue-71406.rs @@ -2,5 +2,5 @@ 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 + //~^ 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 index 22a2ca4f3e233..918163b609473 100644 --- a/src/test/ui/issues/issue-71406.stderr +++ b/src/test/ui/issues/issue-71406.stderr @@ -1,8 +1,8 @@ -error[E0433]: failed to resolve: `channel` in `mpsc` is a concrete value, not a module or Struct you specified +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); - | ^^^^^^^ `channel` in `mpsc` is a concrete value, not a module or Struct you specified + | ^^^^^^^ expected type, found function `channel` in `mpsc` error: aborting due to previous error