diff --git a/gcc/rust/ast/rust-ast-collector.cc b/gcc/rust/ast/rust-ast-collector.cc index f0fc4caad66..9bec1c7cc17 100644 --- a/gcc/rust/ast/rust-ast-collector.cc +++ b/gcc/rust/ast/rust-ast-collector.cc @@ -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) { diff --git a/gcc/rust/ast/rust-ast-collector.h b/gcc/rust/ast/rust-ast-collector.h index b0f1ff5fd7f..fa835ce4c4a 100644 --- a/gcc/rust/ast/rust-ast-collector.h +++ b/gcc/rust/ast/rust-ast-collector.h @@ -277,6 +277,8 @@ class TokenCollector : public ASTVisitor void visit (ClosureParam ¶m); 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); diff --git a/gcc/rust/ast/rust-ast-full-decls.h b/gcc/rust/ast/rust-ast-full-decls.h index ae103da4401..aabb1e4bd38 100644 --- a/gcc/rust/ast/rust-ast-full-decls.h +++ b/gcc/rust/ast/rust-ast-full-decls.h @@ -115,6 +115,8 @@ struct ClosureParam; class ClosureExpr; class ClosureExprInner; class BlockExpr; +class AnonConst; +class ConstBlock; class ClosureExprInnerTyped; class ContinueExpr; class BreakExpr; @@ -146,7 +148,6 @@ class MatchExpr; class AwaitExpr; class AsyncBlockExpr; enum class InlineAsmOption; -struct AnonConst; struct InlineAsmRegOrRegClass; class InlineAsmOperand; struct InlineAsmPlaceHolder; diff --git a/gcc/rust/ast/rust-ast-visitor.cc b/gcc/rust/ast/rust-ast-visitor.cc index 7584d1af5bb..fd6398a46a6 100644 --- a/gcc/rust/ast/rust-ast-visitor.cc +++ b/gcc/rust/ast/rust-ast-visitor.cc @@ -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) { @@ -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: { diff --git a/gcc/rust/ast/rust-ast-visitor.h b/gcc/rust/ast/rust-ast-visitor.h index dca8cbc645b..2a3c7447914 100644 --- a/gcc/rust/ast/rust-ast-visitor.h +++ b/gcc/rust/ast/rust-ast-visitor.h @@ -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; @@ -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; diff --git a/gcc/rust/ast/rust-ast.cc b/gcc/rust/ast/rust-ast.cc index 494b21a1ba5..c53b5adc3f0 100644 --- a/gcc/rust/ast/rust-ast.cc +++ b/gcc/rust/ast/rust-ast.cc @@ -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 { @@ -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) { diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h index 9581dd57b73..7f30f78d539 100644 --- a/gcc/rust/ast/rust-ast.h +++ b/gcc/rust/ast/rust-ast.h @@ -1256,6 +1256,8 @@ class Expr : public Visitable FieldAccess, Closure, Block, + ConstExpr, + ConstBlock, Continue, Break, Range, diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h index fdb6360eb3b..1ba10d306ab 100644 --- a/gcc/rust/ast/rust-expr.h +++ b/gcc/rust/ast/rust-expr.h @@ -1214,6 +1214,8 @@ class ArrayElemsValues : public ArrayElems class ArrayElemsCopied : public ArrayElems { std::unique_ptr elem_to_copy; + + // TODO: This should be replaced by a ConstExpr std::unique_ptr num_copies; location_t locus; @@ -2744,6 +2746,128 @@ class BlockExpr : public ExprWithBlock } }; +class AnonConst : public ExprWithBlock +{ +public: + AnonConst (std::unique_ptr &&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 &get_outer_attrs () override + { + static auto attrs = std::vector (); + return attrs; + } + + void set_outer_attrs (std::vector) 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; + + 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 &&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 &get_outer_attrs () override { return outer_attrs; } + + void set_outer_attrs (std::vector 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 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 { @@ -4836,29 +4960,6 @@ enum class InlineAsmOption MAY_UNWIND = 1 << 8, }; -struct AnonConst -{ - NodeId id; - std::unique_ptr expr; - AnonConst (NodeId id, std::unique_ptr 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 diff --git a/gcc/rust/backend/rust-compile-block.cc b/gcc/rust/backend/rust-compile-block.cc index 56d0c417f0a..b55fe68ca94 100644 --- a/gcc/rust/backend/rust-compile-block.cc +++ b/gcc/rust/backend/rust-compile-block.cc @@ -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 { diff --git a/gcc/rust/backend/rust-compile-block.h b/gcc/rust/backend/rust-compile-block.h index 896ff758442..e288bd89f26 100644 --- a/gcc/rust/backend/rust-compile-block.h +++ b/gcc/rust/backend/rust-compile-block.h @@ -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 {} @@ -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 {} @@ -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) diff --git a/gcc/rust/backend/rust-compile-expr.cc b/gcc/rust/backend/rust-compile-expr.cc index 339317d8174..6c3a60b6ee4 100644 --- a/gcc/rust/backend/rust-compile-expr.cc +++ b/gcc/rust/backend/rust-compile-expr.cc @@ -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" @@ -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"); return; } @@ -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) { diff --git a/gcc/rust/backend/rust-compile-expr.h b/gcc/rust/backend/rust-compile-expr.h index a9c59ab7139..fda508ddb55 100644 --- a/gcc/rust/backend/rust-compile-expr.h +++ b/gcc/rust/backend/rust-compile-expr.h @@ -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; diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.cc b/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.cc index 70ad7ed21a5..406b5a233a0 100644 --- a/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.cc +++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.cc @@ -414,6 +414,18 @@ ExprStmtBuilder::visit (HIR::BlockExpr &block) ctx.place_db.pop_scope (); } +void +ExprStmtBuilder::visit (HIR::AnonConst &block) +{ + rust_unreachable (); +} + +void +ExprStmtBuilder::visit (HIR::ConstBlock &block) +{ + rust_unreachable (); +} + void ExprStmtBuilder::visit (HIR::ContinueExpr &cont) { diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.h b/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.h index 48b81991e07..0db44e17907 100644 --- a/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.h +++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.h @@ -84,6 +84,8 @@ class ExprStmtBuilder final : public AbstractExprBuilder, void visit (HIR::MethodCallExpr &expr) override; void visit (HIR::FieldAccessExpr &expr) override; void visit (HIR::BlockExpr &block) override; + void visit (HIR::AnonConst &block) override; + void visit (HIR::ConstBlock &block) override; void visit (HIR::ContinueExpr &cont) override; void visit (HIR::BreakExpr &brk) override; void visit (HIR::RangeFromToExpr &range) override; diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-builder-lazyboolexpr.h b/gcc/rust/checks/errors/borrowck/rust-bir-builder-lazyboolexpr.h index dbf365a3478..31adca10b5f 100644 --- a/gcc/rust/checks/errors/borrowck/rust-bir-builder-lazyboolexpr.h +++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder-lazyboolexpr.h @@ -169,6 +169,14 @@ class LazyBooleanExprBuilder : public AbstractExprBuilder { return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ()); } + void visit (HIR::AnonConst &expr) override + { + return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ()); + } + void visit (HIR::ConstBlock &expr) override + { + return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ()); + } void visit (HIR::UnsafeBlockExpr &expr) override { return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ()); diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-builder-struct.h b/gcc/rust/checks/errors/borrowck/rust-bir-builder-struct.h index fdec3291acd..a689eda845f 100644 --- a/gcc/rust/checks/errors/borrowck/rust-bir-builder-struct.h +++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder-struct.h @@ -133,6 +133,8 @@ class StructBuilder : public AbstractBuilder, public HIR::HIRFullVisitor void visit (HIR::MethodCallExpr &expr) override { rust_unreachable (); } void visit (HIR::FieldAccessExpr &expr) override { rust_unreachable (); } void visit (HIR::BlockExpr &expr) override { rust_unreachable (); } + void visit (HIR::AnonConst &expr) override { rust_unreachable (); } + void visit (HIR::ConstBlock &expr) override { rust_unreachable (); } void visit (HIR::ClosureExpr &expr) override { rust_unreachable (); } void visit (HIR::ContinueExpr &expr) override { rust_unreachable (); } void visit (HIR::BreakExpr &expr) override { rust_unreachable (); } diff --git a/gcc/rust/checks/errors/borrowck/rust-function-collector.h b/gcc/rust/checks/errors/borrowck/rust-function-collector.h index 74b5f4365c1..67a2c1a8352 100644 --- a/gcc/rust/checks/errors/borrowck/rust-function-collector.h +++ b/gcc/rust/checks/errors/borrowck/rust-function-collector.h @@ -104,6 +104,8 @@ class FunctionCollector : public HIR::HIRFullVisitor void visit (HIR::MethodCallExpr &expr) override {} void visit (HIR::FieldAccessExpr &expr) override {} void visit (HIR::BlockExpr &expr) override {} + void visit (HIR::AnonConst &expr) override {} + void visit (HIR::ConstBlock &expr) override {} void visit (HIR::ContinueExpr &expr) override {} void visit (HIR::BreakExpr &expr) override {} void visit (HIR::RangeFromToExpr &expr) override {} diff --git a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc index c78a2f5dcc6..0b1428a6e7f 100644 --- a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc +++ b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc @@ -517,6 +517,18 @@ PrivacyReporter::visit (HIR::BlockExpr &expr) expr.get_final_expr ().accept_vis (*this); } +void +PrivacyReporter::visit (HIR::AnonConst &expr) +{ + expr.get_inner_expr ().accept_vis (*this); +} + +void +PrivacyReporter::visit (HIR::ConstBlock &expr) +{ + expr.get_const_expr ().accept_vis (*this); +} + void PrivacyReporter::visit (HIR::ContinueExpr &) {} diff --git a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.h b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.h index c3d9f3011f9..d38854fdd19 100644 --- a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.h +++ b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.h @@ -106,6 +106,8 @@ types virtual void visit (HIR::MethodCallExpr &expr); virtual void visit (HIR::FieldAccessExpr &expr); virtual void visit (HIR::BlockExpr &expr); + virtual void visit (HIR::AnonConst &expr); + virtual void visit (HIR::ConstBlock &expr); virtual void visit (HIR::ContinueExpr &expr); virtual void visit (HIR::BreakExpr &expr); virtual void visit (HIR::RangeFromToExpr &expr); diff --git a/gcc/rust/checks/errors/rust-const-checker.cc b/gcc/rust/checks/errors/rust-const-checker.cc index 7423b82779a..4e108471237 100644 --- a/gcc/rust/checks/errors/rust-const-checker.cc +++ b/gcc/rust/checks/errors/rust-const-checker.cc @@ -416,6 +416,26 @@ ConstChecker::visit (BlockExpr &expr) expr.get_final_expr ().accept_vis (*this); } +void +ConstChecker::visit (AnonConst &expr) +{ + const_context.enter (expr.get_mappings ().get_hirid ()); + + expr.get_inner_expr ().accept_vis (*this); + + const_context.exit (); +} + +void +ConstChecker::visit (ConstBlock &expr) +{ + const_context.enter (expr.get_mappings ().get_hirid ()); + + expr.get_const_expr ().accept_vis (*this); + + const_context.exit (); +} + void ConstChecker::visit (ContinueExpr &) {} diff --git a/gcc/rust/checks/errors/rust-const-checker.h b/gcc/rust/checks/errors/rust-const-checker.h index 33f956ac0e5..90cfebd59ec 100644 --- a/gcc/rust/checks/errors/rust-const-checker.h +++ b/gcc/rust/checks/errors/rust-const-checker.h @@ -113,6 +113,8 @@ class ConstChecker : public HIRFullVisitor virtual void visit (FieldAccessExpr &expr) override; virtual void visit (ClosureExpr &expr) override; virtual void visit (BlockExpr &expr) override; + virtual void visit (AnonConst &expr) override; + virtual void visit (ConstBlock &expr) override; virtual void visit (ContinueExpr &expr) override; virtual void visit (BreakExpr &expr) override; virtual void visit (RangeFromToExpr &expr) override; diff --git a/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc b/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc index 648bc07762d..8cff8e6c5d4 100644 --- a/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc +++ b/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc @@ -294,6 +294,18 @@ PatternChecker::visit (BlockExpr &expr) expr.get_final_expr ().accept_vis (*this); } +void +PatternChecker::visit (AnonConst &expr) +{ + expr.get_inner_expr ().accept_vis (*this); +} + +void +PatternChecker::visit (ConstBlock &expr) +{ + expr.get_const_expr ().accept_vis (*this); +} + void PatternChecker::visit (ContinueExpr &) {} diff --git a/gcc/rust/checks/errors/rust-hir-pattern-analysis.h b/gcc/rust/checks/errors/rust-hir-pattern-analysis.h index 6d60ceda538..620b0792048 100644 --- a/gcc/rust/checks/errors/rust-hir-pattern-analysis.h +++ b/gcc/rust/checks/errors/rust-hir-pattern-analysis.h @@ -86,6 +86,8 @@ class PatternChecker : public HIR::HIRFullVisitor virtual void visit (MethodCallExpr &expr) override; virtual void visit (FieldAccessExpr &expr) override; virtual void visit (BlockExpr &expr) override; + virtual void visit (AnonConst &expr) override; + virtual void visit (ConstBlock &expr) override; virtual void visit (ClosureExpr &expr) override; virtual void visit (ContinueExpr &expr) override; virtual void visit (BreakExpr &expr) override; diff --git a/gcc/rust/checks/errors/rust-unsafe-checker.cc b/gcc/rust/checks/errors/rust-unsafe-checker.cc index 7097c500035..1cc618f0258 100644 --- a/gcc/rust/checks/errors/rust-unsafe-checker.cc +++ b/gcc/rust/checks/errors/rust-unsafe-checker.cc @@ -539,6 +539,18 @@ UnsafeChecker::visit (BlockExpr &expr) expr.get_final_expr ().accept_vis (*this); } +void +UnsafeChecker::visit (AnonConst &expr) +{ + expr.get_inner_expr ().accept_vis (*this); +} + +void +UnsafeChecker::visit (ConstBlock &expr) +{ + expr.get_const_expr ().accept_vis (*this); +} + void UnsafeChecker::visit (ContinueExpr &) {} diff --git a/gcc/rust/checks/errors/rust-unsafe-checker.h b/gcc/rust/checks/errors/rust-unsafe-checker.h index 7f5388c8e18..a77de824f21 100644 --- a/gcc/rust/checks/errors/rust-unsafe-checker.h +++ b/gcc/rust/checks/errors/rust-unsafe-checker.h @@ -95,6 +95,8 @@ class UnsafeChecker : public HIRFullVisitor virtual void visit (FieldAccessExpr &expr) override; virtual void visit (ClosureExpr &expr) override; virtual void visit (BlockExpr &expr) override; + virtual void visit (AnonConst &expr) override; + virtual void visit (ConstBlock &expr) override; virtual void visit (ContinueExpr &expr) override; virtual void visit (BreakExpr &expr) override; virtual void visit (RangeFromToExpr &expr) override; diff --git a/gcc/rust/expand/rust-derive.h b/gcc/rust/expand/rust-derive.h index ff7839dcafe..131b33ed750 100644 --- a/gcc/rust/expand/rust-derive.h +++ b/gcc/rust/expand/rust-derive.h @@ -147,6 +147,8 @@ class DeriveVisitor : public AST::ASTVisitor virtual void visit (FieldAccessExpr &expr) override final{}; virtual void visit (ClosureExprInner &expr) override final{}; virtual void visit (BlockExpr &expr) override final{}; + virtual void visit (AnonConst &expr) override final{}; + virtual void visit (ConstBlock &expr) override final{}; virtual void visit (ClosureExprInnerTyped &expr) override final{}; virtual void visit (ContinueExpr &expr) override final{}; virtual void visit (BreakExpr &expr) override final{}; diff --git a/gcc/rust/hir/rust-ast-lower-base.cc b/gcc/rust/hir/rust-ast-lower-base.cc index 7be5922eeb4..b3815676cc1 100644 --- a/gcc/rust/hir/rust-ast-lower-base.cc +++ b/gcc/rust/hir/rust-ast-lower-base.cc @@ -201,6 +201,12 @@ void ASTLoweringBase::visit (AST::BlockExpr &) {} void +ASTLoweringBase::visit (AST::AnonConst &) +{} +void +ASTLoweringBase::visit (AST::ConstBlock &) +{} +void ASTLoweringBase::visit (AST::ClosureExprInnerTyped &) {} void diff --git a/gcc/rust/hir/rust-ast-lower-base.h b/gcc/rust/hir/rust-ast-lower-base.h index b3017ac09c9..653e2e88bc4 100644 --- a/gcc/rust/hir/rust-ast-lower-base.h +++ b/gcc/rust/hir/rust-ast-lower-base.h @@ -131,6 +131,8 @@ class ASTLoweringBase : public AST::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; diff --git a/gcc/rust/hir/rust-ast-lower-expr.cc b/gcc/rust/hir/rust-ast-lower-expr.cc index e9e3b4e2e04..d5aef7ed070 100644 --- a/gcc/rust/hir/rust-ast-lower-expr.cc +++ b/gcc/rust/hir/rust-ast-lower-expr.cc @@ -25,6 +25,7 @@ #include "rust-ast-lower-type.h" #include "rust-ast.h" #include "rust-diagnostics.h" +#include "rust-hir-map.h" #include "rust-system.h" #include "tree/rust-hir-expr.h" @@ -126,6 +127,43 @@ ASTLoweringExpr::visit (AST::BlockExpr &expr) translated = ASTLoweringBlock::translate (expr, &terminated); } +void +ASTLoweringExpr::visit (AST::AnonConst &expr) +{ + auto inner_expr = ASTLoweringExpr::translate (expr.get_inner_expr ()); + + auto &mappings = Analysis::Mappings::get (); + auto crate_num = mappings.get_current_crate (); + auto mapping = Analysis::NodeMapping (crate_num, expr.get_node_id (), + mappings.get_next_hir_id (crate_num), + UNKNOWN_LOCAL_DEFID); + + translated = new HIR::AnonConst (std::move (mapping), + std::unique_ptr (inner_expr), + expr.get_locus ()); +} + +void +ASTLoweringExpr::visit (AST::ConstBlock &expr) +{ + auto inner_expr = ASTLoweringExpr::translate (expr.get_const_expr ()); + + // we know this will always be an `AnonConst`, or we have an issue. Let's + // assert just to be sure. + rust_assert (inner_expr->get_expression_type () == Expr::ExprType::AnonConst); + auto anon_const = static_cast (inner_expr); + + auto &mappings = Analysis::Mappings::get (); + auto crate_num = mappings.get_current_crate (); + auto mapping = Analysis::NodeMapping (crate_num, expr.get_node_id (), + mappings.get_next_hir_id (crate_num), + UNKNOWN_LOCAL_DEFID); + + translated + = new HIR::ConstBlock (std::move (mapping), std::move (*anon_const), + expr.get_locus (), expr.get_outer_attrs ()); +} + void ASTLoweringExpr::visit (AST::UnsafeBlockExpr &expr) { @@ -841,6 +879,7 @@ translate_operand_out (const AST::InlineAsmOperand &operand) *out_value.expr.get ()))); return out; } + HIR::InlineAsmOperand translate_operand_inout (const AST::InlineAsmOperand &operand) { @@ -851,6 +890,7 @@ translate_operand_inout (const AST::InlineAsmOperand &operand) *inout_value.expr.get ()))); return inout; } + HIR::InlineAsmOperand translate_operand_split_in_out (const AST::InlineAsmOperand &operand) { @@ -863,19 +903,21 @@ translate_operand_split_in_out (const AST::InlineAsmOperand &operand) ASTLoweringExpr::translate (*split_in_out_value.out_expr.get ()))); return split_in_out; } + HIR::InlineAsmOperand translate_operand_const (const AST::InlineAsmOperand &operand) { auto const_value = operand.get_const (); - struct HIR::AnonConst anon_const (const_value.anon_const.id, - std::unique_ptr ( - ASTLoweringExpr::translate ( - *const_value.anon_const.expr.get ()))); - struct HIR::InlineAsmOperand::Const cnst - { - anon_const - }; - return cnst; + + auto inner_expr = ASTLoweringExpr::translate (const_value.anon_const); + + // Like `ConstBlock`, we know this should only be an `AnonConst` - let's + // assert to make sure and static cast + rust_assert (inner_expr->get_expression_type () == Expr::ExprType::AnonConst); + + auto anon_const = static_cast (inner_expr); + + return HIR::InlineAsmOperand::Const{*anon_const}; } HIR::InlineAsmOperand diff --git a/gcc/rust/hir/rust-ast-lower-expr.h b/gcc/rust/hir/rust-ast-lower-expr.h index b8681fb07ca..231217d1dea 100644 --- a/gcc/rust/hir/rust-ast-lower-expr.h +++ b/gcc/rust/hir/rust-ast-lower-expr.h @@ -82,6 +82,8 @@ class ASTLoweringExpr : public ASTLoweringBase void visit (AST::IfLetExpr &expr) override; void visit (AST::IfLetExprConseqElse &expr) override; void visit (AST::BlockExpr &expr) override; + void visit (AST::AnonConst &expr) override; + void visit (AST::ConstBlock &expr) override; void visit (AST::UnsafeBlockExpr &expr) override; void visit (AST::PathInExpression &expr) override; void visit (AST::QualifiedPathInExpression &expr) override; diff --git a/gcc/rust/hir/rust-hir-dump.cc b/gcc/rust/hir/rust-hir-dump.cc index 156bd813907..b91eaab1ebb 100644 --- a/gcc/rust/hir/rust-hir-dump.cc +++ b/gcc/rust/hir/rust-hir-dump.cc @@ -1296,6 +1296,28 @@ Dump::visit (BlockExpr &e) end ("BlockExpr"); } +void +Dump::visit (AnonConst &e) +{ + begin ("AnonConst"); + do_expr (e); + + visit_field ("inner", e.get_inner_expr ()); + + end ("AnonConst"); +} + +void +Dump::visit (ConstBlock &e) +{ + begin ("ConstBlock"); + do_expr (e); + + visit_field ("inner", e.get_const_expr ()); + + end ("ConstBlock"); +} + void Dump::visit (ContinueExpr &e) { diff --git a/gcc/rust/hir/rust-hir-dump.h b/gcc/rust/hir/rust-hir-dump.h index b3015c639cf..119a0980044 100644 --- a/gcc/rust/hir/rust-hir-dump.h +++ b/gcc/rust/hir/rust-hir-dump.h @@ -146,6 +146,8 @@ class Dump : public HIRFullVisitor virtual void visit (FieldAccessExpr &) override; virtual void visit (ClosureExpr &) override; virtual void visit (BlockExpr &) override; + virtual void visit (AnonConst &) override; + virtual void visit (ConstBlock &) override; virtual void visit (ContinueExpr &) override; virtual void visit (BreakExpr &) override; virtual void visit (RangeFromToExpr &) override; diff --git a/gcc/rust/hir/tree/rust-hir-expr-abstract.h b/gcc/rust/hir/tree/rust-hir-expr-abstract.h index 5bc5d890309..8272a82808c 100644 --- a/gcc/rust/hir/tree/rust-hir-expr-abstract.h +++ b/gcc/rust/hir/tree/rust-hir-expr-abstract.h @@ -43,7 +43,7 @@ class Expr : public Node, virtual public FullVisitable WITHOUT_BLOCK, }; - enum ExprType + enum class ExprType { Lit, Operator, @@ -58,6 +58,8 @@ class Expr : public Node, virtual public FullVisitable FieldAccess, Closure, Block, + AnonConst, + ConstBlock, Continue, Break, Range, diff --git a/gcc/rust/hir/tree/rust-hir-expr.cc b/gcc/rust/hir/tree/rust-hir-expr.cc index 266c79c2fe8..49f046775c7 100644 --- a/gcc/rust/hir/tree/rust-hir-expr.cc +++ b/gcc/rust/hir/tree/rust-hir-expr.cc @@ -790,6 +790,50 @@ BlockExpr::operator= (BlockExpr const &other) return *this; } +AnonConst::AnonConst (Analysis::NodeMapping mappings, + std::unique_ptr &&expr, location_t locus) + : ExprWithBlock (std::move (mappings), {}), locus (locus), + expr (std::move (expr)) +{ + rust_assert (this->expr); +} + +AnonConst::AnonConst (const AnonConst &other) + : ExprWithBlock (other), locus (other.locus), expr (other.expr->clone_expr ()) +{} + +AnonConst +AnonConst::operator= (const AnonConst &other) +{ + ExprWithBlock::operator= (other); + + locus = other.locus; + expr = other.expr->clone_expr (); + + return *this; +} + +ConstBlock::ConstBlock (Analysis::NodeMapping mappings, AnonConst &&expr, + location_t locus, AST::AttrVec outer_attrs) + : ExprWithBlock (std::move (mappings), std::move (outer_attrs)), + expr (std::move (expr)), locus (locus) +{} + +ConstBlock::ConstBlock (const ConstBlock &other) + : ExprWithBlock (other), expr (other.expr), locus (other.locus) +{} + +ConstBlock +ConstBlock::operator= (const ConstBlock &other) +{ + ExprWithBlock::operator= (other); + + expr = other.expr; + locus = other.locus; + + return *this; +} + ContinueExpr::ContinueExpr (Analysis::NodeMapping mappings, location_t locus, tl::optional label, AST::AttrVec outer_attribs) @@ -1310,26 +1354,6 @@ OperatorExprMeta::OperatorExprMeta (HIR::ComparisonExpr &expr) locus (expr.get_locus ()) {} -AnonConst::AnonConst (NodeId id, std::unique_ptr expr) - : id (id), expr (std::move (expr)) -{ - rust_assert (this->expr != nullptr); -} - -AnonConst::AnonConst (const AnonConst &other) -{ - id = other.id; - expr = other.expr->clone_expr (); -} - -AnonConst -AnonConst::operator= (const AnonConst &other) -{ - id = other.id; - expr = other.expr->clone_expr (); - return *this; -} - InlineAsmOperand::In::In ( const tl::optional ®, std::unique_ptr expr) diff --git a/gcc/rust/hir/tree/rust-hir-expr.h b/gcc/rust/hir/tree/rust-hir-expr.h index 6400cb9aacf..a46dd109e3a 100644 --- a/gcc/rust/hir/tree/rust-hir-expr.h +++ b/gcc/rust/hir/tree/rust-hir-expr.h @@ -19,12 +19,14 @@ #ifndef RUST_HIR_EXPR_H #define RUST_HIR_EXPR_H +#include "rust-ast.h" #include "rust-hir-expr-abstract.h" #include "rust-hir-literal.h" #include "rust-common.h" #include "rust-hir-bound.h" #include "rust-hir-attrs.h" #include "rust-expr.h" +#include "rust-hir-map.h" namespace Rust { namespace HIR { @@ -1800,6 +1802,71 @@ class BlockExpr : public ExprWithBlock, public WithInnerAttrs } }; +class AnonConst : public ExprWithBlock +{ +public: + AnonConst (Analysis::NodeMapping mappings, std::unique_ptr &&expr, + location_t locus = UNKNOWN_LOCATION); + AnonConst (const AnonConst &other); + AnonConst operator= (const AnonConst &other); + + std::string as_string () const override; + + void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRExpressionVisitor &vis) override; + + ExprType get_expression_type () const final override + { + return ExprType::AnonConst; + } + + location_t get_locus () const override { return locus; } + Expr &get_inner_expr () { return *expr; } + const Expr &get_inner_expr () const { return *expr; } + +private: + location_t locus; + std::unique_ptr expr; + + AnonConst *clone_expr_with_block_impl () const override + { + return new AnonConst (*this); + } +}; + +class ConstBlock : public ExprWithBlock +{ +public: + ConstBlock (Analysis::NodeMapping mappings, AnonConst &&expr, + location_t locus = UNKNOWN_LOCATION, + AST::AttrVec outer_attrs = {}); + ConstBlock (const ConstBlock &other); + ConstBlock operator= (const ConstBlock &other); + + void accept_vis (HIRFullVisitor &vis) override; + void accept_vis (HIRExpressionVisitor &vis) override; + + std::string as_string () const override; + + ExprType get_expression_type () const final override + { + return ExprType::ConstBlock; + } + + location_t get_locus () const override { return locus; } + AnonConst &get_const_expr () { return expr; } + const AnonConst &get_const_expr () const { return expr; } + +private: + AnonConst expr; + location_t locus; + + ConstBlock *clone_expr_with_block_impl () const override + { + return new ConstBlock (*this); + } +}; + // HIR node representing continue expression within loops class ContinueExpr : public ExprWithoutBlock { @@ -2892,18 +2959,6 @@ class InlineAsmRegClass std::string placeholder; }; -struct AnonConst -{ - NodeId id; - std::unique_ptr expr; - - AnonConst (NodeId id, std::unique_ptr expr); - - AnonConst (const AnonConst &other); - - AnonConst operator= (const AnonConst &other); -}; - class InlineAsmOperand { public: diff --git a/gcc/rust/hir/tree/rust-hir-full-decls.h b/gcc/rust/hir/tree/rust-hir-full-decls.h index a1722b06821..ac88deea934 100644 --- a/gcc/rust/hir/tree/rust-hir-full-decls.h +++ b/gcc/rust/hir/tree/rust-hir-full-decls.h @@ -95,6 +95,8 @@ class FieldAccessExpr; struct ClosureParam; class ClosureExpr; class BlockExpr; +class AnonConst; +class ConstBlock; class ContinueExpr; class BreakExpr; class RangeExpr; @@ -123,7 +125,6 @@ class AwaitExpr; class AsyncBlockExpr; class InlineAsmReg; class InlineAsmRegClass; -struct AnonConst; class InlineAsmOperand; class InlineAsm; class LlvmInlineAsm; diff --git a/gcc/rust/hir/tree/rust-hir-visitor.h b/gcc/rust/hir/tree/rust-hir-visitor.h index c9344846798..d3c209ec661 100644 --- a/gcc/rust/hir/tree/rust-hir-visitor.h +++ b/gcc/rust/hir/tree/rust-hir-visitor.h @@ -64,6 +64,8 @@ class HIRFullVisitor virtual void visit (MethodCallExpr &expr) = 0; virtual void visit (FieldAccessExpr &expr) = 0; virtual void visit (BlockExpr &expr) = 0; + virtual void visit (AnonConst &expr) = 0; + virtual void visit (ConstBlock &expr) = 0; virtual void visit (ClosureExpr &expr) = 0; virtual void visit (ContinueExpr &expr) = 0; virtual void visit (BreakExpr &expr) = 0; @@ -201,6 +203,8 @@ class HIRFullVisitorBase : public HIRFullVisitor virtual void visit (FieldAccessExpr &) override {} virtual void visit (ClosureExpr &) override {} virtual void visit (BlockExpr &) override {} + virtual void visit (AnonConst &) override {} + virtual void visit (ConstBlock &) override {} virtual void visit (ContinueExpr &) override {} virtual void visit (BreakExpr &) override {} virtual void visit (RangeFromToExpr &) override {} @@ -427,6 +431,8 @@ class HIRExpressionVisitor virtual void visit (MethodCallExpr &expr) = 0; virtual void visit (FieldAccessExpr &expr) = 0; virtual void visit (BlockExpr &expr) = 0; + virtual void visit (AnonConst &expr) = 0; + virtual void visit (ConstBlock &expr) = 0; virtual void visit (ContinueExpr &expr) = 0; virtual void visit (BreakExpr &expr) = 0; virtual void visit (RangeFromToExpr &expr) = 0; diff --git a/gcc/rust/hir/tree/rust-hir.cc b/gcc/rust/hir/tree/rust-hir.cc index c94335734de..ec45a8da665 100644 --- a/gcc/rust/hir/tree/rust-hir.cc +++ b/gcc/rust/hir/tree/rust-hir.cc @@ -1047,6 +1047,33 @@ BlockExpr::as_string () const return str; } +std::string +AnonConst::as_string () const +{ + std::string istr = indent_spaces (enter); + std::string str = istr + "AnonConst:\n" + istr; + + str += get_inner_expr ().as_string (); + + str += "\n" + indent_spaces (out); + + return str; +} + +std::string +ConstBlock::as_string () const +{ + std::string istr = indent_spaces (enter); + + std::string str = istr + "ConstBlock:\n" + istr; + + str += get_const_expr ().as_string (); + + str += "\n" + indent_spaces (out); + + return str; +} + std::string TypeAlias::as_string () const { @@ -4054,6 +4081,18 @@ BlockExpr::accept_vis (HIRFullVisitor &vis) vis.visit (*this); } +void +AnonConst::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +ConstBlock::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + void ContinueExpr::accept_vis (HIRFullVisitor &vis) { @@ -5026,6 +5065,18 @@ BlockExpr::accept_vis (HIRExpressionVisitor &vis) vis.visit (*this); } +void +AnonConst::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +ConstBlock::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + void Function::accept_vis (HIRStmtVisitor &vis) { diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h index e47b9e015e2..7aced436bc2 100644 --- a/gcc/rust/parse/rust-parse-impl.h +++ b/gcc/rust/parse/rust-parse-impl.h @@ -7238,6 +7238,30 @@ Parser::parse_block_expr ( std::move (label), locus, end_locus)); } +/* Parse a "const block", a block preceded by the `const` keyword whose + * statements can be const evaluated and used in constant contexts */ +template +std::unique_ptr +Parser::parse_const_block_expr (AST::AttrVec outer_attrs, + location_t locus) +{ + auto block = parse_block_expr (); + + if (!block) + { + add_error (Error (locus, "failed to parse inner block in const block")); + skip_after_end_block (); + + return nullptr; + } + + auto block_locus = block->get_locus (); + + return std::make_unique (AST::AnonConst (std::move (block), + block_locus), + locus, std::move (outer_attrs)); +} + /* Parses a "grouped" expression (expression in parentheses), used to control * precedence. */ template @@ -12469,6 +12493,9 @@ Parser::null_denotation_not_path ( "use of %qs is not allowed on the right-side of an assignment", tok->get_token_description ())); return nullptr; + case CONST: + return parse_const_block_expr (std::move (outer_attrs), + tok->get_locus ()); default: if (!restrictions.expr_can_be_null) add_error (Error (tok->get_locus (), diff --git a/gcc/rust/parse/rust-parse.h b/gcc/rust/parse/rust-parse.h index 827d91d6cbb..1dc12af0a3a 100644 --- a/gcc/rust/parse/rust-parse.h +++ b/gcc/rust/parse/rust-parse.h @@ -17,6 +17,7 @@ along with GCC; see the file COPYING3. If not see #ifndef RUST_PARSE_H #define RUST_PARSE_H +#include "rust-ast.h" #include "rust-item.h" #include "rust-lex.h" #include "rust-ast-full.h" @@ -165,6 +166,10 @@ template class Parser tl::optional = tl::nullopt, location_t pratt_parsed_loc = UNKNOWN_LOCATION); + std::unique_ptr + parse_const_block_expr (AST::AttrVec outer_attrs = AST::AttrVec (), + location_t loc = UNKNOWN_LOCATION); + bool is_macro_rules_def (const_TokenPtr t); std::unique_ptr parse_item (bool called_from_statement); std::unique_ptr parse_pattern (); diff --git a/gcc/rust/resolve/rust-ast-resolve-base.cc b/gcc/rust/resolve/rust-ast-resolve-base.cc index 397abf5b9a2..a9efed91ed7 100644 --- a/gcc/rust/resolve/rust-ast-resolve-base.cc +++ b/gcc/rust/resolve/rust-ast-resolve-base.cc @@ -231,6 +231,14 @@ void ResolverBase::visit (AST::BlockExpr &) {} +void +ResolverBase::visit (AST::AnonConst &) +{} + +void +ResolverBase::visit (AST::ConstBlock &) +{} + void ResolverBase::visit (AST::ClosureExprInnerTyped &) {} diff --git a/gcc/rust/resolve/rust-ast-resolve-base.h b/gcc/rust/resolve/rust-ast-resolve-base.h index 3a44d95bed5..70549ca35e1 100644 --- a/gcc/rust/resolve/rust-ast-resolve-base.h +++ b/gcc/rust/resolve/rust-ast-resolve-base.h @@ -21,6 +21,7 @@ #include "rust-ast-visitor.h" #include "rust-ast.h" +#include "rust-expr.h" #include "rust-name-resolver.h" #include "rust-diagnostics.h" #include "rust-location.h" @@ -85,6 +86,8 @@ class ResolverBase : public AST::ASTVisitor void visit (AST::FieldAccessExpr &); void visit (AST::ClosureExprInner &); void visit (AST::BlockExpr &); + void visit (AST::AnonConst &); + void visit (AST::ConstBlock &); void visit (AST::ClosureExprInnerTyped &); void visit (AST::ContinueExpr &); void visit (AST::BreakExpr &); diff --git a/gcc/rust/resolve/rust-ast-resolve-expr.cc b/gcc/rust/resolve/rust-ast-resolve-expr.cc index bc972fe74eb..66f18bd315b 100644 --- a/gcc/rust/resolve/rust-ast-resolve-expr.cc +++ b/gcc/rust/resolve/rust-ast-resolve-expr.cc @@ -314,6 +314,18 @@ ResolveExpr::visit (AST::BlockExpr &expr) resolver->get_label_scope ().pop (); } +void +ResolveExpr::visit (AST::AnonConst &expr) +{ + ResolveExpr::go (expr.get_inner_expr (), prefix, canonical_prefix); +} + +void +ResolveExpr::visit (AST::ConstBlock &expr) +{ + ResolveExpr::go (expr.get_const_expr (), prefix, canonical_prefix); +} + void translate_operand (AST::InlineAsm &expr, const CanonicalPath &prefix, const CanonicalPath &canonical_prefix) @@ -347,7 +359,8 @@ translate_operand (AST::InlineAsm &expr, const CanonicalPath &prefix, } case RegisterType::Const: { auto anon_const = operand.get_const ().anon_const; - ResolveExpr::go (*anon_const.expr, prefix, canonical_prefix); + ResolveExpr::go (anon_const.get_inner_expr (), prefix, + canonical_prefix); break; } case RegisterType::Sym: { diff --git a/gcc/rust/resolve/rust-ast-resolve-expr.h b/gcc/rust/resolve/rust-ast-resolve-expr.h index d43318f5d92..d45346b807d 100644 --- a/gcc/rust/resolve/rust-ast-resolve-expr.h +++ b/gcc/rust/resolve/rust-ast-resolve-expr.h @@ -56,6 +56,8 @@ class ResolveExpr : public ResolverBase void visit (AST::IfLetExpr &expr) override; void visit (AST::IfLetExprConseqElse &expr) override; void visit (AST::BlockExpr &expr) override; + void visit (AST::AnonConst &expr) override; + void visit (AST::ConstBlock &expr) override; void visit (AST::InlineAsm &expr) override; void visit (AST::LlvmInlineAsm &expr) override; void visit (AST::UnsafeBlockExpr &expr) override; diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc b/gcc/rust/typecheck/rust-hir-type-check-expr.cc index 115aba7047b..2cb255b0fd1 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc @@ -642,6 +642,18 @@ TypeCheckExpr::visit (HIR::BlockExpr &expr) } } +void +TypeCheckExpr::visit (HIR::AnonConst &expr) +{ + infered = TypeCheckExpr::Resolve (expr.get_inner_expr ()); +} + +void +TypeCheckExpr::visit (HIR::ConstBlock &expr) +{ + infered = TypeCheckExpr::Resolve (expr.get_const_expr ()); +} + void TypeCheckExpr::visit (HIR::RangeFromToExpr &expr) { @@ -813,7 +825,7 @@ typecheck_inline_asm_operand (HIR::InlineAsm &expr) } case RegisterType::Const: { auto anon_const = operand.get_const ().anon_const; - TypeCheckExpr::Resolve (*anon_const.expr); + TypeCheckExpr::Resolve (anon_const.get_inner_expr ()); break; } case RegisterType::Sym: { diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h index 0b859f76f61..6ee383bd6e2 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-expr.h +++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h @@ -46,6 +46,8 @@ class TypeCheckExpr : private TypeCheckBase, private 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::ArrayIndexExpr &expr) override; void visit (HIR::ArrayExpr &expr) override; diff --git a/gcc/testsuite/rust/execute/torture/const_block1.rs b/gcc/testsuite/rust/execute/torture/const_block1.rs new file mode 100644 index 00000000000..eaf343249d1 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/const_block1.rs @@ -0,0 +1,9 @@ +const X: i32 = const { + let a = 15; + let b = 14; + a + b +}; + +fn main() -> i32 { + X - 29 +}