Skip to content

Commit

Permalink
rust: Desugar IfLet* into MatchExpr
Browse files Browse the repository at this point in the history
Replace the "regular" AST->HIR lowering for IfLet* with a desugaring
into a MatchExpr.

Desugar a simple if let:

   if let Some(y) = some_value {
     bar();
   }

into:

   match some_value {
     Some(y) => {bar();},
     _ => ()
   }

Same applies for IfLetExprConseqElse (if let with an else block).

Desugar:

   if let Some(y) = some_value {
     bar();
   } else {
     baz();
   }

into:

   match some_value {
     Some(y) => {bar();},
     _ => {baz();}
   }

Fixes #1177

gcc/rust/ChangeLog:

	* backend/rust-compile-block.h: Adjust after removal of
	HIR::IfLetExpr and HIR::IfLetExprConseqElse.
	* backend/rust-compile-expr.h: Likewise.
	* checks/errors/borrowck/rust-bir-builder-expr-stmt.cc
	(ExprStmtBuilder::visit): Likewise.
	* checks/errors/borrowck/rust-bir-builder-expr-stmt.h: Likewise.
	* checks/errors/borrowck/rust-bir-builder-lazyboolexpr.h:
	Likewise.
	* checks/errors/borrowck/rust-bir-builder-struct.h: Likewise.
	* checks/errors/borrowck/rust-function-collector.h: Likewise.
	* checks/errors/privacy/rust-privacy-reporter.cc
	(PrivacyReporter::visit): Likewise.
	* checks/errors/privacy/rust-privacy-reporter.h: Likewise.
	* checks/errors/rust-const-checker.cc (ConstChecker::visit):
	Likewise.
	* checks/errors/rust-const-checker.h: Likewise.
	* checks/errors/rust-unsafe-checker.cc (UnsafeChecker::visit):
	Likewise.
	* checks/errors/rust-unsafe-checker.h: Likewise.
	* hir/rust-ast-lower-block.h (ASTLoweringIfLetBlock::translate):
	Change return type.
	* hir/rust-ast-lower.cc (ASTLoweringIfLetBlock::desugar_iflet):
	New.
	(ASTLoweringIfLetBlock::visit(AST::IfLetExpr &)): Adjust and use
	desugar_iflet.
	* hir/rust-ast-lower.h: Add comment.
	* hir/rust-hir-dump.cc (Dump::do_ifletexpr): Remove.
	(Dump::visit(IfLetExpr&)): Remove.
	(Dump::visit(IfLetExprConseqElse&)): Remove.
	* hir/rust-hir-dump.h (Dump::do_ifletexpr): Remove.
	(Dump::visit(IfLetExpr&)): Remove.
	(Dump::visit(IfLetExprConseqElse&)): Remove.
	* hir/tree/rust-hir-expr.h (class IfLetExpr): Remove.
	(class IfLetExprConseqElse): Remove.
	* hir/tree/rust-hir-full-decls.h (class IfLetExpr): Remove.
	(class IfLetExprConseqElse): Remove.
	* hir/tree/rust-hir-visitor.h: Adjust after removal of
	HIR::IfLetExpr and HIR::IfLetExprConseqElse.
	* hir/tree/rust-hir.cc (IfLetExpr::as_string): Remove.
	(IfLetExprConseqElse::as_string): Remove.
	(IfLetExpr::accept_vis): Remove.
	(IfLetExprConseqElse::accept_vis): Remove.
	* hir/tree/rust-hir.h: Adjust after removal of HIR::IfLetExpr and
	HIR::IfLetExprConseqElse.
	* typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit):
	Likewise.
	* typecheck/rust-hir-type-check-expr.h: Likewise.
	* checks/errors/rust-hir-pattern-analysis.cc
	(PatternChecker::visit (IfLetExpr &)): Remove.
	(PatternChecker::visit (IfLetExprConseqElse &)): Remove.
	* checks/errors/rust-hir-pattern-analysis.h (visit(IfLetExpr &)): Remove.
	(visit(IfLetExprConseqElse &)): Remove.

gcc/testsuite/ChangeLog:

	* rust/compile/if_let_expr.rs: Adjust.
	* rust/compile/if_let_expr_simple.rs: New test.
	* rust/compile/iflet.rs: New test.
	* rust/execute/torture/iflet.rs: New test.

