Skip to content

Handle const blocks #3738

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

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions gcc/rust/ast/rust-ast-collector.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1263,6 +1263,22 @@ TokenCollector::visit (BlockExpr &expr)
newline ();
}

void
TokenCollector::visit (AnonConst &expr)
{
visit (expr.get_inner_expr ());
}

void
TokenCollector::visit (ConstBlock &expr)
{
push (Rust::Token::make (CONST, expr.get_locus ()));

// The inner expression is already a block expr, so we don't need to add
// curlies
visit (expr.get_const_expr ());
}

void
TokenCollector::visit (ClosureExprInnerTyped &expr)
{
Expand Down
2 changes: 2 additions & 0 deletions gcc/rust/ast/rust-ast-collector.h
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,8 @@ class TokenCollector : public ASTVisitor
void visit (ClosureParam &param);
void visit (ClosureExprInner &expr);
void visit (BlockExpr &expr);
void visit (AnonConst &expr);
void visit (ConstBlock &expr);
void visit (ClosureExprInnerTyped &expr);
void visit (ContinueExpr &expr);
void visit (BreakExpr &expr);
Expand Down
3 changes: 2 additions & 1 deletion gcc/rust/ast/rust-ast-full-decls.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ struct ClosureParam;
class ClosureExpr;
class ClosureExprInner;
class BlockExpr;
class AnonConst;
class ConstBlock;
class ClosureExprInnerTyped;
class ContinueExpr;
class BreakExpr;
Expand Down Expand Up @@ -146,7 +148,6 @@ class MatchExpr;
class AwaitExpr;
class AsyncBlockExpr;
enum class InlineAsmOption;
struct AnonConst;
struct InlineAsmRegOrRegClass;
class InlineAsmOperand;
struct InlineAsmPlaceHolder;
Expand Down
14 changes: 13 additions & 1 deletion gcc/rust/ast/rust-ast-visitor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,18 @@ DefaultASTVisitor::visit (AST::BlockExpr &expr)
visit (expr.get_tail_expr ());
}

void
DefaultASTVisitor::visit (AST::ConstBlock &expr)
{
visit (expr.get_const_expr ());
}

void
DefaultASTVisitor::visit (AST::AnonConst &expr)
{
visit (expr.get_inner_expr ());
}

void
DefaultASTVisitor::visit (AST::ClosureExprInnerTyped &expr)
{
Expand Down Expand Up @@ -699,7 +711,7 @@ DefaultASTVisitor::visit (AST::InlineAsm &expr)
break;
}
case RegisterType::Const: {
visit (operand.get_const ().anon_const.expr);
visit (operand.get_const ().anon_const.get_inner_expr ());
break;
}
case RegisterType::Sym: {
Expand Down
4 changes: 4 additions & 0 deletions gcc/rust/ast/rust-ast-visitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ class ASTVisitor
virtual void visit (FieldAccessExpr &expr) = 0;
virtual void visit (ClosureExprInner &expr) = 0;
virtual void visit (BlockExpr &expr) = 0;
virtual void visit (AnonConst &expr) = 0;
virtual void visit (ConstBlock &expr) = 0;
virtual void visit (ClosureExprInnerTyped &expr) = 0;
virtual void visit (ContinueExpr &expr) = 0;
virtual void visit (BreakExpr &expr) = 0;
Expand Down Expand Up @@ -293,6 +295,8 @@ class DefaultASTVisitor : public ASTVisitor
virtual void visit (AST::FieldAccessExpr &expr) override;
virtual void visit (AST::ClosureExprInner &expr) override;
virtual void visit (AST::BlockExpr &expr) override;
virtual void visit (AST::AnonConst &expr) override;
virtual void visit (AST::ConstBlock &expr) override;
virtual void visit (AST::ClosureExprInnerTyped &expr) override;
virtual void visit (AST::ContinueExpr &expr) override;
virtual void visit (AST::BreakExpr &expr) override;
Expand Down
24 changes: 24 additions & 0 deletions gcc/rust/ast/rust-ast.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1271,6 +1271,18 @@ BlockExpr::as_string () const
return str;
}

std::string
AnonConst::as_string () const
{
return "AnonConst: " + expr->as_string ();
}

std::string
ConstBlock::as_string () const
{
return "ConstBlock: " + expr.as_string ();
}

std::string
TraitImpl::as_string () const
{
Expand Down Expand Up @@ -4512,6 +4524,18 @@ BlockExpr::accept_vis (ASTVisitor &vis)
vis.visit (*this);
}

