diff options
-rw-r--r-- | gcc/rust/backend/rust-compile-context.h | 3 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-implitem.h | 28 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-resolve-path.cc | 47 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile.cc | 2 | ||||
-rw-r--r-- | gcc/rust/hir/rust-ast-lower-implitem.h | 18 | ||||
-rw-r--r-- | gcc/rust/hir/rust-ast-lower-item.h | 22 | ||||
-rw-r--r-- | gcc/rust/hir/tree/rust-hir-item.h | 5 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-implitem.h | 22 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-item.h | 12 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-type.h | 67 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve.cc | 29 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-implitem.h | 23 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-toplevel.h | 19 | ||||
-rw-r--r-- | gcc/rust/util/rust-hir-map.cc | 16 | ||||
-rw-r--r-- | gcc/rust/util/rust-hir-map.h | 10 | ||||
-rw-r--r-- | gcc/testsuite/rust.test/compile/generics8.rs | 15 |
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 ¶m) 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 > : generics.get_type_args ()) - ResolveType::go (gt.get (), UNKNOWN_NODEID); + if (!path_only_flag) + { + AST::GenericArgs &generics = seg.get_generic_args (); + for (auto > : 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); +} |