Skip to content

Commit f942905

Browse files
philbertyCohenArthur
authored andcommitted
gccrs: Add support for initial generic associated types
This patch is the initial part in supporting generic associated types. In rust we have trait item types that get implemented for example: trait Foo<T> { type Bar } impl<T> Foo for T { type Bar = T } The trait position uses a Ty::Placeholder which is just a thing that gets set for lazy evaluation to the impl type alias which is actually a Ty::Projection see: 0798add For more info the projection type needs to hold onto generics in order to properly support generic types this GAT's support extends this all the way to the placeholder which still needs to be done. Fixes #4276 gcc/rust/ChangeLog: * ast/rust-ast.cc (TraitItemType::as_string): add generic params * ast/rust-ast.h: remove old comment * ast/rust-item.h: add generic params to associated type * ast/rust-type.h: remove old comment * hir/rust-ast-lower-implitem.cc (ASTLowerTraitItem::visit): hir lowering for gat's * hir/tree/rust-hir-item.cc (TraitItemType::TraitItemType): gat's on TraitItemType (TraitItemType::operator=): preserve generic params * hir/tree/rust-hir-item.h: likewise * hir/tree/rust-hir.cc (TraitItemType::as_string): likewise * parse/rust-parse-impl.h (Parser::parse_trait_type): hit the < and parse params * typecheck/rust-hir-type-check-implitem.cc (TypeCheckImplItemWithTrait::visit): typecheck * typecheck/rust-tyty.cc (BaseType::has_substitutions_defined): dont destructure gcc/testsuite/ChangeLog: * rust/compile/gat1.rs: New test. * rust/execute/torture/gat1.rs: New test. Signed-off-by: Philip Herron <[email protected]>
1 parent 8c9fcb9 commit f942905

File tree

13 files changed

+134
-18
lines changed

13 files changed

+134
-18
lines changed

gcc/rust/ast/rust-ast.cc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3050,6 +3050,18 @@ TraitItemType::as_string () const
30503050

30513051
str += "\ntype " + name.as_string ();
30523052