Signed-off-by: Marc Poulhiès <[email protected]>
  • Loading branch information
dkm committed Sep 21, 2024
1 parent 39eb3a4 commit 07c54ea
Show file tree
Hide file tree
Showing 31 changed files with 257 additions and 477 deletions.
4 changes: 0 additions & 4 deletions gcc/rust/backend/rust-compile-block.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,6 @@ class CompileConditionalBlocks : public HIRCompileBase,
void visit (HIR::LoopExpr &) override {}
void visit (HIR::WhileLoopExpr &) override {}
void visit (HIR::WhileLetLoopExpr &) override {}
void visit (HIR::IfLetExpr &) override {}
void visit (HIR::IfLetExprConseqElse &) override {}
void visit (HIR::MatchExpr &) override {}
void visit (HIR::AwaitExpr &) override {}
void visit (HIR::AsyncBlockExpr &) override {}
Expand Down Expand Up @@ -180,8 +178,6 @@ class CompileExprWithBlock : public HIRCompileBase,
void visit (HIR::LoopExpr &) override {}
void visit (HIR::WhileLoopExpr &) override {}
void visit (HIR::WhileLetLoopExpr &) override {}
void visit (HIR::IfLetExpr &) override {}
void visit (HIR::IfLetExprConseqElse &) override {}
void visit (HIR::MatchExpr &) override {}
void visit (HIR::AwaitExpr &) override {}
void visit (HIR::AsyncBlockExpr &) override {}
Expand Down
2 changes: 0 additions & 2 deletions gcc/rust/backend/rust-compile-expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,6 @@ class CompileExpr : private HIRCompileBase, protected HIR::HIRExpressionVisitor
// TODO
// these need to be sugared in the HIR to if statements and a match
void visit (HIR::WhileLetLoopExpr &) override {}
void visit (HIR::IfLetExpr &) override {}
void visit (HIR::IfLetExprConseqElse &) override {}

// lets not worry about async yet....
void visit (HIR::AwaitExpr &) override {}
Expand Down
12 changes: 0 additions & 12 deletions gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.cc
Original file line number Diff line number Diff line change
Expand Up @@ -611,18 +611,6 @@ ExprStmtBuilder::visit (HIR::IfExprConseqElse &expr)
add_jump (else_end_bb, final_start_bb);
}

void
ExprStmtBuilder::visit (HIR::IfLetExpr &expr)
{
rust_sorry_at (expr.get_locus (), "if let expressions are not supported");
}

void
ExprStmtBuilder::visit (HIR::IfLetExprConseqElse &expr)
{
rust_sorry_at (expr.get_locus (), "if let expressions are not supported");
}

