diff options
author | Philip Herron <herron.philip@googlemail.com> | 2023-05-05 19:06:37 +0100 |
---|---|---|
committer | Arthur Cohen <arthur.cohen@embecosm.com> | 2024-01-16 18:37:15 +0100 |
commit | cf046027a23df64ed46ade5ae4a5c9d77ea191ab (patch) | |
tree | ab8bacf59c17455cdc4c6844c367d4cb4220d2aa /gcc/rust/backend | |
parent | c6f1b887e8f52ba6252ad83e03cbea41af326f6e (diff) | |
download | gcc-cf046027a23df64ed46ade5ae4a5c9d77ea191ab.zip gcc-cf046027a23df64ed46ade5ae4a5c9d77ea191ab.tar.gz gcc-cf046027a23df64ed46ade5ae4a5c9d77ea191ab.tar.bz2 |
gccrs: Redo how we handle unit types for the final time
We had a very inconsistant way for dealing with unit-types in gccrs we
tried to optimize the case for a function returning unit type to be clever
and not emit any return value for unit types. Then for other cases we would
use an empty constructor for an empty tuple and in others use a zero
percsion integer. This was all just confusing and made the IR less
conformant to Rust. In this patch I change all of this to use an empty
tuple type for all cases so we pass around {} which maps over to Rust and
gets optimized away in the middle end anyway.
In the patch we also remove old gccgo code which optimizes away zero
size types to void_type_node which is why my original attempt at doing this
two years ago failed.
Fixes #2188
gcc/rust/ChangeLog:
* backend/rust-compile-base.cc (HIRCompileBase::compile_function_body): use unit_expression
(HIRCompileBase::unit_expression): new helper
* backend/rust-compile-base.h: update prototype
* backend/rust-compile-block.cc (CompileBlock::visit): use unit_expression
* backend/rust-compile-expr.cc (CompileExpr::visit): likewise
(CompileExpr::generate_closure_function): likewise
* backend/rust-compile-implitem.cc (CompileTraitItem::visit): cleanup
* backend/rust-compile-item.cc (CompileItem::visit): likewise
* backend/rust-compile-pattern.cc (CompilePatternLet::visit): likewise
* backend/rust-compile-resolve-path.cc (ResolvePathRef::resolve): likewise
* backend/rust-compile-type.cc (TyTyResolveCompile::get_unit_type): new helper
(TyTyResolveCompile::visit): use new unit_type helper
* backend/rust-compile-type.h: likewise
* rust-backend.h: simplify the return_expression
* rust-gcc.cc (Gcc_backend::function_type): likewise
(Gcc_backend::return_statement): likewise
* backend/rust-constexpr.cc (eval_constant_expression): remove bad assertion
gcc/testsuite/ChangeLog:
* rust/compile/issue-2188.rs: New test.
Signed-off-by: Philip Herron <herron.philip@googlemail.com>
Diffstat (limited to 'gcc/rust/backend')
-rw-r--r-- | gcc/rust/backend/rust-compile-base.cc | 103 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-base.h | 34 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-block.cc | 41 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-expr.cc | 149 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-implitem.cc | 13 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-item.cc | 10 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-pattern.cc | 6 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-resolve-path.cc | 6 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-type.cc | 31 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-type.h | 2 | ||||
-rw-r--r-- | gcc/rust/backend/rust-constexpr.cc | 1 |
11 files changed, 193 insertions, 203 deletions
diff --git a/gcc/rust/backend/rust-compile-base.cc b/gcc/rust/backend/rust-compile-base.cc index 60ae25c..70147a3 100644 --- a/gcc/rust/backend/rust-compile-base.cc +++ b/gcc/rust/backend/rust-compile-base.cc @@ -35,6 +35,7 @@ #include "stringpool.h" #include "attribs.h" #include "tree.h" +#include "print-tree.h" namespace Rust { namespace Compile { @@ -466,9 +467,9 @@ HIRCompileBase::compile_locals_for_block (Context *ctx, Resolver::Rib &rib, } void -HIRCompileBase::compile_function_body (Context *ctx, tree fndecl, +HIRCompileBase::compile_function_body (tree fndecl, HIR::BlockExpr &function_body, - bool has_return_type) + TyTy::BaseType *fn_return_ty) { for (auto &s : function_body.get_statements ()) { @@ -482,40 +483,48 @@ HIRCompileBase::compile_function_body (Context *ctx, tree fndecl, if (function_body.has_expr ()) { - // the previous passes will ensure this is a valid return - // or a valid trailing expression - tree compiled_expr - = CompileExpr::Compile (function_body.expr.get (), ctx); + Location locus = function_body.get_final_expr ()->get_locus (); + tree return_value = CompileExpr::Compile (function_body.expr.get (), ctx); - if (compiled_expr != nullptr) + // we can only return this if non unit value return type + if (!fn_return_ty->is_unit ()) { - if (has_return_type) - { - std::vector<tree> retstmts; - retstmts.push_back (compiled_expr); - - auto ret = ctx->get_backend ()->return_statement ( - fndecl, retstmts, - function_body.get_final_expr ()->get_locus ()); - ctx->add_statement (ret); - } - else - { - // FIXME can this actually happen? - ctx->add_statement (compiled_expr); - } + tree return_stmt + = ctx->get_backend ()->return_statement (fndecl, return_value, + locus); + ctx->add_statement (return_stmt); } + else + { + // just add the stmt expression + ctx->add_statement (return_value); + + // now just return unit expression + tree unit_expr = unit_expression (ctx, locus); + tree return_stmt + = ctx->get_backend ()->return_statement (fndecl, unit_expr, locus); + ctx->add_statement (return_stmt); + } + } + else if (fn_return_ty->is_unit ()) + { + // we can only do this if the function is of unit type otherwise other + // errors should have occurred + Location locus = function_body.get_locus (); + tree return_value = unit_expression (ctx, locus); + tree return_stmt + = ctx->get_backend ()->return_statement (fndecl, return_value, locus); + ctx->add_statement (return_stmt); } } tree HIRCompileBase::compile_function ( - Context *ctx, const std::string &fn_name, HIR::SelfParam &self_param, + const std::string &fn_name, HIR::SelfParam &self_param, std::vector<HIR::FunctionParam> &function_params, const HIR::FunctionQualifiers &qualifiers, HIR::Visibility &visibility, AST::AttrVec &outer_attrs, Location locus, HIR::BlockExpr *function_body, - const Resolver::CanonicalPath *canonical_path, TyTy::FnType *fntype, - bool function_has_return) + const Resolver::CanonicalPath *canonical_path, TyTy::FnType *fntype) { tree compiled_fn_type = TyTyResolveCompile::compile (ctx, fntype); std::string ir_symbol_name @@ -606,24 +615,19 @@ HIRCompileBase::compile_function ( ctx->push_block (code_block); Bvariable *return_address = nullptr; - if (function_has_return) - { - tree return_type = TyTyResolveCompile::compile (ctx, tyret); - - bool address_is_taken = false; - tree ret_var_stmt = NULL_TREE; + tree return_type = TyTyResolveCompile::compile (ctx, tyret); - return_address - = ctx->get_backend ()->temporary_variable (fndecl, code_block, - return_type, NULL, - address_is_taken, locus, - &ret_var_stmt); + bool address_is_taken = false; + tree ret_var_stmt = NULL_TREE; + return_address + = ctx->get_backend ()->temporary_variable (fndecl, code_block, return_type, + NULL, address_is_taken, locus, + &ret_var_stmt); - ctx->add_statement (ret_var_stmt); - } + ctx->add_statement (ret_var_stmt); ctx->push_fn (fndecl, return_address); - compile_function_body (ctx, fndecl, *function_body, function_has_return); + compile_function_body (fndecl, *function_body, tyret); tree bind_tree = ctx->pop_block (); gcc_assert (TREE_CODE (bind_tree) == BIND_EXPR); @@ -642,14 +646,13 @@ HIRCompileBase::compile_function ( tree HIRCompileBase::compile_constant_item ( - Context *ctx, TyTy::BaseType *resolved_type, - const Resolver::CanonicalPath *canonical_path, HIR::Expr *const_value_expr, - Location locus) + TyTy::BaseType *resolved_type, const Resolver::CanonicalPath *canonical_path, + HIR::Expr *const_value_expr, Location locus) { const std::string &ident = canonical_path->get (); + tree type = TyTyResolveCompile::compile (ctx, resolved_type); tree const_type = build_qualified_type (type, TYPE_QUAL_CONST); - bool is_block_expr = const_value_expr->get_expression_type () == HIR::Expr::ExprType::Block; @@ -661,7 +664,6 @@ HIRCompileBase::compile_constant_item ( tree compiled_fn_type = ctx->get_backend ()->function_type ( receiver, {}, {Backend::typed_identifier ("_", const_type, locus)}, NULL, locus); - tree fndecl = ctx->get_backend ()->function (compiled_fn_type, ident, "", 0, locus); TREE_READONLY (fndecl) = 1; @@ -703,13 +705,14 @@ HIRCompileBase::compile_constant_item ( { HIR::BlockExpr *function_body = static_cast<HIR::BlockExpr *> (const_value_expr); - compile_function_body (ctx, fndecl, *function_body, true); + compile_function_body (fndecl, *function_body, resolved_type); } else { tree value = CompileExpr::Compile (const_value_expr, ctx); + tree return_expr = ctx->get_backend ()->return_statement ( - fndecl, {value}, const_value_expr->get_locus ()); + fndecl, value, const_value_expr->get_locus ()); ctx->add_statement (return_expr); } @@ -831,5 +834,13 @@ HIRCompileBase::resolve_method_address ( return CompileInherentImplItem::Compile (impl_item, ctx, monomorphized); } +tree +HIRCompileBase::unit_expression (Context *ctx, Location locus) +{ + tree unit_type = TyTyResolveCompile::get_unit_type (ctx); + return ctx->get_backend ()->constructor_expression (unit_type, false, {}, -1, + locus); +} + } // namespace Compile } // namespace Rust diff --git a/gcc/rust/backend/rust-compile-base.h b/gcc/rust/backend/rust-compile-base.h index 7a5c9cb..db47c0f 100644 --- a/gcc/rust/backend/rust-compile-base.h +++ b/gcc/rust/backend/rust-compile-base.h @@ -86,6 +86,23 @@ protected: const Analysis::NodeMapping &expr_mappings, Location expr_locus); + void compile_function_body (tree fndecl, HIR::BlockExpr &function_body, + TyTy::BaseType *fn_return_ty); + + tree compile_constant_item (TyTy::BaseType *resolved_type, + const Resolver::CanonicalPath *canonical_path, + HIR::Expr *const_value_expr, Location locus); + + tree compile_function (const std::string &fn_name, HIR::SelfParam &self_param, + std::vector<HIR::FunctionParam> &function_params, + const HIR::FunctionQualifiers &qualifiers, + HIR::Visibility &visibility, AST::AttrVec &outer_attrs, + Location locus, HIR::BlockExpr *function_body, + const Resolver::CanonicalPath *canonical_path, + TyTy::FnType *fntype); + + static tree unit_expression (Context *ctx, Location locus); + static void setup_fndecl (tree fndecl, bool is_main_entry_point, bool is_generic_fn, HIR::Visibility &visibility, const HIR::FunctionQualifiers &qualifiers, @@ -121,23 +138,6 @@ protected: static std::vector<Bvariable *> compile_locals_for_block (Context *ctx, Resolver::Rib &rib, tree fndecl); - static void compile_function_body (Context *ctx, tree fndecl, - HIR::BlockExpr &function_body, - bool has_return_type); - - static tree compile_function ( - Context *ctx, const std::string &fn_name, HIR::SelfParam &self_param, - std::vector<HIR::FunctionParam> &function_params, - const HIR::FunctionQualifiers &qualifiers, HIR::Visibility &visibility, - AST::AttrVec &outer_attrs, Location locus, HIR::BlockExpr *function_body, - const Resolver::CanonicalPath *canonical_path, TyTy::FnType *fntype, - bool function_has_return); - - static tree - compile_constant_item (Context *ctx, TyTy::BaseType *resolved_type, - const Resolver::CanonicalPath *canonical_path, - HIR::Expr *const_value_expr, Location locus); - static tree named_constant_expression (tree type_tree, const std::string &name, tree const_val, Location location); diff --git a/gcc/rust/backend/rust-compile-block.cc b/gcc/rust/backend/rust-compile-block.cc index 470ece2..5591d95 100644 --- a/gcc/rust/backend/rust-compile-block.cc +++ b/gcc/rust/backend/rust-compile-block.cc @@ -71,28 +71,33 @@ CompileBlock::visit (HIR::BlockExpr &expr) if (expr.has_expr ()) { - // the previous passes will ensure this is a valid return or - // a valid trailing expression tree compiled_expr = CompileExpr::Compile (expr.expr.get (), ctx); - if (compiled_expr != nullptr) + if (result != nullptr) { - if (result == nullptr) - { - ctx->add_statement (compiled_expr); - } - else - { - tree result_reference = ctx->get_backend ()->var_expression ( - result, expr.get_final_expr ()->get_locus ()); - - tree assignment - = ctx->get_backend ()->assignment_statement (result_reference, - compiled_expr, - expr.get_locus ()); - ctx->add_statement (assignment); - } + Location locus = expr.get_final_expr ()->get_locus (); + tree result_reference + = ctx->get_backend ()->var_expression (result, locus); + + tree assignment + = ctx->get_backend ()->assignment_statement (result_reference, + compiled_expr, + expr.get_locus ()); + ctx->add_statement (assignment); } } + else if (result != nullptr) + { + Location locus = expr.get_locus (); + tree compiled_expr = unit_expression (ctx, expr.get_locus ()); + tree result_reference + = ctx->get_backend ()->var_expression (result, locus); + + tree assignment + = ctx->get_backend ()->assignment_statement (result_reference, + compiled_expr, + expr.get_locus ()); + ctx->add_statement (assignment); + } ctx->pop_block (); translated = new_block; diff --git a/gcc/rust/backend/rust-compile-expr.cc b/gcc/rust/backend/rust-compile-expr.cc index e108704..07e5d79 100644 --- a/gcc/rust/backend/rust-compile-expr.cc +++ b/gcc/rust/backend/rust-compile-expr.cc @@ -76,7 +76,7 @@ CompileExpr::visit (HIR::TupleExpr &expr) { if (expr.is_unit ()) { - translated = ctx->get_backend ()->unit_expression (); + translated = unit_expression (ctx, expr.get_locus ()); return; } @@ -110,18 +110,13 @@ CompileExpr::visit (HIR::ReturnExpr &expr) { auto fncontext = ctx->peek_fn (); - std::vector<tree> retstmts; - if (expr.has_return_expr ()) - { - tree compiled_expr = CompileExpr::Compile (expr.return_expr.get (), ctx); - rust_assert (compiled_expr != nullptr); - - retstmts.push_back (compiled_expr); - } - - auto s = ctx->get_backend ()->return_statement (fncontext.fndecl, retstmts, - expr.get_locus ()); - ctx->add_statement (s); + tree return_value = expr.has_return_expr () + ? CompileExpr::Compile (expr.return_expr.get (), ctx) + : unit_expression (ctx, expr.get_locus ()); + tree return_stmt + = ctx->get_backend ()->return_statement (fncontext.fndecl, return_value, + expr.get_locus ()); + ctx->add_statement (return_stmt); } void @@ -318,28 +313,23 @@ CompileExpr::visit (HIR::IfExprConseqElse &expr) } Bvariable *tmp = NULL; - bool needs_temp = !if_type->is_unit (); - if (needs_temp) - { - fncontext fnctx = ctx->peek_fn (); - tree enclosing_scope = ctx->peek_enclosing_scope (); - tree block_type = TyTyResolveCompile::compile (ctx, if_type); + fncontext fnctx = ctx->peek_fn (); + tree enclosing_scope = ctx->peek_enclosing_scope (); + tree block_type = TyTyResolveCompile::compile (ctx, if_type); - bool is_address_taken = false; - tree ret_var_stmt = nullptr; - tmp = ctx->get_backend ()->temporary_variable ( - fnctx.fndecl, enclosing_scope, block_type, NULL, is_address_taken, - expr.get_locus (), &ret_var_stmt); - ctx->add_statement (ret_var_stmt); - } + bool is_address_taken = false; + tree ret_var_stmt = nullptr; + tmp = ctx->get_backend ()->temporary_variable (fnctx.fndecl, enclosing_scope, + block_type, NULL, + is_address_taken, + expr.get_locus (), + &ret_var_stmt); + ctx->add_statement (ret_var_stmt); auto stmt = CompileConditionalBlocks::compile (&expr, ctx, tmp); ctx->add_statement (stmt); - if (tmp != NULL) - { - translated = ctx->get_backend ()->var_expression (tmp, expr.get_locus ()); - } + translated = ctx->get_backend ()->var_expression (tmp, expr.get_locus ()); } void @@ -354,29 +344,24 @@ CompileExpr::visit (HIR::BlockExpr &expr) } Bvariable *tmp = NULL; - bool needs_temp = !block_tyty->is_unit (); - if (needs_temp) - { - fncontext fnctx = ctx->peek_fn (); - tree enclosing_scope = ctx->peek_enclosing_scope (); - tree block_type = TyTyResolveCompile::compile (ctx, block_tyty); + fncontext fnctx = ctx->peek_fn (); + tree enclosing_scope = ctx->peek_enclosing_scope (); + tree block_type = TyTyResolveCompile::compile (ctx, block_tyty); - bool is_address_taken = false; - tree ret_var_stmt = nullptr; - tmp = ctx->get_backend ()->temporary_variable ( - fnctx.fndecl, enclosing_scope, block_type, NULL, is_address_taken, - expr.get_locus (), &ret_var_stmt); - ctx->add_statement (ret_var_stmt); - } + bool is_address_taken = false; + tree ret_var_stmt = nullptr; + tmp = ctx->get_backend ()->temporary_variable (fnctx.fndecl, enclosing_scope, + block_type, NULL, + is_address_taken, + expr.get_locus (), + &ret_var_stmt); + ctx->add_statement (ret_var_stmt); auto block_stmt = CompileBlock::compile (&expr, ctx, tmp); rust_assert (TREE_CODE (block_stmt) == BIND_EXPR); ctx->add_statement (block_stmt); - if (tmp != NULL) - { - translated = ctx->get_backend ()->var_expression (tmp, expr.get_locus ()); - } + translated = ctx->get_backend ()->var_expression (tmp, expr.get_locus ()); } void @@ -397,7 +382,7 @@ CompileExpr::visit (HIR::StructExprStruct &struct_expr) } rust_assert (tyty->is_unit ()); - translated = ctx->get_backend ()->unit_expression (); + translated = unit_expression (ctx, struct_expr.get_locus ()); } void @@ -1318,19 +1303,17 @@ CompileExpr::visit (HIR::MatchExpr &expr) fncontext fnctx = ctx->peek_fn (); Bvariable *tmp = NULL; - bool needs_temp = !expr_tyty->is_unit (); - if (needs_temp) - { - tree enclosing_scope = ctx->peek_enclosing_scope (); - tree block_type = TyTyResolveCompile::compile (ctx, expr_tyty); + tree enclosing_scope = ctx->peek_enclosing_scope (); + tree block_type = TyTyResolveCompile::compile (ctx, expr_tyty); - bool is_address_taken = false; - tree ret_var_stmt = nullptr; - tmp = ctx->get_backend ()->temporary_variable ( - fnctx.fndecl, enclosing_scope, block_type, NULL, is_address_taken, - expr.get_locus (), &ret_var_stmt); - ctx->add_statement (ret_var_stmt); - } + bool is_address_taken = false; + tree ret_var_stmt = nullptr; + tmp = ctx->get_backend ()->temporary_variable (fnctx.fndecl, enclosing_scope, + block_type, NULL, + is_address_taken, + expr.get_locus (), + &ret_var_stmt); + ctx->add_statement (ret_var_stmt); // lets compile the scrutinee expression tree match_scrutinee_expr @@ -1450,7 +1433,6 @@ CompileExpr::visit (HIR::MatchExpr &expr) // setup the switch-body-block Location start_location; // FIXME Location end_location; // FIXME - tree enclosing_scope = ctx->peek_enclosing_scope (); tree switch_body_block = ctx->get_backend ()->block (fndecl, enclosing_scope, {}, start_location, end_location); @@ -1481,16 +1463,12 @@ CompileExpr::visit (HIR::MatchExpr &expr) // compile the expr and setup the assignment if required when tmp != NULL tree kase_expr_tree = CompileExpr::Compile (kase.get_expr ().get (), ctx); - if (tmp != NULL) - { - tree result_reference - = ctx->get_backend ()->var_expression (tmp, arm_locus); - tree assignment - = ctx->get_backend ()->assignment_statement (result_reference, - kase_expr_tree, - arm_locus); - ctx->add_statement (assignment); - } + tree result_reference + = ctx->get_backend ()->var_expression (tmp, arm_locus); + tree assignment + = ctx->get_backend ()->assignment_statement (result_reference, + kase_expr_tree, arm_locus); + ctx->add_statement (assignment); // go to end label tree goto_end_label = build1_loc (arm_locus.gcc_location (), GOTO_EXPR, @@ -1507,10 +1485,7 @@ CompileExpr::visit (HIR::MatchExpr &expr) ctx->add_statement (match_expr_stmt); ctx->add_statement (end_label_decl_statement); - if (tmp != NULL) - { - translated = ctx->get_backend ()->var_expression (tmp, expr.get_locus ()); - } + translated = ctx->get_backend ()->var_expression (tmp, expr.get_locus ()); } void @@ -2824,34 +2799,32 @@ CompileExpr::generate_closure_function (HIR::ClosureExpr &expr, ctx->push_block (code_block); TyTy::BaseType *tyret = &closure_tyty.get_result_type (); - bool function_has_return = !closure_tyty.get_result_type ().is_unit (); Bvariable *return_address = nullptr; - if (function_has_return) - { - tree return_type = TyTyResolveCompile::compile (ctx, tyret); - bool address_is_taken = false; - tree ret_var_stmt = NULL_TREE; + tree return_type = TyTyResolveCompile::compile (ctx, tyret); + bool address_is_taken = false; + tree ret_var_stmt = NULL_TREE; - return_address = ctx->get_backend ()->temporary_variable ( - fndecl, code_block, return_type, NULL, address_is_taken, - expr.get_locus (), &ret_var_stmt); + return_address + = ctx->get_backend ()->temporary_variable (fndecl, code_block, return_type, + NULL, address_is_taken, + expr.get_locus (), + &ret_var_stmt); - ctx->add_statement (ret_var_stmt); - } + ctx->add_statement (ret_var_stmt); ctx->push_fn (fndecl, return_address); if (is_block_expr) { HIR::BlockExpr *body = static_cast<HIR::BlockExpr *> (function_body); - compile_function_body (ctx, fndecl, *body, true); + compile_function_body (fndecl, *body, tyret); } else { tree value = CompileExpr::Compile (function_body, ctx); tree return_expr - = ctx->get_backend ()->return_statement (fndecl, {value}, + = ctx->get_backend ()->return_statement (fndecl, value, function_body->get_locus ()); ctx->add_statement (return_expr); } diff --git a/gcc/rust/backend/rust-compile-implitem.cc b/gcc/rust/backend/rust-compile-implitem.cc index b207594..445a153 100644 --- a/gcc/rust/backend/rust-compile-implitem.cc +++ b/gcc/rust/backend/rust-compile-implitem.cc @@ -17,8 +17,6 @@ // <http://www.gnu.org/licenses/>. #include "rust-compile-implitem.h" -#include "rust-compile-expr.h" -#include "rust-compile-fnparam.h" namespace Rust { namespace Compile { @@ -36,8 +34,8 @@ CompileTraitItem::visit (HIR::TraitItemConst &constant) HIR::Expr *const_value_expr = constant.get_expr ().get (); tree const_expr - = compile_constant_item (ctx, resolved_type, canonical_path, - const_value_expr, constant.get_locus ()); + = compile_constant_item (resolved_type, canonical_path, const_value_expr, + constant.get_locus ()); ctx->push_const (const_expr); ctx->insert_const_decl (constant.get_mappings ().get_hirid (), const_expr); @@ -88,12 +86,11 @@ CompileTraitItem::visit (HIR::TraitItemFunc &func) auto vis = HIR::Visibility (HIR::Visibility::VisType::PUBLIC); HIR::TraitFunctionDecl &function = func.get_decl (); tree fndecl - = compile_function (ctx, function.get_function_name (), - function.get_self (), function.get_function_params (), + = compile_function (function.get_function_name (), function.get_self (), + function.get_function_params (), function.get_qualifiers (), vis, func.get_outer_attrs (), func.get_locus (), - func.get_block_expr ().get (), canonical_path, fntype, - function.has_return_type ()); + func.get_block_expr ().get (), canonical_path, fntype); reference = address_expression (fndecl, ref_locus); } diff --git a/gcc/rust/backend/rust-compile-item.cc b/gcc/rust/backend/rust-compile-item.cc index d953e4b1..26f56c7 100644 --- a/gcc/rust/backend/rust-compile-item.cc +++ b/gcc/rust/backend/rust-compile-item.cc @@ -49,7 +49,7 @@ CompileItem::visit (HIR::StaticItem &var) HIR::Expr *const_value_expr = var.get_expr (); ctx->push_const_context (); - tree value = compile_constant_item (ctx, resolved_type, canonical_path, + tree value = compile_constant_item (resolved_type, canonical_path, const_value_expr, var.get_locus ()); ctx->pop_const_context (); @@ -97,8 +97,8 @@ CompileItem::visit (HIR::ConstantItem &constant) HIR::Expr *const_value_expr = constant.get_expr (); ctx->push_const_context (); tree const_expr - = compile_constant_item (ctx, resolved_type, canonical_path, - const_value_expr, constant.get_locus ()); + = compile_constant_item (resolved_type, canonical_path, const_value_expr, + constant.get_locus ()); ctx->pop_const_context (); ctx->push_const (const_expr); @@ -161,13 +161,13 @@ CompileItem::visit (HIR::Function &function) ctx->push_const_context (); tree fndecl - = compile_function (ctx, function.get_function_name (), + = compile_function (function.get_function_name (), function.get_self_param (), function.get_function_params (), function.get_qualifiers (), function.get_visibility (), function.get_outer_attrs (), function.get_locus (), function.get_definition ().get (), canonical_path, - fntype, function.has_function_return_type ()); + fntype); reference = address_expression (fndecl, ref_locus); if (function.get_qualifiers ().is_const ()) diff --git a/gcc/rust/backend/rust-compile-pattern.cc b/gcc/rust/backend/rust-compile-pattern.cc index a96b1b9..742dfa0 100644 --- a/gcc/rust/backend/rust-compile-pattern.cc +++ b/gcc/rust/backend/rust-compile-pattern.cc @@ -359,11 +359,7 @@ CompilePatternLet::visit (HIR::IdentifierPattern &pattern) { ctx->add_statement (init_expr); - tree stmt_type = TyTyResolveCompile::compile (ctx, ty); - - auto unit_type_init_expr - = ctx->get_backend ()->constructor_expression (stmt_type, false, {}, -1, - rval_locus); + auto unit_type_init_expr = unit_expression (ctx, rval_locus); auto s = ctx->get_backend ()->init_statement (fnctx.fndecl, var, unit_type_init_expr); ctx->add_statement (s); diff --git a/gcc/rust/backend/rust-compile-resolve-path.cc b/gcc/rust/backend/rust-compile-resolve-path.cc index cbe2f67..97cfe9c 100644 --- a/gcc/rust/backend/rust-compile-resolve-path.cc +++ b/gcc/rust/backend/rust-compile-resolve-path.cc @@ -65,12 +65,8 @@ ResolvePathRef::resolve (const HIR::PathIdentSegment &final_segment, return error_mark_node; TyTy::ADTType *adt = static_cast<TyTy::ADTType *> (lookup); - - // it might be a unit-struct if (adt->is_unit ()) - { - return ctx->get_backend ()->unit_expression (); - } + return unit_expression (ctx, expr_locus); if (!adt->is_enum ()) return error_mark_node; diff --git a/gcc/rust/backend/rust-compile-type.cc b/gcc/rust/backend/rust-compile-type.cc index f0c6547..fc58be9 100644 --- a/gcc/rust/backend/rust-compile-type.cc +++ b/gcc/rust/backend/rust-compile-type.cc @@ -86,6 +86,20 @@ TyTyResolveCompile::get_implicit_enumeral_node_type (Context *ctx) return enum_node; } +tree +TyTyResolveCompile::get_unit_type (Context *ctx) +{ + static tree unit_type; + if (unit_type == nullptr) + { + auto unit_type_node = ctx->get_backend ()->struct_type ({}); + unit_type + = ctx->get_backend ()->named_type ("()", unit_type_node, + Linemap::predeclared_location ()); + } + return unit_type; +} + void TyTyResolveCompile::visit (const TyTy::ErrorType &) { @@ -163,14 +177,11 @@ TyTyResolveCompile::visit (const TyTy::FnType &type) std::vector<Backend::typed_identifier> parameters; std::vector<Backend::typed_identifier> results; - if (!type.get_return_type ()->is_unit ()) - { - auto hir_type = type.get_return_type (); - auto ret = TyTyResolveCompile::compile (ctx, hir_type, trait_object_mode); - results.push_back (Backend::typed_identifier ( - "_", ret, - ctx->get_mappings ()->lookup_location (hir_type->get_ref ()))); - } + auto hir_type = type.get_return_type (); + auto ret = TyTyResolveCompile::compile (ctx, hir_type, trait_object_mode); + Location return_type_locus + = ctx->get_mappings ()->lookup_location (hir_type->get_ref ()); + results.push_back (Backend::typed_identifier ("_", ret, return_type_locus)); for (auto ¶m_pair : type.get_params ()) { @@ -362,7 +373,7 @@ TyTyResolveCompile::visit (const TyTy::TupleType &type) { if (type.num_fields () == 0) { - translated = ctx->get_backend ()->unit_type (); + translated = get_unit_type (ctx); return; } @@ -651,7 +662,7 @@ TyTyResolveCompile::visit (const TyTy::StrType &type) void TyTyResolveCompile::visit (const TyTy::NeverType &) { - translated = ctx->get_backend ()->unit_type (); + translated = get_unit_type (ctx); } void diff --git a/gcc/rust/backend/rust-compile-type.h b/gcc/rust/backend/rust-compile-type.h index 3abf143..ce13795 100644 --- a/gcc/rust/backend/rust-compile-type.h +++ b/gcc/rust/backend/rust-compile-type.h @@ -32,6 +32,8 @@ public: static tree get_implicit_enumeral_node_type (Context *ctx); + static tree get_unit_type (Context *ctx); + void visit (const TyTy::InferType &) override; void visit (const TyTy::ADTType &) override; void visit (const TyTy::TupleType &) override; diff --git a/gcc/rust/backend/rust-constexpr.cc b/gcc/rust/backend/rust-constexpr.cc index a7ae416..3fd1b96 100644 --- a/gcc/rust/backend/rust-constexpr.cc +++ b/gcc/rust/backend/rust-constexpr.cc @@ -2247,7 +2247,6 @@ eval_constant_expression (const constexpr_ctx *ctx, tree t, bool lval, /* Don't VERIFY_CONSTANT here. */ if (*non_constant_p) return t; - gcc_checking_assert (TREE_CODE (op) != CONSTRUCTOR); /* This function does more aggressive folding than fold itself. */ r = build_fold_addr_expr_with_type (op, TREE_TYPE (t)); if (TREE_CODE (r) == ADDR_EXPR && TREE_OPERAND (r, 0) == oldop) |