diff options
Diffstat (limited to 'gcc/rust')
-rw-r--r-- | gcc/rust/ast/rust-item.h | 119 | ||||
-rw-r--r-- | gcc/rust/hir/rust-ast-lower-item.h | 72 | ||||
-rw-r--r-- | gcc/rust/hir/rust-ast-lower-type.h | 72 | ||||
-rw-r--r-- | gcc/rust/hir/tree/rust-hir-item.h | 106 | ||||
-rw-r--r-- | gcc/rust/parse/rust-parse-impl.h | 5 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-item.h | 48 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-type.h | 30 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-implitem.h | 10 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-toplevel.h | 31 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-type.h | 105 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty.h | 2 |
11 files changed, 480 insertions, 120 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> &¶m) { @@ -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 ¶m) 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 |