3053+
if (has_generics ())
3054+
{
3055+
str += "<";
3056+
for (size_t i = 0; i < generic_params.size (); i++)
3057+
{
3058+
if (i > 0)
3059+
str += ", ";
3060+
str += generic_params[i]->as_string ();
3061+
}
3062+
str += ">";
3063+
}
3064+
30533065
str += "\n Type param bounds: ";
30543066
if (!has_type_param_bounds ())
30553067
{

gcc/rust/ast/rust-ast.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1891,7 +1891,6 @@ struct MacroInvocData
18911891
{
18921892
parsed_items = std::move (new_items);
18931893
}
1894-
// TODO: mutable getter seems kinda dodgy
18951894
std::vector<std::unique_ptr<MetaItemInner>> &get_meta_items ()
18961895
{
18971896
return parsed_items;

gcc/rust/ast/rust-item.h

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2726,21 +2726,28 @@ class TraitItemType : public TraitItem
27262726

27272727
Identifier name;
27282728

2729+
// Generic parameters for GATs (Generic Associated Types)
2730+
std::vector<std::unique_ptr<GenericParam>> generic_params;
2731+
27292732
// bool has_type_param_bounds;
27302733
// TypeParamBounds type_param_bounds;
27312734
std::vector<std::unique_ptr<TypeParamBound>>
27322735
type_param_bounds; // inlined form
27332736

27342737
public:
2738+
bool has_generics () const { return !generic_params.empty (); }
2739+
27352740
// Returns whether trait item type has type param bounds.
27362741
bool has_type_param_bounds () const { return !type_param_bounds.empty (); }
27372742

27382743
TraitItemType (Identifier name,
2744+
std::vector<std::unique_ptr<GenericParam>> generic_params,
27392745
std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds,
27402746
std::vector<Attribute> outer_attrs, Visibility vis,
27412747
location_t locus)
27422748
: TraitItem (vis, locus), outer_attrs (std::move (outer_attrs)),
2743-
name (std::move (name)), type_param_bounds (std::move (type_param_bounds))
2749+
name (std::move (name)), generic_params (std::move (generic_params)),
2750+
type_param_bounds (std::move (type_param_bounds))
27442751
{}
27452752

27462753
// Copy constructor with vector clone
@@ -2749,6 +2756,9 @@ class TraitItemType : public TraitItem
27492756
name (other.name)
27502757
{
27512758
node_id = other.node_id;
2759+
generic_params.reserve (other.generic_params.size ());
2760+
for (const auto &e : other.generic_params)
2761+
generic_params.push_back (e->clone_generic_param ());
27522762
type_param_bounds.reserve (other.type_param_bounds.size ());
27532763
for (const auto &e : other.type_param_bounds)
27542764
type_param_bounds.push_back (e->clone_type_param_bound ());
@@ -2763,6 +2773,9 @@ class TraitItemType : public TraitItem
27632773
locus = other.locus;
27642774
node_id = other.node_id;
27652775

2776+
generic_params.reserve (other.generic_params.size ());
2777+
for (const auto &e : other.generic_params)
2778+
generic_params.push_back (e->clone_generic_param ());
27662779
type_param_bounds.reserve (other.type_param_bounds.size ());
27672780
for (const auto &e : other.type_param_bounds)
27682781
type_param_bounds.push_back (e->clone_type_param_bound ());
@@ -2786,7 +2799,15 @@ class TraitItemType : public TraitItem
27862799
std::vector<Attribute> &get_outer_attrs () { return outer_attrs; }
27872800
const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; }
27882801

2789-
// TODO: mutable getter seems kinda dodgy
2802+
std::vector<std::unique_ptr<GenericParam>> &get_generic_params ()
2803+
{
2804+
return generic_params;
2805+
}
2806+
const std::vector<std::unique_ptr<GenericParam>> &get_generic_params () const
2807+
{
2808+
return generic_params;
2809+
}
2810+
27902811
std::vector<std::unique_ptr<TypeParamBound>> &get_type_param_bounds ()
27912812
{
27922813
return type_param_bounds;

gcc/rust/ast/rust-type.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,6 @@ class ImplTraitType : public Type
177177

178178
void accept_vis (ASTVisitor &vis) override;
179179

180-
// TODO: mutable getter seems kinda dodgy
181180
std::vector<std::unique_ptr<TypeParamBound> > &get_type_param_bounds ()
182181
{
183182
return type_param_bounds;
@@ -250,7 +249,6 @@ class TraitObjectType : public Type
250249

251250
bool is_dyn () const { return has_dyn; }
252251

253-
// TODO: mutable getter seems kinda dodgy
254252
std::vector<std::unique_ptr<TypeParamBound> > &get_type_param_bounds ()
255253
{
256254
return type_param_bounds;
@@ -463,7 +461,6 @@ class TupleType : public TypeNoBounds
463461

464462
void accept_vis (ASTVisitor &vis) override;
465463

466-
// TODO: mutable getter seems kinda dodgy
467464
std::vector<std::unique_ptr<Type> > &get_elems () { return elems; }
468465
const std::vector<std::unique_ptr<Type> > &get_elems () const
469466
{

gcc/rust/hir/rust-ast-lower-implitem.cc

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,11 @@ ASTLowerImplItem::translate (AST::AssociatedItem &item, HirId parent_impl_id)
5555
void
5656
ASTLowerImplItem::visit (AST::TypeAlias &alias)
5757
{
58-
std::vector<std::unique_ptr<HIR::WhereClauseItem> > where_clause_items;
58+
std::vector<std::unique_ptr<HIR::WhereClauseItem>> where_clause_items;
5959
HIR::WhereClause where_clause (std::move (where_clause_items));
6060
HIR::Visibility vis = translate_visibility (alias.get_visibility ());
6161

62-
std::vector<std::unique_ptr<HIR::GenericParam> > generic_params;
62+
std::vector<std::unique_ptr<HIR::GenericParam>> generic_params;
6363
if (alias.has_generics ())
6464
generic_params = lower_generic_params (alias.get_generic_params ());
6565

@@ -110,7 +110,7 @@ void
110110
ASTLowerImplItem::visit (AST::Function &function)
111111
{
112112
// ignore for now and leave empty
113-
std::vector<std::unique_ptr<HIR::WhereClauseItem> > where_clause_items;
113+
std::vector<std::unique_ptr<HIR::WhereClauseItem>> where_clause_items;
114114
for (auto &item : function.get_where_clause ().get_items ())
115115
{
116116
HIR::WhereClauseItem *i
@@ -124,7 +124,7 @@ ASTLowerImplItem::visit (AST::Function &function)
124124
HIR::Visibility vis = translate_visibility (function.get_visibility ());
125125

126126
// need
127-
std::vector<std::unique_ptr<HIR::GenericParam> > generic_params;
127+
std::vector<std::unique_ptr<HIR::GenericParam>> generic_params;
128128
if (function.has_generics ())
129129
{
130130
generic_params = lower_generic_params (function.get_generic_params ());
@@ -233,12 +233,12 @@ ASTLowerTraitItem::translate (AST::AssociatedItem &item)
233233
void
234234
ASTLowerTraitItem::visit (AST::Function &func)
235235
{
236-
std::vector<std::unique_ptr<HIR::WhereClauseItem> > where_clause_items;
236+
std::vector<std::unique_ptr<HIR::WhereClauseItem>> where_clause_items;
237237
HIR::WhereClause where_clause (std::move (where_clause_items));
238238
HIR::FunctionQualifiers qualifiers
239239
= lower_qualifiers (func.get_qualifiers ());
240240

241-
std::vector<std::unique_ptr<HIR::GenericParam> > generic_params;
241+
std::vector<std::unique_ptr<HIR::GenericParam>> generic_params;
242242
if (func.has_generics ())
243243
generic_params = lower_generic_params (func.get_generic_params ());
244244

@@ -342,14 +342,32 @@ ASTLowerTraitItem::visit (AST::ConstantItem &constant)
342342
void
343343
ASTLowerTraitItem::visit (AST::TraitItemType &type)
344344
{
345-
std::vector<std::unique_ptr<HIR::TypeParamBound> > type_param_bounds;
345+
// Lower generic parameters (for GATs)
346+
std::vector<std::unique_ptr<HIR::GenericParam>> generic_params;
347+
for (auto &param : type.get_generic_params ())
348+
{
349+
auto lowered_param = ASTLowerGenericParam::translate (*param.get ());
350+
generic_params.push_back (
351+
std::unique_ptr<HIR::GenericParam> (lowered_param));
352+
}
353+
354+
// Lower type parameter bounds
355+
std::vector<std::unique_ptr<HIR::TypeParamBound>> type_param_bounds;
356+
for (auto &bound : type.get_type_param_bounds ())
357+
{
358+
auto lowered_bound = lower_bound (*bound.get ());
359+
type_param_bounds.push_back (
360+
std::unique_ptr<HIR::TypeParamBound> (lowered_bound));
361+
}
362+
346363
auto crate_num = mappings.get_current_crate ();
347364
Analysis::NodeMapping mapping (crate_num, type.get_node_id (),
348365
mappings.get_next_hir_id (crate_num),
349366
mappings.get_next_localdef_id (crate_num));
350367

351368
HIR::TraitItemType *trait_item
352369
= new HIR::TraitItemType (mapping, type.get_identifier (),
370+
std::move (generic_params),
353371
std::move (type_param_bounds),
354372
type.get_outer_attrs (), type.get_locus ());
355373
translated = trait_item;

gcc/rust/hir/tree/rust-hir-item.cc

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -716,17 +716,21 @@ TraitItemConst::operator= (TraitItemConst const &other)
716716

717717
TraitItemType::TraitItemType (
718718
Analysis::NodeMapping mappings, Identifier name,
719+
std::vector<std::unique_ptr<GenericParam>> generic_params,
719720
std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds,
720721
AST::AttrVec outer_attrs, location_t locus)
721722
: TraitItem (mappings), outer_attrs (std::move (outer_attrs)),
722-
name (std::move (name)), type_param_bounds (std::move (type_param_bounds)),
723-
locus (locus)
723+
name (std::move (name)), generic_params (std::move (generic_params)),
724+
type_param_bounds (std::move (type_param_bounds)), locus (locus)
724725
{}
725726

726727
TraitItemType::TraitItemType (TraitItemType const &other)
727728
: TraitItem (other.mappings), outer_attrs (other.outer_attrs),
728729
name (other.name), locus (other.locus)
729730
{
731+
generic_params.reserve (other.generic_params.size ());
732+
for (const auto &e : other.generic_params)
733+
generic_params.push_back (e->clone_generic_param ());
730734
type_param_bounds.reserve (other.type_param_bounds.size ());
731735
for (const auto &e : other.type_param_bounds)
732736
type_param_bounds.push_back (e->clone_type_param_bound ());
@@ -741,6 +745,9 @@ TraitItemType::operator= (TraitItemType const &other)
741745
locus = other.locus;
742746
mappings = other.mappings;
743747

748+
generic_params.reserve (other.generic_params.size ());
749+
for (const auto &e : other.generic_params)
750+
generic_params.push_back (e->clone_generic_param ());
744751
type_param_bounds.reserve (other.type_param_bounds.size ());
745752
for (const auto &e : other.type_param_bounds)
746753
type_param_bounds.push_back (e->clone_type_param_bound ());

gcc/rust/hir/tree/rust-hir-item.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2121,15 +2121,20 @@ class TraitItemType : public TraitItem
21212121
AST::AttrVec outer_attrs;
21222122

21232123
Identifier name;
2124+
// Generic parameters for GATs (Generic Associated Types)
2125+
std::vector<std::unique_ptr<GenericParam>> generic_params;
21242126
std::vector<std::unique_ptr<TypeParamBound>>
21252127
type_param_bounds; // inlined form
21262128
location_t locus;
21272129

21282130
public:
2131+
bool has_generics () const { return !generic_params.empty (); }
2132+
21292133
// Returns whether trait item type has type param bounds.
21302134
bool has_type_param_bounds () const { return !type_param_bounds.empty (); }
21312135

21322136
TraitItemType (Analysis::NodeMapping mappings, Identifier name,
2137+
std::vector<std::unique_ptr<GenericParam>> generic_params,
21332138
std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds,
21342139
AST::AttrVec outer_attrs, location_t locus);
21352140

@@ -2152,6 +2157,15 @@ class TraitItemType : public TraitItem
21522157

21532158
Identifier get_name () const { return name; }
21542159

2160+
std::vector<std::unique_ptr<GenericParam>> &get_generic_params ()
2161+
{
2162+
return generic_params;
2163+
}
2164+
const std::vector<std::unique_ptr<GenericParam>> &get_generic_params () const
2165+
{
2166+
return generic_params;
2167+
}
2168+
21552169
std::vector<std::unique_ptr<TypeParamBound>> &get_type_param_bounds ()
21562170
{
21572171
return type_param_bounds;

gcc/rust/hir/tree/rust-hir.cc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3582,6 +3582,18 @@ TraitItemType::as_string () const
35823582

35833583
str += "\ntype " + name.as_string ();
35843584

3585+
if (has_generics ())
3586+
{
3587+
str += "<";
3588+
for (size_t i = 0; i < generic_params.size (); i++)
3589+
{
3590+
if (i > 0)
3591+
str += ", ";
3592+
str += generic_params[i]->as_string ();
3593+
}
3594+
str += ">";
3595+
}
3596+
35853597
str += "\n Type param bounds: ";
35863598
if (!has_type_param_bounds ())
35873599
{

gcc/rust/parse/rust-parse-impl.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5221,6 +5221,13 @@ Parser<ManagedTokenSource>::parse_trait_type (AST::AttrVec outer_attrs,
52215221

52225222
Identifier ident{ident_tok};
52235223

5224+
// Parse optional generic parameters for GATs (Generic Associated Types)
5225+
std::vector<std::unique_ptr<AST::GenericParam>> generic_params;
5226+
if (lexer.peek_token ()->get_id () == LEFT_ANGLE)
5227+
{
5228+
generic_params = parse_generic_params_in_angles ();
5229+
}
5230+
52245231
std::vector<std::unique_ptr<AST::TypeParamBound>> bounds;
52255232

52265233
// parse optional colon
@@ -5241,8 +5248,9 @@ Parser<ManagedTokenSource>::parse_trait_type (AST::AttrVec outer_attrs,
52415248
}
52425249

52435250
return std::unique_ptr<AST::TraitItemType> (
5244-
new AST::TraitItemType (std::move (ident), std::move (bounds),
5245-
std::move (outer_attrs), vis, locus));
5251+
new AST::TraitItemType (std::move (ident), std::move (generic_params),
5252+
std::move (bounds), std::move (outer_attrs), vis,
5253+
locus));
52465254
}
52475255

52485256
// Parses a constant trait item.

gcc/rust/typecheck/rust-hir-type-check-implitem.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,12 @@ TypeCheckImplItemWithTrait::visit (HIR::ConstantItem &constant)
519519
void
520520
TypeCheckImplItemWithTrait::visit (HIR::TypeAlias &type)
521521
{
522+
auto binder_pin = context->push_lifetime_binder ();
523+
524+
if (type.has_generics ())
525+
resolve_generic_params (HIR::Item::ItemKind::TypeAlias, type.get_locus (),
526+
type.get_generic_params (), substitutions);
527+
522528
// normal resolution of the item
523529
TyTy::BaseType *lookup
524530
= TypeCheckImplItem::Resolve (parent, type, self, substitutions);

0 commit comments

Comments
 (0)