Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions gcc/rust/ast/rust-ast.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3050,6 +3050,18 @@ TraitItemType::as_string () const

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

if (has_generics ())
{
str += "<";
for (size_t i = 0; i < generic_params.size (); i++)
{
if (i > 0)
str += ", ";
str += generic_params[i]->as_string ();
}
str += ">";
}

str += "\n Type param bounds: ";
if (!has_type_param_bounds ())
{
Expand Down
1 change: 0 additions & 1 deletion gcc/rust/ast/rust-ast.h
Original file line number Diff line number Diff line change
Expand Up @@ -1891,7 +1891,6 @@ struct MacroInvocData
{
parsed_items = std::move (new_items);
}
// TODO: mutable getter seems kinda dodgy
std::vector<std::unique_ptr<MetaItemInner>> &get_meta_items ()
{
return parsed_items;
Expand Down
25 changes: 23 additions & 2 deletions gcc/rust/ast/rust-item.h
Original file line number Diff line number Diff line change
Expand Up @@ -2726,21 +2726,28 @@ class TraitItemType : public TraitItem

Identifier name;

// Generic parameters for GATs (Generic Associated Types)
std::vector<std::unique_ptr<GenericParam>> generic_params;

// bool has_type_param_bounds;
// TypeParamBounds type_param_bounds;
std::vector<std::unique_ptr<TypeParamBound>>
type_param_bounds; // inlined form

public:
bool has_generics () const { return !generic_params.empty (); }

// Returns whether trait item type has type param bounds.
bool has_type_param_bounds () const { return !type_param_bounds.empty (); }

TraitItemType (Identifier name,
std::vector<std::unique_ptr<GenericParam>> generic_params,
std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds,
std::vector<Attribute> outer_attrs, Visibility vis,
location_t locus)
: TraitItem (vis, locus), outer_attrs (std::move (outer_attrs)),
name (std::move (name)), type_param_bounds (std::move (type_param_bounds))
name (std::move (name)), generic_params (std::move (generic_params)),
type_param_bounds (std::move (type_param_bounds))
{}

// Copy constructor with vector clone
Expand All @@ -2749,6 +2756,9 @@ class TraitItemType : public TraitItem
name (other.name)
{
node_id = other.node_id;
generic_params.reserve (other.generic_params.size ());
for (const auto &e : other.generic_params)
generic_params.push_back (e->clone_generic_param ());
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 ());
Expand All @@ -2763,6 +2773,9 @@ class TraitItemType : public TraitItem
locus = other.locus;
node_id = other.node_id;

generic_params.reserve (other.generic_params.size ());
for (const auto &e : other.generic_params)
generic_params.push_back (e->clone_generic_param ());
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 ());
Expand All @@ -2786,7 +2799,15 @@ class TraitItemType : public TraitItem
std::vector<Attribute> &get_outer_attrs () { return outer_attrs; }
const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; }

// TODO: mutable getter seems kinda dodgy
std::vector<std::unique_ptr<GenericParam>> &get_generic_params ()
{
return generic_params;
}
const std::vector<std::unique_ptr<GenericParam>> &get_generic_params () const
{
return generic_params;
}

