Skip to content

Commit 5528001

Browse files
committed
Fix ICE during HIR lowering of ExprWithBlock MatchExpr
When we are lowering blocks using the visitor pattern we must use the BaseClass of ExprWithBlock to abstract away the notion that this expr has a block such that we can handle cases like a block expr vs expressions with a block. This makes the usage of hir lowering of match expressions to be recursive, if we had more fine grained visitors in the AST we could fix these types of problems with compile time enforced interfaces. Fixes #858
1 parent d17e0aa commit 5528001

File tree

4 files changed

+86
-46
lines changed

4 files changed

+86
-46
lines changed

gcc/rust/hir/rust-ast-lower-block.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,8 @@ class ASTLoweringExprWithBlock : public ASTLoweringBase
191191

192192
void visit (AST::WhileLoopExpr &expr) override;
193193

194+
void visit (AST::MatchExpr &expr) override;
195+
194196
private:
195197
ASTLoweringExprWithBlock ()
196198
: ASTLoweringBase (), translated (nullptr), terminated (false)

gcc/rust/hir/rust-ast-lower-expr.h

Lines changed: 1 addition & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -674,52 +674,7 @@ class ASTLoweringExpr : public ASTLoweringBase
674674

675675
void visit (AST::MatchExpr &expr) override
676676
{
677-
HIR::Expr *branch_value
678-
= ASTLoweringExpr::translate (expr.get_scrutinee_expr ().get ());
679-
680-
std::vector<HIR::MatchCase> match_arms;
681-
for (auto &match_case : expr.get_match_cases ())
682-
{
683-
HIR::Expr *kase_expr
684-
= ASTLoweringExpr::translate (match_case.get_expr ().get ());
685-
686-
HIR::Expr *kase_guard_expr = nullptr;
687-
if (match_case.get_arm ().has_match_arm_guard ())
688-
{
689-
kase_guard_expr = ASTLoweringExpr::translate (
690-
match_case.get_arm ().get_guard_expr ().get ());
691-
}
692-
693-
std::vector<std::unique_ptr<HIR::Pattern> > match_arm_patterns;
694-
for (auto &pattern : match_case.get_arm ().get_patterns ())
695-
{
696-
HIR::Pattern *ptrn = ASTLoweringPattern::translate (pattern.get ());
697-
match_arm_patterns.push_back (std::unique_ptr<HIR::Pattern> (ptrn));
698-
}
699-
700-
HIR::MatchArm arm (std::move (match_arm_patterns), expr.get_locus (),
701-
std::unique_ptr<HIR::Expr> (kase_guard_expr),
702-
match_case.get_arm ().get_outer_attrs ());
703-
704-
auto crate_num = mappings->get_current_crate ();
705-
Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
706-
mappings->get_next_hir_id (crate_num),
707-
UNKNOWN_LOCAL_DEFID);
708-
709-
HIR::MatchCase kase (std::move (mapping), std::move (arm),
710-
std::unique_ptr<HIR::Expr> (kase_expr));
711-
match_arms.push_back (std::move (kase));
712-
}
713-
714-
auto crate_num = mappings->get_current_crate ();
715-
Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
716-
mappings->get_next_hir_id (crate_num),
717-
UNKNOWN_LOCAL_DEFID);
718-
719-
translated
720-
= new HIR::MatchExpr (mapping, std::unique_ptr<HIR::Expr> (branch_value),
721-
std::move (match_arms), expr.get_inner_attrs (),
722-
expr.get_outer_attrs (), expr.get_locus ());
677+
translated = ASTLoweringExprWithBlock::translate (&expr, &terminated);
723678
}
724679

725680
void visit (AST::RangeFromToExpr &expr) override

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

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,57 @@ ASTLoweringExprWithBlock::visit (AST::WhileLoopExpr &expr)
299299
expr.get_outer_attrs ());
300300
}
301301

302+
void
303+
ASTLoweringExprWithBlock::visit (AST::MatchExpr &expr)
304+
{
305+
HIR::Expr *branch_value
306+
= ASTLoweringExpr::translate (expr.get_scrutinee_expr ().get ());
307+
308+
std::vector<HIR::MatchCase> match_arms;
309+
for (auto &match_case : expr.get_match_cases ())
310+
{
311+
HIR::Expr *kase_expr
312+
= ASTLoweringExpr::translate (match_case.get_expr ().get ());
313+
314+
HIR::Expr *kase_guard_expr = nullptr;
315+
if (match_case.get_arm ().has_match_arm_guard ())
316+
{
317+
kase_guard_expr = ASTLoweringExpr::translate (
318+
match_case.get_arm ().get_guard_expr ().get ());
319+
}
320+
321+
std::vector<std::unique_ptr<HIR::Pattern> > match_arm_patterns;
322+
for (auto &pattern : match_case.get_arm ().get_patterns ())
323+
{
324+
HIR::Pattern *ptrn = ASTLoweringPattern::translate (pattern.get ());
325+
match_arm_patterns.push_back (std::unique_ptr<HIR::Pattern> (ptrn));
326+
}
327+
328+
HIR::MatchArm arm (std::move (match_arm_patterns), expr.get_locus (),
329+
std::unique_ptr<HIR::Expr> (kase_guard_expr),
330+
match_case.get_arm ().get_outer_attrs ());
331+
332+
auto crate_num = mappings->get_current_crate ();
333+
Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
334+
mappings->get_next_hir_id (crate_num),
335+
UNKNOWN_LOCAL_DEFID);
336+
337+
HIR::MatchCase kase (std::move (mapping), std::move (arm),
338+
std::unique_ptr<HIR::Expr> (kase_expr));
339+
match_arms.push_back (std::move (kase));
340+
}
341+
342+
auto crate_num = mappings->get_current_crate ();
343+
Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
344+
mappings->get_next_hir_id (crate_num),
345+
UNKNOWN_LOCAL_DEFID);
346+
347+
translated
348+
= new HIR::MatchExpr (mapping, std::unique_ptr<HIR::Expr> (branch_value),
349+
std::move (match_arms), expr.get_inner_attrs (),
350+
expr.get_outer_attrs (), expr.get_locus ());
351+
}
352+
302353
// rust-ast-lower-expr.h
303354

304355
void
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/* { dg-output "Result: 123\n" } */
2+
extern "C" {
3+
fn printf(s: *const i8, ...);
4+
}
5+
6+
enum Foo<T> {
7+
A,
8+
B(T),
9+
}
10+
11+
fn main() -> i32 {
12+
let result = Foo::B(123);
13+
14+
match result {
15+
Foo::A => unsafe {
16+
let a = "A\n\0";
17+
let b = a as *const str;
18+
let c = b as *const i8;
19+
20+
printf(c);
21+
},
22+
Foo::B(x) => unsafe {
23+
let a = "Result: %i\n\0";
24+
let b = a as *const str;
25+
let c = b as *const i8;
26+
27+
printf(c, x);
28+
},
29+
}
30+
31+
0
32+
}

0 commit comments

Comments
 (0)