void
AnonConst::accept_vis (ASTVisitor &vis)
{
vis.visit (*this);
}

void
ConstBlock::accept_vis (ASTVisitor &vis)
{
vis.visit (*this);
}

void
ClosureExprInnerTyped::accept_vis (ASTVisitor &vis)
{
Expand Down
2 changes: 2 additions & 0 deletions gcc/rust/ast/rust-ast.h
Original file line number Diff line number Diff line change
Expand Up @@ -1256,6 +1256,8 @@ class Expr : public Visitable
FieldAccess,
Closure,
Block,
ConstExpr,
ConstBlock,
Continue,
Break,
Range,
Expand Down
147 changes: 124 additions & 23 deletions gcc/rust/ast/rust-expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -1214,6 +1214,8 @@ class ArrayElemsValues : public ArrayElems
class ArrayElemsCopied : public ArrayElems
{
std::unique_ptr<Expr> elem_to_copy;

// TODO: This should be replaced by a ConstExpr
std::unique_ptr<Expr> num_copies;
location_t locus;

Expand Down Expand Up @@ -2744,6 +2746,128 @@ class BlockExpr : public ExprWithBlock
}
};

class AnonConst : public ExprWithBlock
{
public:
AnonConst (std::unique_ptr<Expr> &&expr, location_t locus = UNKNOWN_LOCATION)
: id (Analysis::Mappings::get ().get_next_node_id ()), locus (locus),
expr (std::move (expr))
{
rust_assert (this->expr);
}

AnonConst (const AnonConst &other)
{
id = other.id;
locus = other.locus;
expr = other.expr->clone_expr ();
}

AnonConst operator= (const AnonConst &other)
{
id = other.id;
locus = other.locus;
expr = other.expr->clone_expr ();

return *this;
}

std::string as_string () const override;

Expr::Kind get_expr_kind () const override { return Expr::Kind::ConstExpr; }

location_t get_locus () const override { return locus; }
Expr &get_inner_expr () { return *expr; }
NodeId get_node_id () const { return id; }

/* FIXME: AnonConst are always "internal" and should not have outer attributes
* - is that true? Or should we instead call
* expr->get_outer_attrs()/expr->set_outer_attrs() */

std::vector<Attribute> &get_outer_attrs () override
{
static auto attrs = std::vector<Attribute> ();
return attrs;
}

void set_outer_attrs (std::vector<Attribute>) override {}

/* FIXME: Likewise for mark_for_strip() ? */
void mark_for_strip () override {}
bool is_marked_for_strip () const override { return false; }

void accept_vis (ASTVisitor &vis) override;

private:
NodeId id;
location_t locus;
std::unique_ptr<Expr> expr;

AnonConst *clone_expr_with_block_impl () const override
{
return new AnonConst (*this);
}
};

class ConstBlock : public ExprWithBlock
{
public:
ConstBlock (AnonConst &&expr, location_t locus = UNKNOWN_LOCATION,
std::vector<Attribute> &&outer_attrs = {})
: expr (std::move (expr)),
id (Analysis::Mappings::get ().get_next_node_id ()),
outer_attrs (std::move (outer_attrs)), locus (locus)
{}

ConstBlock (const ConstBlock &other)
: expr (other.expr), id (other.id), outer_attrs (other.outer_attrs),
locus (other.locus)
{}

ConstBlock operator= (const ConstBlock &other)
{
expr = other.expr;
id = other.id;
outer_attrs = other.outer_attrs;
locus = other.locus;

return *this;
}

std::string as_string () const override;

Expr::Kind get_expr_kind () const override { return Expr::Kind::ConstBlock; }

AnonConst &get_const_expr () { return expr; }

void accept_vis (ASTVisitor &vis) override;

std::vector<Attribute> &get_outer_attrs () override { return outer_attrs; }

void set_outer_attrs (std::vector<Attribute> new_attrs) override
{
outer_attrs = std::move (new_attrs);
}

location_t get_locus () const override { return locus; }

bool is_marked_for_strip () const override { return marked_for_strip; }
void mark_for_strip () override { marked_for_strip = true; }

private:
AnonConst expr;

NodeId id;
std::vector<Attribute> outer_attrs;
location_t locus;
bool marked_for_strip;

ConstBlock *clone_expr_with_block_impl () const override
{
return new ConstBlock (*this);
}
};

// Represents a type-specified closure expression AST node
class ClosureExprInnerTyped : public ClosureExpr
{
Expand Down Expand Up @@ -4836,29 +4960,6 @@ enum class InlineAsmOption
MAY_UNWIND = 1 << 8,
};

