aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Herron <philip.herron@embecosm.com>2021-07-28 18:34:00 +0100
committerPhilip Herron <philip.herron@embecosm.com>2021-08-05 18:17:40 +0100
commitb333711461c8244bc2b46c736858950837ba7bbf (patch)
tree50adf3b7b04bf4da624b60546c11652cce5e8baa
parent074c070c02e61033694f2f969a33a795036ad540 (diff)
downloadgcc-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.h13
-rw-r--r--gcc/rust/ast/rust-type.h3
-rw-r--r--gcc/rust/hir/rust-ast-lower-base.h20
-rw-r--r--gcc/rust/hir/rust-ast-lower-type.h78
-rw-r--r--gcc/rust/hir/rust-ast-lower.cc6
-rw-r--r--gcc/rust/hir/tree/rust-hir-full-test.cc9
-rw-r--r--gcc/rust/hir/tree/rust-hir-item.h3
-rw-r--r--gcc/rust/hir/tree/rust-hir-type.h24
-rw-r--r--gcc/rust/hir/tree/rust-hir.h53
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