From: Owen Avery <[email protected]>
Adds support for handling trait aliases up to lowering. These are
unstable even in current rustc (1.99.0) but are available well before
1.49 and first used by core somewhere between 1.51 and 1.54 inclusive.
gcc/rust/ChangeLog:
* ast/rust-ast-collector.cc
(TokenCollector::visit (TraitAlias)): New function definition.
* ast/rust-ast-collector.h (TokenCollector::visit (TraitAlias)):
New function declaration.
* ast/rust-ast-visitor.cc
(DefaultASTVisitor::visit (TraitAlias)): New function
definition.
* ast/rust-ast-visitor.h (ASTVisitor::visit (TraitAlias)):
Likewise.
(DefaultASTVisitor::visit (TraitAlias)): New function
declaration.
* ast/rust-ast.cc (TraitAlias::as_string): New function
definition.
(TraitAlias::accept_vis): Likewise.
* ast/rust-ast.h (Item::Kind::TraitAlias): New enumerator.
* ast/rust-item.h (class TraitAlias): New.
* checks/errors/feature/rust-feature-gate.cc
(FeatureGate::visit (TraitAlias)): New function definition, gate
trait alias usage.
* checks/errors/feature/rust-feature-gate.h
(FeatureGate::visit (TraitAlias)): New function declaration.
* expand/rust-derive.h (DeriveVisitor::visit (TraitAlias)): New
function definition.
* hir/rust-ast-lower-base.cc
(ASTLoweringBase::visit (TraitAlias)): Likewise.
* hir/rust-ast-lower-base.h
(ASTLoweringBase::visit (TraitAlias)): New function declaration.
* hir/rust-ast-lower-item.cc
(ASTLoweringItem::visit (TraitAlias)): New function definition,
left as a stub for now.
* hir/rust-ast-lower-item.h
(ASTLoweringItem::visit (TraitAlias)): New function declaration.
* parse/rust-parse-impl.hxx (Parser::parse_trait): Handle trait
aliases in addition to normal trait definitions.
* parse/rust-parse.h (Parser::parse_trait): Change return type
to allow returning trait aliases.
* resolve/rust-default-resolver.cc
(DefaultResolver::visit (TraitAlias)): New function definition.
* resolve/rust-default-resolver.h
(DefaultResolver::Visit (TraitAlias)): New function declaration.
* resolve/rust-toplevel-name-resolver-2.0.cc
(TopLevel::visit (TraitAlias)): New function definition.
* resolve/rust-toplevel-name-resolver-2.0.h
(TopLevel::visit (TraitAlias)): New function declaration.
gcc/testsuite/ChangeLog:
* rust/compile/trait-alias-gate.rs: New test.
* rust/compile/trait-alias-lowering.rs: New test.
Signed-off-by: Owen Avery <[email protected]>
---
This change was merged into the gccrs repository and is posted here for
upstream visibility and potential drive-by review, as requested by GCC
release managers.
Each commit email contains a link to its details on github from where you can
find the Pull-Request and associated discussions.
Commit on github:
https://github.com/Rust-GCC/gccrs/commit/e6fdf5044492f62d282933854131c52ccb5de6e9
The commit has NOT been mentioned in any issue.
The commit has been mentioned in the following pull-request(s):
- https://github.com/Rust-GCC/gccrs/pull/4955
gcc/rust/ast/rust-ast-collector.cc | 29 ++++
gcc/rust/ast/rust-ast-collector.h | 1 +
gcc/rust/ast/rust-ast-visitor.cc | 13 ++
gcc/rust/ast/rust-ast-visitor.h | 2 +
gcc/rust/ast/rust-ast.cc | 59 ++++++++
gcc/rust/ast/rust-ast.h | 1 +
gcc/rust/ast/rust-item.h | 129 ++++++++++++++++++
.../errors/feature/rust-feature-gate.cc | 9 ++
.../checks/errors/feature/rust-feature-gate.h | 1 +
gcc/rust/expand/rust-derive.h | 1 +
gcc/rust/hir/rust-ast-lower-base.cc | 3 +
gcc/rust/hir/rust-ast-lower-base.h | 1 +
gcc/rust/hir/rust-ast-lower-item.cc | 6 +
gcc/rust/hir/rust-ast-lower-item.h | 1 +
gcc/rust/parse/rust-parse-impl.hxx | 37 ++++-
gcc/rust/parse/rust-parse.h | 4 +-
gcc/rust/resolve/rust-default-resolver.cc | 15 ++
gcc/rust/resolve/rust-default-resolver.h | 1 +
.../rust-toplevel-name-resolver-2.0.cc | 9 ++
.../resolve/rust-toplevel-name-resolver-2.0.h | 1 +
.../rust/compile/trait-alias-gate.rs | 6 +
.../rust/compile/trait-alias-lowering.rs | 7 +
22 files changed, 331 insertions(+), 5 deletions(-)
create mode 100644 gcc/testsuite/rust/compile/trait-alias-gate.rs
create mode 100644 gcc/testsuite/rust/compile/trait-alias-lowering.rs
diff --git a/gcc/rust/ast/rust-ast-collector.cc
b/gcc/rust/ast/rust-ast-collector.cc
index b1238f3e5..97a0df706 100644
--- a/gcc/rust/ast/rust-ast-collector.cc
+++ b/gcc/rust/ast/rust-ast-collector.cc
@@ -2233,6 +2233,35 @@ TokenCollector::visit (TypeAlias &type_alias)
});
}
+void
+TokenCollector::visit (TraitAlias &trait_alias)
+{
+ // Syntax:
+ // Visibility? trait IDENTIFIER GenericParams? = TypeBounds? WhereClause?;
+ // https://github.com/rust-lang/rfcs/blob/main/text/1733-trait-alias.md
+ describe_node (std::string ("TraitAlias"), [this, &trait_alias] () {
+ visit_items_as_lines (trait_alias.get_outer_attrs ());
+ if (trait_alias.has_visibility ())
+ visit (trait_alias.get_visibility ());
+ auto alias_name = trait_alias.get_alias_name ().as_string ();
+ push (Rust::Token::make (TRAIT, trait_alias.get_locus ()));
+ push (
+ Rust::Token::make_identifier (UNDEF_LOCATION, std::move (alias_name)));
+
+ if (trait_alias.has_generics ())
+ visit (trait_alias.get_generic_params ());
+
+ push (Rust::Token::make (EQUAL, UNDEF_LOCATION));
+
+ visit_items_joined_by_separator (trait_alias.get_alias_bounds (), PLUS);
+
+ if (trait_alias.has_where_clause ())
+ visit (trait_alias.get_where_clause ());
+
+ push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
+ });
+}
+
void
TokenCollector::visit (StructStruct &struct_item)
{
diff --git a/gcc/rust/ast/rust-ast-collector.h
b/gcc/rust/ast/rust-ast-collector.h
index e3cd70373..fc723f2c9 100644
--- a/gcc/rust/ast/rust-ast-collector.h
+++ b/gcc/rust/ast/rust-ast-collector.h
@@ -366,6 +366,7 @@ public:
void visit (UseDeclaration &use_decl);
void visit (Function &function);
void visit (TypeAlias &type_alias);
+ void visit (TraitAlias &trait_alias);
void visit (StructStruct &struct_item);
void visit (TupleStruct &tuple_struct);
void visit (EnumItem &item);
diff --git a/gcc/rust/ast/rust-ast-visitor.cc b/gcc/rust/ast/rust-ast-visitor.cc
index 7e10ef750..3dc60c324 100644
--- a/gcc/rust/ast/rust-ast-visitor.cc
+++ b/gcc/rust/ast/rust-ast-visitor.cc
@@ -915,6 +915,19 @@ DefaultASTVisitor::visit (AST::TypeAlias &type_alias)
visit (type_alias.get_type_aliased ());
}
+void
+DefaultASTVisitor::visit (AST::TraitAlias &trait_alias)
+{
+ visit_outer_attrs (trait_alias);
+ visit (trait_alias.get_visibility ());
+ for (auto &generic : trait_alias.get_generic_params ())
+ visit (generic);
+ if (trait_alias.has_where_clause ())
+ visit (trait_alias.get_where_clause ());
+ for (auto &bound : trait_alias.get_alias_bounds ())
+ visit (bound);
+}
+
void
DefaultASTVisitor::visit (AST::StructField &field)
{
diff --git a/gcc/rust/ast/rust-ast-visitor.h b/gcc/rust/ast/rust-ast-visitor.h
index e670cbe21..3c48ef7b1 100644
--- a/gcc/rust/ast/rust-ast-visitor.h
+++ b/gcc/rust/ast/rust-ast-visitor.h
@@ -155,6 +155,7 @@ public:
virtual void visit (UseDeclaration &use_decl) = 0;
virtual void visit (Function &function) = 0;
virtual void visit (TypeAlias &type_alias) = 0;
+ virtual void visit (TraitAlias &type_alias) = 0;
virtual void visit (StructStruct &struct_item) = 0;
virtual void visit (TupleStruct &tuple_struct) = 0;
virtual void visit (EnumItem &item) = 0;
@@ -337,6 +338,7 @@ public:
virtual void visit (AST::UseDeclaration &use_decl) override;
virtual void visit (AST::Function &function) override;
virtual void visit (AST::TypeAlias &type_alias) override;
+ virtual void visit (AST::TraitAlias &trait_alias) override;
virtual void visit (AST::StructStruct &struct_item) override;
virtual void visit (AST::TupleStruct &tuple_struct) override;
virtual void visit (AST::EnumItem &item) override;
diff --git a/gcc/rust/ast/rust-ast.cc b/gcc/rust/ast/rust-ast.cc
index 872dff315..091cdf5ac 100644
--- a/gcc/rust/ast/rust-ast.cc
+++ b/gcc/rust/ast/rust-ast.cc
@@ -1418,6 +1418,59 @@ TypeAlias::as_string () const
return str;
}
+std::string
+TraitAlias::as_string () const
+{
+ std::string str = VisItem::as_string ();
+
+ str += " " + alias_name.as_string ();
+
+ // generic params
+ str += "\n Generic params: ";
+ if (!has_generics ())
+ {
+ str += "none";
+ }
+ else
+ {
+ auto i = generic_params.begin ();
+ auto e = generic_params.end ();
+
+ for (; i != e; i++)
+ {
+ str += (*i)->as_string ();
+ if (e != i + 1)
+ str += ", ";
+ }
+ }
+
+ str += "\n Bounds: ";
+ if (alias_bounds.empty ())
+ {
+ str += "none";
+ }
+ else
+ {
+ bool needs_plus = false;
+
+ for (auto &bound : alias_bounds)
+ {
+ if (needs_plus)
+ str += " + ";
+ needs_plus = true;
+ str += bound->as_string ();
+ }
+ }
+
+ str += "\n Where clause: ";
+ if (!has_where_clause ())
+ str += "none";
+ else
+ str += where_clause.as_string ();
+
+ return str;
+}
+
std::string
ExternBlock::as_string () const
{
@@ -4754,6 +4807,12 @@ TypeAlias::accept_vis (ASTVisitor &vis)
vis.visit (*this);
}
+void
+TraitAlias::accept_vis (ASTVisitor &vis)
+{
+ vis.visit (*this);
+}
+
void
StructStruct::accept_vis (ASTVisitor &vis)
{
diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h
index e8ebd850a..bbba4a5c3 100644
--- a/gcc/rust/ast/rust-ast.h
+++ b/gcc/rust/ast/rust-ast.h
@@ -1072,6 +1072,7 @@ public:
UseDeclaration,
Function,
TypeAlias,
+ TraitAlias,
Struct,
EnumItem,
Enum,
diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h
index 0724638f2..2129ac423 100644
--- a/gcc/rust/ast/rust-item.h
+++ b/gcc/rust/ast/rust-item.h
@@ -1640,6 +1640,135 @@ protected:
}
};
+// Rust trait alias AST node
+// like a type alias, but for traits
+// unstable but used in core
+class TraitAlias : public VisItem
+{
+ Identifier alias_name;
+
+ // bool has_generics;
+ // Generics generic_params;
+ std::vector<std::unique_ptr<GenericParam>> generic_params; // inlined
+
+ // bool has_where_clause;
+ WhereClause where_clause;
+
+ std::vector<std::unique_ptr<TypeParamBound>> alias_bounds;
+
+ location_t locus;
+
+ bool m_mark_for_strip;
+
+public:
+ std::string as_string () const override;
+
+ // Returns whether type alias has generic parameters.
+ bool has_generics () const { return !generic_params.empty (); }
+
+ // Returns whether type alias has a where clause.
+ bool has_where_clause () const { return !where_clause.is_empty (); }
+
+ // Mega-constructor with all possible fields
+ TraitAlias (Identifier alias_name,
+ std::vector<std::unique_ptr<GenericParam>> generic_params,
+ WhereClause where_clause,
+ std::vector<std::unique_ptr<TypeParamBound>> alias_bounds,
+ Visibility vis, std::vector<Attribute> outer_attrs,
+ location_t locus)
+ : VisItem (std::move (vis), std::move (outer_attrs)),
+ alias_name (std::move (alias_name)),
+ generic_params (std::move (generic_params)),
+ where_clause (std::move (where_clause)),
+ alias_bounds (std::move (alias_bounds)), locus (locus),
+ m_mark_for_strip (false)
+ {}
+
+ // Copy constructor
+ TraitAlias (TraitAlias const &other)
+ : VisItem (other), alias_name (other.alias_name),
+ where_clause (other.where_clause), 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 ());
+
+ alias_bounds.reserve (other.alias_bounds.size ());
+ for (const auto &b : other.alias_bounds)
+ alias_bounds.push_back (b->clone_type_param_bound ());
+ }
+
+ // Overloaded assignment operator to clone
+ TraitAlias &operator= (TraitAlias const &other)
+ {
+ VisItem::operator= (other);
+ alias_name = other.alias_name;
+ where_clause = other.where_clause;
+ // visibility = other.visibility->clone_visibility();
+ // outer_attrs = other.outer_attrs;
+ locus = other.locus;
+
+ generic_params.clear ();
+ generic_params.reserve (other.generic_params.size ());
+ for (const auto &e : other.generic_params)
+ generic_params.push_back (e->clone_generic_param ());
+
+ alias_bounds.clear ();
+ alias_bounds.reserve (other.alias_bounds.size ());
+ for (const auto &b : other.alias_bounds)
+ alias_bounds.push_back (b->clone_type_param_bound ());
+
+ return *this;
+ }
+
+ // move constructors
+ TraitAlias (TraitAlias &&other) = default;
+ TraitAlias &operator= (TraitAlias &&other) = default;
+
+ location_t get_locus () const override final { return locus; }
+
+ // needed to override AssociatedItem::get_node_id
+ NodeId get_node_id () const override final { return VisItem::get_node_id ();
}
+
+ void accept_vis (ASTVisitor &vis) override;
+
+ void mark_for_strip () override { m_mark_for_strip = true; }
+ bool is_marked_for_strip () const override { return m_mark_for_strip; }
+
+ 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;
+ }
+
+ // TODO: is this better? Or is a "vis_block" better?
+ WhereClause &get_where_clause () { return where_clause; }
+
+ std::vector<std::unique_ptr<TypeParamBound>> &get_alias_bounds ()
+ {
+ return alias_bounds;
+ }
+ const std::vector<std::unique_ptr<TypeParamBound>> &get_alias_bounds () const
+ {
+ return alias_bounds;
+ }
+
+ const Identifier &get_alias_name () const { return alias_name; }
+
+ Item::Kind get_item_kind () const override { return Item::Kind::TraitAlias; }
+
+protected:
+ /* Use covariance to implement clone function as returning this object
+ * rather than base */
+ TraitAlias *clone_item_impl () const override
+ {
+ return new TraitAlias (*this);
+ }
+};
+
// Rust base struct declaration AST node - abstract base class
class Struct : public VisItem
{
diff --git a/gcc/rust/checks/errors/feature/rust-feature-gate.cc
b/gcc/rust/checks/errors/feature/rust-feature-gate.cc
index f32165327..43a8a6199 100644
--- a/gcc/rust/checks/errors/feature/rust-feature-gate.cc
+++ b/gcc/rust/checks/errors/feature/rust-feature-gate.cc
@@ -385,6 +385,15 @@ FeatureGate::visit (AST::StaticItem &static_item)
AST::DefaultASTVisitor::visit (static_item);
}
+void
+FeatureGate::visit (AST::TraitAlias &trait_alias)
+{
+ gate (Feature::Name::TRAIT_ALIAS, trait_alias.get_locus (),
+ "trait aliases are experimental");
+
+ AST::DefaultASTVisitor::visit (trait_alias);
+}
+
void
FeatureGate::visit (AST::Attribute &attr)
{
diff --git a/gcc/rust/checks/errors/feature/rust-feature-gate.h
b/gcc/rust/checks/errors/feature/rust-feature-gate.h
index e83a14ea7..41bae8363 100644
--- a/gcc/rust/checks/errors/feature/rust-feature-gate.h
+++ b/gcc/rust/checks/errors/feature/rust-feature-gate.h
@@ -52,6 +52,7 @@ public:
void visit (AST::Enum &enum_item) override;
void visit (AST::EnumItem &enum_variant) override;
void visit (AST::StaticItem &static_item) override;
+ void visit (AST::TraitAlias &trait_alias) override;
void visit (AST::Attribute &attr) override;
diff --git a/gcc/rust/expand/rust-derive.h b/gcc/rust/expand/rust-derive.h
index 670619126..3fc87ed88 100644
--- a/gcc/rust/expand/rust-derive.h
+++ b/gcc/rust/expand/rust-derive.h
@@ -188,6 +188,7 @@ private:
virtual void visit (UseDeclaration &use_decl) override final{};
virtual void visit (Function &function) override final{};
virtual void visit (TypeAlias &type_alias) override final{};
+ virtual void visit (TraitAlias &trait_alias) override final{};
virtual void visit (EnumItem &item) override final{};
virtual void visit (EnumItemTuple &item) override final{};
virtual void visit (EnumItemStruct &item) override final{};
diff --git a/gcc/rust/hir/rust-ast-lower-base.cc
b/gcc/rust/hir/rust-ast-lower-base.cc
index e69b717d0..8742643b4 100644
--- a/gcc/rust/hir/rust-ast-lower-base.cc
+++ b/gcc/rust/hir/rust-ast-lower-base.cc
@@ -354,6 +354,9 @@ void
ASTLoweringBase::visit (AST::TypeAlias &)
{}
void
+ASTLoweringBase::visit (AST::TraitAlias &)
+{}
+void
ASTLoweringBase::visit (AST::StructStruct &)
{}
void
diff --git a/gcc/rust/hir/rust-ast-lower-base.h
b/gcc/rust/hir/rust-ast-lower-base.h
index cfc09becf..c6e4bb0fb 100644
--- a/gcc/rust/hir/rust-ast-lower-base.h
+++ b/gcc/rust/hir/rust-ast-lower-base.h
@@ -180,6 +180,7 @@ public:
virtual void visit (AST::UseDeclaration &use_decl) override;
virtual void visit (AST::Function &function) override;
virtual void visit (AST::TypeAlias &type_alias) override;
+ virtual void visit (AST::TraitAlias &type_alias) override;
virtual void visit (AST::StructStruct &struct_item) override;
virtual void visit (AST::TupleStruct &tuple_struct) override;
virtual void visit (AST::EnumItem &item) override;
diff --git a/gcc/rust/hir/rust-ast-lower-item.cc
b/gcc/rust/hir/rust-ast-lower-item.cc
index 7e2f357be..04217dcf1 100644
--- a/gcc/rust/hir/rust-ast-lower-item.cc
+++ b/gcc/rust/hir/rust-ast-lower-item.cc
@@ -119,6 +119,12 @@ ASTLoweringItem::visit (AST::TypeAlias &alias)
alias.get_locus ());
}
+void
+ASTLoweringItem::visit (AST::TraitAlias &alias)
+{
+ rust_sorry_at (alias.get_locus (), "trait alias lowering");
+}
+
void
ASTLoweringItem::visit (AST::TupleStruct &struct_decl)
{
diff --git a/gcc/rust/hir/rust-ast-lower-item.h
b/gcc/rust/hir/rust-ast-lower-item.h
index 9223d86b9..3d4defdfa 100644
--- a/gcc/rust/hir/rust-ast-lower-item.h
+++ b/gcc/rust/hir/rust-ast-lower-item.h
@@ -33,6 +33,7 @@ public:
void visit (AST::Module &module) override;
void visit (AST::TypeAlias &alias) override;
+ void visit (AST::TraitAlias &alias) override;
void visit (AST::TupleStruct &struct_decl) override;
void visit (AST::StructStruct &struct_decl) override;
void visit (AST::Enum &enum_decl) override;
diff --git a/gcc/rust/parse/rust-parse-impl.hxx
b/gcc/rust/parse/rust-parse-impl.hxx
index 652f128c6..406da39fd 100644
--- a/gcc/rust/parse/rust-parse-impl.hxx
+++ b/gcc/rust/parse/rust-parse-impl.hxx
@@ -3881,14 +3881,16 @@ Parser<ManagedTokenSource>::parse_static_item
(AST::Visibility vis,
}
// Parses a trait definition item, including unsafe ones.
+// also handles trait aliases
template <typename ManagedTokenSource>
-std::unique_ptr<AST::Trait>
+std::unique_ptr<AST::VisItem>
Parser<ManagedTokenSource>::parse_trait (AST::Visibility vis,
AST::AttrVec outer_attrs)
{
location_t locus = lexer.peek_token ()->get_locus ();
bool is_unsafe = false;
bool is_auto_trait = false;
+ bool is_alias = false;
if (lexer.peek_token ()->get_id () == UNSAFE)
{
@@ -3918,8 +3920,23 @@ Parser<ManagedTokenSource>::parse_trait (AST::Visibility
vis,
// create placeholder type param bounds in case they don't exist
std::vector<std::unique_ptr<AST::TypeParamBound>> type_param_bounds;
- // parse type param bounds (if they exist)
- if (lexer.peek_token ()->get_id () == COLON)
+ // this might be a trait alias
+ if (lexer.peek_token ()->get_id () == EQUAL)
+ {
+ lexer.skip_token ();
+
+ if (is_auto_trait)
+ rust_error_at (locus, "trait aliases cannot be %<auto%>");
+ if (is_unsafe)
+ rust_error_at (locus, "trait aliases cannot be %<unsafe%>");
+
+ type_param_bounds = parse_type_param_bounds (
+ [] (TokenId id) { return id == WHERE || id == SEMICOLON; });
+
+ is_alias = true;
+ }
+ // otherwise, parse type param bounds (if they exist)
+ else if (lexer.peek_token ()->get_id () == COLON)
{
lexer.skip_token ();
@@ -3931,6 +3948,20 @@ Parser<ManagedTokenSource>::parse_trait (AST::Visibility
vis,
// parse where clause (if it exists)
AST::WhereClause where_clause = parse_where_clause ();
+ // if this was a trait alias, finish up
+ if (is_alias)
+ {
+ if (!skip_token (SEMICOLON))
+ return nullptr;
+
+ return std::make_unique<AST::TraitAlias> (std::move (ident),
+ std::move (generic_params),
+ std::move (where_clause),
+ std::move (type_param_bounds),
+ std::move (vis),
+ std::move (outer_attrs), locus);
+ }
+
if (!skip_token (LEFT_CURLY))
{
skip_after_end_block ();
diff --git a/gcc/rust/parse/rust-parse.h b/gcc/rust/parse/rust-parse.h
index 4b389a827..33fdec986 100644
--- a/gcc/rust/parse/rust-parse.h
+++ b/gcc/rust/parse/rust-parse.h
@@ -461,8 +461,8 @@ private:
parse_const_item (AST::Visibility vis, AST::AttrVec outer_attrs);
std::unique_ptr<AST::StaticItem> parse_static_item (AST::Visibility vis,
AST::AttrVec outer_attrs);
- std::unique_ptr<AST::Trait> parse_trait (AST::Visibility vis,
- AST::AttrVec outer_attrs);
+ std::unique_ptr<AST::VisItem> parse_trait (AST::Visibility vis,
+ AST::AttrVec outer_attrs);
std::unique_ptr<AST::TraitItemType>
parse_trait_type (AST::AttrVec outer_attrs, AST::Visibility);
std::unique_ptr<AST::ConstantItem>
diff --git a/gcc/rust/resolve/rust-default-resolver.cc
b/gcc/rust/resolve/rust-default-resolver.cc
index cbfd84ac2..7b697a9ba 100644
--- a/gcc/rust/resolve/rust-default-resolver.cc
+++ b/gcc/rust/resolve/rust-default-resolver.cc
@@ -370,6 +370,21 @@ DefaultResolver::visit (AST::TypeAlias &type)
inner_fn_2, type.get_new_type_name ());
}
+void
+DefaultResolver::visit (AST::TraitAlias &trait)
+{
+ auto inner_fn_1
+ = [this, &trait] () { AST::DefaultASTVisitor::visit (trait); };
+
+ auto inner_fn_2 = [this, &trait, &inner_fn_1] () {
+ ctx.canonical_ctx.scope (trait.get_node_id (), trait.get_alias_name (),
+ std::move (inner_fn_1));
+ };
+
+ ctx.scoped (Rib::Kind::Item, trait.get_node_id (), inner_fn_2,
+ trait.get_alias_name ());
+}
+
void
DefaultResolver::visit_closure_params (AST::ClosureExpr &expr)
{
diff --git a/gcc/rust/resolve/rust-default-resolver.h
b/gcc/rust/resolve/rust-default-resolver.h
index bd2bab9f8..8530be391 100644
--- a/gcc/rust/resolve/rust-default-resolver.h
+++ b/gcc/rust/resolve/rust-default-resolver.h
@@ -77,6 +77,7 @@ public:
void visit (AST::Enum &) override;
void visit (AST::Union &) override;
void visit (AST::TypeAlias &) override;
+ void visit (AST::TraitAlias &) override;
// Visitors that visit their expression node(s)
virtual void visit_closure_params (AST::ClosureExpr &);
diff --git a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
index fa81639b6..db973be17 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
@@ -414,6 +414,15 @@ TopLevel::visit (AST::TypeAlias &type_item)
DefaultResolver::visit (type_item);
}
+void
+TopLevel::visit (AST::TraitAlias &trait_item)
+{
+ insert_or_error_out (trait_item.get_alias_name (), trait_item,
+ Namespace::Types);
+
+ DefaultResolver::visit (trait_item);
+}
+
void
TopLevel::visit (AST::ExternalTypeItem &type_item)
{
diff --git a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h
b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h
index 28c340b1c..b1ba0447b 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h
@@ -184,6 +184,7 @@ private:
void visit (AST::Union &union_item) override;
void visit (AST::ConstantItem &const_item) override;
void visit (AST::TypeAlias &type_item) override;
+ void visit (AST::TraitAlias &type_item) override;
void visit (AST::ExternalTypeItem &type_item) override;
void visit_extern_crate (AST::ExternCrate &, AST::Crate &, CrateNum)
override;
void visit (AST::TypeParam &type_param) override;
diff --git a/gcc/testsuite/rust/compile/trait-alias-gate.rs
b/gcc/testsuite/rust/compile/trait-alias-gate.rs
new file mode 100644
index 000000000..00bad59b8
--- /dev/null
+++ b/gcc/testsuite/rust/compile/trait-alias-gate.rs
@@ -0,0 +1,6 @@
+#![feature(no_core)]
+#![no_core]
+
+trait A {}
+
+trait B = A; // { dg-error "trait aliases are experimental" }
diff --git a/gcc/testsuite/rust/compile/trait-alias-lowering.rs
b/gcc/testsuite/rust/compile/trait-alias-lowering.rs
new file mode 100644
index 000000000..9986c043a
--- /dev/null
+++ b/gcc/testsuite/rust/compile/trait-alias-lowering.rs
@@ -0,0 +1,7 @@
+// { dg-additional-options "-w -frust-compile-until=lowering" }
+#![feature(no_core, trait_alias)]
+#![no_core]
+
+trait A {}
+
+trait B = A;
base-commit: 2e8c317e34dc5531ca3e7927e2abfdbce497c646
--
2.55.0