Rollup merge of #104864 - chenyukang:yukang/fix-104700-binding, r=estebank

Account for item-local in inner scope for E0425

Fixes #104700
This commit is contained in:
Matthias Krüger 2022-12-13 01:17:08 +01:00 committed by GitHub
commit 6dbaf86672
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 55 additions and 1 deletions

View File

@ -566,6 +566,9 @@ struct LateResolutionVisitor<'a, 'b, 'ast> {
/// FIXME #4948: Reuse ribs to avoid allocation.
ribs: PerNS<Vec<Rib<'a>>>,
/// Previous poped `rib`, only used for diagnostic.
last_block_rib: Option<Rib<'a>>,
/// The current set of local scopes, for labels.
label_ribs: Vec<Rib<'a, NodeId>>,
@ -873,6 +876,8 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
// Ignore errors in function bodies if this is rustdoc
// Be sure not to set this until the function signature has been resolved.
let previous_state = replace(&mut this.in_func_body, true);
// We only care block in the same function
this.last_block_rib = None;
// Resolve the function body, potentially inside the body of an async closure
this.with_lifetime_rib(
LifetimeRibKind::Elided(LifetimeRes::Infer),
@ -1168,6 +1173,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
type_ns: vec![Rib::new(start_rib_kind)],
macro_ns: vec![Rib::new(start_rib_kind)],
},
last_block_rib: None,
label_ribs: Vec::new(),
lifetime_ribs: Vec::new(),
lifetime_elision_candidates: None,
@ -3769,7 +3775,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
self.ribs[ValueNS].pop();
self.label_ribs.pop();
}
self.ribs[ValueNS].pop();
self.last_block_rib = self.ribs[ValueNS].pop();
if anonymous_module.is_some() {
self.ribs[TypeNS].pop();
}

View File

@ -623,6 +623,22 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
return (true, candidates);
}
}
// Try to find in last block rib
if let Some(rib) = &self.last_block_rib && let RibKind::NormalRibKind = rib.kind {
for (ident, &res) in &rib.bindings {
if let Res::Local(_) = res && path.len() == 1 &&
ident.span.eq_ctxt(path[0].ident.span) &&
ident.name == path[0].ident.name {
err.span_help(
ident.span,
&format!("the binding `{}` is available in a different scope in the same function", path_str),
);
return (true, candidates);
}
}
}
return (false, candidates);
}

View File

@ -0,0 +1,11 @@
fn main() {
let foo = 1;
{
let bar = 2;
let test_func = |x| x > 3;
}
if bar == 2 { //~ ERROR cannot find value
println!("yes");
}
test_func(1); //~ ERROR cannot find function
}

View File

@ -0,0 +1,21 @@
error[E0425]: cannot find value `bar` in this scope
--> $DIR/issue-104700-inner_scope.rs:7:8
|
LL | if bar == 2 {
| ^^^
|
help: the binding `bar` is available in a different scope in the same function
--> $DIR/issue-104700-inner_scope.rs:4:13
|
LL | let bar = 2;
| ^^^
error[E0425]: cannot find function `test_func` in this scope
--> $DIR/issue-104700-inner_scope.rs:10:5
|
LL | test_func(1);
| ^^^^^^^^^ not found in this scope
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0425`.