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`.