diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/backend/rust-compile-resolve-path.cc | 8 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile.cc | 70 | ||||
-rw-r--r-- | gcc/rust/hir/tree/rust-hir-path.h | 5 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-item.h | 2 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-type.h | 96 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-path.cc | 1 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-toplevel.h | 2 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-type.cc | 325 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-type.h | 7 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check.h | 30 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty.cc | 55 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty.h | 23 | ||||
-rw-r--r-- | gcc/rust/util/rust-canonical-path.h | 19 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/generic-default1.rs | 2 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/generics5.rs | 5 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/generics9.rs | 1 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/method2.rs | 1 |
17 files changed, 491 insertions, 161 deletions
diff --git a/gcc/rust/backend/rust-compile-resolve-path.cc b/gcc/rust/backend/rust-compile-resolve-path.cc index 98c04df..9e8236c 100644 --- a/gcc/rust/backend/rust-compile-resolve-path.cc +++ b/gcc/rust/backend/rust-compile-resolve-path.cc @@ -197,11 +197,11 @@ ResolvePathRef::query_compile (HirId ref, TyTy::BaseType *lookup, Analysis::NodeMapping trait_mappings = trait_item_ref->get_parent_trait_mappings (); - auto associated_impl_id - = ctx->get_tyctx ()->lookup_associated_impl_mapping_for_self ( - trait_mappings.get_hirid (), receiver); - rust_assert (associated_impl_id != UNKNOWN_HIRID); + HirId associated_impl_id; + ok = ctx->get_tyctx ()->lookup_associated_impl_mapping_for_self ( + trait_mappings.get_hirid (), receiver, &associated_impl_id); + rust_assert (ok); Resolver::AssociatedImplTrait *associated = nullptr; bool found_associated_trait_impl diff --git a/gcc/rust/backend/rust-compile.cc b/gcc/rust/backend/rust-compile.cc index 56d3e40..f97f701 100644 --- a/gcc/rust/backend/rust-compile.cc +++ b/gcc/rust/backend/rust-compile.cc @@ -322,12 +322,21 @@ CompileExpr::visit (HIR::MethodCallExpr &expr) return; } - // lookup compiled functions + // address of compiled function + Bexpression *fn_expr = ctx->get_backend ()->error_expression (); + + // lookup compiled functions since it may have already been compiled Bfunction *fn = nullptr; - if (!ctx->lookup_function_decl (fntype->get_ty_ref (), &fn)) + if (ctx->lookup_function_decl (fntype->get_ty_ref (), &fn)) + { + fn_expr + = ctx->get_backend ()->function_code_expression (fn, expr.get_locus ()); + } + else { - // this might fail because its a forward decl so we can attempt to - // resolve it now + // Now we can try and resolve the address since this might be a forward + // declared function, generic function which has not be compiled yet or + // its an not yet trait bound function HIR::ImplItem *resolved_item = ctx->get_mappings ()->lookup_hir_implitem ( expr.get_mappings ().get_crate_num (), ref, nullptr); if (resolved_item == nullptr) @@ -380,16 +389,9 @@ CompileExpr::visit (HIR::MethodCallExpr &expr) return; } - CompileTraitItem::Compile (self_type, - trait_item_ref->get_hir_trait_item (), - ctx, fntype); - if (!ctx->lookup_function_decl (fntype->get_ty_ref (), &fn)) - { - translated = ctx->get_backend ()->error_expression (); - rust_error_at (expr.get_locus (), - "forward declaration was not compiled"); - return; - } + fn_expr = CompileTraitItem::Compile ( + self_type, trait_item_ref->get_hir_trait_item (), ctx, fntype, + true, expr.get_locus ()); } else { @@ -418,20 +420,13 @@ CompileExpr::visit (HIR::MethodCallExpr &expr) } if (!fntype->has_subsititions_defined ()) - CompileInherentImplItem::Compile (self_type, impl_item, ctx, - true); + fn_expr + = CompileInherentImplItem::Compile (self_type, impl_item, ctx, + true); else - CompileInherentImplItem::Compile (self_type, impl_item, ctx, - true, fntype); - - if (!ctx->lookup_function_decl ( - impl_item->get_impl_mappings ().get_hirid (), &fn)) - { - translated = ctx->get_backend ()->error_expression (); - rust_error_at (expr.get_locus (), - "forward declaration was not compiled"); - return; - } + fn_expr + = CompileInherentImplItem::Compile (self_type, impl_item, ctx, + true, fntype); } } else @@ -446,25 +441,16 @@ CompileExpr::visit (HIR::MethodCallExpr &expr) } if (!fntype->has_subsititions_defined ()) - CompileInherentImplItem::Compile (self_type, resolved_item, ctx, - true); + fn_expr + = CompileInherentImplItem::Compile (self_type, resolved_item, ctx, + true); else - CompileInherentImplItem::Compile (self_type, resolved_item, ctx, - true, fntype); - - if (!ctx->lookup_function_decl (fntype->get_ty_ref (), &fn)) - { - translated = ctx->get_backend ()->error_expression (); - rust_error_at (expr.get_locus (), - "forward declaration was not compiled"); - return; - } + fn_expr + = CompileInherentImplItem::Compile (self_type, resolved_item, ctx, + true, fntype); } } - Bexpression *fn_expr - = ctx->get_backend ()->function_code_expression (fn, expr.get_locus ()); - std::vector<Bexpression *> args; // lookup the autoderef mappings diff --git a/gcc/rust/hir/tree/rust-hir-path.h b/gcc/rust/hir/tree/rust-hir-path.h index 13e246f..a04398e 100644 --- a/gcc/rust/hir/tree/rust-hir-path.h +++ b/gcc/rust/hir/tree/rust-hir-path.h @@ -420,6 +420,11 @@ public: const Analysis::NodeMapping &get_mappings () const { return mappings; } const PathIdentSegment &get_ident_segment () const { return ident_segment; } + + bool is_generic_segment () const + { + return get_type () == SegmentType::GENERIC; + } }; // Segment used in type path with generic args diff --git a/gcc/rust/resolve/rust-ast-resolve-item.h b/gcc/rust/resolve/rust-ast-resolve-item.h index 87bf10e..71085f6 100644 --- a/gcc/rust/resolve/rust-ast-resolve-item.h +++ b/gcc/rust/resolve/rust-ast-resolve-item.h @@ -591,7 +591,7 @@ public: // Self is an implicit TypeParam so lets mark it as such resolver->get_type_scope ().append_reference_for_def ( - Self.get_id (), implicit_self->get_node_id ()); + Self.get_node_id (), implicit_self->get_node_id ()); if (trait.has_type_param_bounds ()) { diff --git a/gcc/rust/resolve/rust-ast-resolve-type.h b/gcc/rust/resolve/rust-ast-resolve-type.h index 137b16a..2dc7fbf 100644 --- a/gcc/rust/resolve/rust-ast-resolve-type.h +++ b/gcc/rust/resolve/rust-ast-resolve-type.h @@ -188,46 +188,11 @@ class ResolveRelativeTypePath : public ResolveTypeToCanonicalPath using ResolveTypeToCanonicalPath::visit; public: - static NodeId go (AST::TypePath &path, NodeId parent, - const CanonicalPath &prefix, - bool canonicalize_type_with_generics) - { - CanonicalPath canonical_path - = ResolveTypeToCanonicalPath::resolve (path, - canonicalize_type_with_generics, - true); - if (canonical_path.is_empty ()) - { - rust_error_at (path.get_locus (), - "Failed to resolve canonical path for TypePath"); - return UNKNOWN_NODEID; - } - - CanonicalPath lookup = canonical_path; - if (!prefix.is_empty ()) - lookup = prefix.append (canonical_path); - - auto resolver = Resolver::get (); - NodeId resolved_node = UNKNOWN_NODEID; - - // We may need to change how names are resolved, like described in : - // https://github.com/rust-lang/rust/blob/1f94abcda6884893d4723304102089198caa0839/compiler/rustc_resolve/src/lib.rs#L1722 - if (!resolver->get_type_scope ().lookup (canonical_path, &resolved_node)) - { - rust_error_at (path.get_locus (), "failed to resolve TypePath: %s", - canonical_path.get ().c_str ()); - return UNKNOWN_NODEID; - } - - return resolved_node; - } - static NodeId go (AST::QualifiedPathInType &path, NodeId parent, - const CanonicalPath &prefix, bool canonicalize_type_with_generics) { auto &qualified_path = path.get_qualified_path_type (); - CanonicalPath result = prefix; + CanonicalPath result = CanonicalPath::create_empty (); if (!resolve_qual_seg (qualified_path, result)) return UNKNOWN_NODEID; @@ -322,12 +287,58 @@ public: void visit (AST::TypePath &path) override { - resolved_node - = ResolveRelativeTypePath::go (path, parent, - CanonicalPath::create_empty (), - canonicalize_type_with_generics); - ok = resolved_node != UNKNOWN_NODEID; - if (ok) + auto canonical_path + = ResolveTypeToCanonicalPath::resolve (path, + canonicalize_type_with_generics, + true); + if (canonical_path.is_empty ()) + { + rust_error_at (path.get_locus (), + "Failed to resolve canonical path for TypePath"); + return; + } + + ok = !canonical_path.is_empty (); + + // lets try and resolve in one go else leave it up to the type resolver to + // figure outer + + if (resolver->get_type_scope ().lookup (canonical_path, &resolved_node)) + { + resolver->insert_resolved_type (path.get_node_id (), resolved_node); + resolver->insert_new_definition (path.get_node_id (), + Definition{path.get_node_id (), + parent}); + return; + } + + // lets resolve as many segments as we can and leave it up to the type + // resolver otherwise + size_t nprocessed = 0; + canonical_path.iterate ([&] (const CanonicalPath &seg) -> bool { + resolved_node = UNKNOWN_NODEID; + + if (!resolver->get_type_scope ().lookup (seg, &resolved_node)) + return false; + + resolver->insert_resolved_type (seg.get_node_id (), resolved_node); + resolver->insert_new_definition (seg.get_node_id (), + Definition{path.get_node_id (), parent}); + nprocessed++; + return true; + }); + + if (nprocessed == 0) + { + rust_error_at (path.get_locus (), "failed to resolve TypePath: %s", + path.as_string ().c_str ()); + return; + } + + // its ok if this fails since the type resolver sometimes will need to + // investigate the bounds of a type for the associated type for example see: + // https://github.com/Rust-GCC/gccrs/issues/746 + if (nprocessed == canonical_path.size ()) { resolver->insert_resolved_type (path.get_node_id (), resolved_node); resolver->insert_new_definition (path.get_node_id (), @@ -340,7 +351,6 @@ public: { resolved_node = ResolveRelativeTypePath::go (path, parent, - CanonicalPath::create_empty (), canonicalize_type_with_generics); ok = resolved_node != UNKNOWN_NODEID; } diff --git a/gcc/rust/typecheck/rust-hir-type-check-path.cc b/gcc/rust/typecheck/rust-hir-type-check-path.cc index 8b53e44..0aea8ca 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-path.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-path.cc @@ -41,6 +41,7 @@ TypeCheckExpr::visit (HIR::QualifiedPathInExpression &expr) resolve_segments (root_resolved_node_id, expr.get_segments (), 0, root, expr.get_mappings (), expr.get_locus ()); + return; } // Resolve the trait now diff --git a/gcc/rust/typecheck/rust-hir-type-check-toplevel.h b/gcc/rust/typecheck/rust-hir-type-check-toplevel.h index 131149f..be53a0d 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-toplevel.h +++ b/gcc/rust/typecheck/rust-hir-type-check-toplevel.h @@ -266,7 +266,7 @@ public: { auto resolved = TypeCheckType::Resolve (function.get_return_type ().get ()); - if (resolved == nullptr) + if (resolved->get_kind () == TyTy::TypeKind::ERROR) { rust_error_at (function.get_locus (), "failed to resolve return type"); diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.cc b/gcc/rust/typecheck/rust-hir-type-check-type.cc index 7ad6d03..a479581 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-type.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-type.cc @@ -28,10 +28,26 @@ TypeCheckType::visit (HIR::TypePath &path) // lookup the Node this resolves to NodeId ref; auto nid = path.get_mappings ().get_nodeid (); - if (!resolver->lookup_resolved_type (nid, &ref)) + bool is_fully_resolved = resolver->lookup_resolved_type (nid, &ref); + + TyTy::BaseType *lookup = nullptr; + if (!is_fully_resolved) { - rust_fatal_error (path.get_locus (), "failed to resolve node '%d' to HIR", - nid); + // this can happen so we need to look up the root then resolve the + // remaining segments if possible + size_t offset = 0; + NodeId resolved_node_id = UNKNOWN_NODEID; + TyTy::BaseType *root + = resolve_root_path (path, &offset, &resolved_node_id); + + rust_assert (root != nullptr); + if (root->get_kind () == TyTy::TypeKind::ERROR) + return; + + translated + = resolve_segments (resolved_node_id, path.get_mappings ().get_hirid (), + path.get_segments (), offset, root, + path.get_mappings (), path.get_locus ()); return; } @@ -43,7 +59,6 @@ TypeCheckType::visit (HIR::TypePath &path) return; } - TyTy::BaseType *lookup = nullptr; if (!context->lookup_type (hir_lookup, &lookup)) { rust_error_at (path.get_locus (), "failed to lookup HIR TyTy"); @@ -109,8 +124,12 @@ TypeCheckType::visit (HIR::QualifiedPathInType &path) &root_resolved_node_id); rust_assert (ok); - resolve_segments (root_resolved_node_id, path.get_segments (), 0, - translated, path.get_mappings (), path.get_locus ()); + translated = resolve_segments (root_resolved_node_id, + path.get_mappings ().get_hirid (), + path.get_segments (), 0, translated, + path.get_mappings (), path.get_locus ()); + + return; } // Resolve the trait now @@ -207,18 +226,302 @@ TypeCheckType::visit (HIR::QualifiedPathInType &path) return; } - resolve_segments (root_resolved_node_id, path.get_segments (), 0, translated, - path.get_mappings (), path.get_locus ()); + translated + = resolve_segments (root_resolved_node_id, + path.get_mappings ().get_hirid (), path.get_segments (), + 0, translated, path.get_mappings (), path.get_locus ()); } -void +TyTy::BaseType * +TypeCheckType::resolve_root_path (HIR::TypePath &path, size_t *offset, + NodeId *root_resolved_node_id) +{ + TyTy::BaseType *root_tyty = nullptr; + *offset = 0; + for (size_t i = 0; i < path.get_num_segments (); i++) + { + std::unique_ptr<HIR::TypePathSegment> &seg = path.get_segments ().at (i); + + bool have_more_segments = (path.get_num_segments () - 1 != i); + bool is_root = *offset == 0; + NodeId ast_node_id = seg->get_mappings ().get_nodeid (); + + // then lookup the reference_node_id + NodeId ref_node_id = UNKNOWN_NODEID; + if (resolver->lookup_resolved_name (ast_node_id, &ref_node_id)) + { + // these ref_node_ids will resolve to a pattern declaration but we + // are interested in the definition that this refers to get the + // parent id + Definition def; + if (!resolver->lookup_definition (ref_node_id, &def)) + { + rust_error_at (path.get_locus (), + "unknown reference for resolved name"); + return new TyTy::ErrorType (path.get_mappings ().get_hirid ()); + } + ref_node_id = def.parent; + } + else + { + resolver->lookup_resolved_type (ast_node_id, &ref_node_id); + } + + // ref_node_id is the NodeId that the segments refers to. + if (ref_node_id == UNKNOWN_NODEID) + { + if (is_root) + { + rust_error_at (seg->get_locus (), + "failed to type resolve root segment"); + return new TyTy::ErrorType (path.get_mappings ().get_hirid ()); + } + return root_tyty; + } + + // node back to HIR + HirId ref; + if (!mappings->lookup_node_to_hir (path.get_mappings ().get_crate_num (), + ref_node_id, &ref)) + { + if (is_root) + { + rust_error_at (seg->get_locus (), "789 reverse lookup failure"); + rust_debug_loc ( + seg->get_locus (), + "failure with [%s] mappings [%s] ref_node_id [%u]", + seg->as_string ().c_str (), + seg->get_mappings ().as_string ().c_str (), ref_node_id); + + return new TyTy::ErrorType (path.get_mappings ().get_hirid ()); + } + + return root_tyty; + } + + auto seg_is_module + = (nullptr + != mappings->lookup_module (path.get_mappings ().get_crate_num (), + ref)); + + if (seg_is_module) + { + // A::B::C::this_is_a_module::D::E::F + // ^^^^^^^^^^^^^^^^ + // Currently handling this. + if (have_more_segments) + { + (*offset)++; + continue; + } + + // In the case of : + // A::B::C::this_is_a_module + // ^^^^^^^^^^^^^^^^ + // This is an error, we are not expecting a module. + rust_error_at (seg->get_locus (), "expected value"); + return new TyTy::ErrorType (path.get_mappings ().get_hirid ()); + } + + TyTy::BaseType *lookup = nullptr; + if (!context->lookup_type (ref, &lookup)) + { + if (is_root) + { + rust_error_at (seg->get_locus (), + "failed to resolve root segment"); + return new TyTy::ErrorType (path.get_mappings ().get_hirid ()); + } + return root_tyty; + } + + // if we have a previous segment type + if (root_tyty != nullptr) + { + // if this next segment needs substitution we must apply the + // previous type arguments + // + // such as: GenericStruct::<_>::new(123, 456) + if (lookup->needs_generic_substitutions ()) + { + if (!root_tyty->needs_generic_substitutions ()) + { + auto used_args_in_prev_segment + = GetUsedSubstArgs::From (root_tyty); + lookup + = SubstMapperInternal::Resolve (lookup, + used_args_in_prev_segment); + } + } + } + + // turbo-fish segment path::<ty> + if (seg->is_generic_segment ()) + { + HIR::TypePathSegmentGeneric *generic_segment + = static_cast<HIR::TypePathSegmentGeneric *> (seg.get ()); + + if (!lookup->can_substitute ()) + { + rust_error_at (seg->get_locus (), + "substitutions not supported for %s", + lookup->as_string ().c_str ()); + return new TyTy::ErrorType (lookup->get_ref ()); + } + lookup = SubstMapper::Resolve (lookup, path.get_locus (), + &generic_segment->get_generic_args ()); + } + + *root_resolved_node_id = ref_node_id; + *offset = *offset + 1; + root_tyty = lookup; + } + + return root_tyty; +} + +TyTy::BaseType * TypeCheckType::resolve_segments ( - NodeId root_resolved_node_id, + NodeId root_resolved_node_id, HirId expr_id, std::vector<std::unique_ptr<HIR::TypePathSegment>> &segments, size_t offset, TyTy::BaseType *tyseg, const Analysis::NodeMapping &expr_mappings, Location expr_locus) { - gcc_unreachable (); + NodeId resolved_node_id = root_resolved_node_id; + TyTy::BaseType *prev_segment = tyseg; + for (size_t i = offset; i < segments.size (); i++) + { + std::unique_ptr<HIR::TypePathSegment> &seg = segments.at (i); + + bool reciever_is_generic + = prev_segment->get_kind () == TyTy::TypeKind::PARAM; + bool probe_bounds = true; + bool probe_impls = !reciever_is_generic; + bool ignore_mandatory_trait_items = !reciever_is_generic; + + // probe the path is done in two parts one where we search impls if no + // candidate is found then we search extensions from traits + auto candidates + = PathProbeType::Probe (prev_segment, seg->get_ident_segment (), + probe_impls, false, + ignore_mandatory_trait_items); + if (candidates.size () == 0) + { + candidates + = PathProbeType::Probe (prev_segment, seg->get_ident_segment (), + false, probe_bounds, + ignore_mandatory_trait_items); + + if (candidates.size () == 0) + { + rust_error_at ( + seg->get_locus (), + "failed to resolve path segment using an impl Probe"); + return new TyTy::ErrorType (expr_id); + } + } + + if (candidates.size () > 1) + { + ReportMultipleCandidateError::Report (candidates, + seg->get_ident_segment (), + seg->get_locus ()); + return new TyTy::ErrorType (expr_id); + } + + auto &candidate = candidates.at (0); + prev_segment = tyseg; + tyseg = candidate.ty; + + if (candidate.is_impl_candidate ()) + { + resolved_node_id + = candidate.item.impl.impl_item->get_impl_mappings ().get_nodeid (); + } + else + { + resolved_node_id + = candidate.item.trait.item_ref->get_mappings ().get_nodeid (); + + // lookup the associated-impl-trait + HIR::ImplBlock *impl = candidate.item.trait.impl; + if (impl != nullptr) + { + AssociatedImplTrait *lookup_associated = nullptr; + bool found_impl_trait = context->lookup_associated_trait_impl ( + impl->get_mappings ().get_hirid (), &lookup_associated); + rust_assert (found_impl_trait); + + lookup_associated->setup_associated_types (); + + // we need a new ty_ref_id for this trait item + tyseg = tyseg->clone (); + tyseg->set_ty_ref (mappings->get_next_hir_id ()); + } + } + + if (seg->is_generic_segment ()) + { + HIR::TypePathSegmentGeneric *generic_segment + = static_cast<HIR::TypePathSegmentGeneric *> (seg.get ()); + + if (!tyseg->can_substitute ()) + { + rust_error_at (expr_locus, "substitutions not supported for %s", + tyseg->as_string ().c_str ()); + return new TyTy::ErrorType (expr_id); + } + + tyseg = SubstMapper::Resolve (tyseg, expr_locus, + &generic_segment->get_generic_args ()); + if (tyseg->get_kind () == TyTy::TypeKind::ERROR) + return new TyTy::ErrorType (expr_id); + } + } + + context->insert_receiver (expr_mappings.get_hirid (), prev_segment); + if (tyseg->needs_generic_substitutions ()) + { + Location locus = segments.back ()->get_locus (); + if (!prev_segment->needs_generic_substitutions ()) + { + auto used_args_in_prev_segment + = GetUsedSubstArgs::From (prev_segment); + if (!used_args_in_prev_segment.is_error ()) + tyseg + = SubstMapperInternal::Resolve (tyseg, used_args_in_prev_segment); + } + else + { + tyseg = SubstMapper::InferSubst (tyseg, locus); + } + + if (tyseg->get_kind () == TyTy::TypeKind::ERROR) + return new TyTy::ErrorType (expr_id); + } + + rust_assert (resolved_node_id != UNKNOWN_NODEID); + + // lookup if the name resolver was able to canonically resolve this or not + NodeId path_resolved_id = UNKNOWN_NODEID; + if (resolver->lookup_resolved_name (expr_mappings.get_nodeid (), + &path_resolved_id)) + { + rust_assert (path_resolved_id == resolved_node_id); + } + // check the type scope + else if (resolver->lookup_resolved_type (expr_mappings.get_nodeid (), + &path_resolved_id)) + { + rust_assert (path_resolved_id == resolved_node_id); + } + else + { + resolver->insert_resolved_name (expr_mappings.get_nodeid (), + resolved_node_id); + } + + return tyseg; } void diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.h b/gcc/rust/typecheck/rust-hir-type-check-type.h index 3fdbe30..e0c0e91 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-type.h +++ b/gcc/rust/typecheck/rust-hir-type-check-type.h @@ -185,8 +185,11 @@ private: } } - void resolve_segments ( - NodeId root_resolved_node_id, + TyTy::BaseType *resolve_root_path (HIR::TypePath &path, size_t *offset, + NodeId *root_resolved_node_id); + + TyTy::BaseType *resolve_segments ( + NodeId root_resolved_node_id, HirId expr_id, std::vector<std::unique_ptr<HIR::TypePathSegment>> &segments, size_t offset, TyTy::BaseType *tyseg, const Analysis::NodeMapping &expr_mappings, Location expr_locus); diff --git a/gcc/rust/typecheck/rust-hir-type-check.h b/gcc/rust/typecheck/rust-hir-type-check.h index bcad5db..d3dc4c9 100644 --- a/gcc/rust/typecheck/rust-hir-type-check.h +++ b/gcc/rust/typecheck/rust-hir-type-check.h @@ -144,16 +144,24 @@ public: void clear_associated_type_mapping (HirId id) { - associated_type_mappings[id] = UNKNOWN_HIRID; + auto it = associated_type_mappings.find (id); + rust_assert (it != associated_type_mappings.end ()); + associated_type_mappings.erase (it); } - HirId lookup_associated_type_mapping (HirId id, HirId default_value) + // lookup any associated type mappings, the out parameter of mapping is + // allowed to be nullptr which allows this interface to do a simple does exist + // check + bool lookup_associated_type_mapping (HirId id, HirId *mapping) { auto it = associated_type_mappings.find (id); if (it == associated_type_mappings.end ()) - return default_value; + return false; + + if (mapping != nullptr) + *mapping = it->second; - return it->second; + return true; } void insert_associated_impl_mapping (HirId trait_id, @@ -169,19 +177,23 @@ public: associated_traits_to_impls[trait_id].push_back ({impl_type, impl_id}); } - HirId lookup_associated_impl_mapping_for_self (HirId trait_id, - const TyTy::BaseType *self) + bool lookup_associated_impl_mapping_for_self (HirId trait_id, + const TyTy::BaseType *self, + HirId *mapping) { auto it = associated_traits_to_impls.find (trait_id); if (it == associated_traits_to_impls.end ()) - return UNKNOWN_HIRID; + return false; for (auto &item : it->second) { if (item.first->can_eq (self, false)) - return item.second; + { + *mapping = item.second; + return true; + } } - return UNKNOWN_HIRID; + return false; } void insert_autoderef_mappings (HirId id, diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc index 969360e..f2216f9 100644 --- a/gcc/rust/typecheck/rust-tyty.cc +++ b/gcc/rust/typecheck/rust-tyty.cc @@ -108,6 +108,9 @@ void BaseType::inherit_bounds ( const std::vector<TyTy::TypeBoundPredicate> &specified_bounds) { + // FIXME + // 1. This needs to union the bounds + // 2. Do some checking for trait polarity to ensure compatibility for (auto &bound : specified_bounds) { add_bound (bound); @@ -329,6 +332,30 @@ StructFieldType::clone () const } void +SubstitutionParamMapping::fill_param_ty (BaseType &type, Location locus) +{ + if (type.get_kind () == TyTy::TypeKind::INFER) + { + type.inherit_bounds (*param); + } + else + { + if (!param->bounds_compatible (type, locus, true)) + return; + } + + if (type.get_kind () == TypeKind::PARAM) + { + delete param; + param = static_cast<ParamType *> (type.clone ()); + } + else + { + param->set_ty_ref (type.get_ref ()); + } +} + +void SubstitutionParamMapping::override_context () { if (!param->can_resolve ()) @@ -357,7 +384,9 @@ SubstitutionRef::get_mappings_from_generic_args (HIR::GenericArgs &args) return SubstitutionArgumentMappings::error (); } - if (args.get_type_args ().size () > substitutions.size ()) + // for inherited arguments + size_t offs = used_arguments.size (); + if (args.get_type_args ().size () + offs > substitutions.size ()) { RichLocation r (args.get_locus ()); r.add_range (substitutions.front ().get_param_locus ()); @@ -369,7 +398,7 @@ SubstitutionRef::get_mappings_from_generic_args (HIR::GenericArgs &args) return SubstitutionArgumentMappings::error (); } - if (args.get_type_args ().size () < min_required_substitutions ()) + if (args.get_type_args ().size () + offs < min_required_substitutions ()) { RichLocation r (args.get_locus ()); r.add_range (substitutions.front ().get_param_locus ()); @@ -381,9 +410,6 @@ SubstitutionRef::get_mappings_from_generic_args (HIR::GenericArgs &args) return SubstitutionArgumentMappings::error (); } - // for inherited arguments - size_t offs = used_arguments.size (); - std::vector<SubstitutionArg> mappings; for (auto &arg : args.get_type_args ()) { @@ -643,7 +669,7 @@ ADTType::handle_substitions (SubstitutionArgumentMappings subst_mappings) bool ok = subst_mappings.get_argument_for_symbol (sub.get_param_ty (), &arg); if (ok) - sub.fill_param_ty (arg.get_tyty (), subst_mappings.get_locus ()); + sub.fill_param_ty (*arg.get_tyty (), subst_mappings.get_locus ()); } adt->iterate_fields ([&] (StructFieldType *field) mutable -> bool { @@ -924,7 +950,7 @@ FnType::handle_substitions (SubstitutionArgumentMappings subst_mappings) = subst_mappings.get_argument_for_symbol (sub.get_param_ty (), &arg); if (ok) { - sub.fill_param_ty (arg.get_tyty (), subst_mappings.get_locus ()); + sub.fill_param_ty (*arg.get_tyty (), subst_mappings.get_locus ()); } } @@ -2174,9 +2200,7 @@ bool PlaceholderType::can_resolve () const { auto context = Resolver::TypeCheckContext::get (); - HirId val - = context->lookup_associated_type_mapping (get_ty_ref (), UNKNOWN_HIRID); - return val != UNKNOWN_HIRID; + return context->lookup_associated_type_mapping (get_ty_ref (), nullptr); } BaseType * @@ -2184,12 +2208,11 @@ PlaceholderType::resolve () const { auto context = Resolver::TypeCheckContext::get (); - rust_assert (can_resolve ()); - HirId val - = context->lookup_associated_type_mapping (get_ty_ref (), UNKNOWN_HIRID); - rust_assert (val != UNKNOWN_HIRID); + HirId mapping; + bool ok = context->lookup_associated_type_mapping (get_ty_ref (), &mapping); + rust_assert (ok); - return TyVar (val).get_tyty (); + return TyVar (mapping).get_tyty (); } bool @@ -2275,7 +2298,7 @@ ProjectionType::handle_substitions (SubstitutionArgumentMappings subst_mappings) bool ok = subst_mappings.get_argument_for_symbol (sub.get_param_ty (), &arg); if (ok) - sub.fill_param_ty (arg.get_tyty (), subst_mappings.get_locus ()); + sub.fill_param_ty (*arg.get_tyty (), subst_mappings.get_locus ()); } auto fty = projection->base; diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h index f726069..054e327 100644 --- a/gcc/rust/typecheck/rust-tyty.h +++ b/gcc/rust/typecheck/rust-tyty.h @@ -626,28 +626,7 @@ public: std::string as_string () const { return param->as_string (); } - void fill_param_ty (BaseType *type, Location locus) - { - if (type->get_kind () == TyTy::TypeKind::INFER) - { - type->inherit_bounds (*param); - } - else - { - if (!param->bounds_compatible (*type, locus, true)) - return; - } - - if (type->get_kind () == TypeKind::PARAM) - { - delete param; - param = static_cast<ParamType *> (type->clone ()); - } - else - { - param->set_ty_ref (type->get_ref ()); - } - } + void fill_param_ty (BaseType &type, Location locus); SubstitutionParamMapping clone () const { diff --git a/gcc/rust/util/rust-canonical-path.h b/gcc/rust/util/rust-canonical-path.h index b5f8dd7..6b4bfa1 100644 --- a/gcc/rust/util/rust-canonical-path.h +++ b/gcc/rust/util/rust-canonical-path.h @@ -95,7 +95,12 @@ public: } // if we have the path A::B::C this will give a callback for each segment - // example: + // including the prefix, example: + // + // path: + // A::B::C + // + // iterate: // A // A::B // A::B::C @@ -110,6 +115,16 @@ public: } } + // if we have the path A::B::C this will give a callback for each segment + // example: + // + // path: + // A::B::C + // + // iterate: + // A + // B + // C void iterate_segs (std::function<bool (const CanonicalPath &)> cb) const { for (auto &seg : segs) @@ -123,7 +138,7 @@ public: size_t size () const { return segs.size (); } - NodeId get_id () const + NodeId get_node_id () const { rust_assert (!segs.empty ()); return segs.back ().first; diff --git a/gcc/testsuite/rust/compile/generic-default1.rs b/gcc/testsuite/rust/compile/generic-default1.rs index 1b04f7d..0a132bf 100644 --- a/gcc/testsuite/rust/compile/generic-default1.rs +++ b/gcc/testsuite/rust/compile/generic-default1.rs @@ -1,5 +1,3 @@ -// { dg-error "unresolved type" "" { target *-*-* } 0 } - struct Foo<A = i321>(A); // { dg-error "failed to resolve TypePath: i321" "" { target *-*-* } .-1 } diff --git a/gcc/testsuite/rust/compile/generics5.rs b/gcc/testsuite/rust/compile/generics5.rs index e70afa8..6c847b5 100644 --- a/gcc/testsuite/rust/compile/generics5.rs +++ b/gcc/testsuite/rust/compile/generics5.rs @@ -1,12 +1,9 @@ -// Current errors are too noisy to match specific ones. -// { dg-error "failed to resolve TypePath: T" "" { target *-*-* } 0 } -// { dg-error "unresolved type" "" { target *-*-* } 0 } - struct GenericStruct<T>(T, usize); fn main() { let a2; a2 = GenericStruct::<i8, T>(1, 456); + // { dg-error "failed to resolve TypePath: T" "" { target *-*-* } .-1 } let b2: i32 = a2.0; let c2: usize = a2.1; diff --git a/gcc/testsuite/rust/compile/generics9.rs b/gcc/testsuite/rust/compile/generics9.rs index f3fd6b5..3766703 100644 --- a/gcc/testsuite/rust/compile/generics9.rs +++ b/gcc/testsuite/rust/compile/generics9.rs @@ -1,6 +1,5 @@ struct Foo<A, B = (A, B)>(A, B); // { dg-error "failed to resolve TypePath: B" "" { target *-*-* } .-1 } -// { dg-error "unresolved type" "" { target *-*-* } .-2 } fn main() { let a: Foo<bool>; diff --git a/gcc/testsuite/rust/compile/method2.rs b/gcc/testsuite/rust/compile/method2.rs index 4a0e784..c8699f7 100644 --- a/gcc/testsuite/rust/compile/method2.rs +++ b/gcc/testsuite/rust/compile/method2.rs @@ -13,5 +13,4 @@ fn main() { let b; b = a.test::<asfasfr>(false); // { dg-error "failed to resolve TypePath: asfasfr" "" { target *-*-* } .-1 } - // { dg-error "unresolved type" "" { target *-*-* } .-2 } } |