aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/rust/ast/rust-item.h119
-rw-r--r--gcc/rust/hir/rust-ast-lower-item.h72
-rw-r--r--gcc/rust/hir/rust-ast-lower-type.h72
-rw-r--r--gcc/rust/hir/tree/rust-hir-item.h106
-rw-r--r--gcc/rust/parse/rust-parse-impl.h5
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-item.h48
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-type.h30
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-implitem.h10
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-toplevel.h31
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-type.h105
-rw-r--r--gcc/rust/typecheck/rust-tyty.h2
-rw-r--r--gcc/testsuite/rust/compile/torture/traits10.rs5
-rw-r--r--gcc/testsuite/rust/compile/torture/traits18.rs8
-rw-r--r--gcc/testsuite/rust/execute/torture/trait11.rs41
14 files changed, 531 insertions, 123 deletions
diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h
index d075a57..323548a 100644
--- a/gcc/rust/ast/rust-item.h
+++ b/gcc/rust/ast/rust-item.h
@@ -177,6 +177,8 @@ public:
virtual void accept_vis (ASTVisitor &vis) = 0;
+ virtual NodeId get_node_id () const = 0;
+
protected:
// Clone function implementation as pure virtual method
virtual WhereClauseItem *clone_where_clause_item_impl () const = 0;
@@ -186,24 +188,31 @@ protected:
class LifetimeWhereClauseItem : public WhereClauseItem
{
Lifetime lifetime;
-
- // LifetimeBounds lifetime_bounds;
- std::vector<Lifetime> lifetime_bounds; // inlined lifetime bounds
-
+ std::vector<Lifetime> lifetime_bounds;
Location locus;
+ NodeId node_id;
public:
LifetimeWhereClauseItem (Lifetime lifetime,
std::vector<Lifetime> lifetime_bounds,
Location locus)
: lifetime (std::move (lifetime)),
- lifetime_bounds (std::move (lifetime_bounds)), locus (locus)
+ lifetime_bounds (std::move (lifetime_bounds)), locus (locus),
+ node_id (Analysis::Mappings::get ()->get_next_node_id ())
{}
std::string as_string () const override;
void accept_vis (ASTVisitor &vis) override;
+ NodeId get_node_id () const override final { return node_id; }
+
+ Lifetime &get_lifetime () { return lifetime; }
+
+ std::vector<Lifetime> &get_lifetime_bounds () { return lifetime_bounds; }
+
+ Location get_locus () const { return locus; }
+
protected:
// Clone function implementation as (not pure) virtual method
LifetimeWhereClauseItem *clone_where_clause_item_impl () const override
@@ -215,18 +224,10 @@ protected:
// A type bound where clause item
class TypeBoundWhereClauseItem : public WhereClauseItem
{
- // bool has_for_lifetimes;
- // LifetimeParams for_lifetimes;
- std::vector<LifetimeParam> for_lifetimes; // inlined
-
+ std::vector<LifetimeParam> for_lifetimes;
std::unique_ptr<Type> bound_type;
-
- // bool has_type_param_bounds;
- // TypeParamBounds type_param_bounds;
- std::vector<std::unique_ptr<TypeParamBound>>
- type_param_bounds; // inlined form
-
- // should this store location info?
+ std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds;
+ NodeId node_id;
public:
// Returns whether the item has ForLifetimes
@@ -240,7 +241,8 @@ public:
std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds)
: for_lifetimes (std::move (for_lifetimes)),
bound_type (std::move (bound_type)),
- type_param_bounds (std::move (type_param_bounds))
+ type_param_bounds (std::move (type_param_bounds)),
+ node_id (Analysis::Mappings::get ()->get_next_node_id ())
{}
// Copy constructor requires clone
@@ -248,6 +250,7 @@ public:
: for_lifetimes (other.for_lifetimes),
bound_type (other.bound_type->clone_type ())
{
+ node_id = other.node_id;
type_param_bounds.reserve (other.type_param_bounds.size ());
for (const auto &e : other.type_param_bounds)
type_param_bounds.push_back (e->clone_type_param_bound ());
@@ -256,9 +259,9 @@ public:
// Overload assignment operator to clone
TypeBoundWhereClauseItem &operator= (TypeBoundWhereClauseItem const &other)
{
+ node_id = other.node_id;
for_lifetimes = other.for_lifetimes;
bound_type = other.bound_type->clone_type ();
-
type_param_bounds.reserve (other.type_param_bounds.size ());
for (const auto &e : other.type_param_bounds)
type_param_bounds.push_back (e->clone_type_param_bound ());
@@ -275,7 +278,6 @@ public:
void accept_vis (ASTVisitor &vis) override;
- // TODO: is this better? Or is a "vis_block" better?
std::unique_ptr<Type> &get_type ()
{
rust_assert (bound_type != nullptr);
@@ -287,12 +289,15 @@ public:
{
return type_param_bounds;
}
+
const std::vector<std::unique_ptr<TypeParamBound>> &
get_type_param_bounds () const
{
return type_param_bounds;
}
+ NodeId get_node_id () const override final { return node_id; }
+
protected:
// Clone function implementation as (not pure) virtual method
TypeBoundWhereClauseItem *clone_where_clause_item_impl () const override
@@ -306,17 +311,18 @@ struct WhereClause
{
private:
std::vector<std::unique_ptr<WhereClauseItem>> where_clause_items;
-
- // should this store location info?
+ NodeId node_id;
public:
WhereClause (std::vector<std::unique_ptr<WhereClauseItem>> where_clause_items)
- : where_clause_items (std::move (where_clause_items))
+ : where_clause_items (std::move (where_clause_items)),
+ node_id (Analysis::Mappings::get ()->get_next_node_id ())
{}
// copy constructor with vector clone
WhereClause (WhereClause const &other)
{
+ node_id = other.node_id;
where_clause_items.reserve (other.where_clause_items.size ());
for (const auto &e : other.where_clause_items)
where_clause_items.push_back (e->clone_where_clause_item ());
@@ -325,6 +331,7 @@ public:
// overloaded assignment operator with vector clone
WhereClause &operator= (WhereClause const &other)
{
+ node_id = other.node_id;
where_clause_items.reserve (other.where_clause_items.size ());
for (const auto &e : other.where_clause_items)
where_clause_items.push_back (e->clone_where_clause_item ());
@@ -347,6 +354,8 @@ public:
std::string as_string () const;
+ NodeId get_node_id () const { return node_id; }
+
// TODO: this mutable getter seems kinda dodgy
std::vector<std::unique_ptr<WhereClauseItem>> &get_items ()
{
@@ -878,11 +887,7 @@ public:
}
// TODO: is this better? Or is a "vis_block" better?
- WhereClause &get_where_clause ()
- {
- rust_assert (has_where_clause ());
- return where_clause;
- }
+ WhereClause &get_where_clause () { return where_clause; }
Identifier get_method_name () const { return method_name; }
@@ -1578,11 +1583,7 @@ public:
Identifier get_function_name () const { return function_name; }
// TODO: is this better? Or is a "vis_block" better?
- WhereClause &get_where_clause ()
- {
- rust_assert (has_where_clause ());
- return where_clause;
- }
+ WhereClause &get_where_clause () { return where_clause; }
// TODO: is this better? Or is a "vis_block" better?
std::unique_ptr<Type> &get_return_type ()
@@ -1710,11 +1711,7 @@ public:
}
// TODO: is this better? Or is a "vis_block" better?
- WhereClause &get_where_clause ()
- {
- rust_assert (has_where_clause ());
- return where_clause;
- }
+ WhereClause &get_where_clause () { return where_clause; }
// TODO: is this better? Or is a "vis_block" better?
std::unique_ptr<Type> &get_type_aliased ()
@@ -1780,11 +1777,7 @@ public:
}
// TODO: is this better? Or is a "vis_block" better?
- WhereClause &get_where_clause ()
- {
- rust_assert (has_where_clause ());
- return where_clause;
- }
+ WhereClause &get_where_clause () { return where_clause; }
Identifier get_identifier () const { return struct_name; }
@@ -2401,11 +2394,7 @@ public:
}
// TODO: is this better? Or is a "vis_block" better?
- WhereClause &get_where_clause ()
- {
- rust_assert (has_where_clause ());
- return where_clause;
- }
+ WhereClause &get_where_clause () { return where_clause; }
protected:
/* Use covariance to implement clone function as returning this object
@@ -2511,11 +2500,7 @@ public:
}
// TODO: is this better? Or is a "vis_block" better?
- WhereClause &get_where_clause ()
- {
- rust_assert (has_where_clause ());
- return where_clause;
- }
+ WhereClause &get_where_clause () { return where_clause; }
Identifier get_identifier () const { return union_name; }
@@ -2868,11 +2853,7 @@ public:
}
// TODO: is this better? Or is a "vis_block" better?
- WhereClause &get_where_clause ()
- {
- rust_assert (has_where_clause ());
- return where_clause;
- }
+ WhereClause &get_where_clause () { return where_clause; }
};
// Actual trait item function declaration within traits
@@ -3095,11 +3076,7 @@ public:
}
// TODO: is this better? Or is a "vis_block" better?
- WhereClause &get_where_clause ()
- {
- rust_assert (has_where_clause ());
- return where_clause;
- }
+ WhereClause &get_where_clause () { return where_clause; }
SelfParam &get_self_param () { return self_param; }
const SelfParam &get_self_param () const { return self_param; }
@@ -3533,11 +3510,7 @@ public:
return type_param_bounds;
}
- WhereClause &get_where_clause ()
- {
- rust_assert (has_where_clause ());
- return where_clause;
- }
+ WhereClause &get_where_clause () { return where_clause; }
void insert_implict_self (std::unique_ptr<AST::GenericParam> &&param)
{
@@ -3610,11 +3583,7 @@ public:
}
// TODO: is this better? Or is a "vis_block" better?
- WhereClause &get_where_clause ()
- {
- rust_assert (has_where_clause ());
- return where_clause;
- }
+ WhereClause &get_where_clause () { return where_clause; }
// TODO: is this better? Or is a "vis_block" better?
std::unique_ptr<Type> &get_type ()
@@ -4261,11 +4230,7 @@ public:
}
// TODO: is this better? Or is a "vis_block" better?
- WhereClause &get_where_clause ()
- {
- rust_assert (has_where_clause ());
- return where_clause;
- }
+ WhereClause &get_where_clause () { return where_clause; }
// TODO: is this better? Or is a "vis_block" better?
std::unique_ptr<Type> &get_return_type ()
diff --git a/gcc/rust/hir/rust-ast-lower-item.h b/gcc/rust/hir/rust-ast-lower-item.h
index 9372e94..db0425f 100644
--- a/gcc/rust/hir/rust-ast-lower-item.h
+++ b/gcc/rust/hir/rust-ast-lower-item.h
@@ -95,6 +95,14 @@ public:
void visit (AST::TypeAlias &alias) override
{
std::vector<std::unique_ptr<HIR::WhereClauseItem>> where_clause_items;
+ for (auto &item : alias.get_where_clause ().get_items ())
+ {
+ HIR::WhereClauseItem *i
+ = ASTLowerWhereClauseItem::translate (*item.get ());
+ where_clause_items.push_back (
+ std::unique_ptr<HIR::WhereClauseItem> (i));
+ }
+
HIR::WhereClause where_clause (std::move (where_clause_items));
HIR::Visibility vis = HIR::Visibility::create_public ();
@@ -134,6 +142,14 @@ public:
}
std::vector<std::unique_ptr<HIR::WhereClauseItem>> where_clause_items;
+ for (auto &item : struct_decl.get_where_clause ().get_items ())
+ {
+ HIR::WhereClauseItem *i
+ = ASTLowerWhereClauseItem::translate (*item.get ());
+ where_clause_items.push_back (
+ std::unique_ptr<HIR::WhereClauseItem> (i));
+ }
+
HIR::WhereClause where_clause (std::move (where_clause_items));
HIR::Visibility vis = HIR::Visibility::create_public ();
@@ -186,6 +202,14 @@ public:
}
std::vector<std::unique_ptr<HIR::WhereClauseItem>> where_clause_items;
+ for (auto &item : struct_decl.get_where_clause ().get_items ())
+ {
+ HIR::WhereClauseItem *i
+ = ASTLowerWhereClauseItem::translate (*item.get ());
+ where_clause_items.push_back (
+ std::unique_ptr<HIR::WhereClauseItem> (i));
+ }
+
HIR::WhereClause where_clause (std::move (where_clause_items));
HIR::Visibility vis = HIR::Visibility::create_public ();
@@ -242,6 +266,14 @@ public:
}
std::vector<std::unique_ptr<HIR::WhereClauseItem>> where_clause_items;
+ for (auto &item : enum_decl.get_where_clause ().get_items ())
+ {
+ HIR::WhereClauseItem *i
+ = ASTLowerWhereClauseItem::translate (*item.get ());
+ where_clause_items.push_back (
+ std::unique_ptr<HIR::WhereClauseItem> (i));
+ }
+
HIR::WhereClause where_clause (std::move (where_clause_items));
HIR::Visibility vis = HIR::Visibility::create_public ();
@@ -282,6 +314,13 @@ public:
}
std::vector<std::unique_ptr<HIR::WhereClauseItem>> where_clause_items;
+ for (auto &item : union_decl.get_where_clause ().get_items ())
+ {
+ HIR::WhereClauseItem *i
+ = ASTLowerWhereClauseItem::translate (*item.get ());
+ where_clause_items.push_back (
+ std::unique_ptr<HIR::WhereClauseItem> (i));
+ }
HIR::WhereClause where_clause (std::move (where_clause_items));
HIR::Visibility vis = HIR::Visibility::create_public ();
@@ -380,8 +419,15 @@ public:
void visit (AST::Function &function) override
{
- // ignore for now and leave empty
std::vector<std::unique_ptr<HIR::WhereClauseItem>> where_clause_items;
+ for (auto &item : function.get_where_clause ().get_items ())
+ {
+ HIR::WhereClauseItem *i
+ = ASTLowerWhereClauseItem::translate (*item.get ());
+ where_clause_items.push_back (
+ std::unique_ptr<HIR::WhereClauseItem> (i));
+ }
+
HIR::WhereClause where_clause (std::move (where_clause_items));
HIR::FunctionQualifiers qualifiers (
HIR::FunctionQualifiers::AsyncConstStatus::NONE, Unsafety::Normal);
@@ -466,6 +512,13 @@ public:
void visit (AST::InherentImpl &impl_block) override
{
std::vector<std::unique_ptr<HIR::WhereClauseItem>> where_clause_items;
+ for (auto &item : impl_block.get_where_clause ().get_items ())
+ {
+ HIR::WhereClauseItem *i
+ = ASTLowerWhereClauseItem::translate (*item.get ());
+ where_clause_items.push_back (
+ std::unique_ptr<HIR::WhereClauseItem> (i));
+ }
HIR::WhereClause where_clause (std::move (where_clause_items));
HIR::Visibility vis = HIR::Visibility::create_public ();
@@ -545,8 +598,15 @@ public:
void visit (AST::Trait &trait) override
{
std::vector<std::unique_ptr<HIR::WhereClauseItem>> where_clause_items;
-
+ for (auto &item : trait.get_where_clause ().get_items ())
+ {
+ HIR::WhereClauseItem *i
+ = ASTLowerWhereClauseItem::translate (*item.get ());
+ where_clause_items.push_back (
+ std::unique_ptr<HIR::WhereClauseItem> (i));
+ }
HIR::WhereClause where_clause (std::move (where_clause_items));
+
HIR::Visibility vis = HIR::Visibility::create_public ();
std::vector<std::unique_ptr<HIR::GenericParam>> generic_params;
@@ -632,7 +692,13 @@ public:
void visit (AST::TraitImpl &impl_block) override
{
std::vector<std::unique_ptr<HIR::WhereClauseItem>> where_clause_items;
-
+ for (auto &item : impl_block.get_where_clause ().get_items ())
+ {
+ HIR::WhereClauseItem *i
+ = ASTLowerWhereClauseItem::translate (*item.get ());
+ where_clause_items.push_back (
+ std::unique_ptr<HIR::WhereClauseItem> (i));
+ }
HIR::WhereClause where_clause (std::move (where_clause_items));
HIR::Visibility vis = HIR::Visibility::create_public ();
diff --git a/gcc/rust/hir/rust-ast-lower-type.h b/gcc/rust/hir/rust-ast-lower-type.h
index 0a71e3a..8205d07 100644
--- a/gcc/rust/hir/rust-ast-lower-type.h
+++ b/gcc/rust/hir/rust-ast-lower-type.h
@@ -60,7 +60,7 @@ public:
void visit (AST::TypePath &path) override
{
- std::vector<std::unique_ptr<HIR::TypePathSegment> > translated_segments;
+ std::vector<std::unique_ptr<HIR::TypePathSegment>> translated_segments;
path.iterate_segments ([&] (AST::TypePathSegment *seg) mutable -> bool {
translated_segment = nullptr;
@@ -188,7 +188,7 @@ public:
void visit (AST::TupleType &tuple) override
{
- std::vector<std::unique_ptr<HIR::Type> > elems;
+ std::vector<std::unique_ptr<HIR::Type>> elems;
for (auto &e : tuple.get_elems ())
{
HIR::Type *t = ASTLoweringType::translate (e.get ());
@@ -340,7 +340,7 @@ public:
void visit (AST::TypeParam &param) override
{
AST::Attribute outer_attr = AST::Attribute::create_empty ();
- std::vector<std::unique_ptr<HIR::TypeParamBound> > type_param_bounds;
+ std::vector<std::unique_ptr<HIR::TypeParamBound>> type_param_bounds;
if (param.has_type_param_bounds ())
{
for (auto &bound : param.get_type_param_bounds ())
@@ -422,6 +422,72 @@ private:
HIR::TypeParamBound *translated;
};
+class ASTLowerWhereClauseItem : public ASTLoweringBase
+{
+ using Rust::HIR::ASTLoweringBase::visit;
+
+public:
+ static HIR::WhereClauseItem *translate (AST::WhereClauseItem &item)
+ {
+ ASTLowerWhereClauseItem compiler;
+ item.accept_vis (compiler);
+ rust_assert (compiler.translated != nullptr);
+ return compiler.translated;
+ }
+
+ void visit (AST::LifetimeWhereClauseItem &item) override
+ {
+ HIR::Lifetime l = lower_lifetime (item.get_lifetime ());
+ std::vector<HIR::Lifetime> lifetime_bounds;
+ for (auto &lifetime_bound : item.get_lifetime_bounds ())
+ {
+ HIR::Lifetime ll = lower_lifetime (lifetime_bound);
+ lifetime_bounds.push_back (std::move (ll));
+ }
+
+ auto crate_num = mappings->get_current_crate ();
+ Analysis::NodeMapping mapping (crate_num, item.get_node_id (),
+ mappings->get_next_hir_id (crate_num),
+ UNKNOWN_LOCAL_DEFID);
+
+ translated = new HIR::LifetimeWhereClauseItem (mapping, std::move (l),
+ std::move (lifetime_bounds),
+ item.get_locus ());
+ }
+
+ void visit (AST::TypeBoundWhereClauseItem &item) override
+ {
+ // FIXME
+ std::vector<HIR::LifetimeParam> for_lifetimes;
+
+ std::unique_ptr<HIR::Type> bound_type = std::unique_ptr<HIR::Type> (
+ ASTLoweringType::translate (item.get_type ().get ()));
+
+ std::vector<std::unique_ptr<HIR::TypeParamBound>> type_param_bounds;
+ for (auto &bound : item.get_type_param_bounds ())
+ {
+ HIR::TypeParamBound *b
+ = ASTLoweringTypeBounds::translate (bound.get ());
+ type_param_bounds.push_back (std::unique_ptr<HIR::TypeParamBound> (b));
+ }
+
+ auto crate_num = mappings->get_current_crate ();
+ Analysis::NodeMapping mapping (crate_num, item.get_node_id (),
+ mappings->get_next_hir_id (crate_num),
+ UNKNOWN_LOCAL_DEFID);
+
+ translated
+ = new HIR::TypeBoundWhereClauseItem (mapping, std::move (for_lifetimes),
+ std::move (bound_type),
+ std::move (type_param_bounds));
+ }
+
+private:
+ ASTLowerWhereClauseItem () : ASTLoweringBase (), translated (nullptr) {}
+
+ HIR::WhereClauseItem *translated;
+};
+
} // namespace HIR
} // namespace Rust
diff --git a/gcc/rust/hir/tree/rust-hir-item.h b/gcc/rust/hir/tree/rust-hir-item.h
index ab9eab6..21f0781 100644
--- a/gcc/rust/hir/tree/rust-hir-item.h
+++ b/gcc/rust/hir/tree/rust-hir-item.h
@@ -20,6 +20,7 @@
#define RUST_HIR_ITEM_H
#include "rust-ast-full-decls.h"
+#include "rust-common.h"
#include "rust-hir.h"
#include "rust-hir-path.h"
@@ -140,6 +141,12 @@ protected:
class WhereClauseItem
{
public:
+ enum ItemType
+ {
+ LIFETIME,
+ TYPE_BOUND,
+ };
+
virtual ~WhereClauseItem () {}
// Unique pointer custom clone function
@@ -152,6 +159,10 @@ public:
virtual void accept_vis (HIRVisitor &vis) = 0;
+ virtual Analysis::NodeMapping get_mappings () const = 0;
+
+ virtual ItemType get_item_type () const = 0;
+
protected:
// Clone function implementation as pure virtual method
virtual WhereClauseItem *clone_where_clause_item_impl () const = 0;
@@ -161,24 +172,37 @@ protected:
class LifetimeWhereClauseItem : public WhereClauseItem
{
Lifetime lifetime;
-
- // LifetimeBounds lifetime_bounds;
- std::vector<Lifetime> lifetime_bounds; // inlined lifetime bounds
-
+ std::vector<Lifetime> lifetime_bounds;
Location locus;
+ Analysis::NodeMapping mappings;
public:
- LifetimeWhereClauseItem (Lifetime lifetime,
+ LifetimeWhereClauseItem (Analysis::NodeMapping mappings, Lifetime lifetime,
std::vector<Lifetime> lifetime_bounds,
Location locus)
: lifetime (std::move (lifetime)),
- lifetime_bounds (std::move (lifetime_bounds)), locus (locus)
+ lifetime_bounds (std::move (lifetime_bounds)), locus (locus),
+ mappings (std::move (mappings))
{}
std::string as_string () const override;
void accept_vis (HIRVisitor &vis) override;
+ Lifetime &get_lifetime () { return lifetime; }
+
+ std::vector<Lifetime> &get_lifetime_bounds () { return lifetime_bounds; }
+
+ Analysis::NodeMapping get_mappings () const override final
+ {
+ return mappings;
+ };
+
+ ItemType get_item_type () const override final
+ {
+ return WhereClauseItem::ItemType::LIFETIME;
+ }
+
protected:
// Clone function implementation as (not pure) virtual method
LifetimeWhereClauseItem *clone_where_clause_item_impl () const override
@@ -190,18 +214,10 @@ protected:
// A type bound where clause item
class TypeBoundWhereClauseItem : public WhereClauseItem
{
- // bool has_for_lifetimes;
- // LifetimeParams for_lifetimes;
- std::vector<LifetimeParam> for_lifetimes; // inlined
-
+ std::vector<LifetimeParam> for_lifetimes;
std::unique_ptr<Type> bound_type;
-
- // bool has_type_param_bounds;
- // TypeParamBounds type_param_bounds;
- std::vector<std::unique_ptr<TypeParamBound>>
- type_param_bounds; // inlined form
-
- // should this store location info?
+ std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds;
+ Analysis::NodeMapping mappings;
public:
// Returns whether the item has ForLifetimes
@@ -211,17 +227,19 @@ public:
bool has_type_param_bounds () const { return !type_param_bounds.empty (); }
TypeBoundWhereClauseItem (
- std::vector<LifetimeParam> for_lifetimes, std::unique_ptr<Type> bound_type,
+ Analysis::NodeMapping mappings, std::vector<LifetimeParam> for_lifetimes,
+ std::unique_ptr<Type> bound_type,
std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds)
: for_lifetimes (std::move (for_lifetimes)),
bound_type (std::move (bound_type)),
- type_param_bounds (std::move (type_param_bounds))
+ type_param_bounds (std::move (type_param_bounds)),
+ mappings (std::move (mappings))
{}
// Copy constructor requires clone
TypeBoundWhereClauseItem (TypeBoundWhereClauseItem const &other)
: for_lifetimes (other.for_lifetimes),
- bound_type (other.bound_type->clone_type ())
+ bound_type (other.bound_type->clone_type ()), mappings (other.mappings)
{
type_param_bounds.reserve (other.type_param_bounds.size ());
for (const auto &e : other.type_param_bounds)
@@ -231,9 +249,9 @@ public:
// Overload assignment operator to clone
TypeBoundWhereClauseItem &operator= (TypeBoundWhereClauseItem const &other)
{
+ mappings = other.mappings;
for_lifetimes = other.for_lifetimes;
bound_type = other.bound_type->clone_type ();
-
type_param_bounds.reserve (other.type_param_bounds.size ());
for (const auto &e : other.type_param_bounds)
type_param_bounds.push_back (e->clone_type_param_bound ());
@@ -250,6 +268,25 @@ public:
void accept_vis (HIRVisitor &vis) override;
+ std::vector<LifetimeParam> &get_for_lifetimes () { return for_lifetimes; }
+
+ std::unique_ptr<Type> &get_bound_type () { return bound_type; }
+
+ std::vector<std::unique_ptr<TypeParamBound>> &get_type_param_bounds ()
+ {
+ return type_param_bounds;
+ }
+
+ Analysis::NodeMapping get_mappings () const override final
+ {
+ return mappings;
+ };
+
+ ItemType get_item_type () const override final
+ {
+ return WhereClauseItem::ItemType::TYPE_BOUND;
+ }
+
protected:
// Clone function implementation as (not pure) virtual method
TypeBoundWhereClauseItem *clone_where_clause_item_impl () const override
@@ -303,6 +340,15 @@ public:
bool is_empty () const { return where_clause_items.empty (); }
std::string as_string () const;
+
+ std::vector<std::unique_ptr<WhereClauseItem>> &get_items ()
+ {
+ return where_clause_items;
+ }
+ const std::vector<std::unique_ptr<WhereClauseItem>> &get_items () const
+ {
+ return where_clause_items;
+ }
};
// A self parameter in a method
@@ -1168,11 +1214,7 @@ public:
Identifier get_function_name () const { return function_name; }
// TODO: is this better? Or is a "vis_block" better?
- WhereClause &get_where_clause ()
- {
- rust_assert (has_where_clause ());
- return where_clause;
- }
+ WhereClause &get_where_clause () { return where_clause; }
bool has_return_type () const { return return_type != nullptr; }
@@ -1285,11 +1327,7 @@ public:
return generic_params;
}
- WhereClause &get_where_clause ()
- {
- rust_assert (has_where_clause ());
- return where_clause;
- }
+ WhereClause &get_where_clause () { return where_clause; }
std::unique_ptr<Type> &get_type_aliased ()
{
@@ -1349,6 +1387,8 @@ public:
return generic_params;
}
+ WhereClause &get_where_clause () { return where_clause; }
+
protected:
Struct (Analysis::NodeMapping mappings, Identifier struct_name,
std::vector<std::unique_ptr<GenericParam>> generic_params,
@@ -1956,6 +1996,8 @@ public:
}
}
+ WhereClause &get_where_clause () { return where_clause; }
+
protected:
/* Use covariance to implement clone function as returning this object
* rather than base */
@@ -2666,6 +2708,8 @@ public:
return trait_ref;
}
+ WhereClause &get_where_clause () { return where_clause; }
+
protected:
ImplBlock *clone_item_impl () const override { return new ImplBlock (*this); }
};
diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h
index 14e4e80..8bddfcd 100644
--- a/gcc/rust/parse/rust-parse-impl.h
+++ b/gcc/rust/parse/rust-parse-impl.h
@@ -6239,9 +6239,7 @@ Parser<ManagedTokenSource>::parse_path_generic_args ()
const_TokenPtr t = lexer.peek_token ();
Location locus = t->get_locus ();
- const_TokenPtr t2 = lexer.peek_token (1);
- while (t->get_id () == LIFETIME
- && (t2->get_id () == COMMA || !is_right_angle_tok (t2->get_id ())))
+ while (!is_right_angle_tok (t->get_id ()))
{
AST::Lifetime lifetime = parse_lifetime ();
if (lifetime.is_error ())
@@ -6261,7 +6259,6 @@ Parser<ManagedTokenSource>::parse_path_generic_args ()
lexer.skip_token ();
t = lexer.peek_token ();
- t2 = lexer.peek_token (1);
}
// try to parse types second
diff --git a/gcc/rust/resolve/rust-ast-resolve-item.h b/gcc/rust/resolve/rust-ast-resolve-item.h
index fbb8fd4..86c9934 100644
--- a/gcc/rust/resolve/rust-ast-resolve-item.h
+++ b/gcc/rust/resolve/rust-ast-resolve-item.h
@@ -58,7 +58,8 @@ public:
resolver->get_type_scope ().append_reference_for_def (type.get_node_id (),
type.get_node_id ());
- // TODO resolve the type-bounds
+ for (auto &bound : type.get_type_param_bounds ())
+ ResolveTypeBound::go (bound.get (), type.get_node_id ());
}
void visit (AST::TraitItemFunc &func) override
@@ -95,6 +96,9 @@ public:
param.get_node_id ());
}
+ if (function.has_where_clause ())
+ ResolveWhereClause::Resolve (function.get_where_clause ());
+
// trait items have an optional body
if (func.has_definition ())
ResolveExpr::go (func.get_definition ().get (), func.get_node_id ());
@@ -158,6 +162,9 @@ public:
param.get_node_id ());
}
+ if (function.has_where_clause ())
+ ResolveWhereClause::Resolve (function.get_where_clause ());
+
// trait items have an optional body
if (func.has_definition ())
ResolveExpr::go (func.get_definition ().get (), func.get_node_id ());
@@ -211,6 +218,9 @@ public:
ResolveGenericParam::go (generic.get (), alias.get_node_id ());
}
+ if (alias.has_where_clause ())
+ ResolveWhereClause::Resolve (alias.get_where_clause ());
+
ResolveType::go (alias.get_type_aliased ().get (), alias.get_node_id ());
resolver->get_type_scope ().pop ();
@@ -251,6 +261,9 @@ public:
}
}
+ if (struct_decl.has_where_clause ())
+ ResolveWhereClause::Resolve (struct_decl.get_where_clause ());
+
struct_decl.iterate ([&] (AST::TupleField &field) mutable -> bool {
ResolveType::go (field.get_field_type ().get (),
struct_decl.get_node_id ());
@@ -273,6 +286,9 @@ public:
}
}
+ if (enum_decl.has_where_clause ())
+ ResolveWhereClause::Resolve (enum_decl.get_where_clause ());
+
/* The actual fields are inside the variants. */
for (auto &variant : enum_decl.get_variants ())
ResolveItem::go (variant.get ());
@@ -310,6 +326,9 @@ public:
}
}
+ if (struct_decl.has_where_clause ())
+ ResolveWhereClause::Resolve (struct_decl.get_where_clause ());
+
struct_decl.iterate ([&] (AST::StructField &field) mutable -> bool {
ResolveType::go (field.get_field_type ().get (),
struct_decl.get_node_id ());
@@ -332,6 +351,9 @@ public:
}
}
+ if (union_decl.has_where_clause ())
+ ResolveWhereClause::Resolve (union_decl.get_where_clause ());
+
union_decl.iterate ([&] (AST::StructField &field) mutable -> bool {
ResolveType::go (field.get_field_type ().get (),
union_decl.get_node_id ());
@@ -379,6 +401,10 @@ public:
ResolveGenericParam::go (generic.get (), function.get_node_id ());
}
+ // resolve any where clause items
+ if (function.has_where_clause ())
+ ResolveWhereClause::Resolve (function.get_where_clause ());
+
if (function.has_return_type ())
ResolveType::go (function.get_return_type ().get (),
function.get_node_id ());
@@ -422,6 +448,10 @@ public:
}
}
+ // resolve any where clause items
+ if (impl_block.has_where_clause ())
+ ResolveWhereClause::Resolve (impl_block.get_where_clause ());
+
bool canonicalize_type_with_generics = false;
NodeId resolved_node = ResolveType::go (impl_block.get_type ().get (),
impl_block.get_node_id (),
@@ -468,6 +498,10 @@ public:
ResolveGenericParam::go (generic.get (), method.get_node_id ());
}
+ // resolve any where clause items
+ if (method.has_where_clause ())
+ ResolveWhereClause::Resolve (method.get_where_clause ());
+
if (method.has_return_type ())
ResolveType::go (method.get_return_type ().get (), method.get_node_id ());
@@ -505,6 +539,10 @@ public:
param.get_node_id ());
}
+ // resolve any where clause items
+ if (method.has_where_clause ())
+ ResolveWhereClause::Resolve (method.get_where_clause ());
+
// resolve the function body
ResolveExpr::go (method.get_definition ().get (), method.get_node_id ());
@@ -529,6 +567,10 @@ public:
}
}
+ // resolve any where clause items
+ if (impl_block.has_where_clause ())
+ ResolveWhereClause::Resolve (impl_block.get_where_clause ());
+
bool canonicalize_type_with_generics = false;
NodeId trait_resolved_node
= ResolveType::go (&impl_block.get_trait_path (),
@@ -601,6 +643,10 @@ public:
}
}
+ // resolve any where clause items
+ if (trait.has_where_clause ())
+ ResolveWhereClause::Resolve (trait.get_where_clause ());
+
for (auto &item : trait.get_trait_items ())
{
ResolveTraitItems::go (item.get (), Self);
diff --git a/gcc/rust/resolve/rust-ast-resolve-type.h b/gcc/rust/resolve/rust-ast-resolve-type.h
index 6b9fb89..4708bff 100644
--- a/gcc/rust/resolve/rust-ast-resolve-type.h
+++ b/gcc/rust/resolve/rust-ast-resolve-type.h
@@ -473,6 +473,36 @@ private:
bool ok;
};
+class ResolveWhereClause : public ResolverBase
+{
+ using Rust::Resolver::ResolverBase::visit;
+
+public:
+ static void Resolve (AST::WhereClause &where_clause)
+ {
+ ResolveWhereClause r (where_clause.get_node_id ());
+ for (auto &clause : where_clause.get_items ())
+ clause->accept_vis (r);
+ }
+
+ void visit (AST::LifetimeWhereClauseItem &) override {}
+
+ void visit (AST::TypeBoundWhereClauseItem &item) override
+ {
+ ResolveType::go (item.get_type ().get (), item.get_node_id ());
+ if (item.has_type_param_bounds ())
+ {
+ for (auto &bound : item.get_type_param_bounds ())
+ {
+ ResolveTypeBound::go (bound.get (), item.get_node_id ());
+ }
+ }
+ }
+
+private:
+ ResolveWhereClause (NodeId parent) : ResolverBase (parent) {}
+}; // 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 501ce3f..062d60b 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-implitem.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-implitem.h
@@ -150,6 +150,11 @@ public:
= TypeCheckType::Resolve (alias.get_type_aliased ().get ());
context->insert_type (alias.get_mappings (), actual_type);
+
+ for (auto &where_clause_item : alias.get_where_clause ().get_items ())
+ {
+ ResolveWhereClauseItem::Resolve (*where_clause_item.get ());
+ }
}
void visit (HIR::ConstantItem &constant) override
@@ -191,6 +196,11 @@ public:
}
}
+ for (auto &where_clause_item : function.get_where_clause ().get_items ())
+ {
+ ResolveWhereClauseItem::Resolve (*where_clause_item.get ());
+ }
+
TyTy::BaseType *ret_type = nullptr;
if (!function.has_function_return_type ())
ret_type = new TyTy::TupleType (function.get_mappings ().get_hirid ());
diff --git a/gcc/rust/typecheck/rust-hir-type-check-toplevel.h b/gcc/rust/typecheck/rust-hir-type-check-toplevel.h
index a85fe66..a32d4a4 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-toplevel.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-toplevel.h
@@ -46,6 +46,11 @@ public:
= TypeCheckType::Resolve (alias.get_type_aliased ().get ());
context->insert_type (alias.get_mappings (), actual_type);
+
+ for (auto &where_clause_item : alias.get_where_clause ().get_items ())
+ {
+ ResolveWhereClauseItem::Resolve (*where_clause_item.get ());
+ }
}
void visit (HIR::TupleStruct &struct_decl) override
@@ -76,6 +81,11 @@ public:
}
}
+ for (auto &where_clause_item : struct_decl.get_where_clause ().get_items ())
+ {
+ ResolveWhereClauseItem::Resolve (*where_clause_item.get ());
+ }
+
std::vector<TyTy::StructFieldType *> fields;
size_t idx = 0;
@@ -136,6 +146,11 @@ public:
}
}
+ for (auto &where_clause_item : struct_decl.get_where_clause ().get_items ())
+ {
+ ResolveWhereClauseItem::Resolve (*where_clause_item.get ());
+ }
+
std::vector<TyTy::StructFieldType *> fields;
for (auto &field : struct_decl.get_fields ())
@@ -188,6 +203,11 @@ public:
}
}
+ for (auto &where_clause_item : union_decl.get_where_clause ().get_items ())
+ {
+ ResolveWhereClauseItem::Resolve (*where_clause_item.get ());
+ }
+
std::vector<TyTy::StructFieldType *> variants;
union_decl.iterate ([&] (HIR::StructField &variant) mutable -> bool {
TyTy::BaseType *variant_type
@@ -259,6 +279,11 @@ public:
}
}
+ for (auto &where_clause_item : function.get_where_clause ().get_items ())
+ {
+ ResolveWhereClauseItem::Resolve (*where_clause_item.get ());
+ }
+
TyTy::BaseType *ret_type = nullptr;
if (!function.has_function_return_type ())
ret_type = new TyTy::TupleType (function.get_mappings ().get_hirid ());
@@ -296,6 +321,7 @@ public:
TyTy::FnType::FNTYPE_DEFAULT_FLAGS,
ABI::RUST, std::move (params), ret_type,
std::move (substitutions));
+
context->insert_type (function.get_mappings (), fnType);
}
@@ -327,6 +353,11 @@ public:
}
}
+ for (auto &where_clause_item : impl_block.get_where_clause ().get_items ())
+ {
+ ResolveWhereClauseItem::Resolve (*where_clause_item.get ());
+ }
+
auto self
= TypeCheckType::Resolve (impl_block.get_type ().get (), &substitutions);
if (self == nullptr || self->get_kind () == TyTy::TypeKind::ERROR)
diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.h b/gcc/rust/typecheck/rust-hir-type-check-type.h
index b56b5a2..c2b6d7c 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-type.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-type.h
@@ -277,6 +277,111 @@ private:
TyTy::ParamType *resolved;
};
+class ResolveWhereClauseItem : public TypeCheckBase
+{
+ using Rust::Resolver::TypeCheckBase::visit;
+
+public:
+ static void Resolve (HIR::WhereClauseItem &item)
+ {
+ ResolveWhereClauseItem resolver;
+ item.accept_vis (resolver);
+ }
+
+ void visit (HIR::LifetimeWhereClauseItem &) override {}
+
+ void visit (HIR::TypeBoundWhereClauseItem &item) override
+ {
+ auto &binding_type_path = item.get_bound_type ();
+ TyTy::BaseType *binding = TypeCheckType::Resolve (binding_type_path.get ());
+
+ std::vector<TyTy::TypeBoundPredicate> specified_bounds;
+ for (auto &bound : item.get_type_param_bounds ())
+ {
+ switch (bound->get_bound_type ())
+ {
+ case HIR::TypeParamBound::BoundType::TRAITBOUND: {
+ HIR::TraitBound *b
+ = static_cast<HIR::TraitBound *> (bound.get ());
+
+ auto &type_path = b->get_path ();
+ TraitReference *trait = resolve_trait_path (type_path);
+ TyTy::TypeBoundPredicate predicate (
+ trait->get_mappings ().get_defid (), b->get_locus ());
+
+ auto &final_seg = type_path.get_final_segment ();
+ if (final_seg->is_generic_segment ())
+ {
+ auto final_generic_seg
+ = static_cast<HIR::TypePathSegmentGeneric *> (
+ final_seg.get ());
+ if (final_generic_seg->has_generic_args ())
+ {
+ HIR::GenericArgs &generic_args
+ = final_generic_seg->get_generic_args ();
+
+ // this is applying generic arguments to a trait
+ // reference
+ predicate.apply_generic_arguments (&generic_args);
+ }
+ }
+
+ specified_bounds.push_back (std::move (predicate));
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ binding->inherit_bounds (specified_bounds);
+
+ // When we apply these bounds we must lookup which type this binding
+ // resolves to, as this is the type which will be used during resolution of
+ // the block.
+ NodeId ast_node_id = binding_type_path->get_mappings ().get_nodeid ();
+
+ // then lookup the reference_node_id
+ NodeId ref_node_id = UNKNOWN_NODEID;
+ if (!resolver->lookup_resolved_type (ast_node_id, &ref_node_id))
+ {
+ // FIXME
+ rust_error_at (Location (),
+ "Failed to lookup type reference for node: %s",
+ binding_type_path->as_string ().c_str ());
+ return;
+ }
+
+ // node back to HIR
+ HirId ref;
+ if (!mappings->lookup_node_to_hir (
+ binding_type_path->get_mappings ().get_crate_num (), ref_node_id,
+ &ref))
+ {
+ // FIXME
+ rust_error_at (Location (), "where-clause reverse lookup failure");
+ return;
+ }
+
+ // the base reference for this name _must_ have a type set
+ TyTy::BaseType *lookup;
+ if (!context->lookup_type (ref, &lookup))
+ {
+ rust_error_at (mappings->lookup_location (ref),
+ "Failed to resolve where-clause binding type: %s",
+ binding_type_path->as_string ().c_str ());
+ return;
+ }
+
+ // FIXME
+ // rust_assert (binding->is_equal (*lookup));
+ lookup->inherit_bounds (specified_bounds);
+ }
+
+private:
+ ResolveWhereClauseItem () : TypeCheckBase () {}
+};
+
} // namespace Resolver
} // namespace Rust
diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h
index aa24464..ef37dc6 100644
--- a/gcc/rust/typecheck/rust-tyty.h
+++ b/gcc/rust/typecheck/rust-tyty.h
@@ -380,7 +380,7 @@ public:
std::string debug_str () const
{
return TypeKindFormat::to_string (get_kind ()) + ":" + as_string () + ":"
- + mappings_str ();
+ + mappings_str () + ":" + bounds_as_string ();
}
void debug () const
diff --git a/gcc/testsuite/rust/compile/torture/traits10.rs b/gcc/testsuite/rust/compile/torture/traits10.rs
index 3e47b1b..a492ec3 100644
--- a/gcc/testsuite/rust/compile/torture/traits10.rs
+++ b/gcc/testsuite/rust/compile/torture/traits10.rs
@@ -1,6 +1,5 @@
-trait Foo
-where
- Self: Sized,
+trait Foo // where
+// Self: Sized,
{
fn get(self) -> i32;
// { dg-warning "unused name" "" { target *-*-* } .-1 }
diff --git a/gcc/testsuite/rust/compile/torture/traits18.rs b/gcc/testsuite/rust/compile/torture/traits18.rs
new file mode 100644
index 0000000..77cc5c2
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/traits18.rs
@@ -0,0 +1,8 @@
+trait Foo<'a> {}
+
+trait Bar {
+ // { dg-warning "unused name .Bar." "" { target *-*-* } .-1 }
+
+ type Item: for<'a> Foo<'a>;
+ // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/execute/torture/trait11.rs b/gcc/testsuite/rust/execute/torture/trait11.rs
new file mode 100644
index 0000000..53a8a8e
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/trait11.rs
@@ -0,0 +1,41 @@
+/* { dg-output "3\n" } */
+extern "C" {
+ fn printf(s: *const i8, ...);
+}
+
+trait FnLike<A, R> {
+ fn call(&self, arg: A) -> R;
+ // { dg-warning "unused name .self." "" { target *-*-* } .-1 }
+ // { dg-warning "unused name .arg." "" { target *-*-* } .-2 }
+}
+
+struct S;
+impl<'a, T> FnLike<&'a T, &'a T> for S {
+ fn call(&self, arg: &'a T) -> &'a T {
+ // { dg-warning "unused name .self." "" { target *-*-* } .-1 }
+ // { dg-warning "unused name" "" { target *-*-* } .-2 }
+ arg
+ }
+}
+
+fn indirect<F>(f: F)
+where
+ F: for<'a> FnLike<&'a isize, &'a isize>,
+{
+ let x = 3;
+ let y = f.call(&x);
+
+ unsafe {
+ let a = "%i\n\0";
+ let b = a as *const str;
+ let c = b as *const i8;
+
+ printf(c, *y);
+ }
+}
+
+fn main() -> i32 {
+ indirect(S);
+
+ 0
+}