Skip to content

Fix issues about block expression evaluation #364

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 9 commits into from
10 changes: 5 additions & 5 deletions gcc/rust/ast/rust-expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -2828,7 +2828,7 @@ class BlockExpr : public ExprWithBlock
std::vector<Attribute> outer_attrs;
std::vector<Attribute> inner_attrs;
std::vector<std::unique_ptr<Stmt> > statements;
std::unique_ptr<ExprWithoutBlock> expr;
std::unique_ptr<Expr> expr;
Location locus;
bool marked_for_strip = false;

Expand All @@ -2842,7 +2842,7 @@ class BlockExpr : public ExprWithBlock
bool has_tail_expr () const { return expr != nullptr; }

BlockExpr (std::vector<std::unique_ptr<Stmt> > block_statements,
std::unique_ptr<ExprWithoutBlock> block_expr,
std::unique_ptr<Expr> block_expr,
std::vector<Attribute> inner_attribs,
std::vector<Attribute> outer_attribs, Location locus)
: outer_attrs (std::move (outer_attribs)),
Expand All @@ -2859,7 +2859,7 @@ class BlockExpr : public ExprWithBlock
{
// guard to protect from null pointer dereference
if (other.expr != nullptr)
expr = other.expr->clone_expr_without_block ();
expr = other.expr->clone_expr ();

statements.reserve (other.statements.size ());
for (const auto &e : other.statements)
Expand All @@ -2877,7 +2877,7 @@ class BlockExpr : public ExprWithBlock

// guard to protect from null pointer dereference
if (other.expr != nullptr)
expr = other.expr->clone_expr_without_block ();
expr = other.expr->clone_expr ();
else
expr = nullptr;

Expand Down Expand Up @@ -2929,7 +2929,7 @@ class BlockExpr : public ExprWithBlock
std::vector<std::unique_ptr<Stmt> > &get_statements () { return statements; }

// TODO: is this better? Or is a "vis_block" better?
std::unique_ptr<ExprWithoutBlock> &get_tail_expr ()
std::unique_ptr<Expr> &get_tail_expr ()
{
rust_assert (has_tail_expr ());
return expr;
Expand Down
9 changes: 7 additions & 2 deletions gcc/rust/ast/rust-stmt.h
Original file line number Diff line number Diff line change
Expand Up @@ -269,14 +269,17 @@ class ExprStmtWithoutBlock : public ExprStmt
class ExprStmtWithBlock : public ExprStmt
{
std::unique_ptr<ExprWithBlock> expr;
bool semicolon_followed;

public:
std::string as_string () const override;

std::vector<LetStmt *> locals;

ExprStmtWithBlock (std::unique_ptr<ExprWithBlock> expr, Location locus)
: ExprStmt (locus), expr (std::move (expr))
ExprStmtWithBlock (std::unique_ptr<ExprWithBlock> expr, Location locus,
bool semicolon_followed)
: ExprStmt (locus), expr (std::move (expr)),
semicolon_followed (semicolon_followed)
{}

// Copy constructor with clone
Expand Down Expand Up @@ -318,6 +321,8 @@ class ExprStmtWithBlock : public ExprStmt
return expr;
}

bool is_semicolon_followed () const { return semicolon_followed; }

protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
Expand Down
17 changes: 12 additions & 5 deletions gcc/rust/backend/rust-compile-block.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,12 @@ class CompileConditionalBlocks : public HIRCompileBase

public:
static Bstatement *compile (HIR::IfExpr *expr, Context *ctx,
Bvariable *result)
Bvariable *result, bool *terminated)
{
CompileConditionalBlocks resolver (ctx, result);
expr->accept_vis (resolver);
if (terminated)
*terminated = resolver.terminated;
return resolver.translated;
}

Expand All @@ -69,9 +71,11 @@ class CompileConditionalBlocks : public HIRCompileBase

private:
CompileConditionalBlocks (Context *ctx, Bvariable *result)
: HIRCompileBase (ctx), translated (nullptr), result (result)
: HIRCompileBase (ctx), translated (nullptr), result (result),
terminated (false)
{}

bool terminated;
Bstatement *translated;
Bvariable *result;
};
Expand All @@ -91,17 +95,20 @@ class CompileExprWithBlock : public HIRCompileBase

void visit (HIR::IfExpr &expr) override
{
translated = CompileConditionalBlocks::compile (&expr, ctx, result);
translated
= CompileConditionalBlocks::compile (&expr, ctx, result, nullptr);
}

void visit (HIR::IfExprConseqElse &expr) override
{
translated = CompileConditionalBlocks::compile (&expr, ctx, result);
translated
= CompileConditionalBlocks::compile (&expr, ctx, result, nullptr);
}

void visit (HIR::IfExprConseqIf &expr) override
{
translated = CompileConditionalBlocks::compile (&expr, ctx, result);
translated
= CompileConditionalBlocks::compile (&expr, ctx, result, nullptr);
}

private:
Expand Down
5 changes: 5 additions & 0 deletions gcc/rust/backend/rust-compile-context.h
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,11 @@ class TyTyResolveCompile : public TyTy::TyVisitor
translated = compiled_type;
}

void visit (TyTy::NeverType &) override
{
translated = ctx->get_backend ()->void_type ();
}

private:
TyTyResolveCompile (Context *ctx) : ctx (ctx), translated (nullptr) {}

Expand Down
Loading