From: Arthur Cohen <arthur.co...@embecosm.com> gcc/rust/ChangeLog:
* ast/rust-ast.cc (Function::Function): Rename is_default -> has_default. (Function::operator=): Likewise. * ast/rust-item.h (class Function): Add `is_default` method. * hir/rust-ast-lower-implitem.cc (ASTLowerImplItem::visit): Lower default qualifier. * hir/rust-ast-lower-item.cc (ASTLoweringItem::visit): Likewise. * hir/tree/rust-hir-item.cc (Function::Function): Add `is_default` member. (Function::operator=): Likewise. * hir/tree/rust-hir-item.h (enum class Defaultness): New enum. (class Function): Use it. gcc/testsuite/ChangeLog: * rust/compile/min_specialization1.rs: New test. --- gcc/rust/ast/rust-ast.cc | 4 ++-- gcc/rust/ast/rust-item.h | 8 +++++--- gcc/rust/hir/rust-ast-lower-implitem.cc | 6 +++++- gcc/rust/hir/rust-ast-lower-item.cc | 5 ++++- gcc/rust/hir/tree/rust-hir-item.cc | 9 ++++++--- gcc/rust/hir/tree/rust-hir-item.h | 17 ++++++++++++++++- .../rust/compile/min_specialization1.rs | 15 +++++++++++++++ 7 files changed, 53 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/rust/compile/min_specialization1.rs diff --git a/gcc/rust/ast/rust-ast.cc b/gcc/rust/ast/rust-ast.cc index ab82303879c..e4a1b369970 100644 --- a/gcc/rust/ast/rust-ast.cc +++ b/gcc/rust/ast/rust-ast.cc @@ -1068,7 +1068,7 @@ Function::Function (Function const &other) : VisItem (other), ExternalItem (other.get_node_id ()), qualifiers (other.qualifiers), function_name (other.function_name), where_clause (other.where_clause), locus (other.locus), - is_default (other.is_default), + has_default (other.has_default), is_external_function (other.is_external_function) { // guard to prevent null dereference (always required) @@ -1100,7 +1100,7 @@ Function::operator= (Function const &other) // visibility = other.visibility->clone_visibility(); // outer_attrs = other.outer_attrs; locus = other.locus; - is_default = other.is_default; + has_default = other.has_default; is_external_function = other.is_external_function; // guard to prevent null dereference (always required) diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h index 8eb0cc51d5d..3bfa30918fa 100644 --- a/gcc/rust/ast/rust-item.h +++ b/gcc/rust/ast/rust-item.h @@ -1330,7 +1330,7 @@ class Function : public VisItem, public AssociatedItem, public ExternalItem WhereClause where_clause; tl::optional<std::unique_ptr<BlockExpr>> function_body; location_t locus; - bool is_default; + bool has_default; bool is_external_function; public: @@ -1355,6 +1355,8 @@ public: bool has_body () const { return function_body.has_value (); } + bool is_default () const { return has_default; } + // Mega-constructor with all possible fields Function (Identifier function_name, FunctionQualifiers qualifiers, std::vector<std::unique_ptr<GenericParam>> generic_params, @@ -1362,7 +1364,7 @@ public: std::unique_ptr<Type> return_type, WhereClause where_clause, tl::optional<std::unique_ptr<BlockExpr>> function_body, Visibility vis, std::vector<Attribute> outer_attrs, - location_t locus, bool is_default = false, + location_t locus, bool has_default = false, bool is_external_function = false) : VisItem (std::move (vis), std::move (outer_attrs)), ExternalItem (Stmt::node_id), qualifiers (std::move (qualifiers)), @@ -1372,7 +1374,7 @@ public: return_type (std::move (return_type)), where_clause (std::move (where_clause)), function_body (std::move (function_body)), locus (locus), - is_default (is_default), is_external_function (is_external_function) + has_default (has_default), is_external_function (is_external_function) {} // TODO: add constructor with less fields diff --git a/gcc/rust/hir/rust-ast-lower-implitem.cc b/gcc/rust/hir/rust-ast-lower-implitem.cc index 5380d255c56..c34be898d03 100644 --- a/gcc/rust/hir/rust-ast-lower-implitem.cc +++ b/gcc/rust/hir/rust-ast-lower-implitem.cc @@ -22,6 +22,7 @@ #include "rust-ast-lower-expr.h" #include "rust-ast-lower-pattern.h" #include "rust-ast-lower-block.h" +#include "rust-hir-item.h" #include "rust-item.h" namespace Rust { @@ -140,6 +141,9 @@ ASTLowerImplItem::visit (AST::Function &function) ASTLoweringType::translate (function.get_return_type ())) : nullptr; + Defaultness defaultness + = function.is_default () ? Defaultness::Default : Defaultness::Final; + std::vector<HIR::FunctionParam> function_params; for (auto &p : function.get_function_params ()) { @@ -183,7 +187,7 @@ ASTLowerImplItem::visit (AST::Function &function) std::move (function_params), std::move (return_type), std::move (where_clause), std::move (function_body), std::move (vis), function.get_outer_attrs (), - std::move (self_param), locus); + std::move (self_param), defaultness, locus); if (!fn->get_self_param ().is_error ()) { diff --git a/gcc/rust/hir/rust-ast-lower-item.cc b/gcc/rust/hir/rust-ast-lower-item.cc index 5dbcad59dfb..c72363da33c 100644 --- a/gcc/rust/hir/rust-ast-lower-item.cc +++ b/gcc/rust/hir/rust-ast-lower-item.cc @@ -451,13 +451,16 @@ ASTLoweringItem::visit (AST::Function &function) mappings.insert_location (function_body->get_mappings ().get_hirid (), function.get_locus ()); + Defaultness defaultness + = function.is_default () ? Defaultness::Default : Defaultness::Final; + auto fn = new HIR::Function (mapping, std::move (function_name), std::move (qualifiers), std::move (generic_params), std::move (function_params), std::move (return_type), std::move (where_clause), std::move (function_body), std::move (vis), function.get_outer_attrs (), - HIR::SelfParam::error (), locus); + HIR::SelfParam::error (), defaultness, locus); // add the mappings for the function params at the end for (auto ¶m : fn->get_function_params ()) diff --git a/gcc/rust/hir/tree/rust-hir-item.cc b/gcc/rust/hir/tree/rust-hir-item.cc index cff06d35269..14f53ce3771 100644 --- a/gcc/rust/hir/tree/rust-hir-item.cc +++ b/gcc/rust/hir/tree/rust-hir-item.cc @@ -263,7 +263,8 @@ Function::Function (Analysis::NodeMapping mappings, Identifier function_name, std::vector<FunctionParam> function_params, std::unique_ptr<Type> return_type, WhereClause where_clause, std::unique_ptr<BlockExpr> function_body, Visibility vis, - AST::AttrVec outer_attrs, SelfParam self, location_t locus) + AST::AttrVec outer_attrs, SelfParam self, + Defaultness defaultness, location_t locus) : VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)), qualifiers (std::move (qualifiers)), function_name (std::move (function_name)), @@ -272,7 +273,7 @@ Function::Function (Analysis::NodeMapping mappings, Identifier function_name, return_type (std::move (return_type)), where_clause (std::move (where_clause)), function_body (std::move (function_body)), self (std::move (self)), - locus (locus) + locus (locus), defaultness (defaultness) {} Function::Function (Function const &other) @@ -280,7 +281,7 @@ Function::Function (Function const &other) function_name (other.function_name), function_params (other.function_params), where_clause (other.where_clause), function_body (other.function_body->clone_block_expr ()), self (other.self), - locus (other.locus) + locus (other.locus), defaultness (other.defaultness) { // guard to prevent null dereference (always required) if (other.return_type != nullptr) @@ -312,6 +313,8 @@ Function::operator= (Function const &other) locus = other.locus; self = other.self; + defaultness = other.defaultness; + generic_params.reserve (other.generic_params.size ()); for (const auto &e : other.generic_params) generic_params.push_back (e->clone_generic_param ()); diff --git a/gcc/rust/hir/tree/rust-hir-item.h b/gcc/rust/hir/tree/rust-hir-item.h index 47447174215..dfba80c4944 100644 --- a/gcc/rust/hir/tree/rust-hir-item.h +++ b/gcc/rust/hir/tree/rust-hir-item.h @@ -945,6 +945,12 @@ protected: class LetStmt; +enum class Defaultness +{ + Default, + Final, +}; + // Rust function declaration HIR node class Function : public VisItem, public ImplItem { @@ -958,6 +964,11 @@ class Function : public VisItem, public ImplItem SelfParam self; location_t locus; + // NOTE: This should be moved to the trait item base class once we start + // implementing specialization for real, instead of just stubbing out the + // feature + Defaultness defaultness; + public: std::string as_string () const override; @@ -973,6 +984,9 @@ public: // Returns whether function has a where clause. bool has_where_clause () const { return !where_clause.is_empty (); } + // Returns whether function has a default qualifier + bool is_default () const { return defaultness == Defaultness::Default; } + ImplItemType get_impl_item_type () const override final { return ImplItem::ImplItemType::FUNCTION; @@ -987,7 +1001,8 @@ public: std::vector<FunctionParam> function_params, std::unique_ptr<Type> return_type, WhereClause where_clause, std::unique_ptr<BlockExpr> function_body, Visibility vis, - AST::AttrVec outer_attrs, SelfParam self, location_t locus); + AST::AttrVec outer_attrs, SelfParam self, Defaultness defaultness, + location_t locus); // Copy constructor with clone Function (Function const &other); diff --git a/gcc/testsuite/rust/compile/min_specialization1.rs b/gcc/testsuite/rust/compile/min_specialization1.rs new file mode 100644 index 00000000000..d38167e9034 --- /dev/null +++ b/gcc/testsuite/rust/compile/min_specialization1.rs @@ -0,0 +1,15 @@ +#![feature(min_specialization)] + +pub trait Foo { + fn foo(&self) -> bool { + false + } +} + +pub struct Bar; + +impl Foo for Bar { + default fn foo(&self) -> bool { // { dg-warning "unused" } + true + } +} -- 2.49.0