Skip to content

Commit 041003d

Browse files
bors[bot]lrh2000
andauthored
Merge #387
387: Don't remove unreachable statements at HIR lowering r=philberty a=lrh2000 This is a legal code segment: ```rust fn foo() -> i32 { return 1; let a = 1; a } ``` And this is illegal: ```rust fn foo() -> i32 { return 1; let a = 1.5; a } ``` So we shouldn't remove unreachable statements at HIR lowering. We can issue warnings for them, but they need to be kept so that their types can be checked. *(Original in #364 Co-authored-by: lrh2000 <[email protected]>
2 parents de9af78 + f48c7e8 commit 041003d

File tree

5 files changed

+50
-16
lines changed

5 files changed

+50
-16
lines changed

gcc/rust/ast/rust-stmt.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ class EmptyStmt : public Stmt
3838

3939
EmptyStmt (Location locus) : locus (locus) {}
4040

41+
Location get_locus_slow () const final override { return get_locus (); }
42+
4143
Location get_locus () const { return locus; }
4244

4345
void accept_vis (ASTVisitor &vis) override;
@@ -135,6 +137,8 @@ class LetStmt : public Stmt
135137
LetStmt (LetStmt &&other) = default;
136138
LetStmt &operator= (LetStmt &&other) = default;
137139

140+
Location get_locus_slow () const final override { return get_locus (); }
141+
138142
Location get_locus () const { return locus; }
139143

140144
void accept_vis (ASTVisitor &vis) override;

gcc/rust/hir/rust-ast-lower.cc

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -71,26 +71,16 @@ ASTLoweringBlock::visit (AST::BlockExpr &expr)
7171
std::vector<std::unique_ptr<HIR::Stmt> > block_stmts;
7272
bool block_did_terminate = false;
7373
expr.iterate_stmts ([&] (AST::Stmt *s) mutable -> bool {
74+
if (block_did_terminate)
75+
rust_warning_at (s->get_locus_slow (), 0, "unreachable statement");
76+
7477
bool terminated = false;
7578
auto translated_stmt = ASTLoweringStmt::translate (s, &terminated);
7679
block_stmts.push_back (std::unique_ptr<HIR::Stmt> (translated_stmt));
77-
block_did_terminate = terminated;
78-
return !block_did_terminate;
79-
});
80-
81-
// if there was a return expression everything after that becomes
82-
// unreachable code. This can be detected for any AST NodeIDs that have no
83-
// associated HIR Mappings
84-
expr.iterate_stmts ([&] (AST::Stmt *s) -> bool {
85-
HirId ref;
86-
if (!mappings->lookup_node_to_hir (mappings->get_current_crate (),
87-
s->get_node_id (), &ref))
88-
rust_warning_at (s->get_locus_slow (), 0, "unreachable statement");
89-
80+
block_did_terminate |= terminated;
9081
return true;
9182
});
9283

93-
bool tail_reachable = !block_did_terminate;
9484
if (expr.has_tail_expr () && block_did_terminate)
9585
{
9686
// warning unreachable tail expressions
@@ -101,10 +91,13 @@ ASTLoweringBlock::visit (AST::BlockExpr &expr)
10191
HIR::ExprWithoutBlock *tail_expr = nullptr;
10292
if (expr.has_tail_expr ())
10393
{
104-
tail_expr = (HIR::ExprWithoutBlock *) ASTLoweringExpr::translate (
105-
expr.get_tail_expr ().get ());
94+
bool terminated = false;
95+
tail_expr = (HIR::ExprWithoutBlock *)
96+
ASTLoweringExpr::translate (expr.get_tail_expr ().get (), &terminated);
97+
block_did_terminate |= terminated;
10698
}
10799

100+
bool tail_reachable = !block_did_terminate;
108101
auto crate_num = mappings->get_current_crate ();
109102
Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
110103
mappings->get_next_hir_id (crate_num),
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
fn foo() -> i32 {
2+
return 1;
3+
4+
let a = -1; // { dg-warning "unreachable statement" }
5+
a // { dg-warning "unreachable expression" }
6+
}
7+
8+
fn main() {
9+
foo();
10+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
fn foo() -> i32 {
2+
return 1;
3+
4+
let mut a = 1; // { dg-warning "unreachable statement" }
5+
a = 1.1; // { dg-warning "unreachable statement" }
6+
// { dg-error "expected .<integer>. got .<float>." "" { target { *-*-* } } .-1 }
7+
}
8+
9+
fn main() {
10+
foo();
11+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
fn foo() -> i32 {
2+
return 1;
3+
return 1.5; // { dg-error "expected .i32. got .<float>." }
4+
// { dg-warning "unreachable statement" "" { target *-*-* } .-1 }
5+
}
6+
7+
fn bar() -> i32 {
8+
return 1.5; // { dg-error "expected .i32. got .<float>." }
9+
return 1;
10+
// { dg-warning "unreachable statement" "" { target *-*-* } .-1 }
11+
}
12+
13+
fn main() {
14+
foo();
15+
bar();
16+
}

0 commit comments

Comments
 (0)