diff options
author | Philip Herron <philip.herron@embecosm.com> | 2021-07-28 18:34:00 +0100 |
---|---|---|
committer | Philip Herron <philip.herron@embecosm.com> | 2021-08-05 18:17:40 +0100 |
commit | b333711461c8244bc2b46c736858950837ba7bbf (patch) | |
tree | 50adf3b7b04bf4da624b60546c11652cce5e8baa | |
parent | 074c070c02e61033694f2f969a33a795036ad540 (diff) | |
download | gcc-b333711461c8244bc2b46c736858950837ba7bbf.zip gcc-b333711461c8244bc2b46c736858950837ba7bbf.tar.gz gcc-b333711461c8244bc2b46c736858950837ba7bbf.tar.bz2 |
Add lowering for TypeBounds on Generic Parameters
Preserve type-bounds into HIR for type resolution and code generation. This
follows the same style of classes in the AST and might need some tweaks
for where constraints.
-rw-r--r-- | gcc/rust/ast/rust-ast.h | 13 | ||||
-rw-r--r-- | gcc/rust/ast/rust-type.h | 3 | ||||
-rw-r--r-- | gcc/rust/hir/rust-ast-lower-base.h | 20 | ||||
-rw-r--r-- | gcc/rust/hir/rust-ast-lower-type.h | 78 | ||||
-rw-r--r-- | gcc/rust/hir/rust-ast-lower.cc | 6 | ||||
-rw-r--r-- | gcc/rust/hir/tree/rust-hir-full-test.cc | 9 | ||||
-rw-r--r-- | gcc/rust/hir/tree/rust-hir-item.h | 3 | ||||
-rw-r--r-- | gcc/rust/hir/tree/rust-hir-type.h | 24 | ||||
-rw-r--r-- | gcc/rust/hir/tree/rust-hir.h | 53 |
9 files changed, 134 insertions, 75 deletions
diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h index 067e2f5b..6baef3f 100644 --- a/gcc/rust/ast/rust-ast.h +++ b/gcc/rust/ast/rust-ast.h @@ -1126,9 +1126,16 @@ public: virtual void accept_vis (ASTVisitor &vis) = 0; + NodeId get_node_id () const { return node_id; } + protected: // Clone function implementation as pure virtual method virtual TypeParamBound *clone_type_param_bound_impl () const = 0; + + TypeParamBound () : node_id (Analysis::Mappings::get ()->get_next_node_id ()) + {} + + NodeId node_id; }; // Represents a lifetime (and is also a kind of type param bound) @@ -1144,14 +1151,8 @@ public: private: LifetimeType lifetime_type; - - // TODO: LIFETIME_OR_LABEL (aka lifetime token) is only field - // find way of enclosing token or something std::string lifetime_name; - // only applies for NAMED lifetime_type - Location locus; - NodeId node_id; public: diff --git a/gcc/rust/ast/rust-type.h b/gcc/rust/ast/rust-type.h index a9c1966..e179bb7 100644 --- a/gcc/rust/ast/rust-type.h +++ b/gcc/rust/ast/rust-type.h @@ -65,6 +65,9 @@ public: TypePath &get_type_path () { return type_path; } const TypePath &get_type_path () const { return type_path; } + bool is_in_parens () const { return in_parens; } + bool has_opening_question_mark () const { return opening_question_mark; } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ diff --git a/gcc/rust/hir/rust-ast-lower-base.h b/gcc/rust/hir/rust-ast-lower-base.h index 7ef5938..b1d0df3 100644 --- a/gcc/rust/hir/rust-ast-lower-base.h +++ b/gcc/rust/hir/rust-ast-lower-base.h @@ -245,20 +245,6 @@ protected: HIR::Lifetime lower_lifetime (AST::Lifetime &lifetime) { - HIR::Lifetime::LifetimeType type = HIR::Lifetime::LifetimeType::NAMED; - switch (lifetime.get_lifetime_type ()) - { - case AST::Lifetime::LifetimeType::NAMED: - type = HIR::Lifetime::LifetimeType::NAMED; - break; - case AST::Lifetime::LifetimeType::STATIC: - type = HIR::Lifetime::LifetimeType::STATIC; - break; - case AST::Lifetime::LifetimeType::WILDCARD: - type = HIR::Lifetime::LifetimeType::WILDCARD; - break; - } - auto crate_num = mappings->get_current_crate (); Analysis::NodeMapping mapping (crate_num, lifetime.get_node_id (), mappings->get_next_hir_id (crate_num), @@ -266,8 +252,8 @@ protected: mappings->insert_node_to_hir (mapping.get_crate_num (), mapping.get_nodeid (), mapping.get_hirid ()); - return HIR::Lifetime (mapping, type, lifetime.get_lifetime_name (), - lifetime.get_locus ()); + return HIR::Lifetime (mapping, lifetime.get_lifetime_type (), + lifetime.get_lifetime_name (), lifetime.get_locus ()); } HIR::LoopLabel lower_loop_label (AST::LoopLabel &loop_label) @@ -296,6 +282,8 @@ protected: HIR::SelfParam lower_self (AST::SelfParam &self); HIR::Type *lower_type_no_bounds (AST::TypeNoBounds *type); + + HIR::TypeParamBound *lower_bound (AST::TypeParamBound *bound); }; } // namespace HIR diff --git a/gcc/rust/hir/rust-ast-lower-type.h b/gcc/rust/hir/rust-ast-lower-type.h index efaf9db..8db8637 100644 --- a/gcc/rust/hir/rust-ast-lower-type.h +++ b/gcc/rust/hir/rust-ast-lower-type.h @@ -294,24 +294,9 @@ public: Analysis::NodeMapping mapping (crate_num, param.get_node_id (), mappings->get_next_hir_id (crate_num), mappings->get_next_localdef_id (crate_num)); - HIR::Lifetime::LifetimeType ltt; - switch (param.get_lifetime ().get_lifetime_type ()) - { - case AST::Lifetime::LifetimeType::NAMED: - ltt = HIR::Lifetime::LifetimeType::NAMED; - break; - case AST::Lifetime::LifetimeType::STATIC: - ltt = HIR::Lifetime::LifetimeType::STATIC; - break; - case AST::Lifetime::LifetimeType::WILDCARD: - ltt = HIR::Lifetime::LifetimeType::WILDCARD; - break; - default: - gcc_unreachable (); - } - - HIR::Lifetime lt (mapping, ltt, param.get_lifetime ().get_lifetime_name (), + HIR::Lifetime lt (mapping, param.get_lifetime ().get_lifetime_type (), + param.get_lifetime ().get_lifetime_name (), param.get_lifetime ().get_locus ()); translated = new HIR::LifetimeParam (mapping, lt, param.get_locus (), @@ -322,6 +307,16 @@ public: { AST::Attribute outer_attr = AST::Attribute::create_empty (); std::vector<std::unique_ptr<HIR::TypeParamBound> > type_param_bounds; + if (param.has_type_param_bounds ()) + { + for (auto &bound : param.get_type_param_bounds ()) + { + HIR::TypeParamBound *lowered_bound = lower_bound (bound.get ()); + type_param_bounds.push_back ( + std::unique_ptr<HIR::TypeParamBound> (lowered_bound)); + } + } + HIR::Type *type = param.has_type () ? ASTLoweringType::translate (param.get_type ().get ()) : nullptr; @@ -344,6 +339,55 @@ private: HIR::GenericParam *translated; }; +class ASTLoweringTypeBounds : public ASTLoweringBase +{ + using Rust::HIR::ASTLoweringBase::visit; + +public: + static HIR::TypeParamBound *translate (AST::TypeParamBound *type) + { + ASTLoweringTypeBounds resolver; + type->accept_vis (resolver); + + rust_assert (resolver.translated != nullptr); + resolver.mappings->insert_location ( + resolver.translated->get_mappings ().get_crate_num (), + resolver.translated->get_mappings ().get_hirid (), + resolver.translated->get_locus_slow ()); + + return resolver.translated; + } + + void visit (AST::TraitBound &bound) override + { + // FIXME + std::vector<HIR::LifetimeParam> lifetimes; + + AST::TypePath &ast_trait_path = bound.get_type_path (); + HIR::TypePath *trait_path = ASTLowerTypePath::translate (ast_trait_path); + + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping mapping (crate_num, bound.get_node_id (), + mappings->get_next_hir_id (crate_num), + UNKNOWN_LOCAL_DEFID); + + translated = new HIR::TraitBound (mapping, *trait_path, bound.get_locus (), + bound.is_in_parens (), + bound.has_opening_question_mark ()); + } + + void visit (AST::Lifetime &bound) override + { + HIR::Lifetime lifetime = lower_lifetime (bound); + translated = new HIR::Lifetime (lifetime); + } + +private: + ASTLoweringTypeBounds () : ASTLoweringBase (), translated (nullptr) {} + + HIR::TypeParamBound *translated; +}; + } // namespace HIR } // namespace Rust diff --git a/gcc/rust/hir/rust-ast-lower.cc b/gcc/rust/hir/rust-ast-lower.cc index 04587ed..23914f8 100644 --- a/gcc/rust/hir/rust-ast-lower.cc +++ b/gcc/rust/hir/rust-ast-lower.cc @@ -403,5 +403,11 @@ ASTLoweringBase::lower_type_no_bounds (AST::TypeNoBounds *type) return ASTLoweringType::translate (type); } +HIR::TypeParamBound * +ASTLoweringBase::lower_bound (AST::TypeParamBound *bound) +{ + return ASTLoweringTypeBounds::translate (bound); +} + } // namespace HIR } // namespace Rust diff --git a/gcc/rust/hir/tree/rust-hir-full-test.cc b/gcc/rust/hir/tree/rust-hir-full-test.cc index d61d060..dee2827 100644 --- a/gcc/rust/hir/tree/rust-hir-full-test.cc +++ b/gcc/rust/hir/tree/rust-hir-full-test.cc @@ -2113,11 +2113,11 @@ Lifetime::as_string () const switch (lifetime_type) { - case NAMED: + case AST::Lifetime::LifetimeType::NAMED: return "'" + lifetime_name; - case STATIC: + case AST::Lifetime::LifetimeType::STATIC: return "'static"; - case WILDCARD: + case AST::Lifetime::LifetimeType::WILDCARD: return "'_"; default: return "ERROR-MARK-STRING: lifetime type failure"; @@ -2747,7 +2747,8 @@ TypePath::to_trait_bound (bool in_parens) const // create clone FIXME is this required? or is copy constructor automatically // called? TypePath copy (*this); - return new TraitBound (std::move (copy), copy.get_locus (), in_parens); + return new TraitBound (mappings, std::move (copy), copy.get_locus (), + in_parens); } std::string diff --git a/gcc/rust/hir/tree/rust-hir-item.h b/gcc/rust/hir/tree/rust-hir-item.h index 182fe87..3ad06c8 100644 --- a/gcc/rust/hir/tree/rust-hir-item.h +++ b/gcc/rust/hir/tree/rust-hir-item.h @@ -333,7 +333,8 @@ public: SelfParam (Analysis::NodeMapping mappings, std::unique_ptr<Type> type, bool is_mut, Location locus) : self_kind (is_mut ? ImplicitSelfKind::MUT : ImplicitSelfKind::IMM), - lifetime (Lifetime (mappings, Lifetime::LifetimeType::NAMED, "", locus)), + lifetime ( + Lifetime (mappings, AST::Lifetime::LifetimeType::NAMED, "", locus)), type (std::move (type)), locus (locus), mappings (mappings) {} diff --git a/gcc/rust/hir/tree/rust-hir-type.h b/gcc/rust/hir/tree/rust-hir-type.h index 3cb4be1..87dffcf 100644 --- a/gcc/rust/hir/tree/rust-hir-type.h +++ b/gcc/rust/hir/tree/rust-hir-type.h @@ -33,26 +33,23 @@ class TraitBound : public TypeParamBound { bool in_parens; bool opening_question_mark; - - // bool has_for_lifetimes; - // LifetimeParams for_lifetimes; - std::vector<LifetimeParam> for_lifetimes; // inlined LifetimeParams - + std::vector<LifetimeParam> for_lifetimes; TypePath type_path; - Location locus; + Analysis::NodeMapping mappings; + public: // Returns whether trait bound has "for" lifetimes bool has_for_lifetimes () const { return !for_lifetimes.empty (); } - TraitBound (TypePath type_path, Location locus, bool in_parens = false, - bool opening_question_mark = false, + TraitBound (Analysis::NodeMapping mapping, TypePath type_path, Location locus, + bool in_parens = false, bool opening_question_mark = false, std::vector<LifetimeParam> for_lifetimes = std::vector<LifetimeParam> ()) : in_parens (in_parens), opening_question_mark (opening_question_mark), for_lifetimes (std::move (for_lifetimes)), - type_path (std::move (type_path)), locus (locus) + type_path (std::move (type_path)), locus (locus), mappings (mapping) {} std::string as_string () const override; @@ -61,6 +58,15 @@ public: void accept_vis (HIRVisitor &vis) override; + Analysis::NodeMapping get_mappings () const override final + { + return mappings; + } + + Location get_locus_slow () const override final { return get_locus (); } + + BoundType get_bound_type () const final override { return TRAITBOUND; } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ diff --git a/gcc/rust/hir/tree/rust-hir.h b/gcc/rust/hir/tree/rust-hir.h index 7d53feb..20408bb 100644 --- a/gcc/rust/hir/tree/rust-hir.h +++ b/gcc/rust/hir/tree/rust-hir.h @@ -406,6 +406,12 @@ protected: class TypeParamBound { public: + enum BoundType + { + LIFETIME, + TRAITBOUND + }; + virtual ~TypeParamBound () {} // Unique pointer custom clone function @@ -418,6 +424,12 @@ public: virtual void accept_vis (HIRVisitor &vis) = 0; + virtual Analysis::NodeMapping get_mappings () const = 0; + + virtual Location get_locus_slow () const = 0; + + virtual BoundType get_bound_type () const = 0; + protected: // Clone function implementation as pure virtual method virtual TypeParamBound *clone_type_param_bound_impl () const = 0; @@ -426,30 +438,16 @@ protected: // Represents a lifetime (and is also a kind of type param bound) class Lifetime : public TypeParamBound { -public: - enum LifetimeType - { - NAMED, // corresponds to LIFETIME_OR_LABEL - STATIC, // corresponds to 'static - WILDCARD // corresponds to '_ - }; - private: - LifetimeType lifetime_type; - - // TODO: LIFETIME_OR_LABEL (aka lifetime token) is only field - // find way of enclosing token or something + AST::Lifetime::LifetimeType lifetime_type; std::string lifetime_name; - // only applies for NAMED lifetime_type - Location locus; - Analysis::NodeMapping mappings; public: // Constructor - Lifetime (Analysis::NodeMapping mapping, LifetimeType type, std::string name, - Location locus) + Lifetime (Analysis::NodeMapping mapping, AST::Lifetime::LifetimeType type, + std::string name, Location locus) : lifetime_type (type), lifetime_name (std::move (name)), locus (locus), mappings (mapping) {} @@ -457,13 +455,14 @@ public: // Returns true if the lifetime is in an error state. bool is_error () const { - return lifetime_type == NAMED && lifetime_name.empty (); + return lifetime_type == AST::Lifetime::LifetimeType::NAMED + && lifetime_name.empty (); } static Lifetime error () { - return Lifetime (Analysis::NodeMapping::get_error (), LifetimeType::NAMED, - "", Location ()); + return Lifetime (Analysis::NodeMapping::get_error (), + AST::Lifetime::LifetimeType::NAMED, "", Location ()); } std::string as_string () const override; @@ -472,11 +471,21 @@ public: std::string get_name () const { return lifetime_name; } - LifetimeType get_lifetime_type () const { return lifetime_type; } + AST::Lifetime::LifetimeType get_lifetime_type () const + { + return lifetime_type; + } Location get_locus () const { return locus; } - Analysis::NodeMapping get_mappings () const { return mappings; } + Analysis::NodeMapping get_mappings () const override final + { + return mappings; + } + + Location get_locus_slow () const override final { return get_locus (); } + + BoundType get_bound_type () const final override { return LIFETIME; } protected: /* Use covariance to implement clone function as returning this object rather |