aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPhilip Herron <philip.herron@embecosm.com>2021-03-25 16:24:59 +0000
committerPhilip Herron <herron.philip@googlemail.com>2021-03-27 18:55:14 +0000
commit573120551a0bc6813f32ed371df65311724e96dd (patch)
treed4262132bacfd6a705078f4e64973a5b8cfbe1c4 /gcc
parente9bb91b4a7caaab185d029d9c093c520366462d8 (diff)
downloadgcc-573120551a0bc6813f32ed371df65311724e96dd.zip
gcc-573120551a0bc6813f32ed371df65311724e96dd.tar.gz
gcc-573120551a0bc6813f32ed371df65311724e96dd.tar.bz2
Add generics for impl blocks
Generics paramters to impl blocks allows each impl-item to inherit these and get handled in a similar way as to normal functions. Fixes #237
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/backend/rust-compile-context.h3
-rw-r--r--gcc/rust/backend/rust-compile-implitem.h28
-rw-r--r--gcc/rust/backend/rust-compile-resolve-path.cc47
-rw-r--r--gcc/rust/backend/rust-compile.cc2
-rw-r--r--gcc/rust/hir/rust-ast-lower-implitem.h18
-rw-r--r--gcc/rust/hir/rust-ast-lower-item.h22
-rw-r--r--gcc/rust/hir/tree/rust-hir-item.h5
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-implitem.h22
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-item.h12
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-type.h67
-rw-r--r--gcc/rust/resolve/rust-ast-resolve.cc29
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-implitem.h23
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-toplevel.h19
-rw-r--r--gcc/rust/util/rust-hir-map.cc16
-rw-r--r--gcc/rust/util/rust-hir-map.h10
-rw-r--r--gcc/testsuite/rust.test/compile/generics8.rs15
16 files changed, 245 insertions, 93 deletions
diff --git a/gcc/rust/backend/rust-compile-context.h b/gcc/rust/backend/rust-compile-context.h
index 6347464..8866575 100644
--- a/gcc/rust/backend/rust-compile-context.h
+++ b/gcc/rust/backend/rust-compile-context.h
@@ -297,8 +297,7 @@ public:
void visit (TyTy::ParamType &param) override
{
- TyTy::TyVar var (param.get_ty_ref ());
- var.get_tyty ()->accept_vis (*this);
+ param.resolve ()->accept_vis (*this);
}
void visit (TyTy::FnType &type) override
diff --git a/gcc/rust/backend/rust-compile-implitem.h b/gcc/rust/backend/rust-compile-implitem.h
index 0817424..15aba9b 100644
--- a/gcc/rust/backend/rust-compile-implitem.h
+++ b/gcc/rust/backend/rust-compile-implitem.h
@@ -35,9 +35,10 @@ class CompileInherentImplItem : public HIRCompileBase
public:
static void Compile (TyTy::BaseType *self, HIR::InherentImplItem *item,
- Context *ctx, bool compile_fns)
+ Context *ctx, bool compile_fns,
+ TyTy::BaseType *concrete = nullptr)
{
- CompileInherentImplItem compiler (self, ctx, compile_fns);
+ CompileInherentImplItem compiler (self, ctx, compile_fns, concrete);
item->accept_vis (compiler);
}
@@ -92,6 +93,21 @@ public:
}
TyTy::FnType *fntype = static_cast<TyTy::FnType *> (fntype_tyty);
+ if (fntype->has_subsititions_defined ())
+ {
+ // we cant do anything for this only when it is used
+ if (concrete == nullptr)
+ return;
+ else
+ {
+ rust_assert (concrete->get_kind () == TyTy::TypeKind::FNDEF);
+ fntype = static_cast<TyTy::FnType *> (concrete);
+
+ // override the Hir Lookups for the substituions in this context
+ fntype->override_context ();
+ }
+ }
+
// convert to the actual function type
::Btype *compiled_fn_type = TyTyResolveCompile::compile (ctx, fntype);
@@ -111,7 +127,6 @@ public:
ctx->insert_function_decl (fntype->get_ty_ref (), fndecl);
// setup the params
-
TyTy::BaseType *tyret = fntype->get_return_type ();
std::vector<Bvariable *> param_vars;
@@ -431,12 +446,15 @@ public:
}
private:
- CompileInherentImplItem (TyTy::BaseType *self, Context *ctx, bool compile_fns)
- : HIRCompileBase (ctx), self (self), compile_fns (compile_fns)
+ CompileInherentImplItem (TyTy::BaseType *self, Context *ctx, bool compile_fns,
+ TyTy::BaseType *concrete)
+ : HIRCompileBase (ctx), self (self), compile_fns (compile_fns),
+ concrete (concrete)
{}
TyTy::BaseType *self;
bool compile_fns;
+ TyTy::BaseType *concrete;
};
} // namespace Compile
diff --git a/gcc/rust/backend/rust-compile-resolve-path.cc b/gcc/rust/backend/rust-compile-resolve-path.cc
index 4fbaae3..90c4eeb 100644
--- a/gcc/rust/backend/rust-compile-resolve-path.cc
+++ b/gcc/rust/backend/rust-compile-resolve-path.cc
@@ -78,19 +78,50 @@ ResolvePathRef::visit (HIR::PathInExpression &expr)
Bfunction *fn = nullptr;
if (!ctx->lookup_function_decl (lookup->get_ty_ref (), &fn))
{
- // it must resolve to some kind of HIR::Item
+ // it must resolve to some kind of HIR::Item or HIR::InheritImplItem
HIR::Item *resolved_item = ctx->get_mappings ()->lookup_hir_item (
expr.get_mappings ().get_crate_num (), ref);
- if (resolved_item == nullptr)
+ if (resolved_item != nullptr)
{
- rust_error_at (expr.get_locus (), "failed to lookup definition decl");
- return;
+ if (!lookup->has_subsititions_defined ())
+ CompileItem::compile (resolved_item, ctx);
+ else
+ CompileItem::compile (resolved_item, ctx, true, lookup);
}
-
- if (!lookup->has_subsititions_defined ())
- CompileItem::compile (resolved_item, ctx);
else
- CompileItem::compile (resolved_item, ctx, true, lookup);
+ {
+ HirId parent_impl_id = UNKNOWN_HIRID;
+ HIR::InherentImplItem *resolved_item
+ = ctx->get_mappings ()->lookup_hir_implitem (
+ expr.get_mappings ().get_crate_num (), ref, &parent_impl_id);
+ if (resolved_item != nullptr)
+ {
+ rust_assert (parent_impl_id != UNKNOWN_HIRID);
+ HIR::Item *impl_ref = ctx->get_mappings ()->lookup_hir_item (
+ expr.get_mappings ().get_crate_num (), parent_impl_id);
+ rust_assert (impl_ref != nullptr);
+ HIR::InherentImpl *impl
+ = static_cast<HIR::InherentImpl *> (impl_ref);
+
+ TyTy::BaseType *self = nullptr;
+ bool ok = ctx->get_tyctx ()->lookup_type (
+ impl->get_type ()->get_mappings ().get_hirid (), &self);
+ rust_assert (ok);
+
+ if (!lookup->has_subsititions_defined ())
+ CompileInherentImplItem::Compile (self, resolved_item, ctx,
+ true);
+ else
+ CompileInherentImplItem::Compile (self, resolved_item, ctx,
+ true, lookup);
+ }
+ else
+ {
+ rust_error_at (expr.get_locus (),
+ "failed to lookup definition decl");
+ return;
+ }
+ }
if (!ctx->lookup_function_decl (lookup->get_ty_ref (), &fn))
{
diff --git a/gcc/rust/backend/rust-compile.cc b/gcc/rust/backend/rust-compile.cc
index 204cce7..7b1b2ff 100644
--- a/gcc/rust/backend/rust-compile.cc
+++ b/gcc/rust/backend/rust-compile.cc
@@ -130,7 +130,7 @@ CompileExpr::visit (HIR::MethodCallExpr &expr)
// resolve it now
HIR::InherentImplItem *resolved_item
= ctx->get_mappings ()->lookup_hir_implitem (
- expr.get_mappings ().get_crate_num (), ref);
+ expr.get_mappings ().get_crate_num (), ref, nullptr);
if (resolved_item == nullptr)
{
rust_error_at (expr.get_locus (), "failed to lookup forward decl");
diff --git a/gcc/rust/hir/rust-ast-lower-implitem.h b/gcc/rust/hir/rust-ast-lower-implitem.h
index 473d14f..3ddc62c 100644
--- a/gcc/rust/hir/rust-ast-lower-implitem.h
+++ b/gcc/rust/hir/rust-ast-lower-implitem.h
@@ -34,9 +34,10 @@ class ASTLowerImplItem : public ASTLoweringBase
using Rust::HIR::ASTLoweringBase::visit;
public:
- static HIR::InherentImplItem *translate (AST::InherentImplItem *item)
+ static HIR::InherentImplItem *translate (AST::InherentImplItem *item,
+ HirId parent_impl_id)
{
- ASTLowerImplItem resolver;
+ ASTLowerImplItem resolver (parent_impl_id);
item->accept_vis (resolver);
rust_assert (resolver.translated != nullptr);
return resolver.translated;
@@ -76,7 +77,8 @@ public:
outer_attrs, constant.get_locus ());
mappings->insert_hir_implitem (mapping.get_crate_num (),
- mapping.get_hirid (), translated);
+ mapping.get_hirid (), parent_impl_id,
+ translated);
mappings->insert_location (crate_num, mapping.get_hirid (),
constant.get_locus ());
}
@@ -144,7 +146,7 @@ public:
std::move (vis), std::move (outer_attrs), locus);
mappings->insert_hir_implitem (mapping.get_crate_num (),
- mapping.get_hirid (), fn);
+ mapping.get_hirid (), parent_impl_id, fn);
mappings->insert_location (crate_num, mapping.get_hirid (),
function.get_locus ());
@@ -221,7 +223,7 @@ public:
std::move (outer_attrs), locus);
mappings->insert_hir_implitem (mapping.get_crate_num (),
- mapping.get_hirid (), mth);
+ mapping.get_hirid (), parent_impl_id, mth);
mappings->insert_location (crate_num, mapping.get_hirid (),
method.get_locus ());
@@ -246,13 +248,15 @@ public:
}
private:
- ASTLowerImplItem () : translated (nullptr) {}
+ ASTLowerImplItem (HirId parent_impl_id)
+ : translated (nullptr), parent_impl_id (parent_impl_id)
+ {}
HIR::InherentImplItem *translated;
+ HirId parent_impl_id;
};
} // namespace HIR
-
} // namespace Rust
#endif // RUST_AST_LOWER_IMPLITEM_H
diff --git a/gcc/rust/hir/rust-ast-lower-item.h b/gcc/rust/hir/rust-ast-lower-item.h
index 50e50f6..6f98b23 100644
--- a/gcc/rust/hir/rust-ast-lower-item.h
+++ b/gcc/rust/hir/rust-ast-lower-item.h
@@ -306,27 +306,35 @@ public:
{
std::vector<HIR::Attribute> inner_attrs;
std::vector<HIR::Attribute> outer_attrs;
- std::vector<std::unique_ptr<HIR::GenericParam> > generic_params;
std::vector<std::unique_ptr<HIR::WhereClauseItem> > where_clause_items;
HIR::WhereClause where_clause (std::move (where_clause_items));
HIR::Visibility vis = HIR::Visibility::create_public ();
+
+ std::vector<std::unique_ptr<HIR::GenericParam> > generic_params;
+ if (impl_block.has_generics ())
+ {
+ generic_params
+ = lower_generic_params (impl_block.get_generic_params ());
+ }
+
HIR::Type *trait_type
= ASTLoweringType::translate (impl_block.get_type ().get ());
+ auto crate_num = mappings->get_current_crate ();
+ Analysis::NodeMapping mapping (crate_num, impl_block.get_node_id (),
+ mappings->get_next_hir_id (crate_num),
+ mappings->get_next_localdef_id (crate_num));
+
std::vector<std::unique_ptr<HIR::InherentImplItem> > impl_items;
for (auto &impl_item : impl_block.get_impl_items ())
{
HIR::InherentImplItem *lowered
- = ASTLowerImplItem::translate (impl_item.get ());
+ = ASTLowerImplItem::translate (impl_item.get (),
+ mapping.get_hirid ());
impl_items.push_back (std::unique_ptr<HIR::InherentImplItem> (lowered));
}
- auto crate_num = mappings->get_current_crate ();
- Analysis::NodeMapping mapping (crate_num, impl_block.get_node_id (),
- mappings->get_next_hir_id (crate_num),
- mappings->get_next_localdef_id (crate_num));
-
translated
= new HIR::InherentImpl (mapping, std::move (impl_items),
std::move (generic_params),
diff --git a/gcc/rust/hir/tree/rust-hir-item.h b/gcc/rust/hir/tree/rust-hir-item.h
index 34ea2c3..c9723f8 100644
--- a/gcc/rust/hir/tree/rust-hir-item.h
+++ b/gcc/rust/hir/tree/rust-hir-item.h
@@ -2915,6 +2915,11 @@ public:
std::unique_ptr<Type> &get_type () { return trait_type; };
+ std::vector<std::unique_ptr<GenericParam> > &get_generic_params ()
+ {
+ return generic_params;
+ }
+
protected:
// Mega-constructor
Impl (Analysis::NodeMapping mappings,
diff --git a/gcc/rust/resolve/rust-ast-resolve-implitem.h b/gcc/rust/resolve/rust-ast-resolve-implitem.h
index d76cbac..d88b275f 100644
--- a/gcc/rust/resolve/rust-ast-resolve-implitem.h
+++ b/gcc/rust/resolve/rust-ast-resolve-implitem.h
@@ -34,13 +34,19 @@ public:
static void go (AST::InherentImplItem *item, AST::Type *base)
{
ResolveToplevelImplItem resolver (base);
+ if (resolver.base_path.is_empty ())
+ {
+ rust_error_at (base->get_locus_slow (),
+ "failed to resolve simple path");
+ return;
+ }
item->accept_vis (resolver);
- };
+ }
void visit (AST::ConstantItem &constant) override
{
std::string identifier
- = base->as_string () + "::" + constant.get_identifier ();
+ = base_path.as_string () + "::" + constant.get_identifier ();
resolver->get_name_scope ().insert (
identifier, constant.get_node_id (), constant.get_locus (), false,
[&] (std::string, NodeId, Location locus) -> void {
@@ -55,7 +61,7 @@ public:
void visit (AST::Function &function) override
{
std::string identifier
- = base->as_string () + "::" + function.get_function_name ();
+ = base_path.as_string () + "::" + function.get_function_name ();
resolver->get_name_scope ().insert (
identifier, function.get_node_id (), function.get_locus (), false,
[&] (std::string, NodeId, Location locus) -> void {
@@ -70,7 +76,7 @@ public:
void visit (AST::Method &method) override
{
std::string identifier
- = base->as_string () + "::" + method.get_method_name ();
+ = base_path.as_string () + "::" + method.get_method_name ();
resolver->get_name_scope ().insert (
identifier, method.get_node_id (), method.get_locus (), false,
[&] (std::string, NodeId, Location locus) -> void {
@@ -84,10 +90,14 @@ public:
private:
ResolveToplevelImplItem (AST::Type *base)
- : ResolverBase (UNKNOWN_NODEID), base (base)
- {}
+ : ResolverBase (UNKNOWN_NODEID), base (base),
+ base_path (AST::SimplePath::create_empty ())
+ {
+ ResolveTypeToSimplePath::go (base, base_path, true);
+ }
AST::Type *base;
+ AST::SimplePath base_path;
};
} // namespace Resolver
diff --git a/gcc/rust/resolve/rust-ast-resolve-item.h b/gcc/rust/resolve/rust-ast-resolve-item.h
index 95e335b..1074031 100644
--- a/gcc/rust/resolve/rust-ast-resolve-item.h
+++ b/gcc/rust/resolve/rust-ast-resolve-item.h
@@ -152,6 +152,17 @@ public:
void visit (AST::InherentImpl &impl_block) override
{
+ NodeId scope_node_id = impl_block.get_node_id ();
+ resolver->get_type_scope ().push (scope_node_id);
+
+ if (impl_block.has_generics ())
+ {
+ for (auto &generic : impl_block.get_generic_params ())
+ {
+ ResolveGenericParam::go (generic.get (), impl_block.get_node_id ());
+ }
+ }
+
NodeId resolved_node = ResolveType::go (impl_block.get_type ().get (),
impl_block.get_node_id ());
if (resolved_node == UNKNOWN_NODEID)
@@ -164,6 +175,7 @@ public:
impl_item->accept_vis (*this);
resolver->get_type_scope ().peek ()->clear_name ("Self", resolved_node);
+ resolver->get_type_scope ().pop ();
}
void visit (AST::Method &method) override
diff --git a/gcc/rust/resolve/rust-ast-resolve-type.h b/gcc/rust/resolve/rust-ast-resolve-type.h
index c829ed0..9e7568e 100644
--- a/gcc/rust/resolve/rust-ast-resolve-type.h
+++ b/gcc/rust/resolve/rust-ast-resolve-type.h
@@ -25,25 +25,22 @@
namespace Rust {
namespace Resolver {
-class ResolveTypePath : public ResolverBase
+class ResolveTypeToSimplePath : public ResolverBase
{
using Rust::Resolver::ResolverBase::visit;
public:
- static NodeId go (AST::TypePath &path, NodeId parent)
+ static bool go (AST::Type *type, AST::SimplePath &simple_path_result,
+ bool path_only = false)
{
- ResolveTypePath resolver (parent);
- resolver.resolve (path);
- return resolver.resolved_node;
+ ResolveTypeToSimplePath resolver (simple_path_result, path_only);
+ type->accept_vis (resolver);
+ return !resolver.type_seg_failed_flag;
}
- void visit (AST::TypePathSegmentGeneric &seg) override;
-
- void visit (AST::TypePathSegment &seg) override;
-
-private:
- void resolve (AST::TypePath &path)
+ void visit (AST::TypePath &path) override
{
+ segs.reserve (path.get_num_segments ());
for (auto &seg : path.get_segments ())
{
seg->accept_vis (*this);
@@ -51,27 +48,55 @@ private:
return;
}
- if (path_buffer.empty ())
+ if (segs.empty ())
{
rust_error_at (path.get_locus (), "failed to resolve path: %s",
path.as_string ().c_str ());
return;
}
- if (!resolver->get_type_scope ().lookup (path_buffer, &resolved_node))
- {
- rust_error_at (path.get_locus (), "failed to resolve TypePath: %s",
- path_buffer.c_str ());
- return;
- }
+ bool has_opening_scope_res = false;
+ result = AST::SimplePath (std::move (segs), has_opening_scope_res,
+ path.get_locus ());
}
- ResolveTypePath (NodeId parent)
- : ResolverBase (parent), type_seg_failed_flag (false)
+ void visit (AST::TypePathSegmentGeneric &seg) override;
+
+ void visit (AST::TypePathSegment &seg) override;
+
+private:
+ ResolveTypeToSimplePath (AST::SimplePath &simple_path_result, bool path_only)
+ : ResolverBase (UNKNOWN_NODEID), type_seg_failed_flag (false),
+ result (simple_path_result), path_only_flag (path_only)
{}
- std::string path_buffer;
bool type_seg_failed_flag;
+ std::vector<AST::SimplePathSegment> segs;
+ AST::SimplePath &result;
+ bool path_only_flag;
+};
+
+class ResolveTypePath
+{
+public:
+ static NodeId go (AST::TypePath &path, NodeId parent)
+ {
+ AST::SimplePath path_buffer = AST::SimplePath::create_empty ();
+ if (!ResolveTypeToSimplePath::go (&path, path_buffer))
+ return UNKNOWN_NODEID;
+
+ auto resolver = Resolver::get ();
+ NodeId resolved_node = UNKNOWN_NODEID;
+ if (!resolver->get_type_scope ().lookup (path_buffer.as_string (),
+ &resolved_node))
+ {
+ rust_error_at (path.get_locus_slow (), "failed to resolve TypePath: %s",
+ path_buffer.as_string ().c_str ());
+ return UNKNOWN_NODEID;
+ }
+
+ return resolved_node;
+ }
};
class ResolveType : public ResolverBase
diff --git a/gcc/rust/resolve/rust-ast-resolve.cc b/gcc/rust/resolve/rust-ast-resolve.cc
index b4ca34f..4cc1a93 100644
--- a/gcc/rust/resolve/rust-ast-resolve.cc
+++ b/gcc/rust/resolve/rust-ast-resolve.cc
@@ -375,11 +375,14 @@ ResolveStructExprField::visit (AST::StructExprFieldIdentifier &field)
// rust-ast-resolve-type.h
void
-ResolveTypePath::visit (AST::TypePathSegmentGeneric &seg)
+ResolveTypeToSimplePath::visit (AST::TypePathSegmentGeneric &seg)
{
- AST::GenericArgs &generics = seg.get_generic_args ();
- for (auto &gt : generics.get_type_args ())
- ResolveType::go (gt.get (), UNKNOWN_NODEID);
+ if (!path_only_flag)
+ {
+ AST::GenericArgs &generics = seg.get_generic_args ();
+ for (auto &gt : generics.get_type_args ())
+ ResolveType::go (gt.get (), UNKNOWN_NODEID);
+ }
if (seg.is_error ())
{
@@ -389,14 +392,12 @@ ResolveTypePath::visit (AST::TypePathSegmentGeneric &seg)
return;
}
- if (seg.get_separating_scope_resolution ())
- path_buffer += "::";
-
- path_buffer += seg.get_ident_segment ().as_string ();
+ segs.push_back (AST::SimplePathSegment (seg.get_ident_segment ().as_string (),
+ seg.get_locus ()));
}
void
-ResolveTypePath::visit (AST::TypePathSegment &seg)
+ResolveTypeToSimplePath::visit (AST::TypePathSegment &seg)
{
if (seg.is_error ())
{
@@ -406,10 +407,8 @@ ResolveTypePath::visit (AST::TypePathSegment &seg)
return;
}
- if (seg.get_separating_scope_resolution ())
- path_buffer += "::";
-
- path_buffer += seg.get_ident_segment ().as_string ();
+ segs.push_back (AST::SimplePathSegment (seg.get_ident_segment ().as_string (),
+ seg.get_locus ()));
}
// rust-ast-resolve-expr.h
@@ -465,8 +464,8 @@ ResolvePath::resolve_path (AST::PathInExpression *expr)
}
else
{
- rust_error_at (expr->get_locus (), "unknown path %s",
- expr->as_string ().c_str ());
+ rust_error_at (expr->get_locus (), "unknown path %s lookup %s",
+ expr->as_string ().c_str (), path_buf.c_str ());
}
}
diff --git a/gcc/rust/typecheck/rust-hir-type-check-implitem.h b/gcc/rust/typecheck/rust-hir-type-check-implitem.h
index e116048..9857045 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-implitem.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-implitem.h
@@ -33,9 +33,11 @@ class TypeCheckTopLevelImplItem : public TypeCheckBase
using Rust::Resolver::TypeCheckBase::visit;
public:
- static void Resolve (HIR::InherentImplItem *item, TyTy::BaseType *self)
+ static void
+ Resolve (HIR::InherentImplItem *item, TyTy::BaseType *self,
+ std::vector<TyTy::SubstitutionParamMapping> substitutions)
{
- TypeCheckTopLevelImplItem resolver (self);
+ TypeCheckTopLevelImplItem resolver (self, substitutions);
item->accept_vis (resolver);
}
@@ -50,7 +52,6 @@ public:
void visit (HIR::Function &function) override
{
- std::vector<TyTy::SubstitutionParamMapping> substitions;
if (function.has_generics ())
{
for (auto &generic_param : function.get_generic_params ())
@@ -59,7 +60,7 @@ public:
= TypeResolveGenericParam::Resolve (generic_param.get ());
context->insert_type (generic_param->get_mappings (), param_type);
- substitions.push_back (
+ substitutions.push_back (
TyTy::SubstitutionParamMapping (generic_param, param_type));
}
}
@@ -97,13 +98,12 @@ public:
auto fnType = new TyTy::FnType (function.get_mappings ().get_hirid (),
std::move (params), ret_type,
- std::move (substitions));
+ std::move (substitutions));
context->insert_type (function.get_mappings (), fnType);
}
void visit (HIR::Method &method) override
{
- std::vector<TyTy::SubstitutionParamMapping> substitions;
if (method.has_generics ())
{
for (auto &generic_param : method.get_generic_params ())
@@ -112,7 +112,7 @@ public:
= TypeResolveGenericParam::Resolve (generic_param.get ());
context->insert_type (generic_param->get_mappings (), param_type);
- substitions.push_back (
+ substitutions.push_back (
TyTy::SubstitutionParamMapping (generic_param, param_type));
}
}
@@ -164,16 +164,19 @@ public:
auto fnType = new TyTy::FnType (method.get_mappings ().get_hirid (),
std::move (params), ret_type,
- std::move (substitions));
+ std::move (substitutions));
context->insert_type (method.get_mappings (), fnType);
}
private:
- TypeCheckTopLevelImplItem (TyTy::BaseType *self)
- : TypeCheckBase (), self (self)
+ TypeCheckTopLevelImplItem (
+ TyTy::BaseType *self,
+ std::vector<TyTy::SubstitutionParamMapping> substitutions)
+ : TypeCheckBase (), self (self), substitutions (substitutions)
{}
TyTy::BaseType *self;
+ std::vector<TyTy::SubstitutionParamMapping> substitutions;
};
class TypeCheckImplItem : public TypeCheckBase
diff --git a/gcc/rust/typecheck/rust-hir-type-check-toplevel.h b/gcc/rust/typecheck/rust-hir-type-check-toplevel.h
index cfc6f59..702c6c7 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-toplevel.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-toplevel.h
@@ -189,15 +189,30 @@ public:
void visit (HIR::InherentImpl &impl_block) override
{
+ std::vector<TyTy::SubstitutionParamMapping> substitutions;
+ if (impl_block.has_generics ())
+ {
+ for (auto &generic_param : impl_block.get_generic_params ())
+ {
+ auto param_type
+ = TypeResolveGenericParam::Resolve (generic_param.get ());
+ context->insert_type (generic_param->get_mappings (), param_type);
+
+ substitutions.push_back (
+ TyTy::SubstitutionParamMapping (generic_param, param_type));
+ }
+ }
+
auto self = TypeCheckType::Resolve (impl_block.get_type ().get ());
- if (self == nullptr)
+ if (self == nullptr || self->get_kind () == TyTy::TypeKind::ERROR)
{
rust_error_at (impl_block.get_locus (), "failed to resolve impl type");
return;
}
for (auto &impl_item : impl_block.get_impl_items ())
- TypeCheckTopLevelImplItem::Resolve (impl_item.get (), self);
+ TypeCheckTopLevelImplItem::Resolve (impl_item.get (), self,
+ substitutions);
}
private:
diff --git a/gcc/rust/util/rust-hir-map.cc b/gcc/rust/util/rust-hir-map.cc
index 4a1d4f7..891618e 100644
--- a/gcc/rust/util/rust-hir-map.cc
+++ b/gcc/rust/util/rust-hir-map.cc
@@ -260,16 +260,18 @@ Mappings::lookup_hir_item (CrateNum crateNum, HirId id)
void
Mappings::insert_hir_implitem (CrateNum crateNum, HirId id,
+ HirId parent_impl_id,
HIR::InherentImplItem *item)
{
- rust_assert (lookup_hir_implitem (crateNum, id) == nullptr);
-
- hirImplItemMappings[crateNum][id] = item;
+ rust_assert (lookup_hir_implitem (crateNum, id, nullptr) == nullptr);
+ hirImplItemMappings[crateNum][id]
+ = std::pair<HirId, HIR::InherentImplItem *> (parent_impl_id, item);
nodeIdToHirMappings[crateNum][item->get_impl_mappings ().get_nodeid ()] = id;
}
HIR::InherentImplItem *
-Mappings::lookup_hir_implitem (CrateNum crateNum, HirId id)
+Mappings::lookup_hir_implitem (CrateNum crateNum, HirId id,
+ HirId *parent_impl_id)
{
auto it = hirImplItemMappings.find (crateNum);
if (it == hirImplItemMappings.end ())
@@ -279,7 +281,11 @@ Mappings::lookup_hir_implitem (CrateNum crateNum, HirId id)
if (iy == it->second.end ())
return nullptr;
- return iy->second;
+ std::pair<HirId, HIR::InherentImplItem *> &ref = iy->second;
+ if (parent_impl_id != nullptr)
+ *parent_impl_id = ref.first;
+
+ return ref.second;
}
void
diff --git a/gcc/rust/util/rust-hir-map.h b/gcc/rust/util/rust-hir-map.h
index b7dbd45..2e8a629 100644
--- a/gcc/rust/util/rust-hir-map.h
+++ b/gcc/rust/util/rust-hir-map.h
@@ -109,9 +109,10 @@ public:
void insert_hir_item (CrateNum crateNum, HirId id, HIR::Item *item);
HIR::Item *lookup_hir_item (CrateNum crateNum, HirId id);
- void insert_hir_implitem (CrateNum crateNum, HirId id,
+ void insert_hir_implitem (CrateNum crateNum, HirId id, HirId parent_impl_id,
HIR::InherentImplItem *item);
- HIR::InherentImplItem *lookup_hir_implitem (CrateNum crateNum, HirId id);
+ HIR::InherentImplItem *lookup_hir_implitem (CrateNum crateNum, HirId id,
+ HirId *parent_impl_id);
void insert_hir_expr (CrateNum crateNum, HirId id, HIR::Expr *expr);
HIR::Expr *lookup_hir_expr (CrateNum crateNum, HirId id);
@@ -165,7 +166,7 @@ public:
{
for (auto iy = it->second.begin (); iy != it->second.end (); iy++)
{
- if (!cb (iy->first, iy->second))
+ if (!cb (iy->first, iy->second.second))
return;
}
}
@@ -193,7 +194,8 @@ private:
std::map<CrateNum, std::map<HirId, HIR::FunctionParam *> > hirParamMappings;
std::map<CrateNum, std::map<HirId, HIR::StructExprField *> >
hirStructFieldMappings;
- std::map<CrateNum, std::map<HirId, HIR::InherentImplItem *> >
+ std::map<CrateNum,
+ std::map<HirId, std::pair<HirId, HIR::InherentImplItem *> > >
hirImplItemMappings;
std::map<CrateNum, std::map<HirId, HIR::SelfParam *> > hirSelfParamMappings;
diff --git a/gcc/testsuite/rust.test/compile/generics8.rs b/gcc/testsuite/rust.test/compile/generics8.rs
new file mode 100644
index 0000000..ad5a1f4
--- /dev/null
+++ b/gcc/testsuite/rust.test/compile/generics8.rs
@@ -0,0 +1,15 @@
+struct GenericStruct<T>(T, usize);
+
+impl<T> GenericStruct<T> {
+ fn new(a: T, b: usize) -> Self {
+ GenericStruct(a, b)
+ }
+}
+
+fn main() {
+ let a: GenericStruct<i32> = GenericStruct::<i32>::new(123, 456);
+
+ let b: GenericStruct<u32> = GenericStruct::<_>::new(123, 456);
+
+ let c: GenericStruct<f32> = GenericStruct::new(123f32, 456);
+}