Skip to content

Commit 5d8f40a

Browse files
committed
No uninitalized report in a pre-returned match arm
1 parent b5b1356 commit 5d8f40a

File tree

3 files changed

+54
-4
lines changed

3 files changed

+54
-4
lines changed

compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs

+17-4
Original file line numberDiff line numberDiff line change
@@ -557,8 +557,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
557557
// for the branching codepaths that aren't covered, to point at them.
558558
let map = self.infcx.tcx.hir();
559559
let body = map.body_owned_by(self.mir_def_id());
560-
561-
let mut visitor = ConditionVisitor { spans: &spans, name: &name, errors: vec![] };
560+
let mut visitor =
561+
ConditionVisitor { tcx: self.infcx.tcx, spans: &spans, name: &name, errors: vec![] };
562562
visitor.visit_body(&body);
563563

564564
let mut show_assign_sugg = false;
@@ -4372,13 +4372,14 @@ impl<'hir> Visitor<'hir> for BreakFinder {
43724372

43734373
/// Given a set of spans representing statements initializing the relevant binding, visit all the
43744374
/// function expressions looking for branching code paths that *do not* initialize the binding.
4375-
struct ConditionVisitor<'b> {
4375+
struct ConditionVisitor<'b, 'tcx> {
4376+
tcx: TyCtxt<'tcx>,
43764377
spans: &'b [Span],
43774378
name: &'b str,
43784379
errors: Vec<(Span, String)>,
43794380
}
43804381

4381-
impl<'b, 'v> Visitor<'v> for ConditionVisitor<'b> {
4382+
impl<'b, 'v, 'tcx> Visitor<'v> for ConditionVisitor<'b, 'tcx> {
43824383
fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) {
43834384
match ex.kind {
43844385
hir::ExprKind::If(cond, body, None) => {
@@ -4464,6 +4465,12 @@ impl<'b, 'v> Visitor<'v> for ConditionVisitor<'b> {
44644465
),
44654466
));
44664467
} else if let Some(guard) = &arm.guard {
4468+
if matches!(
4469+
self.tcx.hir_node(arm.body.hir_id),
4470+
hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Ret(_), .. })
4471+
) {
4472+
continue;
4473+
}
44674474
self.errors.push((
44684475
arm.pat.span.to(guard.span),
44694476
format!(
@@ -4473,6 +4480,12 @@ impl<'b, 'v> Visitor<'v> for ConditionVisitor<'b> {
44734480
),
44744481
));
44754482
} else {
4483+
if matches!(
4484+
self.tcx.hir_node(arm.body.hir_id),
4485+
hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Ret(_), .. })
4486+
) {
4487+
continue;
4488+
}
44764489
self.errors.push((
44774490
arm.pat.span,
44784491
format!(
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
enum E {
2+
A,
3+
B,
4+
C,
5+
}
6+
7+
fn foo(e: E) {
8+
let bar;
9+
10+
match e {
11+
E::A if true => return,
12+
E::A => return,
13+
E::B => {}
14+
E::C => {
15+
bar = 5;
16+
}
17+
}
18+
19+
let _baz = bar; //~ ERROR E0381
20+
}
21+
22+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error[E0381]: used binding `bar` is possibly-uninitialized
2+
--> $DIR/uninitalized-in-match-arm-issue-126133.rs:19:16
3+
|
4+
LL | let bar;
5+
| --- binding declared here but left uninitialized
6+
...
7+
LL | E::B => {}
8+
| ---- if this pattern is matched, `bar` is not initialized
9+
...
10+
LL | let _baz = bar;
11+
| ^^^ `bar` used here but it is possibly-uninitialized
12+
13+
error: aborting due to 1 previous error
14+
15+
For more information about this error, try `rustc --explain E0381`.

0 commit comments

Comments
 (0)