aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/Make-lang.in4
-rw-r--r--gcc/rust/backend/rust-compile-base.h8
-rw-r--r--gcc/rust/backend/rust-compile-context.h6
-rw-r--r--gcc/rust/backend/rust-compile-expr.cc235
-rw-r--r--gcc/rust/backend/rust-compile-expr.h81
-rw-r--r--gcc/rust/backend/rust-compile-item.h11
-rw-r--r--gcc/rust/backend/rust-compile-pattern.cc33
-rw-r--r--gcc/rust/backend/rust-compile-resolve-path.cc23
-rw-r--r--gcc/rust/backend/rust-compile-stmt.h4
-rw-r--r--gcc/rust/backend/rust-compile-type.cc14
-rw-r--r--gcc/rust/backend/rust-compile-type.h5
-rw-r--r--gcc/rust/backend/rust-compile.cc76
-rw-r--r--gcc/rust/backend/rust-constexpr.cc428
-rw-r--r--gcc/rust/backend/rust-constexpr.h (renamed from gcc/rust/typecheck/rust-hir-const-fold-ctx.h)39
-rw-r--r--gcc/rust/rust-backend.h5
-rw-r--r--gcc/rust/rust-gcc.cc42
-rw-r--r--gcc/rust/rust-session-manager.cc4
-rw-r--r--gcc/rust/typecheck/rust-hir-const-fold-base.h54
-rw-r--r--gcc/rust/typecheck/rust-hir-const-fold.cc138
-rw-r--r--gcc/rust/typecheck/rust-hir-const-fold.h499
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-enumitem.h20
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-expr.h149
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-implitem.h3
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-stmt.h5
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-toplevel.h3
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-type.cc23
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check.cc23
-rw-r--r--gcc/rust/typecheck/rust-tyty-cast.h16
-rw-r--r--gcc/rust/typecheck/rust-tyty-cmp.h7
-rw-r--r--gcc/rust/typecheck/rust-tyty-coercion.h16
-rw-r--r--gcc/rust/typecheck/rust-tyty-rules.h16
-rw-r--r--gcc/rust/typecheck/rust-tyty.cc15
-rw-r--r--gcc/rust/typecheck/rust-tyty.h54
-rw-r--r--gcc/testsuite/rust/compile/arrays2.rs3
-rw-r--r--gcc/testsuite/rust/execute/torture/const_fold1.rs13
35 files changed, 1013 insertions, 1062 deletions
diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index 3554982..dcb2d2c 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -85,7 +85,6 @@ GRS_OBJS = \
rust/rust-tyty-bounds.o \
rust/rust-hir-type-check-util.o \
rust/rust-hir-trait-resolve.o \
- rust/rust-hir-const-fold.o \
rust/rust-hir-type-check-type.o \
rust/rust-hir-type-check-struct.o \
rust/rust-hir-address-taken.o \
@@ -98,6 +97,7 @@ GRS_OBJS = \
rust/rust-base62.o \
rust/rust-compile-expr.o \
rust/rust-compile-type.o \
+ rust/rust-constexpr.o \
$(END)
# removed object files from here
@@ -107,7 +107,7 @@ RUST_ALL_OBJS = $(GRS_OBJS) $(RUST_TARGET_OBJS)
rust_OBJS = $(RUST_ALL_OBJS) rust/rustspec.o
# The compiler itself is called rust1 (formerly grs1)
-rust1$(exeext): $(RUST_ALL_OBJS) attribs.o $(BACKEND) $(LIBDEPS)
+rust1$(exeext): $(RUST_ALL_OBJS) attribs.o $(BACKEND) $(LIBDEPS)
+$(LLINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
$(RUST_ALL_OBJS) attribs.o $(BACKEND) $(LIBS) $(BACKENDLIBS)
diff --git a/gcc/rust/backend/rust-compile-base.h b/gcc/rust/backend/rust-compile-base.h
index b3ae1f6..2169ea5 100644
--- a/gcc/rust/backend/rust-compile-base.h
+++ b/gcc/rust/backend/rust-compile-base.h
@@ -44,8 +44,9 @@ protected:
bool compile_locals_for_block (Resolver::Rib &rib, tree fndecl,
std::vector<Bvariable *> &locals);
- tree coercion_site (tree compiled_ref, TyTy::BaseType *actual,
- TyTy::BaseType *expected, Location locus);
+ tree coercion_site (tree rvalue, TyTy::BaseType *actual,
+ TyTy::BaseType *expected, Location lvalue_locus,
+ Location rvalue_locus);
tree coerce_to_dyn_object (tree compiled_ref, const TyTy::BaseType *actual,
const TyTy::BaseType *expected,
@@ -57,6 +58,9 @@ protected:
std::vector<std::pair<Resolver::TraitReference *, HIR::ImplBlock *>>
&receiver_bounds,
const TyTy::BaseType *receiver, const TyTy::BaseType *root, Location locus);
+
+ bool verify_array_capacities (tree ltype, tree rtype, Location ltype_locus,
+ Location rtype_locus);
};
} // namespace Compile
diff --git a/gcc/rust/backend/rust-compile-context.h b/gcc/rust/backend/rust-compile-context.h
index 43c23dd..9be9801 100644
--- a/gcc/rust/backend/rust-compile-context.h
+++ b/gcc/rust/backend/rust-compile-context.h
@@ -27,7 +27,6 @@
#include "rust-compile-tyty.h"
#include "rust-ast-full.h"
#include "rust-hir-full.h"
-#include "rust-hir-const-fold-ctx.h"
#include "rust-mangle.h"
namespace Rust {
@@ -45,8 +44,7 @@ public:
Context (::Backend *backend)
: backend (backend), resolver (Resolver::Resolver::get ()),
tyctx (Resolver::TypeCheckContext::get ()),
- mappings (Analysis::Mappings::get ()),
- const_ctx (ConstFold::Context::get ()), mangler (Mangler ())
+ mappings (Analysis::Mappings::get ()), mangler (Mangler ())
{
// insert the builtins
auto builtins = resolver->get_builtin_types ();
@@ -110,7 +108,6 @@ public:
Resolver::Resolver *get_resolver () { return resolver; }
Resolver::TypeCheckContext *get_tyctx () { return tyctx; }
Analysis::Mappings *get_mappings () { return mappings; }
- ConstFold::Context *get_const_ctx () { return const_ctx; }
void push_block (tree scope)
{
@@ -315,7 +312,6 @@ private:
Resolver::Resolver *resolver;
Resolver::TypeCheckContext *tyctx;
Analysis::Mappings *mappings;
- ConstFold::Context *const_ctx;
std::set<HirId> builtin_range;
Mangler mangler;
diff --git a/gcc/rust/backend/rust-compile-expr.cc b/gcc/rust/backend/rust-compile-expr.cc
index 9b04bbf..33237e5 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -25,10 +25,12 @@
#include "rust-hir-type-bounds.h"
#include "rust-hir-dot-operator.h"
#include "rust-compile-pattern.h"
+#include "rust-constexpr.h"
#include "fold-const.h"
#include "realmpfr.h"
#include "convert.h"
+#include "print-tree.h"
namespace Rust {
namespace Compile {
@@ -381,7 +383,11 @@ CompileExpr::visit (HIR::CallExpr &expr)
rust_assert (ok);
// coerce it if required
- rvalue = coercion_site (rvalue, actual, expected, expr.get_locus ());
+ Location lvalue_locus
+ = ctx->get_mappings ()->lookup_location (expected->get_ty_ref ());
+ Location rvalue_locus = argument->get_locus ();
+ rvalue = coercion_site (rvalue, actual, expected, lvalue_locus,
+ rvalue_locus);
// add it to the list
arguments.push_back (rvalue);
@@ -477,7 +483,11 @@ CompileExpr::visit (HIR::CallExpr &expr)
rust_assert (ok);
// coerce it if required
- rvalue = coercion_site (rvalue, actual, expected, expr.get_locus ());
+ Location lvalue_locus
+ = ctx->get_mappings ()->lookup_location (expected->get_ty_ref ());
+ Location rvalue_locus = argument->get_locus ();
+ rvalue
+ = coercion_site (rvalue, actual, expected, lvalue_locus, rvalue_locus);
// add it to the list
args.push_back (rvalue);
@@ -604,7 +614,11 @@ CompileExpr::visit (HIR::MethodCallExpr &expr)
rust_assert (ok);
// coerce it if required
- rvalue = coercion_site (rvalue, actual, expected, expr.get_locus ());
+ Location lvalue_locus
+ = ctx->get_mappings ()->lookup_location (expected->get_ty_ref ());
+ Location rvalue_locus = argument->get_locus ();
+ rvalue
+ = coercion_site (rvalue, actual, expected, lvalue_locus, rvalue_locus);
// add it to the list
args.push_back (rvalue);
@@ -1093,5 +1107,220 @@ CompileExpr::type_cast_expression (tree type_to_cast_to, tree expr_tree,
expr_tree);
}
+void
+CompileExpr::visit (HIR::ArrayExpr &expr)
+{
+ TyTy::BaseType *tyty = nullptr;
+ if (!ctx->get_tyctx ()->lookup_type (expr.get_mappings ().get_hirid (),
+ &tyty))
+ {
+ rust_fatal_error (expr.get_locus (),
+ "did not resolve type for this array expr");
+ return;
+ }
+
+ tree array_type = TyTyResolveCompile::compile (ctx, tyty);
+ if (TREE_CODE (array_type) != ARRAY_TYPE)
+ {
+ translated = error_mark_node;
+ return;
+ }
+
+ rust_assert (tyty->get_kind () == TyTy::TypeKind::ARRAY);
+ const TyTy::ArrayType &array_tyty
+ = static_cast<const TyTy::ArrayType &> (*tyty);
+
+ HIR::ArrayElems &elements = *expr.get_internal_elements ();
+ switch (elements.get_array_expr_type ())
+ {
+ case HIR::ArrayElems::ArrayExprType::VALUES: {
+ HIR::ArrayElemsValues &elems
+ = static_cast<HIR::ArrayElemsValues &> (elements);
+ translated
+ = array_value_expr (expr.get_locus (), array_tyty, array_type, elems);
+ }
+ return;
+
+ case HIR::ArrayElems::ArrayExprType::COPIED:
+ HIR::ArrayElemsCopied &elems
+ = static_cast<HIR::ArrayElemsCopied &> (elements);
+ translated
+ = array_copied_expr (expr.get_locus (), array_tyty, array_type, elems);
+ }
+}
+
+tree
+CompileExpr::array_value_expr (Location expr_locus,
+ const TyTy::ArrayType &array_tyty,
+ tree array_type, HIR::ArrayElemsValues &elems)
+{
+ std::vector<unsigned long> indexes;
+ std::vector<tree> constructor;
+ size_t i = 0;
+ for (auto &elem : elems.get_values ())
+ {
+ tree translated_expr = CompileExpr::Compile (elem.get (), ctx);
+ constructor.push_back (translated_expr);
+ indexes.push_back (i++);
+ }
+
+ return ctx->get_backend ()->array_constructor_expression (array_type, indexes,
+ constructor,
+ expr_locus);
+}
+
+tree
+CompileExpr::array_copied_expr (Location expr_locus,
+ const TyTy::ArrayType &array_tyty,
+ tree array_type, HIR::ArrayElemsCopied &elems)
+{
+ // see gcc/cp/typeck2.c:1369-1401
+ gcc_assert (TREE_CODE (array_type) == ARRAY_TYPE);
+ tree domain = TYPE_DOMAIN (array_type);
+ if (!domain)
+ return error_mark_node;
+
+ if (!TREE_CONSTANT (TYPE_MAX_VALUE (domain)))
+ {
+ rust_error_at (expr_locus, "non const capacity domain %qT", array_type);
+ return error_mark_node;
+ }
+
+ tree capacity_expr = CompileExpr::Compile (elems.get_num_copies_expr (), ctx);
+ if (!TREE_CONSTANT (capacity_expr))
+ {
+ rust_error_at (expr_locus, "non const num copies %qT", array_type);
+ return error_mark_node;
+ }
+
+ // get the compiled value
+ tree translated_expr = CompileExpr::Compile (elems.get_elem_to_copy (), ctx);
+
+ tree max_domain = TYPE_MAX_VALUE (domain);
+ tree min_domain = TYPE_MIN_VALUE (domain);
+
+ auto max = wi::to_offset (max_domain);
+ auto min = wi::to_offset (min_domain);
+ auto precision = TYPE_PRECISION (TREE_TYPE (domain));
+ auto sign = TYPE_SIGN (TREE_TYPE (domain));
+ unsigned HOST_WIDE_INT len
+ = wi::ext (max - min + 1, precision, sign).to_uhwi ();
+
+ // create the constructor
+ size_t idx = 0;
+ std::vector<unsigned long> indexes;
+ std::vector<tree> constructor;
+ for (unsigned HOST_WIDE_INT i = 0; i < len; i++)
+ {
+ constructor.push_back (translated_expr);
+ indexes.push_back (idx++);
+ }
+
+ return ctx->get_backend ()->array_constructor_expression (array_type, indexes,
+ constructor,
+ expr_locus);
+}
+
+// tree
+// CompileExpr::array_copied_expr (Location expr_locus, tree array_type,
+// HIR::ArrayElemsCopied &elems)
+// {
+// // create tmp for the result
+// fncontext fnctx = ctx->peek_fn ();
+// Location start_location = expr_locus;
+// Location end_location = expr_locus;
+// tree fndecl = fnctx.fndecl;
+// tree enclosing_scope = ctx->peek_enclosing_scope ();
+
+// bool is_address_taken = false;
+// tree result_var_stmt = nullptr;
+// Bvariable *result
+// = ctx->get_backend ()->temporary_variable (fnctx.fndecl,
+// enclosing_scope,
+// array_type, NULL,
+// is_address_taken, expr_locus,
+// &result_var_stmt);
+// ctx->add_statement (result_var_stmt);
+
+// // get the compiled value
+// tree translated_expr = CompileExpr::Compile (elems.get_elem_to_copy (),
+// ctx);
+
+// // lets assign each index in the array
+// TyTy::BaseType *capacity_tyty = nullptr;
+// HirId capacity_ty_id
+// = elems.get_num_copies_expr ()->get_mappings ().get_hirid ();
+// bool ok = ctx->get_tyctx ()->lookup_type (capacity_ty_id,
+// &capacity_tyty); rust_assert (ok); tree capacity_type =
+// TyTyResolveCompile::compile (ctx, capacity_tyty); tree capacity_expr =
+// CompileExpr::Compile (elems.get_num_copies_expr (), ctx);
+
+// // create a loop for this with assignments to array_index exprs
+// tree index_type = capacity_type;
+// Bvariable *idx
+// = ctx->get_backend ()->temporary_variable (fnctx.fndecl,
+// enclosing_scope,
+// index_type, NULL,
+// is_address_taken, expr_locus,
+// &result_var_stmt);
+// ctx->add_statement (result_var_stmt);
+
+// // set index to zero
+// tree index_lvalue = error_mark_node;
+// tree zero = build_int_cst (index_type, 0);
+// tree index_assignment
+// = ctx->get_backend ()->assignment_statement (fnctx.fndecl,
+// index_lvalue,
+// zero, expr_locus);
+// ctx->add_statement (index_assignment);
+
+// // BEGIN loop block
+// tree loop_body = ctx->get_backend ()->block (fndecl, enclosing_scope, {},
+// start_location, end_location);
+// ctx->push_block (loop_body);
+
+// // loop predicate
+// tree loop_predicate
+// = fold_build2_loc (expr_locus.gcc_location (), GE_EXPR,
+// boolean_type_node,
+// ctx->get_backend ()->var_expression (idx, expr_locus),
+// capacity_expr);
+// tree exit_expr = fold_build1_loc (expr_locus.gcc_location (), EXIT_EXPR,
+// void_type_node, loop_predicate);
+// tree break_stmt
+// = ctx->get_backend ()->expression_statement (fnctx.fndecl, exit_expr);
+// ctx->add_statement (break_stmt);
+
+// // increment index
+// tree increment
+// = fold_build2_loc (expr_locus.gcc_location (), POSTINCREMENT_EXPR,
+// index_type,
+// ctx->get_backend ()->var_expression (idx, expr_locus),
+// build_int_cst (index_type, 1));
+
+// // create index_assess
+// tree index_access = ctx->get_backend ()->array_index_expression (
+// ctx->get_backend ()->var_expression (result, expr_locus), increment,
+// expr_locus);
+
+// // create assignment to index_access
+// tree array_assignment
+// = ctx->get_backend ()->assignment_statement (fnctx.fndecl,
+// index_access,
+// translated_expr, expr_locus);
+// ctx->add_statement (array_assignment);
+
+// // END loop block
+// ctx->pop_block ();
+
+// tree loop_expr = ctx->get_backend ()->loop_expression (loop_body,
+// expr_locus); tree loop_stmt
+// = ctx->get_backend ()->expression_statement (fnctx.fndecl, loop_expr);
+// ctx->add_statement (loop_stmt);
+
+// // result is the tmp
+// return ctx->get_backend ()->var_expression (result, expr_locus);
+// }
+
} // namespace Compile
} // namespace Rust
diff --git a/gcc/rust/backend/rust-compile-expr.h b/gcc/rust/backend/rust-compile-expr.h
index 2f44621..b5047d0 100644
--- a/gcc/rust/backend/rust-compile-expr.h
+++ b/gcc/rust/backend/rust-compile-expr.h
@@ -290,7 +290,9 @@ public:
expr.get_rhs ()->get_mappings ().get_hirid (), &actual);
rust_assert (ok);
- rvalue = coercion_site (rvalue, actual, expected, expr.get_locus ());
+ rvalue
+ = coercion_site (rvalue, actual, expected, expr.get_lhs ()->get_locus (),
+ expr.get_rhs ()->get_locus ());
tree assignment
= ctx->get_backend ()->assignment_statement (fn.fndecl, lvalue, rvalue,
@@ -332,56 +334,7 @@ public:
expr.get_locus ());
}
- void visit (HIR::ArrayExpr &expr) override
- {
- TyTy::BaseType *tyty = nullptr;
- if (!ctx->get_tyctx ()->lookup_type (expr.get_mappings ().get_hirid (),
- &tyty))
- {
- rust_fatal_error (expr.get_locus (),
- "did not resolve type for this array expr");
- return;
- }
-
- rust_assert (tyty->get_kind () == TyTy::TypeKind::ARRAY);
- TyTy::ArrayType *array_tyty = static_cast<TyTy::ArrayType *> (tyty);
- capacity_expr = array_tyty->get_capacity ();
-
- tree array_type = TyTyResolveCompile::compile (ctx, array_tyty);
- rust_assert (array_type != nullptr);
-
- expr.get_internal_elements ()->accept_vis (*this);
- std::vector<unsigned long> indexes;
- for (size_t i = 0; i < constructor.size (); i++)
- indexes.push_back (i);
-
- translated
- = ctx->get_backend ()->array_constructor_expression (array_type, indexes,
- constructor,
- expr.get_locus ());
- }
-
- void visit (HIR::ArrayElemsValues &elems) override
- {
- for (auto &elem : elems.get_values ())
- {
- tree translated_expr = CompileExpr::Compile (elem.get (), ctx);
- constructor.push_back (translated_expr);
- }
- }
-
- void visit (HIR::ArrayElemsCopied &elems) override
- {
- tree translated_expr
- = CompileExpr::Compile (elems.get_elem_to_copy (), ctx);
-
- size_t capacity;
- bool ok = ctx->get_backend ()->const_size_cast (capacity_expr, &capacity);
- rust_assert (ok);
-
- for (size_t i = 0; i < capacity; ++i)
- constructor.push_back (translated_expr);
- }
+ void visit (HIR::ArrayExpr &expr) override;
void visit (HIR::ArithmeticOrLogicalExpr &expr) override;
@@ -605,14 +558,18 @@ public:
std::vector<tree> arguments;
for (size_t i = 0; i < struct_expr.get_fields ().size (); i++)
{
- auto &argument = struct_expr.get_fields ().at (i);
- auto rvalue = CompileStructExprField::Compile (argument.get (), ctx);
-
// assignments are coercion sites so lets convert the rvalue if
// necessary
auto respective_field = variant->get_field_at_index (i);
auto expected = respective_field->get_field_type ();
+ // process arguments
+ auto &argument = struct_expr.get_fields ().at (i);
+ auto lvalue_locus
+ = ctx->get_mappings ()->lookup_location (expected->get_ty_ref ());
+ auto rvalue_locus = argument->get_locus ();
+ auto rvalue = CompileStructExprField::Compile (argument.get (), ctx);
+
TyTy::BaseType *actual = nullptr;
bool ok = ctx->get_tyctx ()->lookup_type (
argument->get_mappings ().get_hirid (), &actual);
@@ -621,8 +578,8 @@ public:
// compile/torture/struct_base_init_1.rs
if (ok)
{
- rvalue = coercion_site (rvalue, actual, expected,
- argument->get_locus ());
+ rvalue = coercion_site (rvalue, actual, expected, lvalue_locus,
+ rvalue_locus);
}
// add it to the list
@@ -998,15 +955,19 @@ protected:
tree type_cast_expression (tree type_to_cast_to, tree expr, Location locus);
+ tree array_value_expr (Location expr_locus, const TyTy::ArrayType &array_tyty,
+ tree array_type, HIR::ArrayElemsValues &elems);
+
+ tree array_copied_expr (Location expr_locus,
+ const TyTy::ArrayType &array_tyty, tree array_type,
+ HIR::ArrayElemsCopied &elems);
+
private:
CompileExpr (Context *ctx)
- : HIRCompileBase (ctx), translated (error_mark_node),
- capacity_expr (nullptr)
+ : HIRCompileBase (ctx), translated (error_mark_node)
{}
tree translated;
- tree capacity_expr;
- std::vector<tree> constructor;
};
} // namespace Compile
diff --git a/gcc/rust/backend/rust-compile-item.h b/gcc/rust/backend/rust-compile-item.h
index 5af9ab3..6174950 100644
--- a/gcc/rust/backend/rust-compile-item.h
+++ b/gcc/rust/backend/rust-compile-item.h
@@ -27,6 +27,7 @@
#include "rust-compile-expr.h"
#include "rust-compile-fnparam.h"
#include "rust-compile-extern.h"
+#include "rust-constexpr.h"
namespace Rust {
namespace Compile {
@@ -97,7 +98,10 @@ public:
rust_assert (ok);
tree type = TyTyResolveCompile::compile (ctx, resolved_type);
+ tree const_type = build_qualified_type (type, TYPE_QUAL_CONST);
+
tree value = CompileExpr::Compile (constant.get_expr (), ctx);
+ tree folded_expr = ConstCtx::fold (value);
const Resolver::CanonicalPath *canonical_path = nullptr;
ok = ctx->get_mappings ()->lookup_canonical_path (
@@ -107,7 +111,8 @@ public:
std::string ident = canonical_path->get ();
tree const_expr
- = ctx->get_backend ()->named_constant_expression (type, ident, value,
+ = ctx->get_backend ()->named_constant_expression (const_type, ident,
+ folded_expr,
constant.get_locus ());
ctx->push_const (const_expr);
@@ -183,6 +188,10 @@ public:
if (is_main_fn || function.has_visibility ())
flags |= Backend::function_is_visible;
+ // is it a const function?
+ if (function.get_qualifiers ().is_const ())
+ flags |= Backend::function_read_only;
+
const Resolver::CanonicalPath *canonical_path = nullptr;
bool ok = ctx->get_mappings ()->lookup_canonical_path (
function.get_mappings ().get_crate_num (),
diff --git a/gcc/rust/backend/rust-compile-pattern.cc b/gcc/rust/backend/rust-compile-pattern.cc
index 27ee487..ffda652 100644
--- a/gcc/rust/backend/rust-compile-pattern.cc
+++ b/gcc/rust/backend/rust-compile-pattern.cc
@@ -17,6 +17,8 @@
// <http://www.gnu.org/licenses/>.
#include "rust-compile-pattern.h"
+#include "rust-compile-expr.h"
+#include "rust-constexpr.h"
namespace Rust {
namespace Compile {
@@ -46,20 +48,33 @@ CompilePatternCaseLabelExpr::visit (HIR::PathInExpression &pattern)
ok = adt->lookup_variant_by_id (variant_id, &variant);
rust_assert (ok);
- mpz_t disciminantl;
- if (variant->get_variant_type () == TyTy::VariantDef::VariantType::NUM)
+ tree case_low = error_mark_node;
+ if (variant->is_specified_discriminant_node ())
{
- mpz_init_set_ui (disciminantl, variant->get_discriminant ());
+ auto discrim_node = variant->get_discriminant_node ();
+ auto &discrim_expr = discrim_node->get_discriminant_expression ();
+
+ tree discrim_expr_node = CompileExpr::Compile (discrim_expr.get (), ctx);
+ tree folded_discrim_expr = ConstCtx::fold (discrim_expr_node);
+ case_low = folded_discrim_expr;
}
else
{
- HirId variant_id = variant->get_id ();
- mpz_init_set_ui (disciminantl, variant_id);
- }
+ mpz_t disciminantl;
+ if (variant->get_variant_type () == TyTy::VariantDef::VariantType::NUM)
+ {
+ mpz_init_set_ui (disciminantl, variant->get_discriminant ());
+ }
+ else
+ {
+ HirId variant_id = variant->get_id ();
+ mpz_init_set_ui (disciminantl, variant_id);
+ }
- tree t = TyTyResolveCompile::get_implicit_enumeral_node_type (ctx);
- tree case_low
- = double_int_to_tree (t, mpz_get_double_int (t, disciminantl, true));
+ tree t = TyTyResolveCompile::get_implicit_enumeral_node_type (ctx);
+ case_low
+ = double_int_to_tree (t, mpz_get_double_int (t, disciminantl, true));
+ }
case_label_expr
= build_case_label (case_low, NULL_TREE, associated_case_label);
diff --git a/gcc/rust/backend/rust-compile-resolve-path.cc b/gcc/rust/backend/rust-compile-resolve-path.cc
index 07133b9..c1d0778 100644
--- a/gcc/rust/backend/rust-compile-resolve-path.cc
+++ b/gcc/rust/backend/rust-compile-resolve-path.cc
@@ -95,11 +95,24 @@ ResolvePathRef::resolve (const HIR::PathIdentSegment &final_segment,
tree compiled_adt_type = TyTyResolveCompile::compile (ctx, adt);
// make the ctor for the union
- mpz_t val;
- mpz_init_set_ui (val, variant->get_discriminant ());
- tree t = TyTyResolveCompile::get_implicit_enumeral_node_type (ctx);
- tree qualifier
- = double_int_to_tree (t, mpz_get_double_int (t, val, true));
+ tree qualifier = error_mark_node;
+ if (variant->is_specified_discriminant_node ())
+ {
+ auto discrim_node = variant->get_discriminant_node ();
+ auto &discrim_expr = discrim_node->get_discriminant_expression ();
+
+ tree discrim_expr_node
+ = CompileExpr::Compile (discrim_expr.get (), ctx);
+ tree folded_discrim_expr = ConstCtx::fold (discrim_expr_node);
+ qualifier = folded_discrim_expr;
+ }
+ else
+ {
+ mpz_t val;
+ mpz_init_set_ui (val, variant->get_discriminant ());
+ tree t = TyTyResolveCompile::get_implicit_enumeral_node_type (ctx);
+ qualifier = double_int_to_tree (t, mpz_get_double_int (t, val, true));
+ }
return ctx->get_backend ()->constructor_expression (compiled_adt_type,
true, {qualifier},
diff --git a/gcc/rust/backend/rust-compile-stmt.h b/gcc/rust/backend/rust-compile-stmt.h
index f3ee69d..3e73cce 100644
--- a/gcc/rust/backend/rust-compile-stmt.h
+++ b/gcc/rust/backend/rust-compile-stmt.h
@@ -112,8 +112,10 @@ public:
stmt.get_init_expr ()->get_mappings ().get_hirid (), &actual);
rust_assert (ok);
+ Location lvalue_locus = stmt.get_pattern ()->get_locus ();
+ Location rvalue_locus = stmt.get_init_expr ()->get_locus ();
TyTy::BaseType *expected = ty;
- init = coercion_site (init, actual, expected, stmt.get_locus ());
+ init = coercion_site (init, actual, expected, lvalue_locus, rvalue_locus);
auto fnctx = ctx->peek_fn ();
if (ty->is_unit ())
diff --git a/gcc/rust/backend/rust-compile-type.cc b/gcc/rust/backend/rust-compile-type.cc
index c147a51..d7a8ae5 100644
--- a/gcc/rust/backend/rust-compile-type.cc
+++ b/gcc/rust/backend/rust-compile-type.cc
@@ -17,8 +17,11 @@
// <http://www.gnu.org/licenses/>.
#include "rust-compile-type.h"
+#include "rust-compile-expr.h"
+#include "rust-constexpr.h"
#include "tree.h"
+#include "print-tree.h"
namespace Rust {
namespace Compile {
@@ -63,13 +66,15 @@ TyTyResolveCompile::get_implicit_enumeral_node_type (Context *ctx)
void
TyTyResolveCompile::visit (const TyTy::ErrorType &)
{
- gcc_unreachable ();
+ translated = error_mark_node;
}
+
void
TyTyResolveCompile::visit (const TyTy::InferType &)
{
- gcc_unreachable ();
+ translated = error_mark_node;
}
+
void
TyTyResolveCompile::visit (const TyTy::ClosureType &)
{
@@ -332,8 +337,11 @@ TyTyResolveCompile::visit (const TyTy::ArrayType &type)
{
tree element_type
= TyTyResolveCompile::compile (ctx, type.get_element_type ());
+ tree capacity_expr = CompileExpr::Compile (&type.get_capacity_expr (), ctx);
+ tree folded_capacity_expr = ConstCtx::fold (capacity_expr);
+
translated
- = ctx->get_backend ()->array_type (element_type, type.get_capacity ());
+ = ctx->get_backend ()->array_type (element_type, folded_capacity_expr);
}
void
diff --git a/gcc/rust/backend/rust-compile-type.h b/gcc/rust/backend/rust-compile-type.h
index 1e05e5d..4d9c780 100644
--- a/gcc/rust/backend/rust-compile-type.h
+++ b/gcc/rust/backend/rust-compile-type.h
@@ -63,13 +63,14 @@ public:
private:
TyTyResolveCompile (Context *ctx, bool trait_object_mode)
- : ctx (ctx), trait_object_mode (trait_object_mode), translated (nullptr),
- recursion_count (0)
+ : ctx (ctx), trait_object_mode (trait_object_mode),
+ translated (error_mark_node), recursion_count (0)
{}
Context *ctx;
bool trait_object_mode;
tree translated;
+
size_t recursion_count;
static const size_t kDefaultRecusionLimit = 5;
diff --git a/gcc/rust/backend/rust-compile.cc b/gcc/rust/backend/rust-compile.cc
index 610e3aa..b12860d 100644
--- a/gcc/rust/backend/rust-compile.cc
+++ b/gcc/rust/backend/rust-compile.cc
@@ -288,21 +288,33 @@ HIRCompileBase::compile_locals_for_block (Resolver::Rib &rib, tree fndecl,
}
tree
-HIRCompileBase::coercion_site (tree compiled_ref, TyTy::BaseType *actual,
- TyTy::BaseType *expected, Location locus)
+HIRCompileBase::coercion_site (tree rvalue, TyTy::BaseType *actual,
+ TyTy::BaseType *expected, Location lvalue_locus,
+ Location rvalue_locus)
{
auto root_actual_kind = actual->get_root ()->get_kind ();
auto root_expected_kind = expected->get_root ()->get_kind ();
- if (root_expected_kind == TyTy::TypeKind::DYNAMIC
- && root_actual_kind != TyTy::TypeKind::DYNAMIC)
+ if (root_expected_kind == TyTy::TypeKind::ARRAY
+ && root_actual_kind == TyTy::TypeKind::ARRAY)
+ {
+ tree tree_rval_type
+ = TyTyResolveCompile::compile (ctx, actual->get_root ());
+ tree tree_lval_type
+ = TyTyResolveCompile::compile (ctx, expected->get_root ());
+ if (!verify_array_capacities (tree_lval_type, tree_rval_type,
+ lvalue_locus, rvalue_locus))
+ return error_mark_node;
+ }
+ else if (root_expected_kind == TyTy::TypeKind::DYNAMIC
+ && root_actual_kind != TyTy::TypeKind::DYNAMIC)
{
const TyTy::DynamicObjectType *dyn
= static_cast<const TyTy::DynamicObjectType *> (expected->get_root ());
- return coerce_to_dyn_object (compiled_ref, actual, expected, dyn, locus);
+ return coerce_to_dyn_object (rvalue, actual, expected, dyn, rvalue_locus);
}
- return compiled_ref;
+ return rvalue;
}
tree
@@ -530,5 +542,57 @@ HIRCompileBase::compute_address_for_trait_item (
true, locus);
}
+bool
+HIRCompileBase::verify_array_capacities (tree ltype, tree rtype,
+ Location lvalue_locus,
+ Location rvalue_locus)
+{
+ rust_assert (ltype != NULL_TREE);
+ rust_assert (rtype != NULL_TREE);
+
+ // lets just return ok as other errors have already occurred
+ if (ltype == error_mark_node || rtype == error_mark_node)
+ return true;
+
+ tree ltype_domain = TYPE_DOMAIN (ltype);
+ if (!ltype_domain)
+ return false;
+
+ if (!TREE_CONSTANT (TYPE_MAX_VALUE (ltype_domain)))
+ return false;
+
+ auto ltype_length
+ = wi::ext (wi::to_offset (TYPE_MAX_VALUE (ltype_domain))
+ - wi::to_offset (TYPE_MIN_VALUE (ltype_domain)) + 1,
+ TYPE_PRECISION (TREE_TYPE (ltype_domain)),
+ TYPE_SIGN (TREE_TYPE (ltype_domain)))
+ .to_uhwi ();
+
+ tree rtype_domain = TYPE_DOMAIN (rtype);
+ if (!rtype_domain)
+ return false;
+
+ if (!TREE_CONSTANT (TYPE_MAX_VALUE (rtype_domain)))
+ return false;
+
+ auto rtype_length
+ = wi::ext (wi::to_offset (TYPE_MAX_VALUE (rtype_domain))
+ - wi::to_offset (TYPE_MIN_VALUE (rtype_domain)) + 1,
+ TYPE_PRECISION (TREE_TYPE (rtype_domain)),
+ TYPE_SIGN (TREE_TYPE (rtype_domain)))
+ .to_uhwi ();
+
+ if (ltype_length != rtype_length)
+ {
+ rust_error_at (rvalue_locus,
+ "expected an array with a fixed size of %lu "
+ "elements, found one with %lu elements",
+ ltype_length, rtype_length);
+ return false;
+ }
+
+ return true;
+}
+
} // namespace Compile
} // namespace Rust
diff --git a/gcc/rust/backend/rust-constexpr.cc b/gcc/rust/backend/rust-constexpr.cc
new file mode 100644
index 0000000..293f110
--- /dev/null
+++ b/gcc/rust/backend/rust-constexpr.cc
@@ -0,0 +1,428 @@
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include "rust-constexpr.h"
+#include "rust-location.h"
+#include "rust-diagnostics.h"
+
+#include "fold-const.h"
+#include "realmpfr.h"
+#include "convert.h"
+#include "print-tree.h"
+#include "gimplify.h"
+#include "tree-iterator.h"
+
+/* Returns true if NODE is a pointer. */
+#define TYPE_PTR_P(NODE) (TREE_CODE (NODE) == POINTER_TYPE)
+
+/* Returns true if NODE is a reference. */
+#define TYPE_REF_P(NODE) (TREE_CODE (NODE) == REFERENCE_TYPE)
+
+/* Returns true if NODE is a pointer or a reference. */
+#define INDIRECT_TYPE_P(NODE) (TYPE_PTR_P (NODE) || TYPE_REF_P (NODE))
+
+/* [basic.fundamental]
+
+ Types bool, char, wchar_t, and the signed and unsigned integer types
+ are collectively called integral types.
+
+ Note that INTEGRAL_TYPE_P, as defined in tree.h, allows enumeration
+ types as well, which is incorrect in C++. Keep these checks in
+ ascending code order. */
+#define RS_INTEGRAL_TYPE_P(TYPE) \
+ (TREE_CODE (TYPE) == BOOLEAN_TYPE || TREE_CODE (TYPE) == INTEGER_TYPE)
+
+/* [basic.fundamental]
+
+ Integral and floating types are collectively called arithmetic
+ types.
+
+ As a GNU extension, we also accept complex types.
+
+ Keep these checks in ascending code order. */
+#define ARITHMETIC_TYPE_P(TYPE) \
+ (RS_INTEGRAL_TYPE_P (TYPE) || TREE_CODE (TYPE) == REAL_TYPE \
+ || TREE_CODE (TYPE) == COMPLEX_TYPE)
+
+/* True iff TYPE is cv decltype(nullptr). */
+#define NULLPTR_TYPE_P(TYPE) (TREE_CODE (TYPE) == NULLPTR_TYPE)
+
+/* [basic.types]
+
+ Arithmetic types, enumeration types, pointer types,
+ pointer-to-member types, and std::nullptr_t are collectively called
+ scalar types.
+
+ Keep these checks in ascending code order. */
+#define SCALAR_TYPE_P(TYPE) \
+ (TREE_CODE (TYPE) == ENUMERAL_TYPE || ARITHMETIC_TYPE_P (TYPE) \
+ || TYPE_PTR_P (TYPE) || NULLPTR_TYPE_P (TYPE))
+
+namespace Rust {
+namespace Compile {
+
+static tree
+constant_value_1 (tree decl, bool strict_p, bool return_aggregate_cst_ok_p,
+ bool unshare_p);
+tree
+decl_constant_value (tree decl, bool unshare_p);
+
+static void
+non_const_var_error (location_t loc, tree r);
+
+static tree
+get_function_named_in_call (tree t);
+
+ConstCtx::ConstCtx () : constexpr_ops_count (0) {}
+
+tree
+ConstCtx::fold (tree expr)
+{
+ tree folded = ConstCtx ().constexpr_expression (expr);
+ rust_assert (folded != NULL_TREE);
+ return folded;
+}
+
+tree
+ConstCtx::constexpr_expression (tree t)
+{
+ location_t loc = EXPR_LOCATION (t);
+ if (CONSTANT_CLASS_P (t))
+ {
+ if (TREE_OVERFLOW (t))
+ {
+ rust_error_at (Location (loc), "overflow in constant expression");
+ return t;
+ }
+
+ if (TREE_CODE (t) == INTEGER_CST && TYPE_PTR_P (TREE_TYPE (t))
+ && !integer_zerop (t))
+ {
+ // FIXME check does this actually work to print out tree types
+ rust_error_at (Location (loc),
+ "value %qE of type %qT is not a constant expression",
+ t, TREE_TYPE (t));
+ return t;
+ }
+
+ return t;
+ }
+
+ // Avoid excessively long constexpr evaluations
+ if (++constexpr_ops_count >= constexpr_ops_limit)
+ {
+ rust_error_at (
+ Location (loc),
+ "%<constexpr%> evaluation operation count exceeds limit of "
+ "%wd (use %<-fconstexpr-ops-limit=%> to increase the limit)",
+ constexpr_ops_limit);
+
+ return t;
+ }
+
+ tree r = t;
+ tree_code tcode = TREE_CODE (t);
+ switch (tcode)
+ {
+ case CONST_DECL: {
+ r = decl_constant_value (t, /*unshare_p=*/false);
+ if (TREE_CODE (r) == TARGET_EXPR
+ && TREE_CODE (TARGET_EXPR_INITIAL (r)) == CONSTRUCTOR)
+ r = TARGET_EXPR_INITIAL (r);
+ if (DECL_P (r))
+ {
+ non_const_var_error (loc, r);
+ return r;
+ }
+ }
+ break;
+
+ case POINTER_PLUS_EXPR:
+ case POINTER_DIFF_EXPR:
+ case PLUS_EXPR:
+ case MINUS_EXPR:
+ case MULT_EXPR:
+ case TRUNC_DIV_EXPR:
+ case CEIL_DIV_EXPR:
+ case FLOOR_DIV_EXPR:
+ case ROUND_DIV_EXPR:
+ case TRUNC_MOD_EXPR:
+ case CEIL_MOD_EXPR:
+ case ROUND_MOD_EXPR:
+ case RDIV_EXPR:
+ case EXACT_DIV_EXPR:
+ case MIN_EXPR:
+ case MAX_EXPR:
+ case LSHIFT_EXPR:
+ case RSHIFT_EXPR:
+ case LROTATE_EXPR:
+ case RROTATE_EXPR:
+ case BIT_IOR_EXPR:
+ case BIT_XOR_EXPR:
+ case BIT_AND_EXPR:
+ case TRUTH_XOR_EXPR:
+ case LT_EXPR:
+ case LE_EXPR:
+ case GT_EXPR:
+ case GE_EXPR:
+ case EQ_EXPR:
+ case NE_EXPR:
+ case SPACESHIP_EXPR:
+ case UNORDERED_EXPR:
+ case ORDERED_EXPR:
+ case UNLT_EXPR:
+ case UNLE_EXPR:
+ case UNGT_EXPR:
+ case UNGE_EXPR:
+ case UNEQ_EXPR:
+ case LTGT_EXPR:
+ case RANGE_EXPR:
+ case COMPLEX_EXPR:
+ r = eval_binary_expression (t);
+ break;
+
+ case CALL_EXPR:
+ r = eval_call_expression (t);
+ break;
+
+ case RETURN_EXPR:
+ rust_assert (TREE_OPERAND (t, 0) != NULL_TREE);
+ r = constexpr_expression (TREE_OPERAND (t, 0));
+ break;
+
+ case MODIFY_EXPR:
+ r = eval_store_expression (t);
+ break;
+
+ default:
+ break;
+ }
+
+ return r;
+}
+
+tree
+ConstCtx::eval_store_expression (tree t)
+{
+ tree init = TREE_OPERAND (t, 1);
+ if (TREE_CLOBBER_P (init))
+ /* Just ignore clobbers. */
+ return void_node;
+
+ /* First we figure out where we're storing to. */
+ tree target = TREE_OPERAND (t, 0);
+
+ tree type = TREE_TYPE (target);
+ bool preeval = SCALAR_TYPE_P (type) || TREE_CODE (t) == MODIFY_EXPR;
+ if (preeval)
+ {
+ /* Evaluate the value to be stored without knowing what object it will be
+ stored in, so that any side-effects happen first. */
+ init = ConstCtx::fold (init);
+ }
+
+ bool evaluated = false;
+ tree object = NULL_TREE;
+ for (tree probe = target; object == NULL_TREE;)
+ {
+ switch (TREE_CODE (probe))
+ {
+ default:
+ if (evaluated)
+ object = probe;
+ else
+ {
+ probe = constexpr_expression (probe);
+ evaluated = true;
+ }
+ break;
+ }
+ }
+
+ return init;
+}
+
+/* Subroutine of cxx_eval_constant_expression.
+ Like cxx_eval_unary_expression, except for binary expressions. */
+
+tree
+ConstCtx::eval_binary_expression (tree t)
+{
+ tree orig_lhs = TREE_OPERAND (t, 0);
+ tree orig_rhs = TREE_OPERAND (t, 1);
+ tree lhs, rhs;
+
+ lhs = constexpr_expression (orig_lhs);
+ rhs = constexpr_expression (orig_rhs);
+
+ location_t loc = EXPR_LOCATION (t);
+ enum tree_code code = TREE_CODE (t);
+ tree type = TREE_TYPE (t);
+
+ return fold_binary_loc (loc, code, type, lhs, rhs);
+}
+
+// Subroutine of cxx_eval_constant_expression.
+// Evaluate the call expression tree T in the context of OLD_CALL expression
+// evaluation.
+tree
+ConstCtx::eval_call_expression (tree t)
+{
+ tree fun = get_function_named_in_call (t);
+ return constexpr_fn_retval (DECL_SAVED_TREE (fun));
+}
+
+// Subroutine of check_constexpr_fundef. BODY is the body of a function
+// declared to be constexpr, or a sub-statement thereof. Returns the
+// return value if suitable, error_mark_node for a statement not allowed in
+// a constexpr function, or NULL_TREE if no return value was found.
+tree
+ConstCtx::constexpr_fn_retval (tree body)
+{
+ switch (TREE_CODE (body))
+ {
+ case STATEMENT_LIST: {
+ tree expr = NULL_TREE;
+ for (tree stmt : tsi_range (body))
+ {
+ tree s = constexpr_fn_retval (stmt);
+ if (s == error_mark_node)
+ return error_mark_node;
+ else if (s == NULL_TREE)
+ /* Keep iterating. */;
+ else if (expr)
+ /* Multiple return statements. */
+ return error_mark_node;
+ else
+ expr = s;
+ }
+ return expr;
+ }
+
+ case RETURN_EXPR:
+ return constexpr_expression (body);
+
+ case DECL_EXPR: {
+ tree decl = DECL_EXPR_DECL (body);
+ if (TREE_CODE (decl) == USING_DECL
+ /* Accept __func__, __FUNCTION__, and __PRETTY_FUNCTION__. */
+ || DECL_ARTIFICIAL (decl))
+ return NULL_TREE;
+ return error_mark_node;
+ }
+
+ case CLEANUP_POINT_EXPR:
+ return constexpr_fn_retval (TREE_OPERAND (body, 0));
+
+ case BIND_EXPR: {
+ tree b = BIND_EXPR_BODY (body);
+ return constexpr_fn_retval (b);
+ }
+ break;
+
+ default:
+ return error_mark_node;
+ }
+ return error_mark_node;
+}
+
+// Taken from cp/constexpr.c
+//
+// If DECL is a scalar enumeration constant or variable with a
+// constant initializer, return the initializer (or, its initializers,
+// recursively); otherwise, return DECL. If STRICT_P, the
+// initializer is only returned if DECL is a
+// constant-expression. If RETURN_AGGREGATE_CST_OK_P, it is ok to
+// return an aggregate constant. If UNSHARE_P, return an unshared
+// copy of the initializer.
+static tree
+constant_value_1 (tree decl, bool strict_p, bool return_aggregate_cst_ok_p,
+ bool unshare_p)
+{
+ while (TREE_CODE (decl) == CONST_DECL)
+ {
+ tree init;
+ /* If DECL is a static data member in a template
+ specialization, we must instantiate it here. The
+ initializer for the static data member is not processed
+ until needed; we need it now. */
+
+ init = DECL_INITIAL (decl);
+ if (init == error_mark_node)
+ {
+ if (TREE_CODE (decl) == CONST_DECL)
+ /* Treat the error as a constant to avoid cascading errors on
+ excessively recursive template instantiation (c++/9335). */
+ return init;
+ else
+ return decl;
+ }
+
+ decl = init;
+ }
+ return unshare_p ? unshare_expr (decl) : decl;
+}
+
+// A more relaxed version of decl_really_constant_value, used by the
+// common C/C++ code.
+tree
+decl_constant_value (tree decl, bool unshare_p)
+{
+ return constant_value_1 (decl, /*strict_p=*/false,
+ /*return_aggregate_cst_ok_p=*/true,
+ /*unshare_p=*/unshare_p);
+}
+
+static void
+non_const_var_error (location_t loc, tree r)
+{
+ error_at (loc,
+ "the value of %qD is not usable in a constant "
+ "expression",
+ r);
+ /* Avoid error cascade. */
+ if (DECL_INITIAL (r) == error_mark_node)
+ return;
+
+ // more in cp/constexpr.c
+}
+
+static tree
+get_callee (tree call)
+{
+ if (call == NULL_TREE)
+ return call;
+ else if (TREE_CODE (call) == CALL_EXPR)
+ return CALL_EXPR_FN (call);
+
+ return NULL_TREE;
+}
+
+// We have an expression tree T that represents a call, either CALL_EXPR
+// or AGGR_INIT_EXPR. If the call is lexically to a named function,
+// return the _DECL for that function.
+static tree
+get_function_named_in_call (tree t)
+{
+ tree fun = get_callee (t);
+ if (fun && TREE_CODE (fun) == ADDR_EXPR
+ && TREE_CODE (TREE_OPERAND (fun, 0)) == FUNCTION_DECL)
+ fun = TREE_OPERAND (fun, 0);
+ return fun;
+}
+
+} // namespace Compile
+} // namespace Rust
diff --git a/gcc/rust/typecheck/rust-hir-const-fold-ctx.h b/gcc/rust/backend/rust-constexpr.h
index a3f5a16..40d9159 100644
--- a/gcc/rust/typecheck/rust-hir-const-fold-ctx.h
+++ b/gcc/rust/backend/rust-constexpr.h
@@ -1,5 +1,3 @@
-// Copyright (C) 2020-2021 Free Software Foundation, Inc.
-
// This file is part of GCC.
// GCC is free software; you can redistribute it and/or modify it under
@@ -16,38 +14,33 @@
// along with GCC; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
-#ifndef RUST_HIR_CONST_FOLD_CTX_H
-#define RUST_HIR_CONST_FOLD_CTX_H
+#ifndef RUST_CONSTEXPR
+#define RUST_CONSTEXPR
-#include "rust-backend.h"
-#include "rust-hir-map.h"
+#include "rust-system.h"
+#include "tree.h"
namespace Rust {
-namespace ConstFold {
+namespace Compile {
-class Context
+class ConstCtx
{
public:
- ~Context () {}
-
- static void init (::Backend *backend);
-
- static Context *get ();
-
- ::Backend *get_backend () { return backend; }
-
- bool lookup_const (HirId id, tree *expr);
+ static tree fold (tree);
- void insert_const (HirId, tree expr);
+ tree constexpr_expression (tree);
+ tree eval_binary_expression (tree);
+ tree eval_call_expression (tree);
+ tree constexpr_fn_retval (tree);
+ tree eval_store_expression (tree);
private:
- Context (::Backend *backend);
+ ConstCtx ();
- ::Backend *backend;
- std::map<HirId, tree> ctx;
+ HOST_WIDE_INT constexpr_ops_count;
};
-} // namespace ConstFold
+} // namespace Compile
} // namespace Rust
-#endif // RUST_HIR_CONST_FOLD_CTX_H
+#endif // RUST_CONSTEXPR
diff --git a/gcc/rust/rust-backend.h b/gcc/rust/rust-backend.h
index 43a81f2..98aaae9 100644
--- a/gcc/rust/rust-backend.h
+++ b/gcc/rust/rust-backend.h
@@ -74,11 +74,6 @@ public:
virtual void debug (tree) = 0;
virtual void debug (Bvariable *) = 0;
- // const folder helpers
- virtual bool const_size_cast (tree, size_t *) = 0;
- virtual std::string const_size_val_to_string (tree) = 0;
- virtual bool const_values_equal (tree, tree) = 0;
-
static Rust::ABI get_abi_from_string (const std::string &abi, Location locus)
{
if (abi.compare ("rust") == 0)
diff --git a/gcc/rust/rust-gcc.cc b/gcc/rust/rust-gcc.cc
index 43716d9..1fdba7a 100644
--- a/gcc/rust/rust-gcc.cc
+++ b/gcc/rust/rust-gcc.cc
@@ -137,45 +137,6 @@ public:
tree char_type () { return char_type_node; }
- bool const_size_cast (tree expr, size_t *result)
- {
- rust_assert (TREE_CONSTANT (expr));
-
- unsigned char buf[sizeof (size_t) + 1];
- memset (buf, 0, sizeof (buf));
-
- int ret = native_encode_expr (expr, buf, sizeof (buf), 0);
- if (ret <= 0)
- return false;
-
- size_t *tmp = (size_t *) buf;
- *result = *tmp;
- return true;
- }
-
- std::string const_size_val_to_string (tree expr)
- {
- rust_assert (TREE_CONSTANT (expr));
-
- unsigned char buf[sizeof (size_t) + 1];
- memset (buf, 0, sizeof (buf));
-
- int ret = native_encode_expr (expr, buf, sizeof (buf), 0);
- rust_assert (ret > 0);
-
- size_t *ptr = (size_t *) buf;
- return std::to_string (*ptr);
- }
-
- bool const_values_equal (tree a, tree b)
- {
- return operand_equal_p (a, b, OEP_ONLY_CONST | OEP_PURE_SAME);
- // printf ("comparing!\n");
- // debug_tree (a->get_tree ());
- // debug_tree (b->get_tree ());
- // printf ("ok = %s\n", ok ? "true" : "false");
- }
-
tree wchar_type ()
{
tree wchar = make_unsigned_type (32);
@@ -1672,6 +1633,9 @@ Gcc_backend::arithmetic_or_logical_expression (ArithmeticOrLogicalOperator op,
/* Construct a new tree and build an expression from it. */
auto new_tree = fold_build2_loc (location.gcc_location (), tree_code,
tree_type, left_tree, right_tree);
+ TREE_CONSTANT (new_tree)
+ = TREE_CONSTANT (left_tree) && TREE_CONSTANT (right_tree);
+
if (floating_point && extended_type != NULL_TREE)
new_tree = convert (original_type, new_tree);
return new_tree;
diff --git a/gcc/rust/rust-session-manager.cc b/gcc/rust/rust-session-manager.cc
index b844e3b..dccaffe 100644
--- a/gcc/rust/rust-session-manager.cc
+++ b/gcc/rust/rust-session-manager.cc
@@ -52,7 +52,6 @@
#include "rust-lint-scan-deadcode.h"
#include "rust-tycheck-dump.h"
#include "rust-ast-resolve-unused.h"
-#include "rust-hir-const-fold.h"
#include "rust-compile.h"
extern Linemap *
@@ -330,9 +329,6 @@ Session::init ()
// set the default crate name
options.set_crate_name (kDefaultCrateName);
-
- // the constant folder uses gcc
- ConstFold::Context::init (backend);
}
/* Initialise default options. Actually called before handle_option, unlike init
diff --git a/gcc/rust/typecheck/rust-hir-const-fold-base.h b/gcc/rust/typecheck/rust-hir-const-fold-base.h
deleted file mode 100644
index 2ab4450..0000000
--- a/gcc/rust/typecheck/rust-hir-const-fold-base.h
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright (C) 2020-2021 Free Software Foundation, Inc.
-
-// This file is part of GCC.
-
-// GCC is free software; you can redistribute it and/or modify it under
-// the terms of the GNU General Public License as published by the Free
-// Software Foundation; either version 3, or (at your option) any later
-// version.
-
-// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
-// WARRANTY; without even the implied warranty of MERCHANTABILITY or
-// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-// for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with GCC; see the file COPYING3. If not see
-// <http://www.gnu.org/licenses/>.
-
-#ifndef RUST_HIR_CONST_FOLD_BASE_H
-#define RUST_HIR_CONST_FOLD_BASE_H
-
-#include "rust-diagnostics.h"
-#include "rust-hir-visitor.h"
-#include "rust-hir-map.h"
-#include "rust-hir-type-check.h"
-#include "rust-name-resolver.h"
-#include "rust-hir-const-fold-ctx.h"
-
-namespace Rust {
-namespace ConstFold {
-
-// base class to allow derivatives to overload as needed
-class ConstFoldBase : public HIR::HIRFullVisitorBase
-{
-public:
- virtual ~ConstFoldBase () {}
-
-protected:
- ConstFoldBase ()
- : mappings (Analysis::Mappings::get ()),
- resolver (Resolver::Resolver::get ()),
- tyctx (Resolver::TypeCheckContext::get ()), ctx (Context::get ())
- {}
-
- Analysis::Mappings *mappings;
- Resolver::Resolver *resolver;
- Resolver::TypeCheckContext *tyctx;
- Context *ctx;
-};
-
-} // namespace ConstFold
-} // namespace Rust
-
-#endif // RUST_HIR_CONST_FOLD_BASE_H
diff --git a/gcc/rust/typecheck/rust-hir-const-fold.cc b/gcc/rust/typecheck/rust-hir-const-fold.cc
deleted file mode 100644
index 1545c1a..0000000
--- a/gcc/rust/typecheck/rust-hir-const-fold.cc
+++ /dev/null
@@ -1,138 +0,0 @@
-// Copyright (C) 2020-2021 Free Software Foundation, Inc.
-
-// This file is part of GCC.
-
-// GCC is free software; you can redistribute it and/or modify it under
-// the terms of the GNU General Public License as published by the Free
-// Software Foundation; either version 3, or (at your option) any later
-// version.
-
-// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
-// WARRANTY; without even the implied warranty of MERCHANTABILITY or
-// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-// for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with GCC; see the file COPYING3. If not see
-// <http://www.gnu.org/licenses/>.
-
-#include "rust-hir-const-fold-ctx.h"
-#include "rust-hir-const-fold.h"
-
-namespace Rust {
-namespace ConstFold {
-
-static Context *context = nullptr;
-
-Context::Context (::Backend *backend) : backend (backend) {}
-
-void
-Context::init (::Backend *backend)
-{
- rust_assert (context == nullptr);
- context = new Context (backend);
-}
-
-Context *
-Context::get ()
-{
- rust_assert (context != nullptr);
- return context;
-}
-
-bool
-Context::lookup_const (HirId id, tree *expr)
-{
- auto it = ctx.find (id);
- if (it == ctx.end ())
- return false;
-
- *expr = it->second;
- return true;
-}
-
-void
-Context::insert_const (HirId id, tree expr)
-{
- rust_assert (ctx.find (id) == ctx.end ());
- ctx[id] = expr;
-}
-
-// rust-hir-const-fold.h
-
-void
-ConstFoldItem::visit (HIR::ConstantItem &item)
-{
- auto folded_expr = ConstFoldExpr::fold (item.get_expr ());
-
- folded = folded_expr;
-}
-
-void
-ConstFoldArrayElems::visit (HIR::ArrayElemsValues &elems)
-{
- unsigned long index = 0;
- std::vector<unsigned long> indices;
- std::vector<tree> values;
-
- TyTy::BaseType *tyty = nullptr;
- if (!tyctx->lookup_type (expr.get_mappings ().get_hirid (), &tyty))
- {
- rust_fatal_error (expr.get_locus (),
- "did not resolve type for array elems values");
- return;
- }
-
- tree type = ConstFoldType::fold (tyty, ctx->get_backend ());
-
- for (auto &value : elems.get_values ())
- {
- indices.push_back (index++);
- values.push_back (ConstFoldExpr::fold (value.get ()));
- }
-
- folded
- = ctx->get_backend ()->array_constructor_expression (type, indices, values,
- expr.get_locus ());
-}
-
-void
-ConstFoldArrayElems::visit (HIR::ArrayElemsCopied &elems)
-{
- std::vector<unsigned long> indices;
- std::vector<tree> values;
-
- TyTy::BaseType *tyty = nullptr;
- if (!tyctx->lookup_type (expr.get_mappings ().get_hirid (), &tyty))
- {
- rust_fatal_error (expr.get_locus (),
- "did not resolve type for array elems");
- return;
- }
-
- tree type = ConstFoldType::fold (tyty, ctx->get_backend ());
- tree elem = ConstFoldExpr::fold (elems.get_elem_to_copy ());
-
- // num copies expr was already folded in rust-hir-type-check-expr; lookup the
- // earlier result
- tree num_copies_expr = ctx->get_backend ()->error_expression ();
- ctx->lookup_const (elems.get_num_copies_expr ()->get_mappings ().get_hirid (),
- &num_copies_expr);
-
- size_t copies;
- bool ok = ctx->get_backend ()->const_size_cast (num_copies_expr, &copies);
- rust_assert (ok);
-
- for (size_t i = 0; i < copies; i++)
- {
- indices.push_back (i);
- values.push_back (elem);
- }
-
- folded
- = ctx->get_backend ()->array_constructor_expression (type, indices, values,
- expr.get_locus ());
-}
-
-} // namespace ConstFold
-} // namespace Rust
diff --git a/gcc/rust/typecheck/rust-hir-const-fold.h b/gcc/rust/typecheck/rust-hir-const-fold.h
deleted file mode 100644
index 1907816..0000000
--- a/gcc/rust/typecheck/rust-hir-const-fold.h
+++ /dev/null
@@ -1,499 +0,0 @@
-// Copyright (C) 2020-2021 Free Software Foundation, Inc.
-
-// This file is part of GCC.
-
-// GCC is free software; you can redistribute it and/or modify it under
-// the terms of the GNU General Public License as published by the Free
-// Software Foundation; either version 3, or (at your option) any later
-// version.
-
-// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
-// WARRANTY; without even the implied warranty of MERCHANTABILITY or
-// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-// for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with GCC; see the file COPYING3. If not see
-// <http://www.gnu.org/licenses/>.
-
-#ifndef RUST_HIR_CONST_FOLD_H
-#define RUST_HIR_CONST_FOLD_H
-
-#include "rust-hir-const-fold-base.h"
-#include "rust-tyty-visitor.h"
-
-namespace Rust {
-namespace ConstFold {
-
-class ConstFoldType : public TyTy::TyVisitor
-{
-public:
- static tree fold (TyTy::BaseType *type, ::Backend *backend)
- {
- ConstFoldType folder (backend);
- type->accept_vis (folder);
- return folder.translated;
- };
-
- void visit (TyTy::ErrorType &) override { gcc_unreachable (); }
-
- void visit (TyTy::InferType &) override { gcc_unreachable (); }
-
- void visit (TyTy::ADTType &) override { gcc_unreachable (); }
-
- void visit (TyTy::ArrayType &type) override
- {
- tree element_ty = ConstFoldType::fold (type.get_element_type (), backend);
- translated = backend->array_type (element_ty, type.get_capacity ());
- }
-
- void visit (TyTy::ReferenceType &type) override
- {
- tree base_compiled_type = ConstFoldType::fold (type.get_base (), backend);
- if (type.is_mutable ())
- {
- translated = backend->reference_type (base_compiled_type);
- }
- else
- {
- auto base = backend->immutable_type (base_compiled_type);
- translated = backend->reference_type (base);
- }
- }
-
- void visit (TyTy::PointerType &type) override
- {
- tree base_compiled_type = ConstFoldType::fold (type.get_base (), backend);
- if (type.is_mutable ())
- {
- translated = backend->pointer_type (base_compiled_type);
- }
- else
- {
- auto base = backend->immutable_type (base_compiled_type);
- translated = backend->pointer_type (base);
- }
- }
-
- void visit (TyTy::ParamType &) override { gcc_unreachable (); }
-
- void visit (TyTy::FnPtr &) override { gcc_unreachable (); }
-
- void visit (TyTy::FnType &) override { gcc_unreachable (); }
-
- void visit (TyTy::PlaceholderType &) override { gcc_unreachable (); }
-
- void visit (TyTy::ProjectionType &) override { gcc_unreachable (); }
-
- void visit (TyTy::TupleType &type) override
- {
- if (type.num_fields () == 0)
- translated = backend->unit_type ();
- else
- gcc_unreachable ();
- }
-
- void visit (TyTy::BoolType &) override
- {
- translated = backend->named_type ("bool", backend->bool_type (),
- Linemap::predeclared_location ());
- }
-
- void visit (TyTy::IntType &type) override
- {
- switch (type.get_int_kind ())
- {
- case TyTy::IntType::I8:
- translated
- = backend->named_type ("i8", backend->integer_type (false, 8),
- Linemap::predeclared_location ());
- return;
-
- case TyTy::IntType::I16:
- translated
- = backend->named_type ("i16", backend->integer_type (false, 16),
- Linemap::predeclared_location ());
- return;
-
- case TyTy::IntType::I32:
- translated
- = backend->named_type ("i32", backend->integer_type (false, 32),
- Linemap::predeclared_location ());
- return;
-
- case TyTy::IntType::I64:
- translated
- = backend->named_type ("i64", backend->integer_type (false, 64),
- Linemap::predeclared_location ());
- return;
-
- case TyTy::IntType::I128:
- translated
- = backend->named_type ("i128", backend->integer_type (false, 128),
- Linemap::predeclared_location ());
- return;
- }
- gcc_unreachable ();
- }
-
- void visit (TyTy::UintType &type) override
- {
- switch (type.get_uint_kind ())
- {
- case TyTy::UintType::U8:
- translated = backend->named_type ("u8", backend->integer_type (true, 8),
- Linemap::predeclared_location ());
- return;
-
- case TyTy::UintType::U16:
- translated
- = backend->named_type ("u16", backend->integer_type (true, 16),
- Linemap::predeclared_location ());
- return;
-
- case TyTy::UintType::U32:
- translated
- = backend->named_type ("u32", backend->integer_type (true, 32),
- Linemap::predeclared_location ());
- return;
-
- case TyTy::UintType::U64:
- translated
- = backend->named_type ("u64", backend->integer_type (true, 64),
- Linemap::predeclared_location ());
- return;
-
- case TyTy::UintType::U128:
- translated
- = backend->named_type ("u128", backend->integer_type (true, 128),
- Linemap::predeclared_location ());
- return;
- }
- gcc_unreachable ();
- }
-
- void visit (TyTy::FloatType &type) override
- {
- switch (type.get_float_kind ())
- {
- case TyTy::FloatType::F32:
- translated = backend->named_type ("f32", backend->float_type (32),
- Linemap::predeclared_location ());
- return;
-
- case TyTy::FloatType::F64:
- translated = backend->named_type ("f64", backend->float_type (64),
- Linemap::predeclared_location ());
- return;
- }
-
- gcc_unreachable ();
- }
-
- void visit (TyTy::USizeType &) override
- {
- translated = backend->named_type (
- "usize", backend->integer_type (true, backend->get_pointer_size ()),
- Linemap::predeclared_location ());
- }
-
- void visit (TyTy::ISizeType &) override
- {
- translated = backend->named_type (
- "isize", backend->integer_type (false, backend->get_pointer_size ()),
- Linemap::predeclared_location ());
- }
-
- void visit (TyTy::CharType &) override
- {
- translated = backend->named_type ("char", backend->wchar_type (),
- Linemap::predeclared_location ());
- }
-
- void visit (TyTy::StrType &) override
- {
- tree raw_str = backend->raw_str_type ();
- translated
- = backend->named_type ("str", raw_str, Linemap::predeclared_location ());
- }
-
- void visit (TyTy::NeverType &) override { gcc_unreachable (); }
-
- void visit (TyTy::DynamicObjectType &) override { gcc_unreachable (); }
-
- void visit (TyTy::ClosureType &) override { gcc_unreachable (); }
-
-private:
- ConstFoldType (::Backend *backend)
- : backend (backend), translated (backend->error_type ())
- {}
-
- ::Backend *backend;
- ::tree translated;
-};
-
-class ConstFoldItem : public ConstFoldBase
-{
- using ConstFoldBase::visit;
-
-public:
- static tree fold (HIR::Item &item)
- {
- ConstFoldItem folder;
- item.accept_vis (folder);
- if (folder.ctx->get_backend ()->is_error_expression (folder.folded))
- {
- rust_error_at (item.get_locus (), "non const value");
- return nullptr;
- }
-
- folder.ctx->insert_const (item.get_mappings ().get_hirid (), folder.folded);
- return folder.folded;
- };
-
- void visit (HIR::ConstantItem &item) override;
-
-private:
- ConstFoldItem ()
- : ConstFoldBase (), folded (ctx->get_backend ()->error_expression ())
- {}
-
- tree folded;
-};
-
-class ConstFoldArrayElems : public ConstFoldBase
-{
- using ConstFoldBase::visit;
-
-public:
- static tree fold (HIR::ArrayExpr &expr)
- {
- ConstFoldArrayElems folder (expr);
- HIR::ArrayElems *elems = expr.get_internal_elements ();
- elems->accept_vis (folder);
- return folder.folded;
- }
-
- void visit (HIR::ArrayElemsValues &elems) override;
- void visit (HIR::ArrayElemsCopied &elems) override;
-
-private:
- ConstFoldArrayElems (HIR::ArrayExpr &expr)
- : ConstFoldBase (), folded (ctx->get_backend ()->error_expression ()),
- expr (expr)
- {}
-
- tree folded;
- HIR::ArrayExpr &expr;
-};
-
-class ConstFoldExpr : public ConstFoldBase
-{
- using ConstFoldBase::visit;
-
-public:
- static tree fold (HIR::Expr *expr)
- {
- ConstFoldExpr folder;
- expr->accept_vis (folder);
- if (folder.ctx->get_backend ()->is_error_expression (folder.folded))
- {
- rust_error_at (expr->get_locus (), "non const value");
- return folder.ctx->get_backend ()->error_expression ();
- }
-
- folder.ctx->insert_const (expr->get_mappings ().get_hirid (),
- folder.folded);
- return folder.folded;
- };
-
- void visit (HIR::IdentifierExpr &expr) override
- {
- NodeId ast_node_id = expr.get_mappings ().get_nodeid ();
-
- // then lookup the reference_node_id
- NodeId ref_node_id = UNKNOWN_NODEID;
- if (resolver->lookup_resolved_name (ast_node_id, &ref_node_id))
- {
- // these ref_node_ids will resolve to a pattern declaration but we are
- // interested in the definition that this refers to get the parent id
- Resolver::Definition def;
- if (!resolver->lookup_definition (ref_node_id, &def))
- {
- rust_error_at (expr.get_locus (),
- "unknown reference for resolved name");
- return;
- }
- ref_node_id = def.parent;
- }
-
- if (ref_node_id == UNKNOWN_NODEID)
- {
- rust_error_at (expr.get_locus (), "unresolved node: %s",
- expr.as_string ().c_str ());
- return;
- }
-
- // node back to HIR
- HirId ref;
- if (!mappings->lookup_node_to_hir (expr.get_mappings ().get_crate_num (),
- ref_node_id, &ref))
- {
- rust_error_at (expr.get_locus (), "reverse lookup failure");
- return;
- }
-
- // lookup constant
- ctx->lookup_const (ref, &folded);
- }
-
- void visit (HIR::LiteralExpr &expr) override
- {
- auto literal_value = expr.get_literal ();
- switch (expr.get_lit_type ())
- {
- case HIR::Literal::INT: {
- mpz_t ival;
- if (mpz_init_set_str (ival, literal_value.as_string ().c_str (), 10)
- != 0)
- {
- rust_fatal_error (expr.get_locus (), "bad number in literal");
- return;
- }
-
- TyTy::BaseType *tyty = nullptr;
- if (!tyctx->lookup_type (expr.get_mappings ().get_hirid (), &tyty))
- {
- rust_fatal_error (expr.get_locus (),
- "did not resolve type for this literal expr");
- return;
- }
-
- tree type = ConstFoldType::fold (tyty, ctx->get_backend ());
- folded
- = ctx->get_backend ()->integer_constant_expression (type, ival);
- }
- return;
-
- case HIR::Literal::BOOL: {
- bool bval = literal_value.as_string ().compare ("true") == 0;
- folded = ctx->get_backend ()->boolean_constant_expression (bval);
- }
- return;
-
- case HIR::Literal::FLOAT: {
- mpfr_t fval;
- if (mpfr_init_set_str (fval, literal_value.as_string ().c_str (), 10,
- MPFR_RNDN)
- != 0)
- {
- rust_fatal_error (expr.get_locus (),
- "bad floating-point number in literal");
- return;
- }
-
- TyTy::BaseType *tyty = nullptr;
- if (!tyctx->lookup_type (expr.get_mappings ().get_hirid (), &tyty))
- {
- rust_fatal_error (expr.get_locus (),
- "did not resolve type for this literal expr");
- return;
- }
-
- tree type = ConstFoldType::fold (tyty, ctx->get_backend ());
- folded = ctx->get_backend ()->float_constant_expression (type, fval);
- }
- return;
-
- /* handle other literals */
-
- default:
- gcc_unreachable ();
- return;
- }
-
- gcc_unreachable ();
- }
-
- void visit (HIR::ArrayExpr &expr) override
- {
- folded = ConstFoldArrayElems::fold (expr);
- }
-
- void visit (HIR::ArithmeticOrLogicalExpr &expr) override
- {
- auto lhs = ConstFoldExpr::fold (expr.get_lhs ());
- auto rhs = ConstFoldExpr::fold (expr.get_rhs ());
-
- auto op = expr.get_expr_type ();
- auto location = expr.get_locus ();
-
- folded
- = ctx->get_backend ()->arithmetic_or_logical_expression (op, lhs, rhs,
- location);
- }
-
- void visit (HIR::NegationExpr &expr) override
- {
- auto negated_expr = ConstFoldExpr::fold (expr.get_expr ().get ());
-
- auto op = expr.get_expr_type ();
- auto location = expr.get_locus ();
-
- folded
- = ctx->get_backend ()->negation_expression (op, negated_expr, location);
- }
-
- void visit (HIR::ArrayIndexExpr &expr) override
- {
- tree array = ConstFoldExpr::fold (expr.get_array_expr ());
- tree index = ConstFoldExpr::fold (expr.get_index_expr ());
-
- folded = ctx->get_backend ()->array_index_expression (array, index,
- expr.get_locus ());
- }
-
- void visit (HIR::BorrowExpr &expr) override
- {
- tree main_expr = ConstFoldExpr::fold (expr.get_expr ().get ());
-
- folded
- = ctx->get_backend ()->address_expression (main_expr, expr.get_locus ());
- }
-
- void visit (HIR::DereferenceExpr &expr) override
- {
- tree main_expr = ConstFoldExpr::fold (expr.get_expr ().get ());
-
- TyTy::BaseType *tyty = nullptr;
- if (!tyctx->lookup_type (expr.get_mappings ().get_hirid (), &tyty))
- {
- rust_fatal_error (expr.get_locus (),
- "did not resolve type for this TupleExpr");
- return;
- }
-
- tree expected_type = ConstFoldType::fold (tyty, ctx->get_backend ());
- bool known_valid = true;
- folded = ctx->get_backend ()->indirect_expression (expected_type, main_expr,
- known_valid,
- expr.get_locus ());
- }
-
- void visit (HIR::GroupedExpr &expr) override
- {
- folded = ConstFoldExpr::fold (expr.get_expr_in_parens ().get ());
- }
-
-private:
- ConstFoldExpr ()
- : ConstFoldBase (), folded (ctx->get_backend ()->error_expression ())
- {}
-
- tree folded;
-};
-
-} // namespace ConstFold
-} // namespace Rust
-
-#endif // RUST_HIR_CONST_FOLD_H
diff --git a/gcc/rust/typecheck/rust-hir-type-check-enumitem.h b/gcc/rust/typecheck/rust-hir-type-check-enumitem.h
index 4df7df6..f770bed 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-enumitem.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-enumitem.h
@@ -63,28 +63,16 @@ public:
if (capacity_type->get_kind () == TyTy::TypeKind::ERROR)
return;
- TyTy::USizeType *expected_ty
- = new TyTy::USizeType (discriminant->get_mappings ().get_hirid ());
+ TyTy::ISizeType *expected_ty
+ = new TyTy::ISizeType (discriminant->get_mappings ().get_hirid ());
context->insert_type (discriminant->get_mappings (), expected_ty);
auto unified = expected_ty->unify (capacity_type);
if (unified->get_kind () == TyTy::TypeKind::ERROR)
return;
- auto backend = rust_get_backend ();
- auto folded_discriminant
- = ConstFold::ConstFoldExpr::fold (discriminant.get ());
- if (backend->is_error_expression (folded_discriminant))
- return;
-
- size_t specified_discriminant;
- bool ok
- = backend->const_size_cast (folded_discriminant, &specified_discriminant);
- rust_assert (ok);
-
- variant
- = new TyTy::VariantDef (item.get_mappings ().get_hirid (),
- item.get_identifier (), specified_discriminant);
+ variant = new TyTy::VariantDef (item.get_mappings ().get_hirid (),
+ item.get_identifier (), &item);
}
void visit (HIR::EnumItemTuple &item) override
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h
index b636e29..1ac4946 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h
@@ -27,7 +27,6 @@
#include "rust-hir-type-check-struct-field.h"
#include "rust-hir-path-probe.h"
#include "rust-substitution-mapper.h"
-#include "rust-hir-const-fold.h"
#include "rust-hir-trait-resolve.h"
#include "rust-hir-type-bounds.h"
#include "rust-hir-dot-operator.h"
@@ -728,17 +727,17 @@ public:
It is a constant, but for fold it to get a tree. */
std::string capacity_str
= std::to_string (expr.get_literal ().as_string ().size ());
- HIR::LiteralExpr literal_capacity (capacity_mapping, capacity_str,
- HIR::Literal::LitType::INT,
- PrimitiveCoreType::CORETYPE_USIZE,
- expr.get_locus ());
+ HIR::LiteralExpr *literal_capacity
+ = new HIR::LiteralExpr (capacity_mapping, capacity_str,
+ HIR::Literal::LitType::INT,
+ PrimitiveCoreType::CORETYPE_USIZE,
+ expr.get_locus ());
// mark the type for this implicit node
- context->insert_type (capacity_mapping,
- new TyTy::USizeType (
- capacity_mapping.get_hirid ()));
-
- tree capacity = ConstFold::ConstFoldExpr::fold (&literal_capacity);
+ TyTy::BaseType *expected_ty = nullptr;
+ ok = context->lookup_builtin ("usize", &expected_ty);
+ rust_assert (ok);
+ context->insert_type (capacity_mapping, expected_ty);
Analysis::NodeMapping array_mapping (crate_num, UNKNOWN_NODEID,
mappings->get_next_hir_id (
@@ -746,7 +745,8 @@ public:
UNKNOWN_LOCAL_DEFID);
TyTy::ArrayType *array
- = new TyTy::ArrayType (array_mapping.get_hirid (), capacity,
+ = new TyTy::ArrayType (array_mapping.get_hirid (),
+ *literal_capacity,
TyTy::TyVar (u8->get_ref ()));
context->insert_type (array_mapping, array);
@@ -979,77 +979,75 @@ public:
void visit (HIR::ArrayExpr &expr) override
{
- HIR::ArrayElems *elements = expr.get_internal_elements ();
- root_array_expr_locus = expr.get_locus ();
-
- elements->accept_vis (*this);
- if (infered_array_elems == nullptr)
- return;
- if (folded_array_capacity == nullptr)
- return;
+ HIR::ArrayElems &elements = *expr.get_internal_elements ();
- infered
- = new TyTy::ArrayType (expr.get_mappings ().get_hirid (),
- folded_array_capacity,
- TyTy::TyVar (infered_array_elems->get_ref ()));
- }
-
- void visit (HIR::ArrayElemsValues &elems) override
- {
- std::vector<TyTy::BaseType *> types;
-
- for (auto &elem : elems.get_values ())
+ HIR::Expr *capacity_expr = nullptr;
+ TyTy::BaseType *element_type = nullptr;
+ switch (elements.get_array_expr_type ())
{
- types.push_back (TypeCheckExpr::Resolve (elem.get (), false));
- }
+ case HIR::ArrayElems::ArrayExprType::COPIED: {
+ HIR::ArrayElemsCopied &elems
+ = static_cast<HIR::ArrayElemsCopied &> (elements);
+ element_type
+ = TypeCheckExpr::Resolve (elems.get_elem_to_copy (), false);
- infered_array_elems
- = TyTy::TyVar::get_implicit_infer_var (root_array_expr_locus).get_tyty ();
+ auto capacity_type
+ = TypeCheckExpr::Resolve (elems.get_num_copies_expr (), false);
- for (auto &type : types)
- {
- infered_array_elems = infered_array_elems->unify (type);
- }
- for (auto &elem : types)
- {
- infered_array_elems->append_reference (elem->get_ref ());
- }
+ TyTy::BaseType *expected_ty = nullptr;
+ bool ok = context->lookup_builtin ("usize", &expected_ty);
+ rust_assert (ok);
+ context->insert_type (elems.get_num_copies_expr ()->get_mappings (),
+ expected_ty);
- auto crate_num = mappings->get_current_crate ();
- Analysis::NodeMapping mapping (crate_num, UNKNOWN_NODEID,
- mappings->get_next_hir_id (crate_num),
- UNKNOWN_LOCAL_DEFID);
- std::string capacity_str = std::to_string (elems.get_num_elements ());
- HIR::LiteralExpr implicit_literal_capacity (
- mapping, capacity_str, HIR::Literal::LitType::INT,
- PrimitiveCoreType::CORETYPE_USIZE, Location ());
+ auto unified = expected_ty->unify (capacity_type);
+ if (unified->get_kind () == TyTy::TypeKind::ERROR)
+ return;
- // mark the type for this implicit node
- context->insert_type (mapping, new TyTy::USizeType (mapping.get_hirid ()));
+ capacity_expr = elems.get_num_copies_expr ();
+ }
+ break;
- folded_array_capacity
- = ConstFold::ConstFoldExpr::fold (&implicit_literal_capacity);
- }
+ case HIR::ArrayElems::ArrayExprType::VALUES: {
+ HIR::ArrayElemsValues &elems
+ = static_cast<HIR::ArrayElemsValues &> (elements);
- void visit (HIR::ArrayElemsCopied &elems) override
- {
- auto capacity_type
- = TypeCheckExpr::Resolve (elems.get_num_copies_expr (), false);
+ std::vector<TyTy::BaseType *> types;
+ for (auto &elem : elems.get_values ())
+ {
+ types.push_back (TypeCheckExpr::Resolve (elem.get (), false));
+ }
- TyTy::USizeType *expected_ty = new TyTy::USizeType (
- elems.get_num_copies_expr ()->get_mappings ().get_hirid ());
- context->insert_type (elems.get_num_copies_expr ()->get_mappings (),
- expected_ty);
+ element_type = TyTy::TyVar::get_implicit_infer_var (expr.get_locus ())
+ .get_tyty ();
+ for (auto &type : types)
+ {
+ element_type = element_type->unify (type);
+ }
- auto unified = expected_ty->unify (capacity_type);
- if (unified->get_kind () == TyTy::TypeKind::ERROR)
- return;
+ auto crate_num = mappings->get_current_crate ();
+ Analysis::NodeMapping mapping (crate_num, UNKNOWN_NODEID,
+ mappings->get_next_hir_id (crate_num),
+ UNKNOWN_LOCAL_DEFID);
+ std::string capacity_str = std::to_string (elems.get_num_elements ());
+ capacity_expr
+ = new HIR::LiteralExpr (mapping, capacity_str,
+ HIR::Literal::LitType::INT,
+ PrimitiveCoreType::CORETYPE_USIZE,
+ Location ());
- folded_array_capacity
- = ConstFold::ConstFoldExpr::fold (elems.get_num_copies_expr ());
+ // mark the type for this implicit node
+ TyTy::BaseType *expected_ty = nullptr;
+ bool ok = context->lookup_builtin ("usize", &expected_ty);
+ rust_assert (ok);
+ context->insert_type (mapping, expected_ty);
+ }
+ break;
+ }
- infered_array_elems
- = TypeCheckExpr::Resolve (elems.get_elem_to_copy (), false);
+ infered
+ = new TyTy::ArrayType (expr.get_mappings ().get_hirid (), *capacity_expr,
+ TyTy::TyVar (element_type->get_ref ()));
}
// empty struct
@@ -1547,8 +1545,7 @@ protected:
private:
TypeCheckExpr (bool inside_loop)
- : TypeCheckBase (), infered (nullptr), infered_array_elems (nullptr),
- folded_array_capacity (nullptr), inside_loop (inside_loop)
+ : TypeCheckBase (), infered (nullptr), inside_loop (inside_loop)
{}
// Beware: currently returns Tyty::ErrorType or nullptr in case of error.
@@ -1617,14 +1614,8 @@ private:
/* The return value of TypeCheckExpr::Resolve */
TyTy::BaseType *infered;
- /* The return value of visit(ArrayElemsValues&) and visit(ArrayElemsCopied&)
- Stores the type of array elements, if `expr` is ArrayExpr. */
- TyTy::BaseType *infered_array_elems;
- tree folded_array_capacity;
- Location root_array_expr_locus;
-
bool inside_loop;
-}; // namespace Resolver
+};
} // namespace Resolver
} // namespace Rust
diff --git a/gcc/rust/typecheck/rust-hir-type-check-implitem.h b/gcc/rust/typecheck/rust-hir-type-check-implitem.h
index a860608..25b592c 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-implitem.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-implitem.h
@@ -170,9 +170,6 @@ public:
= TypeCheckExpr::Resolve (constant.get_expr (), false);
context->insert_type (constant.get_mappings (), type->unify (expr_type));
-
- // notify the constant folder of this
- ConstFold::ConstFoldItem::fold (constant);
}
void visit (HIR::Function &function) override
diff --git a/gcc/rust/typecheck/rust-hir-type-check-stmt.h b/gcc/rust/typecheck/rust-hir-type-check-stmt.h
index fb0e047..22b6f3f 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-stmt.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-stmt.h
@@ -64,9 +64,6 @@ public:
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
@@ -98,7 +95,7 @@ public:
if (unified_ty->get_kind () == TyTy::TypeKind::ERROR)
return;
- context->insert_type (stmt.get_mappings (), unified_ty);
+ context->insert_type (stmt.get_mappings (), specified_ty);
}
else
{
diff --git a/gcc/rust/typecheck/rust-hir-type-check-toplevel.h b/gcc/rust/typecheck/rust-hir-type-check-toplevel.h
index 7b1dfc9..3733e429 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-toplevel.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-toplevel.h
@@ -315,9 +315,6 @@ public:
= TypeCheckExpr::Resolve (constant.get_expr (), false);
context->insert_type (constant.get_mappings (), type->unify (expr_type));
-
- // notify the constant folder of this
- ConstFold::ConstFoldItem::fold (constant);
}
void visit (HIR::Function &function) override
diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.cc b/gcc/rust/typecheck/rust-hir-type-check-type.cc
index cfe9652..93f46e6 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-type.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-type.cc
@@ -18,6 +18,7 @@
#include "rust-hir-type-check-type.h"
#include "rust-hir-trait-resolve.h"
+#include "rust-hir-type-check-expr.h"
namespace Rust {
namespace Resolver {
@@ -575,5 +576,27 @@ TypeCheckType::visit (HIR::TraitObjectType &type)
std::move (specified_bounds));
}
+void
+TypeCheckType::visit (HIR::ArrayType &type)
+{
+ auto capacity_type = TypeCheckExpr::Resolve (type.get_size_expr (), false);
+ if (capacity_type->get_kind () == TyTy::TypeKind::ERROR)
+ return;
+
+ TyTy::BaseType *expected_ty = nullptr;
+ bool ok = context->lookup_builtin ("usize", &expected_ty);
+ rust_assert (ok);
+ context->insert_type (type.get_size_expr ()->get_mappings (), expected_ty);
+
+ auto unified = expected_ty->unify (capacity_type);
+ if (unified->get_kind () == TyTy::TypeKind::ERROR)
+ return;
+
+ TyTy::BaseType *base = TypeCheckType::Resolve (type.get_element_type ());
+ translated = new TyTy::ArrayType (type.get_mappings ().get_hirid (),
+ *type.get_size_expr (),
+ TyTy::TyVar (base->get_ref ()));
+}
+
} // namespace Resolver
} // namespace Rust
diff --git a/gcc/rust/typecheck/rust-hir-type-check.cc b/gcc/rust/typecheck/rust-hir-type-check.cc
index d2da20e..ccde21a 100644
--- a/gcc/rust/typecheck/rust-hir-type-check.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check.cc
@@ -23,7 +23,6 @@
#include "rust-hir-type-check-expr.h"
#include "rust-hir-type-check-struct-field.h"
#include "rust-hir-inherent-impl-overlap.h"
-#include "rust-hir-const-fold.h"
extern bool
saw_errors (void);
@@ -135,28 +134,6 @@ TypeCheckExpr::visit (HIR::BlockExpr &expr)
infered = new TyTy::NeverType (expr.get_mappings ().get_hirid ());
}
-void
-TypeCheckType::visit (HIR::ArrayType &type)
-{
- auto capacity_type = TypeCheckExpr::Resolve (type.get_size_expr (), false);
- if (capacity_type->get_kind () == TyTy::TypeKind::ERROR)
- return;
-
- TyTy::USizeType *expected_ty
- = new TyTy::USizeType (type.get_size_expr ()->get_mappings ().get_hirid ());
- context->insert_type (type.get_size_expr ()->get_mappings (), expected_ty);
-
- auto unified = expected_ty->unify (capacity_type);
- if (unified->get_kind () == TyTy::TypeKind::ERROR)
- return;
-
- auto capacity = ConstFold::ConstFoldExpr::fold (type.get_size_expr ());
-
- TyTy::BaseType *base = TypeCheckType::Resolve (type.get_element_type ());
- translated = new TyTy::ArrayType (type.get_mappings ().get_hirid (), capacity,
- TyTy::TyVar (base->get_ref ()));
-}
-
// rust-hir-trait-ref.h
TraitItemReference::TraitItemReference (
diff --git a/gcc/rust/typecheck/rust-tyty-cast.h b/gcc/rust/typecheck/rust-tyty-cast.h
index 07fedd0..6036a75 100644
--- a/gcc/rust/typecheck/rust-tyty-cast.h
+++ b/gcc/rust/typecheck/rust-tyty-cast.h
@@ -806,19 +806,9 @@ public:
return;
}
- auto backend = rust_get_backend ();
-
- // need to check the base types and capacity
- if (!backend->const_values_equal (type.get_capacity (),
- base->get_capacity ()))
- {
- BaseCastRules::visit (type);
- return;
- }
-
- resolved
- = new ArrayType (type.get_ref (), type.get_ty_ref (),
- type.get_capacity (), TyVar (base_resolved->get_ref ()));
+ resolved = new ArrayType (type.get_ref (), type.get_ty_ref (),
+ type.get_capacity_expr (),
+ TyVar (base_resolved->get_ref ()));
}
private:
diff --git a/gcc/rust/typecheck/rust-tyty-cmp.h b/gcc/rust/typecheck/rust-tyty-cmp.h
index 291e590..6347530 100644
--- a/gcc/rust/typecheck/rust-tyty-cmp.h
+++ b/gcc/rust/typecheck/rust-tyty-cmp.h
@@ -851,13 +851,6 @@ public:
void visit (const ArrayType &type) override
{
- // need to check the base types and capacity
- if (type.get_capacity () != base->get_capacity ())
- {
- BaseCmp::visit (type);
- return;
- }
-
// check base type
const BaseType *base_element = base->get_element_type ();
const BaseType *other_element = type.get_element_type ();
diff --git a/gcc/rust/typecheck/rust-tyty-coercion.h b/gcc/rust/typecheck/rust-tyty-coercion.h
index b483130..25f6810 100644
--- a/gcc/rust/typecheck/rust-tyty-coercion.h
+++ b/gcc/rust/typecheck/rust-tyty-coercion.h
@@ -824,19 +824,9 @@ public:
return;
}
- auto backend = rust_get_backend ();
-
- // need to check the base types and capacity
- if (!backend->const_values_equal (type.get_capacity (),
- base->get_capacity ()))
- {
- BaseCoercionRules::visit (type);
- return;
- }
-
- resolved
- = new ArrayType (type.get_ref (), type.get_ty_ref (),
- type.get_capacity (), TyVar (base_resolved->get_ref ()));
+ resolved = new ArrayType (type.get_ref (), type.get_ty_ref (),
+ type.get_capacity_expr (),
+ TyVar (base_resolved->get_ref ()));
}
private:
diff --git a/gcc/rust/typecheck/rust-tyty-rules.h b/gcc/rust/typecheck/rust-tyty-rules.h
index 5dc2d2f..450a93f 100644
--- a/gcc/rust/typecheck/rust-tyty-rules.h
+++ b/gcc/rust/typecheck/rust-tyty-rules.h
@@ -841,19 +841,9 @@ public:
return;
}
- auto backend = rust_get_backend ();
-
- // need to check the base types and capacity
- if (!backend->const_values_equal (type.get_capacity (),
- base->get_capacity ()))
- {
- BaseRules::visit (type);
- return;
- }
-
- resolved
- = new ArrayType (type.get_ref (), type.get_ty_ref (),
- type.get_capacity (), TyVar (base_resolved->get_ref ()));
+ resolved = new ArrayType (type.get_ref (), type.get_ty_ref (),
+ type.get_capacity_expr (),
+ TyVar (base_resolved->get_ref ()));
}
private:
diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc
index f141a41..679187b 100644
--- a/gcc/rust/typecheck/rust-tyty.cc
+++ b/gcc/rust/typecheck/rust-tyty.cc
@@ -1335,14 +1335,7 @@ ArrayType::accept_vis (TyConstVisitor &vis) const
std::string
ArrayType::as_string () const
{
- return "[" + get_element_type ()->as_string () + ":" + capacity_string ()
- + "]";
-}
-
-std::string
-ArrayType::capacity_string () const
-{
- return rust_get_backend ()->const_size_val_to_string (get_capacity ());
+ return "[" + get_element_type ()->as_string () + ":" + "CAPACITY" + "]";
}
BaseType *
@@ -1381,8 +1374,6 @@ ArrayType::is_equal (const BaseType &other) const
return false;
auto other2 = static_cast<const ArrayType &> (other);
- if (get_capacity () != other2.get_capacity ())
- return false;
auto this_element_type = get_element_type ();
auto other_element_type = other2.get_element_type ();
@@ -1399,8 +1390,8 @@ ArrayType::get_element_type () const
BaseType *
ArrayType::clone () const
{
- return new ArrayType (get_ref (), get_ty_ref (), get_capacity (),
- element_type, get_combined_refs ());
+ return new ArrayType (get_ref (), get_ty_ref (), capacity_expr, element_type,
+ get_combined_refs ());
}
void
diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h
index 40c06a5..bdf85a9 100644
--- a/gcc/rust/typecheck/rust-tyty.h
+++ b/gcc/rust/typecheck/rust-tyty.h
@@ -19,12 +19,12 @@
#ifndef RUST_TYTY
#define RUST_TYTY
-#include "rust-backend.h"
#include "rust-hir-map.h"
#include "rust-hir-full.h"
#include "rust-diagnostics.h"
#include "rust-abi.h"
#include "rust-common.h"
+#include "tree.h"
namespace Rust {
@@ -1034,7 +1034,16 @@ public:
}
VariantDef (HirId id, std::string identifier, int discriminant)
- : id (id), identifier (identifier), discriminant (discriminant)
+ : id (id), identifier (identifier), discriminant (discriminant),
+ discriminant_node (nullptr)
+ {
+ type = VariantType::NUM;
+ fields = {};
+ }
+
+ VariantDef (HirId id, std::string identifier,
+ HIR::EnumItemDiscriminant *discriminant)
+ : id (id), identifier (identifier), discriminant_node (discriminant)
{
type = VariantType::NUM;
fields = {};
@@ -1042,7 +1051,8 @@ public:
VariantDef (HirId id, std::string identifier, VariantType type,
std::vector<StructFieldType *> fields)
- : id (id), identifier (identifier), type (type), fields (fields)
+ : id (id), identifier (identifier), type (type), fields (fields),
+ discriminant_node (nullptr)
{
discriminant = 0;
rust_assert (type == VariantType::TUPLE || type == VariantType::STRUCT);
@@ -1073,7 +1083,12 @@ public:
bool is_dataless_variant () const { return type == VariantType::NUM; }
std::string get_identifier () const { return identifier; }
- int get_discriminant () const { return discriminant; }
+
+ int get_discriminant () const
+ {
+ rust_assert (!is_specified_discriminant_node ());
+ return discriminant;
+ }
size_t num_fields () const { return fields.size (); }
StructFieldType *get_field_at_index (size_t index)
@@ -1109,6 +1124,17 @@ public:
return false;
}
+ bool is_specified_discriminant_node () const
+ {
+ return discriminant_node != nullptr;
+ }
+
+ HIR::EnumItemDiscriminant *get_discriminant_node () const
+ {
+ rust_assert (is_specified_discriminant_node ());
+ return discriminant_node;
+ }
+
std::string as_string () const
{
if (type == VariantType::NUM)
@@ -1166,6 +1192,7 @@ private:
VariantType type;
int discriminant; /* Either discriminant or fields are valid. */
std::vector<StructFieldType *> fields;
+ HIR::EnumItemDiscriminant *discriminant_node;
};
class ADTType : public BaseType, public SubstitutionRef
@@ -1595,16 +1622,16 @@ private:
class ArrayType : public BaseType
{
public:
- ArrayType (HirId ref, tree capacity, TyVar base,
+ ArrayType (HirId ref, HIR::Expr &capacity_expr, TyVar base,
std::set<HirId> refs = std::set<HirId> ())
- : BaseType (ref, ref, TypeKind::ARRAY, refs), capacity (capacity),
- element_type (base)
+ : BaseType (ref, ref, TypeKind::ARRAY, refs), element_type (base),
+ capacity_expr (capacity_expr)
{}
- ArrayType (HirId ref, HirId ty_ref, tree capacity, TyVar base,
+ ArrayType (HirId ref, HirId ty_ref, HIR::Expr &capacity_expr, TyVar base,
std::set<HirId> refs = std::set<HirId> ())
- : BaseType (ref, ty_ref, TypeKind::ARRAY, refs), capacity (capacity),
- element_type (base)
+ : BaseType (ref, ty_ref, TypeKind::ARRAY, refs), element_type (base),
+ capacity_expr (capacity_expr)
{}
void accept_vis (TyVisitor &vis) override;
@@ -1622,9 +1649,6 @@ public:
bool is_equal (const BaseType &other) const override;
- tree get_capacity () const { return capacity; }
- std::string capacity_string () const;
-
BaseType *get_element_type () const;
BaseType *clone () const final override;
@@ -1634,9 +1658,11 @@ public:
return get_element_type ()->is_concrete ();
}
+ HIR::Expr &get_capacity_expr () const { return capacity_expr; }
+
private:
- tree capacity;
TyVar element_type;
+ HIR::Expr &capacity_expr;
};
class BoolType : public BaseType
diff --git a/gcc/testsuite/rust/compile/arrays2.rs b/gcc/testsuite/rust/compile/arrays2.rs
index 9c788db..c96f4f7d 100644
--- a/gcc/testsuite/rust/compile/arrays2.rs
+++ b/gcc/testsuite/rust/compile/arrays2.rs
@@ -1,4 +1,5 @@
+// { dg-additional-options "-w" }
fn main() {
let array: [i32; 5] = [1, 2, 3];
- // { dg-error "expected ..i32:5.. got ..i32:3.." "" { target *-*-* } .-1 }
+ // { dg-error "expected an array with a fixed size of 5 elements, found one with 3 elements" "" { target *-*-* } .-1 }
}
diff --git a/gcc/testsuite/rust/execute/torture/const_fold1.rs b/gcc/testsuite/rust/execute/torture/const_fold1.rs
new file mode 100644
index 0000000..3cd6c0c
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/const_fold1.rs
@@ -0,0 +1,13 @@
+// { dg-additional-options "-w" }
+const fn const_fn() -> usize {
+ 4
+}
+
+const FN_TEST: usize = const_fn();
+
+const TEST: usize = 2 + FN_TEST;
+
+fn main() -> i32 {
+ let a: [_; 12] = [5; TEST * 2];
+ a[6] - 5
+}