Skip to content

Commit 7cd4b67

Browse files
committed
fix #104700, account for item-local in inner scope for E0425
1 parent 1dda298 commit 7cd4b67

File tree

4 files changed

+53
-1
lines changed

4 files changed

+53
-1
lines changed

compiler/rustc_resolve/src/late.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -566,6 +566,9 @@ struct LateResolutionVisitor<'a, 'b, 'ast> {
566566
/// FIXME #4948: Reuse ribs to avoid allocation.
567567
ribs: PerNS<Vec<Rib<'a>>>,
568568

569+
/// Previous poped `rib`, only used for diagnostic.
570+
last_block_rib: Option<Rib<'a>>,
571+
569572
/// The current set of local scopes, for labels.
570573
label_ribs: Vec<Rib<'a, NodeId>>,
571574

@@ -1168,6 +1171,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
11681171
type_ns: vec![Rib::new(start_rib_kind)],
11691172
macro_ns: vec![Rib::new(start_rib_kind)],
11701173
},
1174+
last_block_rib: None,
11711175
label_ribs: Vec::new(),
11721176
lifetime_ribs: Vec::new(),
11731177
lifetime_elision_candidates: None,
@@ -3756,7 +3760,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
37563760
self.ribs[ValueNS].pop();
37573761
self.label_ribs.pop();
37583762
}
3759-
self.ribs[ValueNS].pop();
3763+
self.last_block_rib = self.ribs[ValueNS].pop();
37603764
if anonymous_module.is_some() {
37613765
self.ribs[TypeNS].pop();
37623766
}

compiler/rustc_resolve/src/late/diagnostics.rs

+16
Original file line numberDiff line numberDiff line change
@@ -614,6 +614,22 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
614614
return (true, candidates);
615615
}
616616
}
617+
618+
// Try to find in last block rib
619+
if let Some(rib) = &self.last_block_rib {
620+
for (ident, &res) in &rib.bindings {
621+
if let Res::Local(_) = res && path.len() == 1 &&
622+
ident.span.eq_ctxt(path[0].ident.span) &&
623+
ident.name == path[0].ident.name {
624+
err.span_help(
625+
ident.span,
626+
&format!("the binding `{}` is available in a different scope in the same function", path_str),
627+
);
628+
return (true, candidates);
629+
}
630+
}
631+
}
632+
617633
return (false, candidates);
618634
}
619635

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
fn main() {
2+
let foo = 1;
3+
{
4+
let bar = 2;
5+
let test_func = |x| x > 3;
6+
}
7+
if bar == 2 { //~ ERROR cannot find value
8+
println!("yes");
9+
}
10+
test_func(1); //~ ERROR cannot find function
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
error[E0425]: cannot find value `bar` in this scope
2+
--> $DIR/issue-104700-inner_scope.rs:7:8
3+
|
4+
LL | if bar == 2 {
5+
| ^^^
6+
|
7+
help: the binding `bar` is available in a different scope in the same function
8+
--> $DIR/issue-104700-inner_scope.rs:4:13
9+
|
10+
LL | let bar = 2;
11+
| ^^^
12+
13+
error[E0425]: cannot find function `test_func` in this scope
14+
--> $DIR/issue-104700-inner_scope.rs:10:5
15+
|
16+
LL | test_func(1);
17+
| ^^^^^^^^^ not found in this scope
18+
19+
error: aborting due to 2 previous errors
20+
21+
For more information about this error, try `rustc --explain E0425`.

0 commit comments

Comments
 (0)