Skip to content

Commit e28c43f

Browse files
bors[bot]philberty
andauthored
Merge #771
771: Add higher ranked trait bounds r=philberty a=philberty This adds support for where clauses and higher ranked trait bounds more test cases are needed since where clauses are supported on associated types, impls, ADT's etc. See the individual commits for more detail on implementation. Fixes #773 #442 Co-authored-by: Philip Herron <[email protected]>
2 parents 161a690 + 7604b64 commit e28c43f

14 files changed

+531
-123
lines changed

gcc/rust/ast/rust-item.h

+42-77
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,8 @@ class WhereClauseItem
177177

178178
virtual void accept_vis (ASTVisitor &vis) = 0;
179179

180+
virtual NodeId get_node_id () const = 0;
181+
180182
protected:
181183
// Clone function implementation as pure virtual method
182184
virtual WhereClauseItem *clone_where_clause_item_impl () const = 0;
@@ -186,24 +188,31 @@ class WhereClauseItem
186188
class LifetimeWhereClauseItem : public WhereClauseItem
187189
{
188190
Lifetime lifetime;
189-
190-
// LifetimeBounds lifetime_bounds;
191-
std::vector<Lifetime> lifetime_bounds; // inlined lifetime bounds
192-
191+
std::vector<Lifetime> lifetime_bounds;
193192
Location locus;
193+
NodeId node_id;
194194

195195
public:
196196
LifetimeWhereClauseItem (Lifetime lifetime,
197197
std::vector<Lifetime> lifetime_bounds,
198198
Location locus)
199199
: lifetime (std::move (lifetime)),
200-
lifetime_bounds (std::move (lifetime_bounds)), locus (locus)
200+
lifetime_bounds (std::move (lifetime_bounds)), locus (locus),
201+
node_id (Analysis::Mappings::get ()->get_next_node_id ())
201202
{}
202203

203204
std::string as_string () const override;
204205

205206
void accept_vis (ASTVisitor &vis) override;
206207

208+
NodeId get_node_id () const override final { return node_id; }
209+
210+
Lifetime &get_lifetime () { return lifetime; }
211+
212+
std::vector<Lifetime> &get_lifetime_bounds () { return lifetime_bounds; }
213+
214+
Location get_locus () const { return locus; }
215+
207216
protected:
208217
// Clone function implementation as (not pure) virtual method
209218
LifetimeWhereClauseItem *clone_where_clause_item_impl () const override
@@ -215,18 +224,10 @@ class LifetimeWhereClauseItem : public WhereClauseItem
215224
// A type bound where clause item
216225
class TypeBoundWhereClauseItem : public WhereClauseItem
217226
{
218-
// bool has_for_lifetimes;
219-
// LifetimeParams for_lifetimes;
220-
std::vector<LifetimeParam> for_lifetimes; // inlined
221-
227+
std::vector<LifetimeParam> for_lifetimes;
222228
std::unique_ptr<Type> bound_type;
223-
224-
// bool has_type_param_bounds;
225-
// TypeParamBounds type_param_bounds;
226-
std::vector<std::unique_ptr<TypeParamBound>>
227-
type_param_bounds; // inlined form
228-
229-
// should this store location info?
229+
std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds;
230+
NodeId node_id;
230231

231232
public:
232233
// Returns whether the item has ForLifetimes
@@ -240,14 +241,16 @@ class TypeBoundWhereClauseItem : public WhereClauseItem
240241
std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds)
241242
: for_lifetimes (std::move (for_lifetimes)),
242243
bound_type (std::move (bound_type)),
243-
type_param_bounds (std::move (type_param_bounds))
244+
type_param_bounds (std::move (type_param_bounds)),
245+
node_id (Analysis::Mappings::get ()->get_next_node_id ())
244246
{}
245247

246248
// Copy constructor requires clone
247249
TypeBoundWhereClauseItem (TypeBoundWhereClauseItem const &other)
248250
: for_lifetimes (other.for_lifetimes),
249251
bound_type (other.bound_type->clone_type ())
250252
{
253+
node_id = other.node_id;
251254
type_param_bounds.reserve (other.type_param_bounds.size ());
252255
for (const auto &e : other.type_param_bounds)
253256
type_param_bounds.push_back (e->clone_type_param_bound ());
@@ -256,9 +259,9 @@ class TypeBoundWhereClauseItem : public WhereClauseItem
256259
// Overload assignment operator to clone
257260
TypeBoundWhereClauseItem &operator= (TypeBoundWhereClauseItem const &other)
258261
{
262+
node_id = other.node_id;
259263
for_lifetimes = other.for_lifetimes;
260264
bound_type = other.bound_type->clone_type ();
261-
262265
type_param_bounds.reserve (other.type_param_bounds.size ());
263266
for (const auto &e : other.type_param_bounds)
264267
type_param_bounds.push_back (e->clone_type_param_bound ());
@@ -275,7 +278,6 @@ class TypeBoundWhereClauseItem : public WhereClauseItem
275278

276279
void accept_vis (ASTVisitor &vis) override;
277280

278-
// TODO: is this better? Or is a "vis_block" better?
279281
std::unique_ptr<Type> &get_type ()
280282
{
281283
rust_assert (bound_type != nullptr);
@@ -287,12 +289,15 @@ class TypeBoundWhereClauseItem : public WhereClauseItem
287289
{
288290
return type_param_bounds;
289291
}
292+
290293
const std::vector<std::unique_ptr<TypeParamBound>> &
291294
get_type_param_bounds () const
292295
{
293296
return type_param_bounds;
294297
}
295298

299+
NodeId get_node_id () const override final { return node_id; }
300+
296301
protected:
297302
// Clone function implementation as (not pure) virtual method
298303
TypeBoundWhereClauseItem *clone_where_clause_item_impl () const override
@@ -306,17 +311,18 @@ struct WhereClause
306311
{
307312
private:
308313
std::vector<std::unique_ptr<WhereClauseItem>> where_clause_items;
309-
310-
// should this store location info?
314+
NodeId node_id;
311315

312316
public:
313317
WhereClause (std::vector<std::unique_ptr<WhereClauseItem>> where_clause_items)
314-
: where_clause_items (std::move (where_clause_items))
318+
: where_clause_items (std::move (where_clause_items)),
319+
node_id (Analysis::Mappings::get ()->get_next_node_id ())
315320
{}
316321

317322
// copy constructor with vector clone
318323
WhereClause (WhereClause const &other)
319324
{
325+
node_id = other.node_id;
320326
where_clause_items.reserve (other.where_clause_items.size ());
321327
for (const auto &e : other.where_clause_items)
322328
where_clause_items.push_back (e->clone_where_clause_item ());
@@ -325,6 +331,7 @@ struct WhereClause
325331
// overloaded assignment operator with vector clone
326332
WhereClause &operator= (WhereClause const &other)
327333
{
334+
node_id = other.node_id;
328335
where_clause_items.reserve (other.where_clause_items.size ());
329336
for (const auto &e : other.where_clause_items)
330337
where_clause_items.push_back (e->clone_where_clause_item ());
@@ -347,6 +354,8 @@ struct WhereClause
347354

348355
std::string as_string () const;
349356

357+
NodeId get_node_id () const { return node_id; }
358+
350359
// TODO: this mutable getter seems kinda dodgy
351360
std::vector<std::unique_ptr<WhereClauseItem>> &get_items ()
352361
{
@@ -878,11 +887,7 @@ class Method : public InherentImplItem, public TraitImplItem
878887
}
879888

880889
// TODO: is this better? Or is a "vis_block" better?
881-
WhereClause &get_where_clause ()
882-
{
883-
rust_assert (has_where_clause ());
884-
return where_clause;
885-
}
890+
WhereClause &get_where_clause () { return where_clause; }
886891

887892
Identifier get_method_name () const { return method_name; }
888893

@@ -1578,11 +1583,7 @@ class Function : public VisItem, public InherentImplItem, public TraitImplItem
15781583
Identifier get_function_name () const { return function_name; }
15791584

15801585
// TODO: is this better? Or is a "vis_block" better?
1581-
WhereClause &get_where_clause ()
1582-
{
1583-
rust_assert (has_where_clause ());
1584-
return where_clause;
1585-
}
1586+
WhereClause &get_where_clause () { return where_clause; }
15861587

15871588
// TODO: is this better? Or is a "vis_block" better?
15881589
std::unique_ptr<Type> &get_return_type ()
@@ -1710,11 +1711,7 @@ class TypeAlias : public VisItem, public TraitImplItem
17101711
}
17111712

17121713
// TODO: is this better? Or is a "vis_block" better?
1713-
WhereClause &get_where_clause ()
1714-
{
1715-
rust_assert (has_where_clause ());
1716-
return where_clause;
1717-
}
1714+
WhereClause &get_where_clause () { return where_clause; }
17181715

17191716
// TODO: is this better? Or is a "vis_block" better?
17201717
std::unique_ptr<Type> &get_type_aliased ()
@@ -1780,11 +1777,7 @@ class Struct : public VisItem
17801777
}
17811778

17821779
// TODO: is this better? Or is a "vis_block" better?
1783-
WhereClause &get_where_clause ()
1784-
{
1785-
rust_assert (has_where_clause ());
1786-
return where_clause;
1787-
}
1780+
WhereClause &get_where_clause () { return where_clause; }
17881781

17891782
Identifier get_identifier () const { return struct_name; }
17901783

@@ -2401,11 +2394,7 @@ class Enum : public VisItem
24012394
}
24022395

24032396
// TODO: is this better? Or is a "vis_block" better?
2404-
WhereClause &get_where_clause ()
2405-
{
2406-
rust_assert (has_where_clause ());
2407-
return where_clause;
2408-
}
2397+
WhereClause &get_where_clause () { return where_clause; }
24092398

24102399
protected:
24112400
/* Use covariance to implement clone function as returning this object
@@ -2511,11 +2500,7 @@ class Union : public VisItem
25112500
}
25122501

25132502
// TODO: is this better? Or is a "vis_block" better?
2514-
WhereClause &get_where_clause ()
2515-
{
2516-
rust_assert (has_where_clause ());
2517-
return where_clause;
2518-
}
2503+
WhereClause &get_where_clause () { return where_clause; }
25192504

25202505
Identifier get_identifier () const { return union_name; }
25212506

@@ -2868,11 +2853,7 @@ struct TraitFunctionDecl
28682853
}
28692854

28702855
// TODO: is this better? Or is a "vis_block" better?
2871-
WhereClause &get_where_clause ()
2872-
{
2873-
rust_assert (has_where_clause ());
2874-
return where_clause;
2875-
}
2856+
WhereClause &get_where_clause () { return where_clause; }
28762857
};
28772858

28782859
// Actual trait item function declaration within traits
@@ -3095,11 +3076,7 @@ struct TraitMethodDecl
30953076
}
30963077

30973078
// TODO: is this better? Or is a "vis_block" better?
3098-
WhereClause &get_where_clause ()
3099-
{
3100-
rust_assert (has_where_clause ());
3101-
return where_clause;
3102-
}
3079+
WhereClause &get_where_clause () { return where_clause; }
31033080

31043081
SelfParam &get_self_param () { return self_param; }
31053082
const SelfParam &get_self_param () const { return self_param; }
@@ -3533,11 +3510,7 @@ class Trait : public VisItem
35333510
return type_param_bounds;
35343511
}
35353512

3536-
WhereClause &get_where_clause ()
3537-
{
3538-
rust_assert (has_where_clause ());
3539-
return where_clause;
3540-
}
3513+
WhereClause &get_where_clause () { return where_clause; }
35413514

35423515
void insert_implict_self (std::unique_ptr<AST::GenericParam> &&param)
35433516
{
@@ -3610,11 +3583,7 @@ class Impl : public VisItem
36103583
}
36113584

36123585
// TODO: is this better? Or is a "vis_block" better?
3613-
WhereClause &get_where_clause ()
3614-
{
3615-
rust_assert (has_where_clause ());
3616-
return where_clause;
3617-
}
3586+
WhereClause &get_where_clause () { return where_clause; }
36183587

36193588
// TODO: is this better? Or is a "vis_block" better?
36203589
std::unique_ptr<Type> &get_type ()
@@ -4261,11 +4230,7 @@ class ExternalFunctionItem : public ExternalItem
42614230
}
42624231

42634232
// TODO: is this better? Or is a "vis_block" better?
4264-
WhereClause &get_where_clause ()
4265-
{
4266-
rust_assert (has_where_clause ());
4267-
return where_clause;
4268-
}
4233+
WhereClause &get_where_clause () { return where_clause; }
42694234

42704235
// TODO: is this better? Or is a "vis_block" better?
42714236
std::unique_ptr<Type> &get_return_type ()

0 commit comments

Comments
 (0)