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 &param : 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

Reply via email to