Skip to content

Commit

Permalink
add message for resolution failure because wrong namespace
Browse files Browse the repository at this point in the history
  • Loading branch information
contrun committed Apr 22, 2020
1 parent 25f070d commit bb1eedb
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 45 deletions.
125 changes: 80 additions & 45 deletions src/librustc_resolve/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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,
Expand Down
6 changes: 6 additions & 0 deletions src/test/ui/issues/issue-71406.rs
Original file line number Diff line number Diff line change
@@ -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
}
9 changes: 9 additions & 0 deletions src/test/ui/issues/issue-71406.stderr
Original file line number Diff line number Diff line change
@@ -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`.

0 comments on commit bb1eedb

Please sign in to comment.