public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc/devel/rust/master] Add support for constants within blocks
@ 2022-06-08 11:44 Thomas Schwinge
  0 siblings, 0 replies; only message in thread
From: Thomas Schwinge @ 2022-06-08 11:44 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:657a9735339f6e5b0723bc24f74ad55d78daae8e

commit 657a9735339f6e5b0723bc24f74ad55d78daae8e
Author: Philip Herron <philip.herron@embecosm.com>
Date:   Thu Oct 28 10:57:37 2021 +0100

    Add support for constants within blocks
    
    BlockExpr's can contain constants these are Items which can exist within
    the BlockExpr Stmt list. Items like structs, functions and constants all
    inherit from Item so there is some duplication of code but we still
    do not support the forward declared Items within a stmt list so the
    duplication will need to be fixed as part of that bug.
    
    Fixes #711

Diff:
---
 gcc/rust/backend/rust-compile-stmt.h            | 27 ++++++++++++++++++++++++
 gcc/rust/hir/rust-ast-lower-stmt.h              | 28 +++++++++++++++++++++++++
 gcc/rust/resolve/rust-ast-resolve-stmt.h        | 24 +++++++++++++++++++++
 gcc/rust/typecheck/rust-hir-type-check-stmt.h   | 13 ++++++++++++
 gcc/testsuite/rust/compile/torture/constant2.rs |  6 ++++++
 5 files changed, 98 insertions(+)

diff --git a/gcc/rust/backend/rust-compile-stmt.h b/gcc/rust/backend/rust-compile-stmt.h
index 1a2f02c1ebb..21e581478a0 100644
--- a/gcc/rust/backend/rust-compile-stmt.h
+++ b/gcc/rust/backend/rust-compile-stmt.h
@@ -48,6 +48,33 @@ public:
     translated = CompileExpr::Compile (stmt.get_expr (), ctx);
   }
 
+  void visit (HIR::ConstantItem &constant) override
+  {
+    TyTy::BaseType *resolved_type = nullptr;
+    bool ok
+      = ctx->get_tyctx ()->lookup_type (constant.get_mappings ().get_hirid (),
+					&resolved_type);
+    rust_assert (ok);
+
+    ::Btype *type = TyTyResolveCompile::compile (ctx, resolved_type);
+    Bexpression *value = CompileExpr::Compile (constant.get_expr (), ctx);
+
+    const Resolver::CanonicalPath *canonical_path = nullptr;
+    rust_assert (ctx->get_mappings ()->lookup_canonical_path (
+      constant.get_mappings ().get_crate_num (),
+      constant.get_mappings ().get_nodeid (), &canonical_path));
+
+    std::string ident = canonical_path->get ();
+    Bexpression *const_expr
+      = ctx->get_backend ()->named_constant_expression (type, ident, value,
+							constant.get_locus ());
+
+    ctx->push_const (const_expr);
+    ctx->insert_const_decl (constant.get_mappings ().get_hirid (), const_expr);
+
+    translated = const_expr;
+  }
+
   void visit (HIR::LetStmt &stmt) override
   {
     // nothing to do
diff --git a/gcc/rust/hir/rust-ast-lower-stmt.h b/gcc/rust/hir/rust-ast-lower-stmt.h
index 50ccc9f4ec1..eab0922ca7d 100644
--- a/gcc/rust/hir/rust-ast-lower-stmt.h
+++ b/gcc/rust/hir/rust-ast-lower-stmt.h
@@ -83,6 +83,34 @@ public:
     mappings->insert_hir_stmt (crate_num, mapping.get_hirid (), translated);
   }
 
