From: Arthur Cohen <[email protected]>
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