void
ExprStmtBuilder::visit (HIR::MatchExpr &expr)
{
Expand Down
2 changes: 0 additions & 2 deletions gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,6 @@ class ExprStmtBuilder final : public AbstractExprBuilder,
void visit (HIR::IfExprConseqElse &expr) override;
void visit (HIR::InlineAsm &expr) override;

void visit (HIR::IfLetExpr &expr) override;
void visit (HIR::IfLetExprConseqElse &expr) override;
void visit (HIR::MatchExpr &expr) override;
void visit (HIR::AwaitExpr &expr) override;
void visit (HIR::AsyncBlockExpr &expr) override;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,14 +193,6 @@ class LazyBooleanExprBuilder : public AbstractExprBuilder
{
return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
}
void visit (HIR::IfLetExpr &expr) override
{
return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
}
void visit (HIR::IfLetExprConseqElse &expr) override
{
return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
}
void visit (HIR::MatchExpr &expr) override
{
return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
Expand Down
2 changes: 0 additions & 2 deletions gcc/rust/checks/errors/borrowck/rust-bir-builder-struct.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,6 @@ class StructBuilder : public AbstractBuilder, public HIR::HIRFullVisitor
void visit (HIR::WhileLetLoopExpr &expr) override { rust_unreachable (); }
void visit (HIR::IfExpr &expr) override { rust_unreachable (); }
void visit (HIR::IfExprConseqElse &expr) override { rust_unreachable (); }
void visit (HIR::IfLetExpr &expr) override { rust_unreachable (); }
void visit (HIR::IfLetExprConseqElse &expr) override { rust_unreachable (); }
void visit (HIR::MatchExpr &expr) override { rust_unreachable (); }
void visit (HIR::AwaitExpr &expr) override { rust_unreachable (); }
void visit (HIR::AsyncBlockExpr &expr) override { rust_unreachable (); }
Expand Down
2 changes: 0 additions & 2 deletions gcc/rust/checks/errors/borrowck/rust-function-collector.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,6 @@ class FunctionCollector : public HIR::HIRFullVisitor
void visit (HIR::WhileLetLoopExpr &expr) override {}
void visit (HIR::IfExpr &expr) override {}
void visit (HIR::IfExprConseqElse &expr) override {}
void visit (HIR::IfLetExpr &expr) override {}
void visit (HIR::IfLetExprConseqElse &expr) override {}
void visit (HIR::MatchExpr &expr) override {}
void visit (HIR::AwaitExpr &expr) override {}
void visit (HIR::AsyncBlockExpr &expr) override {}
Expand Down
15 changes: 0 additions & 15 deletions gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -594,21 +594,6 @@ PrivacyReporter::visit (HIR::IfExprConseqElse &expr)
expr.get_else_block ()->accept_vis (*this);
}

void
PrivacyReporter::visit (HIR::IfLetExpr &)
{
// TODO: We need to visit the if_let_expr
// TODO: We need to visit the block as well
}

void
PrivacyReporter::visit (HIR::IfLetExprConseqElse &)
{
// TODO: We need to visit the if_let_expr
// TODO: We need to visit the if_block as well
// TODO: We need to visit the else_block as well
}

void
PrivacyReporter::visit (HIR::MatchExpr &expr)
{
Expand Down
2 changes: 0 additions & 2 deletions gcc/rust/checks/errors/privacy/rust-privacy-reporter.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,6 @@ types
virtual void visit (HIR::WhileLetLoopExpr &expr);
virtual void visit (HIR::IfExpr &expr);
virtual void visit (HIR::IfExprConseqElse &expr);
virtual void visit (HIR::IfLetExpr &expr);
virtual void visit (HIR::IfLetExprConseqElse &expr);
virtual void visit (HIR::MatchExpr &expr);
virtual void visit (HIR::AwaitExpr &expr);
virtual void visit (HIR::AsyncBlockExpr &expr);
Expand Down
16 changes: 0 additions & 16 deletions gcc/rust/checks/errors/rust-const-checker.cc
Original file line number Diff line number Diff line change
Expand Up @@ -497,22 +497,6 @@ ConstChecker::visit (IfExprConseqElse &expr)
expr.get_else_block ()->accept_vis (*this);
}

void
ConstChecker::visit (IfLetExpr &expr)
{
expr.get_scrutinee_expr ()->accept_vis (*this);
expr.get_if_block ()->accept_vis (*this);
}

void
ConstChecker::visit (IfLetExprConseqElse &expr)
{
expr.get_scrutinee_expr ()->accept_vis (*this);
expr.get_if_block ()->accept_vis (*this);

// TODO: Visit else expression
}

void
ConstChecker::visit (MatchExpr &expr)
{
Expand Down
2 changes: 0 additions & 2 deletions gcc/rust/checks/errors/rust-const-checker.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,6 @@ class ConstChecker : public HIRFullVisitor
virtual void visit (WhileLetLoopExpr &expr) override;
virtual void visit (IfExpr &expr) override;
virtual void visit (IfExprConseqElse &expr) override;
virtual void visit (IfLetExpr &expr) override;
virtual void visit (IfLetExprConseqElse &expr) override;
virtual void visit (MatchExpr &expr) override;
virtual void visit (AwaitExpr &expr) override;
virtual void visit (AsyncBlockExpr &expr) override;
Expand Down
16 changes: 0 additions & 16 deletions gcc/rust/checks/errors/rust-hir-pattern-analysis.cc
Original file line number Diff line number Diff line change
Expand Up @@ -375,22 +375,6 @@ PatternChecker::visit (IfExprConseqElse &expr)
expr.get_else_block ()->accept_vis (*this);
}

void
PatternChecker::visit (IfLetExpr &expr)
{
expr.get_scrutinee_expr ()->accept_vis (*this);
expr.get_if_block ()->accept_vis (*this);
}

void
PatternChecker::visit (IfLetExprConseqElse &expr)
{
expr.get_scrutinee_expr ()->accept_vis (*this);
expr.get_if_block ()->accept_vis (*this);

expr.get_else_block ()->accept_vis (*this);
}

void
PatternChecker::visit (MatchExpr &expr)
{
Expand Down
2 changes: 0 additions & 2 deletions gcc/rust/checks/errors/rust-hir-pattern-analysis.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,6 @@ class PatternChecker : public HIR::HIRFullVisitor
virtual void visit (WhileLetLoopExpr &expr) override;
virtual void visit (IfExpr &expr) override;
virtual void visit (IfExprConseqElse &expr) override;
virtual void visit (IfLetExpr &expr) override;
virtual void visit (IfLetExprConseqElse &expr) override;
virtual void visit (HIR::MatchExpr &expr) override;
virtual void visit (AwaitExpr &expr) override;
virtual void visit (AsyncBlockExpr &expr) override;
Expand Down
16 changes: 0 additions & 16 deletions gcc/rust/checks/errors/rust-unsafe-checker.cc
Original file line number Diff line number Diff line change
Expand Up @@ -599,22 +599,6 @@ UnsafeChecker::visit (IfExprConseqElse &expr)
expr.get_else_block ()->accept_vis (*this);
}

void
UnsafeChecker::visit (IfLetExpr &expr)
{
expr.get_scrutinee_expr ()->accept_vis (*this);
expr.get_if_block ()->accept_vis (*this);
}

void
UnsafeChecker::visit (IfLetExprConseqElse &expr)
{
expr.get_scrutinee_expr ()->accept_vis (*this);
expr.get_if_block ()->accept_vis (*this);

// TODO: Visit else expression
}

void
UnsafeChecker::visit (MatchExpr &expr)
{
Expand Down
2 changes: 0 additions & 2 deletions gcc/rust/checks/errors/rust-unsafe-checker.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,6 @@ class UnsafeChecker : public HIRFullVisitor
virtual void visit (WhileLetLoopExpr &expr) override;
virtual void visit (IfExpr &expr) override;
virtual void visit (IfExprConseqElse &expr) override;
virtual void visit (IfLetExpr &expr) override;
virtual void visit (IfLetExprConseqElse &expr) override;
virtual void visit (MatchExpr &expr) override;
virtual void visit (AwaitExpr &expr) override;
virtual void visit (AsyncBlockExpr &expr) override;
Expand Down
11 changes: 6 additions & 5 deletions gcc/rust/hir/rust-ast-lower-block.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ class ASTLoweringIfLetBlock : public ASTLoweringBase
using Rust::HIR::ASTLoweringBase::visit;

public:
static HIR::IfLetExpr *translate (AST::IfLetExpr &expr)
static HIR::MatchExpr *translate (AST::IfLetExpr &expr)
{
ASTLoweringIfLetBlock resolver;
expr.accept_vis (resolver);
Expand All @@ -135,7 +135,10 @@ class ASTLoweringIfLetBlock : public ASTLoweringBase
private:
ASTLoweringIfLetBlock () : ASTLoweringBase (), translated (nullptr) {}

HIR::IfLetExpr *translated;
void desugar_iflet (AST::IfLetExpr &, HIR::Expr **, HIR::Expr *,
std::vector<HIR::MatchCase> &);

HIR::MatchExpr *translated;
};

class ASTLoweringExprWithBlock : public ASTLoweringBase
Expand All @@ -149,9 +152,7 @@ class ASTLoweringExprWithBlock : public ASTLoweringBase
ASTLoweringExprWithBlock resolver;
expr.accept_vis (resolver);
if (resolver.translated != nullptr)
{
resolver.mappings.insert_hir_expr (resolver.translated);
}
resolver.mappings.insert_hir_expr (resolver.translated);

*terminated = resolver.terminated;
return resolver.translated;
Expand Down
Loading

0 comments on commit 07c54ea

Please sign in to comment.