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
This commit is contained in:
parent
d17e0aa769
commit
5528001eca
|
@ -191,6 +191,8 @@ public:
|
|||
|
||||
void visit (AST::WhileLoopExpr &expr) override;
|
||||
|
||||
void visit (AST::MatchExpr &expr) override;
|
||||
|
||||
private:
|
||||
ASTLoweringExprWithBlock ()
|
||||
: ASTLoweringBase (), translated (nullptr), terminated (false)
|
||||
|
|
|
@ -674,52 +674,7 @@ public:
|
|||
|
||||
void visit (AST::MatchExpr &expr) override
|
||||
{
|
||||
HIR::Expr *branch_value
|
||||
= ASTLoweringExpr::translate (expr.get_scrutinee_expr ().get ());
|
||||
|
||||
std::vector<HIR::MatchCase> match_arms;
|
||||
for (auto &match_case : expr.get_match_cases ())
|
||||
{
|
||||
HIR::Expr *kase_expr
|
||||
= ASTLoweringExpr::translate (match_case.get_expr ().get ());
|
||||
|
||||
HIR::Expr *kase_guard_expr = nullptr;
|
||||
if (match_case.get_arm ().has_match_arm_guard ())
|
||||
{
|
||||
kase_guard_expr = ASTLoweringExpr::translate (
|
||||
match_case.get_arm ().get_guard_expr ().get ());
|
||||
}
|
||||
|
||||
std::vector<std::unique_ptr<HIR::Pattern> > match_arm_patterns;
|
||||
for (auto &pattern : match_case.get_arm ().get_patterns ())
|
||||
{
|
||||
HIR::Pattern *ptrn = ASTLoweringPattern::translate (pattern.get ());
|
||||
match_arm_patterns.push_back (std::unique_ptr<HIR::Pattern> (ptrn));
|
||||
}
|
||||
|
||||
HIR::MatchArm arm (std::move (match_arm_patterns), expr.get_locus (),
|
||||
std::unique_ptr<HIR::Expr> (kase_guard_expr),
|
||||
match_case.get_arm ().get_outer_attrs ());
|
||||
|
||||
auto crate_num = mappings->get_current_crate ();
|
||||
Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
|
||||
mappings->get_next_hir_id (crate_num),
|
||||
UNKNOWN_LOCAL_DEFID);
|
||||
|
||||
HIR::MatchCase kase (std::move (mapping), std::move (arm),
|
||||
std::unique_ptr<HIR::Expr> (kase_expr));
|
||||
match_arms.push_back (std::move (kase));
|
||||
}
|
||||
|
||||
auto crate_num = mappings->get_current_crate ();
|
||||
Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
|
||||
mappings->get_next_hir_id (crate_num),
|
||||
UNKNOWN_LOCAL_DEFID);
|
||||
|
||||
translated
|
||||
= new HIR::MatchExpr (mapping, std::unique_ptr<HIR::Expr> (branch_value),
|
||||
std::move (match_arms), expr.get_inner_attrs (),
|
||||
expr.get_outer_attrs (), expr.get_locus ());
|
||||
translated = ASTLoweringExprWithBlock::translate (&expr, &terminated);
|
||||
}
|
||||
|
||||
void visit (AST::RangeFromToExpr &expr) override
|
||||
|
|
|
@ -299,6 +299,57 @@ ASTLoweringExprWithBlock::visit (AST::WhileLoopExpr &expr)
|
|||
expr.get_outer_attrs ());
|
||||
}
|
||||
|
||||
void
|
||||
ASTLoweringExprWithBlock::visit (AST::MatchExpr &expr)
|
||||
{
|
||||
HIR::Expr *branch_value
|
||||
= ASTLoweringExpr::translate (expr.get_scrutinee_expr ().get ());
|
||||
|
||||
std::vector<HIR::MatchCase> match_arms;
|
||||
for (auto &match_case : expr.get_match_cases ())
|
||||
{
|
||||
HIR::Expr *kase_expr
|
||||
= ASTLoweringExpr::translate (match_case.get_expr ().get ());
|
||||
|
||||
HIR::Expr *kase_guard_expr = nullptr;
|
||||
if (match_case.get_arm ().has_match_arm_guard ())
|
||||
{
|
||||
kase_guard_expr = ASTLoweringExpr::translate (
|
||||
match_case.get_arm ().get_guard_expr ().get ());
|
||||
}
|
||||
|
||||
std::vector<std::unique_ptr<HIR::Pattern> > match_arm_patterns;
|
||||
for (auto &pattern : match_case.get_arm ().get_patterns ())
|
||||
{
|
||||
HIR::Pattern *ptrn = ASTLoweringPattern::translate (pattern.get ());
|
||||
match_arm_patterns.push_back (std::unique_ptr<HIR::Pattern> (ptrn));
|
||||
}
|
||||
|
||||
HIR::MatchArm arm (std::move (match_arm_patterns), expr.get_locus (),
|
||||
std::unique_ptr<HIR::Expr> (kase_guard_expr),
|
||||
match_case.get_arm ().get_outer_attrs ());
|
||||
|
||||
auto crate_num = mappings->get_current_crate ();
|
||||
Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
|
||||
mappings->get_next_hir_id (crate_num),
|
||||
UNKNOWN_LOCAL_DEFID);
|
||||
|
||||
HIR::MatchCase kase (std::move (mapping), std::move (arm),
|
||||
std::unique_ptr<HIR::Expr> (kase_expr));
|
||||
match_arms.push_back (std::move (kase));
|
||||
}
|
||||
|
||||
auto crate_num = mappings->get_current_crate ();
|
||||
Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
|
||||
mappings->get_next_hir_id (crate_num),
|
||||
UNKNOWN_LOCAL_DEFID);
|
||||
|
||||
translated
|
||||
= new HIR::MatchExpr (mapping, std::unique_ptr<HIR::Expr> (branch_value),
|
||||
std::move (match_arms), expr.get_inner_attrs (),
|
||||
expr.get_outer_attrs (), expr.get_locus ());
|
||||
}
|
||||
|
||||
// rust-ast-lower-expr.h
|
||||
|
||||
void
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
/* { dg-output "Result: 123\n" } */
|
||||
extern "C" {
|
||||
fn printf(s: *const i8, ...);
|
||||
}
|
||||
|
||||
enum Foo<T> {
|
||||
A,
|
||||
B(T),
|
||||
}
|
||||
|
||||
fn main() -> i32 {
|
||||
let result = Foo::B(123);
|
||||
|
||||
match result {
|
||||
Foo::A => unsafe {
|
||||
let a = "A\n\0";
|
||||
let b = a as *const str;
|
||||
let c = b as *const i8;
|
||||
|
||||
printf(c);
|
||||
},
|
||||
Foo::B(x) => unsafe {
|
||||
let a = "Result: %i\n\0";
|
||||
let b = a as *const str;
|
||||
let c = b as *const i8;
|
||||
|
||||
printf(c, x);
|
||||
},
|
||||
}
|
||||
|
||||
0
|
||||
}
|
Loading…
Reference in New Issue