struct AnonConst
{
NodeId id;
std::unique_ptr<Expr> expr;
AnonConst (NodeId id, std::unique_ptr<Expr> expr)
: id (id), expr (std::move (expr))
{
rust_assert (this->expr != nullptr);
}
AnonConst (const AnonConst &other)
{
id = other.id;
expr = other.expr->clone_expr ();
}

AnonConst operator= (const AnonConst &other)
{
id = other.id;
expr = other.expr->clone_expr ();
return *this;
}
};

struct InlineAsmRegOrRegClass
{
enum Type
Expand Down
1 change: 1 addition & 0 deletions gcc/rust/backend/rust-compile-block.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "rust-compile-block.h"
#include "rust-compile-stmt.h"
#include "rust-compile-expr.h"
#include "rust-hir-expr.h"

namespace Rust {
namespace Compile {
Expand Down
9 changes: 9 additions & 0 deletions gcc/rust/backend/rust-compile-block.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ class CompileConditionalBlocks : public HIRCompileBase,
void visit (HIR::MethodCallExpr &) override {}
void visit (HIR::FieldAccessExpr &) override {}
void visit (HIR::BlockExpr &) override {}
void visit (HIR::AnonConst &) override {}
void visit (HIR::ConstBlock &) override {}
void visit (HIR::ContinueExpr &) override {}
void visit (HIR::BreakExpr &) override {}
void visit (HIR::RangeFromToExpr &) override {}
Expand Down Expand Up @@ -138,6 +140,12 @@ class CompileExprWithBlock : public HIRCompileBase,
translated = CompileBlock::compile (expr, ctx, result);
}

void visit (HIR::ConstBlock &expr) override
{
rust_unreachable ();
// translated = CompileExpr::compile (expr, ctx, result);
}

// Empty visit for unused Expression HIR nodes.
void visit (HIR::PathInExpression &) override {}
void visit (HIR::QualifiedPathInExpression &) override {}
Expand Down Expand Up @@ -184,6 +192,7 @@ class CompileExprWithBlock : public HIRCompileBase,
void visit (HIR::AsyncBlockExpr &) override {}
void visit (HIR::InlineAsm &) override {}
void visit (HIR::LlvmInlineAsm &) override {}
void visit (HIR::AnonConst &) override {}

private:
CompileExprWithBlock (Context *ctx, Bvariable *result)
Expand Down
16 changes: 15 additions & 1 deletion gcc/rust/backend/rust-compile-expr.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "realmpfr.h"
#include "convert.h"
#include "print-tree.h"
#include "rust-hir-expr.h"
#include "rust-system.h"
#include "rust-tyty.h"

Expand Down Expand Up @@ -417,7 +418,8 @@ CompileExpr::visit (HIR::BlockExpr &expr)
if (!ctx->get_tyctx ()->lookup_type (expr.get_mappings ().get_hirid (),
&block_tyty))
{
rust_error_at (expr.get_locus (), "failed to lookup type of BlockExpr");
rust_error_at (expr.get_locus (),
"failed to lookup type of BlockExpr 414");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does the 414 means here ? Is it supposed to be

rust_error_at (expr.get_locus (), ErrorCode::E0414,
		     "failed to lookup type of BlockExpr");

instead ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oops no that was just a random string for grepping, as this error message is duplicated in the compiler. I should have removed it

return;
}

Expand All @@ -440,6 +442,18 @@ CompileExpr::visit (HIR::BlockExpr &expr)
translated = Backend::var_expression (tmp, expr.get_locus ());
}

void
CompileExpr::visit (HIR::AnonConst &expr)
{
expr.get_inner_expr ().accept_vis (*this);
}

void
CompileExpr::visit (HIR::ConstBlock &expr)
{
expr.get_const_expr ().accept_vis (*this);
}

void
CompileExpr::visit (HIR::UnsafeBlockExpr &expr)
{
Expand Down
2 changes: 2 additions & 0 deletions gcc/rust/backend/rust-compile-expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ class CompileExpr : private HIRCompileBase, protected HIR::HIRExpressionVisitor
void visit (HIR::IfExpr &expr) override;
void visit (HIR::IfExprConseqElse &expr) override;
void visit (HIR::BlockExpr &expr) override;
void visit (HIR::AnonConst &expr) override;
void visit (HIR::ConstBlock &expr) override;
void visit (HIR::UnsafeBlockExpr &expr) override;
void visit (HIR::StructExprStruct &struct_expr) override;
void visit (HIR::StructExprStructFields &struct_expr) override;
Expand Down
Loading
Loading