Skip to content

Commit 94ac0ac

Browse files
authored
Rollup merge of #71419 - contrun:wrong-namespace-rustc-resolve, r=petrochenkov
add message for resolution failure because wrong namespace closes #71406
2 parents c95bcbc + eb8a703 commit 94ac0ac

File tree

3 files changed

+98
-45
lines changed

3 files changed

+98
-45
lines changed

src/librustc_resolve/lib.rs

+83-45
Original file line numberDiff line numberDiff line change
@@ -2066,52 +2066,64 @@ impl<'a> Resolver<'a> {
20662066
};
20672067
}
20682068

2069-
let binding = if let Some(module) = module {
2070-
self.resolve_ident_in_module(
2071-
module,
2072-
ident,
2073-
ns,
2074-
parent_scope,
2075-
record_used,
2076-
path_span,
2077-
)
2078-
} else if ribs.is_none() || opt_ns.is_none() || opt_ns == Some(MacroNS) {
2079-
let scopes = ScopeSet::All(ns, opt_ns.is_none());
2080-
self.early_resolve_ident_in_lexical_scope(
2081-
ident,
2082-
scopes,
2083-
parent_scope,
2084-
record_used,
2085-
record_used,
2086-
path_span,
2087-
)
2088-
} else {
2089-
let record_used_id =
2090-
if record_used { crate_lint.node_id().or(Some(CRATE_NODE_ID)) } else { None };
2091-
match self.resolve_ident_in_lexical_scope(
2092-
ident,
2093-
ns,
2094-
parent_scope,
2095-
record_used_id,
2096-
path_span,
2097-
&ribs.unwrap()[ns],
2098-
) {
2099-
// we found a locally-imported or available item/module
2100-
Some(LexicalScopeBinding::Item(binding)) => Ok(binding),
2101-
// we found a local variable or type param
2102-
Some(LexicalScopeBinding::Res(res))
2103-
if opt_ns == Some(TypeNS) || opt_ns == Some(ValueNS) =>
2104-
{
2105-
record_segment_res(self, res);
2106-
return PathResult::NonModule(PartialRes::with_unresolved_segments(
2107-
res,
2108-
path.len() - 1,
2109-
));
2069+
enum FindBindingResult<'a> {
2070+
Binding(Result<&'a NameBinding<'a>, Determinacy>),
2071+
PathResult(PathResult<'a>),
2072+
}
2073+
let find_binding_in_ns = |this: &mut Self, ns| {
2074+
let binding = if let Some(module) = module {
2075+
this.resolve_ident_in_module(
2076+
module,
2077+
ident,
2078+
ns,
2079+
parent_scope,
2080+
record_used,
2081+
path_span,
2082+
)
2083+
} else if ribs.is_none() || opt_ns.is_none() || opt_ns == Some(MacroNS) {
2084+
let scopes = ScopeSet::All(ns, opt_ns.is_none());
2085+
this.early_resolve_ident_in_lexical_scope(
2086+
ident,
2087+
scopes,
2088+
parent_scope,
2089+
record_used,
2090+
record_used,
2091+
path_span,
2092+
)
2093+
} else {
2094+
let record_used_id = if record_used {
2095+
crate_lint.node_id().or(Some(CRATE_NODE_ID))
2096+
} else {
2097+
None
2098+
};
2099+
match this.resolve_ident_in_lexical_scope(
2100+
ident,
2101+
ns,
2102+
parent_scope,
2103+
record_used_id,
2104+
path_span,
2105+
&ribs.unwrap()[ns],
2106+
) {
2107+
// we found a locally-imported or available item/module
2108+
Some(LexicalScopeBinding::Item(binding)) => Ok(binding),
2109+
// we found a local variable or type param
2110+
Some(LexicalScopeBinding::Res(res))
2111+
if opt_ns == Some(TypeNS) || opt_ns == Some(ValueNS) =>
2112+
{
2113+
record_segment_res(this, res);
2114+
return FindBindingResult::PathResult(PathResult::NonModule(
2115+
PartialRes::with_unresolved_segments(res, path.len() - 1),
2116+
));
2117+
}
2118+
_ => Err(Determinacy::determined(record_used)),
21102119
}
2111-
_ => Err(Determinacy::determined(record_used)),
2112-
}
2120+
};
2121+
FindBindingResult::Binding(binding)
2122+
};
2123+
let binding = match find_binding_in_ns(self, ns) {
2124+
FindBindingResult::PathResult(x) => return x,
2125+
FindBindingResult::Binding(binding) => binding,
21132126
};
2114-
21152127
match binding {
21162128
Ok(binding) => {
21172129
if i == 1 {
@@ -2201,7 +2213,33 @@ impl<'a> Resolver<'a> {
22012213
} else if i == 0 {
22022214
(format!("use of undeclared type or module `{}`", ident), None)
22032215
} else {
2204-
(format!("could not find `{}` in `{}`", ident, path[i - 1].ident), None)
2216+
let mut msg =
2217+
format!("could not find `{}` in `{}`", ident, path[i - 1].ident);
2218+
if ns == TypeNS || ns == ValueNS {
2219+
let ns_to_try = if ns == TypeNS { ValueNS } else { TypeNS };
2220+
if let FindBindingResult::Binding(Ok(binding)) =
2221+
find_binding_in_ns(self, ns_to_try)
2222+
{
2223+
let mut found = |what| {
2224+
msg = format!(
2225+
"expected {}, found {} `{}` in `{}`",
2226+
ns.descr(),
2227+
what,
2228+
ident,
2229+
path[i - 1].ident
2230+
)
2231+
};
2232+
if binding.module().is_some() {
2233+
found("module")
2234+
} else {
2235+
match binding.res() {
2236+
def::Res::<NodeId>::Def(kind, id) => found(kind.descr(id)),
2237+
_ => found(ns_to_try.descr()),
2238+
}
2239+
}
2240+
};
2241+
}
2242+
(msg, None)
22052243
};
22062244
return PathResult::Failed {
22072245
span: ident.span,

src/test/ui/issues/issue-71406.rs

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
use std::sync::mpsc;
2+
3+
fn main() {
4+
let (tx, rx) = mpsc::channel::new(1);
5+
//~^ ERROR expected type, found function `channel` in `mpsc`
6+
}

src/test/ui/issues/issue-71406.stderr

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0433]: failed to resolve: expected type, found function `channel` in `mpsc`
2+
--> $DIR/issue-71406.rs:4:26
3+
|
4+
LL | let (tx, rx) = mpsc::channel::new(1);
5+
| ^^^^^^^ expected type, found function `channel` in `mpsc`
6+
7+
error: aborting due to previous error
8+
9+
For more information about this error, try `rustc --explain E0433`.

0 commit comments

Comments
 (0)