std::vector<std::unique_ptr<TypeParamBound>> &get_type_param_bounds ()
{
return type_param_bounds;
Expand Down
3 changes: 0 additions & 3 deletions gcc/rust/ast/rust-type.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,6 @@ class ImplTraitType : public Type

void accept_vis (ASTVisitor &vis) override;

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

bool is_dyn () const { return has_dyn; }

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

void accept_vis (ASTVisitor &vis) override;

// TODO: mutable getter seems kinda dodgy
std::vector<std::unique_ptr<Type> > &get_elems () { return elems; }
const std::vector<std::unique_ptr<Type> > &get_elems () const
{
Expand Down
32 changes: 25 additions & 7 deletions gcc/rust/hir/rust-ast-lower-implitem.cc
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,11 @@ ASTLowerImplItem::translate (AST::AssociatedItem &item, HirId parent_impl_id)
void
ASTLowerImplItem::visit (AST::TypeAlias &alias)
{
std::vector<std::unique_ptr<HIR::WhereClauseItem> > where_clause_items;
std::vector<std::unique_ptr<HIR::WhereClauseItem>> where_clause_items;
HIR::WhereClause where_clause (std::move (where_clause_items));
HIR::Visibility vis = translate_visibility (alias.get_visibility ());

std::vector<std::unique_ptr<HIR::GenericParam> > generic_params;
std::vector<std::unique_ptr<HIR::GenericParam>> generic_params;
if (alias.has_generics ())
generic_params = lower_generic_params (alias.get_generic_params ());

Expand Down Expand Up @@ -110,7 +110,7 @@ void
ASTLowerImplItem::visit (AST::Function &function)
{
// ignore for now and leave empty
std::vector<std::unique_ptr<HIR::WhereClauseItem> > where_clause_items;
std::vector<std::unique_ptr<HIR::WhereClauseItem>> where_clause_items;
for (auto &item : function.get_where_clause ().get_items ())
{
HIR::WhereClauseItem *i
Expand All @@ -124,7 +124,7 @@ ASTLowerImplItem::visit (AST::Function &function)
HIR::Visibility vis = translate_visibility (function.get_visibility ());

// need
std::vector<std::unique_ptr<HIR::GenericParam> > generic_params;
std::vector<std::unique_ptr<HIR::GenericParam>> generic_params;
if (function.has_generics ())
{
generic_params = lower_generic_params (function.get_generic_params ());
Expand Down Expand Up @@ -233,12 +233,12 @@ ASTLowerTraitItem::translate (AST::AssociatedItem &item)
void
ASTLowerTraitItem::visit (AST::Function &func)
{
std::vector<std::unique_ptr<HIR::WhereClauseItem> > where_clause_items;
std::vector<std::unique_ptr<HIR::WhereClauseItem>> where_clause_items;
HIR::WhereClause where_clause (std::move (where_clause_items));
HIR::FunctionQualifiers qualifiers
= lower_qualifiers (func.get_qualifiers ());

std::vector<std::unique_ptr<HIR::GenericParam> > generic_params;
std::vector<std::unique_ptr<HIR::GenericParam>> generic_params;
if (func.has_generics ())
generic_params = lower_generic_params (func.get_generic_params ());

Expand Down Expand Up @@ -342,14 +342,32 @@ ASTLowerTraitItem::visit (AST::ConstantItem &constant)
void
ASTLowerTraitItem::visit (AST::TraitItemType &type)
{
std::vector<std::unique_ptr<HIR::TypeParamBound> > type_param_bounds;
// Lower generic parameters (for GATs)
std::vector<std::unique_ptr<HIR::GenericParam>> generic_params;
for (auto &param : type.get_generic_params ())
{
auto lowered_param = ASTLowerGenericParam::translate (*param.get ());
generic_params.push_back (
std::unique_ptr<HIR::GenericParam> (lowered_param));
}

// Lower type parameter bounds
std::vector<std::unique_ptr<HIR::TypeParamBound>> type_param_bounds;
for (auto &bound : type.get_type_param_bounds ())
{
auto lowered_bound = lower_bound (*bound.get ());
type_param_bounds.push_back (
std::unique_ptr<HIR::TypeParamBound> (lowered_bound));
}

auto crate_num = mappings.get_current_crate ();
Analysis::NodeMapping mapping (crate_num, type.get_node_id (),
mappings.get_next_hir_id (crate_num),
mappings.get_next_localdef_id (crate_num));

HIR::TraitItemType *trait_item
= new HIR::TraitItemType (mapping, type.get_identifier (),
std::move (generic_params),
std::move (type_param_bounds),
type.get_outer_attrs (), type.get_locus ());
translated = trait_item;
Expand Down
11 changes: 9 additions & 2 deletions gcc/rust/hir/tree/rust-hir-item.cc
Original file line number Diff line number Diff line change
Expand Up @@ -716,17 +716,21 @@ TraitItemConst::operator= (TraitItemConst const &other)

TraitItemType::TraitItemType (
Analysis::NodeMapping mappings, Identifier name,
std::vector<std::unique_ptr<GenericParam>> generic_params,
std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds,
AST::AttrVec outer_attrs, location_t locus)
: TraitItem (mappings), outer_attrs (std::move (outer_attrs)),
name (std::move (name)), type_param_bounds (std::move (type_param_bounds)),
locus (locus)
name (std::move (name)), generic_params (std::move (generic_params)),
type_param_bounds (std::move (type_param_bounds)), locus (locus)
{}

TraitItemType::TraitItemType (TraitItemType const &other)
: TraitItem (other.mappings), outer_attrs (other.outer_attrs),
name (other.name), locus (other.locus)
{
generic_params.reserve (other.generic_params.size ());
for (const auto &e : other.generic_params)
generic_params.push_back (e->clone_generic_param ());
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 ());
Expand All @@ -741,6 +745,9 @@ TraitItemType::operator= (TraitItemType const &other)
locus = other.locus;
mappings = other.mappings;

generic_params.reserve (other.generic_params.size ());
for (const auto &e : other.generic_params)
generic_params.push_back (e->clone_generic_param ());
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 ());
Expand Down
14 changes: 14 additions & 0 deletions gcc/rust/hir/tree/rust-hir-item.h
Original file line number Diff line number Diff line change
Expand Up @@ -2121,15 +2121,20 @@ class TraitItemType : public TraitItem
AST::AttrVec outer_attrs;

Identifier name;
// Generic parameters for GATs (Generic Associated Types)
std::vector<std::unique_ptr<GenericParam>> generic_params;
std::vector<std::unique_ptr<TypeParamBound>>
type_param_bounds; // inlined form
location_t locus;

public:
bool has_generics () const { return !generic_params.empty (); }

// Returns whether trait item type has type param bounds.
bool has_type_param_bounds () const { return !type_param_bounds.empty (); }

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

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

Identifier get_name () const { return name; }

std::vector<std::unique_ptr<GenericParam>> &get_generic_params ()
{
return generic_params;
}
const std::vector<std::unique_ptr<GenericParam>> &get_generic_params () const
{
return generic_params;
}

std::vector<std::unique_ptr<TypeParamBound>> &get_type_param_bounds ()
{
return type_param_bounds;
Expand Down
12 changes: 12 additions & 0 deletions gcc/rust/hir/tree/rust-hir.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3582,6 +3582,18 @@ TraitItemType::as_string () const

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

if (has_generics ())
{
str += "<";
for (size_t i = 0; i < generic_params.size (); i++)
{
if (i > 0)
str += ", ";
str += generic_params[i]->as_string ();
}
str += ">";
}

str += "\n Type param bounds: ";
if (!has_type_param_bounds ())
{
Expand Down
12 changes: 10 additions & 2 deletions gcc/rust/parse/rust-parse-impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -5221,6 +5221,13 @@ Parser<ManagedTokenSource>::parse_trait_type (AST::AttrVec outer_attrs,

Identifier ident{ident_tok};

// Parse optional generic parameters for GATs (Generic Associated Types)
std::vector<std::unique_ptr<AST::GenericParam>> generic_params;
if (lexer.peek_token ()->get_id () == LEFT_ANGLE)
{
generic_params = parse_generic_params_in_angles ();
}

std::vector<std::unique_ptr<AST::TypeParamBound>> bounds;

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

return std::unique_ptr<AST::TraitItemType> (
new AST::TraitItemType (std::move (ident), std::move (bounds),
std::move (outer_attrs), vis, locus));
new AST::TraitItemType (std::move (ident), std::move (generic_params),
std::move (bounds), std::move (outer_attrs), vis,
locus));
}

// Parses a constant trait item.
Expand Down
6 changes: 6 additions & 0 deletions gcc/rust/typecheck/rust-hir-type-check-implitem.cc
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,12 @@ TypeCheckImplItemWithTrait::visit (HIR::ConstantItem &constant)
void
TypeCheckImplItemWithTrait::visit (HIR::TypeAlias &type)
{
auto binder_pin = context->push_lifetime_binder ();

if (type.has_generics ())
resolve_generic_params (HIR::Item::ItemKind::TypeAlias, type.get_locus (),
type.get_generic_params (), substitutions);

// normal resolution of the item
TyTy::BaseType *lookup
= TypeCheckImplItem::Resolve (parent, type, self, substitutions);
Expand Down
2 changes: 1 addition & 1 deletion gcc/rust/typecheck/rust-tyty.cc
Original file line number Diff line number Diff line change
Expand Up @@ -890,7 +890,7 @@ BaseType::is_concrete () const
bool
BaseType::has_substitutions_defined () const
{
const TyTy::BaseType *x = destructure ();
const auto x = this;
switch (x->get_kind ())
{
case INFER:
Expand Down
4 changes: 4 additions & 0 deletions gcc/testsuite/rust/compile/gat1.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
trait Foo {
type Bar<T>;
type Baz<'a>;
}
18 changes: 18 additions & 0 deletions gcc/testsuite/rust/execute/torture/gat1.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#[lang = "sized"]
trait Sized {}

pub struct MyBuf;

trait Foo {
type Bar<T>: Sized;
}

impl Foo for MyBuf {
type Bar<T> = T;
}

type A = <MyBuf as Foo>::Bar<u32>;
fn main() -> i32 {
let a: A = 1;
a as i32 - 1
}