aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPhilip Herron <herron.philip@googlemail.com>2025-02-13 17:01:31 +0000
committerPhilip Herron <philip.herron@embecosm.com>2025-02-13 17:35:40 +0000
commit45fc433d0fa4c447df695aae4c2f63cb428ca6b5 (patch)
tree66226f28140b905d4669c19da3cd6d366daae8a2 /gcc
parent5f7213e82064b3b6220a62e103eb361c0428d2d1 (diff)
downloadgcc-45fc433d0fa4c447df695aae4c2f63cb428ca6b5.zip
gcc-45fc433d0fa4c447df695aae4c2f63cb428ca6b5.tar.gz
gcc-45fc433d0fa4c447df695aae4c2f63cb428ca6b5.tar.bz2
gccrs: fix name resolution for generics where type param is declared later
Rust allows you to use generics within type bounds when they are declared later on. This changes the name resolution to walk the genric params in two passes to ensure the type parameters are setup before drilling down into the type parameters This issue has exposed another type checking issue which needs fixed in a subseqent patch. Addresses Rust-GCC#3022 gcc/rust/ChangeLog: * resolve/rust-ast-resolve-item.cc (ResolveTraitItems::visit): use new api (ResolveItem::visit): likewise (ResolveExternItem::visit): likewise * resolve/rust-ast-resolve-stmt.h: likewise * resolve/rust-ast-resolve-type.h (class ResolveGenericParam): remove (class ResolveGenericParams): added new api Signed-off-by: Philip Herron <herron.philip@googlemail.com>
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-item.cc48
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-stmt.h26
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-type.h87
3 files changed, 86 insertions, 75 deletions
diff --git a/gcc/rust/resolve/rust-ast-resolve-item.cc b/gcc/rust/resolve/rust-ast-resolve-item.cc
index b50c158..c96da3d 100644
--- a/gcc/rust/resolve/rust-ast-resolve-item.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-item.cc
@@ -64,8 +64,8 @@ ResolveTraitItems::visit (AST::Function &function)
resolver->push_new_label_rib (resolver->get_label_scope ().peek ());
if (function.has_generics ())
- for (auto &generic : function.get_generic_params ())
- ResolveGenericParam::go (*generic, prefix, canonical_prefix);
+ ResolveGenericParams::go (function.get_generic_params (), prefix,
+ canonical_prefix);
if (function.has_return_type ())
ResolveType::go (function.get_return_type ());
@@ -188,8 +188,8 @@ ResolveItem::visit (AST::TypeAlias &alias)
resolver->get_type_scope ().push (scope_node_id);
if (alias.has_generics ())
- for (auto &generic : alias.get_generic_params ())
- ResolveGenericParam::go (*generic, prefix, canonical_prefix);
+ ResolveGenericParams::go (alias.get_generic_params (), prefix,
+ canonical_prefix);
if (alias.has_where_clause ())
ResolveWhereClause::Resolve (alias.get_where_clause ());
@@ -250,8 +250,8 @@ ResolveItem::visit (AST::TupleStruct &struct_decl)
resolver->get_type_scope ().push (scope_node_id);
if (struct_decl.has_generics ())
- for (auto &generic : struct_decl.get_generic_params ())
- ResolveGenericParam::go (*generic, prefix, canonical_prefix);
+ ResolveGenericParams::go (struct_decl.get_generic_params (), prefix,
+ canonical_prefix);
if (struct_decl.has_where_clause ())
ResolveWhereClause::Resolve (struct_decl.get_where_clause ());
@@ -284,8 +284,8 @@ ResolveItem::visit (AST::Enum &enum_decl)
resolver->get_type_scope ().push (scope_node_id);
if (enum_decl.has_generics ())
- for (auto &generic : enum_decl.get_generic_params ())
- ResolveGenericParam::go (*generic, prefix, cpath);
+ ResolveGenericParams::go (enum_decl.get_generic_params (), prefix,
+ canonical_prefix);
if (enum_decl.has_where_clause ())
ResolveWhereClause::Resolve (enum_decl.get_where_clause ());
@@ -374,8 +374,8 @@ ResolveItem::visit (AST::StructStruct &struct_decl)
resolver->get_type_scope ().push (scope_node_id);
if (struct_decl.has_generics ())
- for (auto &generic : struct_decl.get_generic_params ())
- ResolveGenericParam::go (*generic, prefix, canonical_prefix);
+ ResolveGenericParams::go (struct_decl.get_generic_params (), prefix,
+ canonical_prefix);
if (struct_decl.has_where_clause ())
ResolveWhereClause::Resolve (struct_decl.get_where_clause ());
@@ -409,8 +409,8 @@ ResolveItem::visit (AST::Union &union_decl)
resolver->get_type_scope ().push (scope_node_id);
if (union_decl.has_generics ())
- for (auto &generic : union_decl.get_generic_params ())
- ResolveGenericParam::go (*generic, prefix, canonical_prefix);
+ ResolveGenericParams::go (union_decl.get_generic_params (), prefix,
+ canonical_prefix);
if (union_decl.has_where_clause ())
ResolveWhereClause::Resolve (union_decl.get_where_clause ());
@@ -476,8 +476,8 @@ ResolveItem::visit (AST::Function &function)
resolver->push_new_label_rib (resolver->get_label_scope ().peek ());
if (function.has_generics ())
- for (auto &generic : function.get_generic_params ())
- ResolveGenericParam::go (*generic, prefix, canonical_prefix);
+ ResolveGenericParams::go (function.get_generic_params (), prefix,
+ canonical_prefix);
// resolve any where clause items
if (function.has_where_clause ())
@@ -567,8 +567,8 @@ ResolveItem::visit (AST::InherentImpl &impl_block)
resolve_visibility (impl_block.get_visibility ());
if (impl_block.has_generics ())
- for (auto &generic : impl_block.get_generic_params ())
- ResolveGenericParam::go (*generic, prefix, canonical_prefix);
+ ResolveGenericParams::go (impl_block.get_generic_params (), prefix,
+ canonical_prefix);
// resolve any where clause items
if (impl_block.has_where_clause ())
@@ -651,8 +651,8 @@ ResolveItem::visit (AST::TraitImpl &impl_block)
resolver->push_new_label_rib (resolver->get_label_scope ().peek ());
if (impl_block.has_generics ())
- for (auto &generic : impl_block.get_generic_params ())
- ResolveGenericParam::go (*generic, prefix, canonical_prefix);
+ ResolveGenericParams::go (impl_block.get_generic_params (), prefix,
+ canonical_prefix);
// resolve any where clause items
if (impl_block.has_where_clause ())
@@ -776,10 +776,10 @@ ResolveItem::visit (AST::Trait &trait)
resolver->push_new_name_rib (resolver->get_name_scope ().peek ());
resolver->push_new_type_rib (resolver->get_type_scope ().peek ());
- ResolveGenericParam::go (trait.get_implicit_self (), prefix,
- canonical_prefix);
- for (auto &generic : trait.get_generic_params ())
- ResolveGenericParam::go (*generic, prefix, canonical_prefix);
+ ResolveGenericParams::go_single (trait.get_implicit_self (), prefix,
+ canonical_prefix);
+ ResolveGenericParams::go (trait.get_generic_params (), prefix,
+ canonical_prefix);
// Self is an implicit TypeParam so lets mark it as such
resolver->get_type_scope ().append_reference_for_def (
@@ -1044,8 +1044,8 @@ ResolveExternItem::visit (AST::Function &function)
// resolve the generics
if (function.has_generics ())
- for (auto &generic : function.get_generic_params ())
- ResolveGenericParam::go (*generic, prefix, canonical_prefix);
+ ResolveGenericParams::go (function.get_generic_params (), prefix,
+ canonical_prefix);
if (function.has_return_type ())
ResolveType::go (function.get_return_type ());
diff --git a/gcc/rust/resolve/rust-ast-resolve-stmt.h b/gcc/rust/resolve/rust-ast-resolve-stmt.h
index 700addd..da2bb15 100644
--- a/gcc/rust/resolve/rust-ast-resolve-stmt.h
+++ b/gcc/rust/resolve/rust-ast-resolve-stmt.h
@@ -104,10 +104,8 @@ public:
resolver->get_type_scope ().push (scope_node_id);
if (struct_decl.has_generics ())
- {
- for (auto &generic : struct_decl.get_generic_params ())
- ResolveGenericParam::go (*generic, prefix, canonical_prefix);
- }
+ ResolveGenericParams::go (struct_decl.get_generic_params (), prefix,
+ canonical_prefix);
for (AST::TupleField &field : struct_decl.get_fields ())
ResolveType::go (field.get_field_type ());
@@ -137,10 +135,8 @@ public:
resolver->get_type_scope ().push (scope_node_id);
if (enum_decl.has_generics ())
- {
- for (auto &generic : enum_decl.get_generic_params ())
- ResolveGenericParam::go (*generic, prefix, canonical_prefix);
- }
+ ResolveGenericParams::go (enum_decl.get_generic_params (), prefix,
+ canonical_prefix);
for (auto &variant : enum_decl.get_variants ())
ResolveStmt::go (*variant, path, canonical_prefix, path);
@@ -262,10 +258,8 @@ public:
resolver->get_type_scope ().push (scope_node_id);
if (struct_decl.has_generics ())
- {
- for (auto &generic : struct_decl.get_generic_params ())
- ResolveGenericParam::go (*generic, prefix, canonical_prefix);
- }
+ ResolveGenericParams::go (struct_decl.get_generic_params (), prefix,
+ canonical_prefix);
for (AST::StructField &field : struct_decl.get_fields ())
{
@@ -300,8 +294,8 @@ public:
resolver->get_type_scope ().push (scope_node_id);
if (union_decl.has_generics ())
- for (auto &generic : union_decl.get_generic_params ())
- ResolveGenericParam::go (*generic, prefix, canonical_prefix);
+ ResolveGenericParams::go (union_decl.get_generic_params (), prefix,
+ canonical_prefix);
for (AST::StructField &field : union_decl.get_variants ())
{
@@ -341,8 +335,8 @@ public:
resolver->push_new_label_rib (resolver->get_label_scope ().peek ());
if (function.has_generics ())
- for (auto &generic : function.get_generic_params ())
- ResolveGenericParam::go (*generic, prefix, canonical_prefix);
+ ResolveGenericParams::go (function.get_generic_params (), prefix,
+ canonical_prefix);
if (function.has_return_type ())
ResolveType::go (function.get_return_type ());
diff --git a/gcc/rust/resolve/rust-ast-resolve-type.h b/gcc/rust/resolve/rust-ast-resolve-type.h
index 5870aca..3858144 100644
--- a/gcc/rust/resolve/rust-ast-resolve-type.h
+++ b/gcc/rust/resolve/rust-ast-resolve-type.h
@@ -142,66 +142,83 @@ private:
ResolveTypeBound () : ResolverBase () {}
};
-class ResolveGenericParam : public ResolverBase
+class ResolveGenericParams : public ResolverBase
{
using Rust::Resolver::ResolverBase::visit;
public:
- static NodeId go (AST::GenericParam &param, const CanonicalPath &prefix,
- const CanonicalPath &canonical_prefix)
+ static void go (std::vector<std::unique_ptr<AST::GenericParam>> &params,
+ const CanonicalPath &prefix,
+ const CanonicalPath &canonical_prefix)
{
- ResolveGenericParam resolver (prefix, canonical_prefix);
+ ResolveGenericParams resolver (prefix, canonical_prefix);
+
+ // this needs to be done in two phases as they can be used and defined later
+ // in bounds
+ for (auto &param : params)
+ param->accept_vis (resolver);
+
+ resolver.first_pass = false;
+
+ for (auto &param : params)
+ param->accept_vis (resolver);
+ }
+
+ static void go_single (AST::GenericParam &param, const CanonicalPath &prefix,
+ const CanonicalPath &canonical_prefix)
+ {
+ ResolveGenericParams resolver (prefix, canonical_prefix);
+
+ param.accept_vis (resolver);
+ resolver.first_pass = false;
param.accept_vis (resolver);
- return resolver.resolved_node;
}
void visit (AST::ConstGenericParam &param) override
{
- ResolveType::go (param.get_type ());
-
- if (param.has_default_value ())
+ if (first_pass)
+ ResolveType::go (param.get_type ());
+ else if (param.has_default_value ())
ResolveExpr::go (param.get_default_value ().get_expression (), prefix,
canonical_prefix);
-
- ok = true;
}
void visit (AST::TypeParam &param) override
{
- // if it has a type lets resolve it
- if (param.has_type ())
- ResolveType::go (param.get_type ());
-
- if (param.has_type_param_bounds ())
+ if (first_pass)
+ {
+ // if it has a type lets resolve it
+ if (param.has_type ())
+ ResolveType::go (param.get_type ());
+
+ auto seg = CanonicalPath::new_seg (
+ param.get_node_id (), param.get_type_representation ().as_string ());
+ resolver->get_type_scope ().insert (
+ seg, param.get_node_id (), param.get_locus (), false,
+ Rib::ItemType::Type,
+ [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
+ rust_error_at (param.get_locus (),
+ "generic param redefined multiple times");
+ rust_error_at (locus, "was defined here");
+ });
+
+ mappings.insert_canonical_path (param.get_node_id (), seg);
+ }
+ else if (param.has_type_param_bounds ())
{
for (auto &bound : param.get_type_param_bounds ())
- {
- ResolveTypeBound::go (*bound);
- }
+ ResolveTypeBound::go (*bound);
}
-
- auto seg
- = CanonicalPath::new_seg (param.get_node_id (),
- param.get_type_representation ().as_string ());
- resolver->get_type_scope ().insert (
- seg, param.get_node_id (), param.get_locus (), false, Rib::ItemType::Type,
- [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
- rust_error_at (param.get_locus (),
- "generic param redefined multiple times");
- rust_error_at (locus, "was defined here");
- });
-
- mappings.insert_canonical_path (param.get_node_id (), seg);
}
private:
- ResolveGenericParam (const CanonicalPath &prefix,
- const CanonicalPath &canonical_prefix)
- : ResolverBase (), ok (false), prefix (prefix),
+ ResolveGenericParams (const CanonicalPath &prefix,
+ const CanonicalPath &canonical_prefix)
+ : ResolverBase (), first_pass (true), prefix (prefix),
canonical_prefix (canonical_prefix)
{}
- bool ok;
+ bool first_pass;
const CanonicalPath &prefix;
const CanonicalPath &canonical_prefix;
};