+  void visit (AST::ConstantItem &constant) override
+  {
+    HIR::Visibility vis = HIR::Visibility::create_public ();
+
+    HIR::Type *type = ASTLoweringType::translate (constant.get_type ().get ());
+    HIR::Expr *expr = ASTLoweringExpr::translate (constant.get_expr ().get ());
+
+    auto crate_num = mappings->get_current_crate ();
+    Analysis::NodeMapping mapping (crate_num, constant.get_node_id (),
+				   mappings->get_next_hir_id (crate_num),
+				   mappings->get_next_localdef_id (crate_num));
+
+    HIR::ConstantItem *constant_item
+      = new HIR::ConstantItem (mapping, constant.get_identifier (), vis,
+			       std::unique_ptr<HIR::Type> (type),
+			       std::unique_ptr<HIR::Expr> (expr),
+			       constant.get_outer_attrs (),
+			       constant.get_locus ());
+    translated = constant_item;
+
+    mappings->insert_hir_item (mapping.get_crate_num (), mapping.get_hirid (),
+			       constant_item);
+    mappings->insert_hir_stmt (mapping.get_crate_num (), mapping.get_hirid (),
+			       constant_item);
+    mappings->insert_location (crate_num, mapping.get_hirid (),
+			       constant.get_locus ());
+  }
+
   void visit (AST::LetStmt &stmt) override
   {
     HIR::Pattern *variables
diff --git a/gcc/rust/resolve/rust-ast-resolve-stmt.h b/gcc/rust/resolve/rust-ast-resolve-stmt.h
index 3a0904ebddf..98fcaf2eda5 100644
--- a/gcc/rust/resolve/rust-ast-resolve-stmt.h
+++ b/gcc/rust/resolve/rust-ast-resolve-stmt.h
@@ -51,6 +51,30 @@ public:
     ResolveExpr::go (stmt.get_expr ().get (), stmt.get_node_id ());
   }
 
+  void visit (AST::ConstantItem &constant) override
+  {
+    auto path = ResolveConstantItemToCanonicalPath::resolve (constant);
+    resolver->get_name_scope ().insert (
+      path, constant.get_node_id (), constant.get_locus (), false,
+      [&] (const CanonicalPath &, NodeId, Location locus) -> void {
+	RichLocation r (constant.get_locus ());
+	r.add_range (locus);
+	rust_error_at (r, "redefined multiple times");
+      });
+    resolver->insert_new_definition (constant.get_node_id (),
+				     Definition{constant.get_node_id (),
+						constant.get_node_id ()});
+
+    ResolveType::go (constant.get_type ().get (), constant.get_node_id ());
+    ResolveExpr::go (constant.get_expr ().get (), constant.get_node_id ());
+
+    // the mutability checker needs to verify for immutable decls the number
+    // of assignments are <1. This marks an implicit assignment
+    resolver->mark_decl_mutability (constant.get_node_id (), false);
+    resolver->mark_assignment_to_decl (constant.get_node_id (),
+				       constant.get_node_id ());
+  }
+
   void visit (AST::LetStmt &stmt) override
   {
     if (stmt.has_init_expr ())
diff --git a/gcc/rust/typecheck/rust-hir-type-check-stmt.h b/gcc/rust/typecheck/rust-hir-type-check-stmt.h
index 17def2b6aee..74bc0374cd8 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-stmt.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-stmt.h
@@ -55,6 +55,19 @@ public:
       = TyTy::TupleType::get_unit_type (stmt.get_mappings ().get_hirid ());
   }
 
+  void visit (HIR::ConstantItem &constant) override
+  {
+    TyTy::BaseType *type = TypeCheckType::Resolve (constant.get_type ());
+    TyTy::BaseType *expr_type
+      = TypeCheckExpr::Resolve (constant.get_expr (), false);
+
+    infered = type->unify (expr_type);
+    context->insert_type (constant.get_mappings (), infered);
+
+    // notify the constant folder of this
+    ConstFold::ConstFoldItem::fold (constant);
+  }
+
   void visit (HIR::LetStmt &stmt) override
   {
     infered = new TyTy::TupleType (stmt.get_mappings ().get_hirid ());
diff --git a/gcc/testsuite/rust/compile/torture/constant2.rs b/gcc/testsuite/rust/compile/torture/constant2.rs
new file mode 100644
index 00000000000..d06324e8e65
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/constant2.rs
@@ -0,0 +1,6 @@
+fn main() {
+    const C: usize = 42;
+
+    let _a = C;
+    let _b: [i32; C] = [0; C];
+}


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-06-08 11:44 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-08 11:44 [gcc/devel/rust/master] Add support for constants within blocks Thomas Schwinge

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).