Skip to content

Commit a2ce3ef

Browse files
bors[bot]philberty
andauthored
Merge #775
775: Support const within block-expr's r=philberty a=philberty This adds support for constant folding within block expr's and constant ArrayIndexExpression. Fixes #711 Co-authored-by: Philip Herron <[email protected]>
2 parents e28c43f + 0114e3e commit a2ce3ef

File tree

7 files changed

+117
-0
lines changed

7 files changed

+117
-0
lines changed

gcc/rust/backend/rust-compile-stmt.h

+27
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,33 @@ class CompileStmt : public HIRCompileBase
4848
translated = CompileExpr::Compile (stmt.get_expr (), ctx);
4949
}
5050

51+
void visit (HIR::ConstantItem &constant) override
52+
{
53+
TyTy::BaseType *resolved_type = nullptr;
54+
bool ok
55+
= ctx->get_tyctx ()->lookup_type (constant.get_mappings ().get_hirid (),
56+
&resolved_type);
57+
rust_assert (ok);
58+
59+
::Btype *type = TyTyResolveCompile::compile (ctx, resolved_type);
60+
Bexpression *value = CompileExpr::Compile (constant.get_expr (), ctx);
61+
62+
const Resolver::CanonicalPath *canonical_path = nullptr;
63+
rust_assert (ctx->get_mappings ()->lookup_canonical_path (
64+
constant.get_mappings ().get_crate_num (),
65+
constant.get_mappings ().get_nodeid (), &canonical_path));
66+
67+
std::string ident = canonical_path->get ();
68+
Bexpression *const_expr
69+
= ctx->get_backend ()->named_constant_expression (type, ident, value,
70+
constant.get_locus ());
71+
72+
ctx->push_const (const_expr);
73+
ctx->insert_const_decl (constant.get_mappings ().get_hirid (), const_expr);
74+
75+
translated = const_expr;
76+
}
77+
5178
void visit (HIR::LetStmt &stmt) override
5279
{
5380
// nothing to do

gcc/rust/hir/rust-ast-lower-stmt.h

+28
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,34 @@ class ASTLoweringStmt : public ASTLoweringBase
8383
mappings->insert_hir_stmt (crate_num, mapping.get_hirid (), translated);
8484
}
8585

86+
void visit (AST::ConstantItem &constant) override
87+
{
88+
HIR::Visibility vis = HIR::Visibility::create_public ();
89+
90+
HIR::Type *type = ASTLoweringType::translate (constant.get_type ().get ());
91+
HIR::Expr *expr = ASTLoweringExpr::translate (constant.get_expr ().get ());
92+
93+
auto crate_num = mappings->get_current_crate ();
94+
Analysis::NodeMapping mapping (crate_num, constant.get_node_id (),
95+
mappings->get_next_hir_id (crate_num),
96+
mappings->get_next_localdef_id (crate_num));
97+
98+
HIR::ConstantItem *constant_item
99+
= new HIR::ConstantItem (mapping, constant.get_identifier (), vis,
100+
std::unique_ptr<HIR::Type> (type),
101+
std::unique_ptr<HIR::Expr> (expr),
102+
constant.get_outer_attrs (),
103+
constant.get_locus ());
104+
translated = constant_item;
105+
106+
mappings->insert_hir_item (mapping.get_crate_num (), mapping.get_hirid (),
107+
constant_item);
108+
mappings->insert_hir_stmt (mapping.get_crate_num (), mapping.get_hirid (),
109+
constant_item);
110+
mappings->insert_location (crate_num, mapping.get_hirid (),
111+
constant.get_locus ());
112+
}
113+
86114
void visit (AST::LetStmt &stmt) override
87115
{
88116
HIR::Pattern *variables

gcc/rust/resolve/rust-ast-resolve-stmt.h

+24
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,30 @@ class ResolveStmt : public ResolverBase
5151
ResolveExpr::go (stmt.get_expr ().get (), stmt.get_node_id ());
5252
}
5353

54+
void visit (AST::ConstantItem &constant) override
55+
{
56+
auto path = ResolveConstantItemToCanonicalPath::resolve (constant);
57+
resolver->get_name_scope ().insert (
58+
path, constant.get_node_id (), constant.get_locus (), false,
59+
[&] (const CanonicalPath &, NodeId, Location locus) -> void {
60+
RichLocation r (constant.get_locus ());
61+
r.add_range (locus);
62+
rust_error_at (r, "redefined multiple times");
63+
});
64+
resolver->insert_new_definition (constant.get_node_id (),
65+
Definition{constant.get_node_id (),
66+
constant.get_node_id ()});
67+
68+
ResolveType::go (constant.get_type ().get (), constant.get_node_id ());
69+
ResolveExpr::go (constant.get_expr ().get (), constant.get_node_id ());
70+
71+
// the mutability checker needs to verify for immutable decls the number
72+
// of assignments are <1. This marks an implicit assignment
73+
resolver->mark_decl_mutability (constant.get_node_id (), false);
74+
resolver->mark_assignment_to_decl (constant.get_node_id (),
75+
constant.get_node_id ());
76+
}
77+
5478
void visit (AST::LetStmt &stmt) override
5579
{
5680
if (stmt.has_init_expr ())

gcc/rust/typecheck/rust-hir-const-fold.h

+9
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,15 @@ class ConstFoldExpr : public ConstFoldBase
427427
= ctx->get_backend ()->negation_expression (op, negated_expr, location);
428428
}
429429

430+
void visit (HIR::ArrayIndexExpr &expr) override
431+
{
432+
Bexpression *array = ConstFoldExpr::fold (expr.get_array_expr ());
433+
Bexpression *index = ConstFoldExpr::fold (expr.get_index_expr ());
434+
435+
folded = ctx->get_backend ()->array_index_expression (array, index,
436+
expr.get_locus ());
437+
}
438+
430439
private:
431440
ConstFoldExpr ()
432441
: ConstFoldBase (), folded (ctx->get_backend ()->error_expression ())

gcc/rust/typecheck/rust-hir-type-check-stmt.h

+13
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,19 @@ class TypeCheckStmt : public TypeCheckBase
5555
= TyTy::TupleType::get_unit_type (stmt.get_mappings ().get_hirid ());
5656
}
5757

58+
void visit (HIR::ConstantItem &constant) override
59+
{
60+
TyTy::BaseType *type = TypeCheckType::Resolve (constant.get_type ());
61+
TyTy::BaseType *expr_type
62+
= TypeCheckExpr::Resolve (constant.get_expr (), false);
63+
64+
infered = type->unify (expr_type);
65+
context->insert_type (constant.get_mappings (), infered);
66+
67+
// notify the constant folder of this
68+
ConstFold::ConstFoldItem::fold (constant);
69+
}
70+
5871
void visit (HIR::LetStmt &stmt) override
5972
{
6073
infered = new TyTy::TupleType (stmt.get_mappings ().get_hirid ());
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
fn main() {
2+
const C: usize = 42;
3+
4+
let _a = C;
5+
let _b: [i32; C] = [0; C];
6+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
fn main() {
2+
const A: [i32; 3] = [1, 2, 3];
3+
const B: i32 = A[1];
4+
const C: usize = 42;
5+
const D: i32 = 7;
6+
7+
let _a = C;
8+
let _b: [i32; C] = [0; C];
9+
let _c = B + D;
10+
}

0 commit comments

Comments
 (0)