diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/backend/rust-compile-context.h | 6 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-expr.cc | 27 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-implitem.cc | 1 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-item.cc | 1 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-resolve-path.cc | 15 | ||||
-rw-r--r-- | gcc/rust/rust-backend.h | 3 | ||||
-rw-r--r-- | gcc/rust/rust-gcc.cc | 5 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-path-probe.h | 12 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-trait-ref.h | 11 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-trait-resolve.cc | 270 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-trait-resolve.h | 191 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-item.h | 2 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-path.cc | 71 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-type.cc | 67 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty.cc | 35 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/issue-1128.rs | 6 |
16 files changed, 323 insertions, 400 deletions
diff --git a/gcc/rust/backend/rust-compile-context.h b/gcc/rust/backend/rust-compile-context.h index de9d03f..d17034b 100644 --- a/gcc/rust/backend/rust-compile-context.h +++ b/gcc/rust/backend/rust-compile-context.h @@ -254,7 +254,11 @@ public: bool in_fn () { return fn_stack.size () != 0; } // Note: it is undefined behavior to call peek_fn () if fn_stack is empty. - fncontext peek_fn () { return fn_stack.back (); } + fncontext peek_fn () + { + rust_assert (!fn_stack.empty ()); + return fn_stack.back (); + } void push_type (tree t) { type_decls.push_back (t); } void push_var (::Bvariable *v) { var_decls.push_back (v); } diff --git a/gcc/rust/backend/rust-compile-expr.cc b/gcc/rust/backend/rust-compile-expr.cc index 2128f25..edeea8d 100644 --- a/gcc/rust/backend/rust-compile-expr.cc +++ b/gcc/rust/backend/rust-compile-expr.cc @@ -497,10 +497,8 @@ CompileExpr::visit (HIR::CallExpr &expr) // must be a call to a function auto fn_address = CompileExpr::Compile (expr.get_fnexpr (), ctx); - auto fncontext = ctx->peek_fn (); - translated - = ctx->get_backend ()->call_expression (fncontext.fndecl, fn_address, args, - nullptr, expr.get_locus ()); + translated = ctx->get_backend ()->call_expression (fn_address, args, nullptr, + expr.get_locus ()); } void @@ -610,10 +608,8 @@ CompileExpr::visit (HIR::MethodCallExpr &expr) args.push_back (rvalue); } - auto fncontext = ctx->peek_fn (); - translated - = ctx->get_backend ()->call_expression (fncontext.fndecl, fn_expr, args, - nullptr, expr.get_locus ()); + translated = ctx->get_backend ()->call_expression (fn_expr, args, nullptr, + expr.get_locus ()); } tree @@ -696,8 +692,8 @@ CompileExpr::compile_dyn_dispatch_call (const TyTy::DynamicObjectType *dyn, tree fn_expr = ctx->get_backend ()->var_expression (fn_convert_expr_tmp, expr_locus); - return ctx->get_backend ()->call_expression (fnctx.fndecl, fn_expr, args, - nullptr, expr_locus); + return ctx->get_backend ()->call_expression (fn_expr, args, nullptr, + expr_locus); } tree @@ -866,9 +862,8 @@ CompileExpr::resolve_operator_overload ( if (rhs != nullptr) // can be null for negation_expr (unary ones) args.push_back (rhs); - auto fncontext = ctx->peek_fn (); - return ctx->get_backend ()->call_expression (fncontext.fndecl, fn_expr, args, - nullptr, expr.get_locus ()); + return ctx->get_backend ()->call_expression (fn_expr, args, nullptr, + expr.get_locus ()); } tree @@ -1289,10 +1284,8 @@ HIRCompileBase::resolve_deref_adjustment (Resolver::Adjustment &adjustment, } // make the call - auto fncontext = ctx->peek_fn (); - return ctx->get_backend ()->call_expression (fncontext.fndecl, fn_address, - {adjusted_argument}, nullptr, - locus); + return ctx->get_backend ()->call_expression (fn_address, {adjusted_argument}, + nullptr, locus); } tree diff --git a/gcc/rust/backend/rust-compile-implitem.cc b/gcc/rust/backend/rust-compile-implitem.cc index 7cc214c..9dc6d14 100644 --- a/gcc/rust/backend/rust-compile-implitem.cc +++ b/gcc/rust/backend/rust-compile-implitem.cc @@ -52,6 +52,7 @@ CompileTraitItem::visit (HIR::TraitItemFunc &func) rust_assert (concrete->get_kind () == TyTy::TypeKind::FNDEF); TyTy::FnType *fntype = static_cast<TyTy::FnType *> (concrete); + fntype->monomorphize (); // items can be forward compiled which means we may not need to invoke this // code. We might also have already compiled this generic function as well. diff --git a/gcc/rust/backend/rust-compile-item.cc b/gcc/rust/backend/rust-compile-item.cc index 80b7ceb..969c852 100644 --- a/gcc/rust/backend/rust-compile-item.cc +++ b/gcc/rust/backend/rust-compile-item.cc @@ -127,6 +127,7 @@ CompileItem::visit (HIR::Function &function) { rust_assert (concrete->get_kind () == TyTy::TypeKind::FNDEF); fntype = static_cast<TyTy::FnType *> (concrete); + fntype->monomorphize (); } } diff --git a/gcc/rust/backend/rust-compile-resolve-path.cc b/gcc/rust/backend/rust-compile-resolve-path.cc index 2ad672d..55a2fff 100644 --- a/gcc/rust/backend/rust-compile-resolve-path.cc +++ b/gcc/rust/backend/rust-compile-resolve-path.cc @@ -251,21 +251,6 @@ HIRCompileBase::query_compile (HirId ref, TyTy::BaseType *lookup, rust_assert (ok); // found rust_assert (trait_item_ref->is_optional ()); // has definition - Analysis::NodeMapping trait_mappings - = trait_item_ref->get_parent_trait_mappings (); - - 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 - = ctx->get_tyctx ()->lookup_associated_trait_impl ( - associated_impl_id, &associated); - rust_assert (found_associated_trait_impl); - associated->setup_associated_types (); - return CompileTraitItem::Compile ( trait_item_ref->get_hir_trait_item (), ctx, lookup, true, expr_locus); diff --git a/gcc/rust/rust-backend.h b/gcc/rust/rust-backend.h index 17b7bae..6d631a0 100644 --- a/gcc/rust/rust-backend.h +++ b/gcc/rust/rust-backend.h @@ -285,8 +285,7 @@ public: // Create an expression for a call to FN with ARGS, taking place within // caller CALLER. - virtual tree call_expression (tree caller, tree fn, - const std::vector<tree> &args, + virtual tree call_expression (tree fn, const std::vector<tree> &args, tree static_chain, Location) = 0; diff --git a/gcc/rust/rust-gcc.cc b/gcc/rust/rust-gcc.cc index 334e9e5..445cb0d 100644 --- a/gcc/rust/rust-gcc.cc +++ b/gcc/rust/rust-gcc.cc @@ -250,7 +250,7 @@ public: tree array_index_expression (tree array, tree index, Location); - tree call_expression (tree caller, tree fn, const std::vector<tree> &args, + tree call_expression (tree fn, const std::vector<tree> &args, tree static_chain, Location); // Statements. @@ -1794,8 +1794,7 @@ Gcc_backend::array_index_expression (tree array_tree, tree index_tree, // Create an expression for a call to FN_EXPR with FN_ARGS. tree -Gcc_backend::call_expression (tree, // containing fcn for call - tree fn, const std::vector<tree> &fn_args, +Gcc_backend::call_expression (tree fn, const std::vector<tree> &fn_args, tree chain_expr, Location location) { if (fn == error_mark_node || TREE_TYPE (fn) == error_mark_node) diff --git a/gcc/rust/typecheck/rust-hir-path-probe.h b/gcc/rust/typecheck/rust-hir-path-probe.h index fda505a..348b9f7 100644 --- a/gcc/rust/typecheck/rust-hir-path-probe.h +++ b/gcc/rust/typecheck/rust-hir-path-probe.h @@ -326,18 +326,6 @@ protected: } TyTy::BaseType *trait_item_tyty = trait_item_ref->get_tyty (); - if (impl != nullptr && !is_reciever_generic ()) - - { - HirId impl_block_id = impl->get_mappings ().get_hirid (); - AssociatedImplTrait *lookup_associated = nullptr; - bool found_impl_trait - = context->lookup_associated_trait_impl (impl_block_id, - &lookup_associated); - // see testsuite/rust/compile/torture/traits10.rs this can be false - if (found_impl_trait) - lookup_associated->setup_associated_types (); - } // we can substitute the Self with the receiver here if (trait_item_tyty->get_kind () == TyTy::TypeKind::FNDEF) diff --git a/gcc/rust/typecheck/rust-hir-trait-ref.h b/gcc/rust/typecheck/rust-hir-trait-ref.h index a12736f..6eec461 100644 --- a/gcc/rust/typecheck/rust-hir-trait-ref.h +++ b/gcc/rust/typecheck/rust-hir-trait-ref.h @@ -454,18 +454,11 @@ public: TyTy::BaseType *get_self () { return self; } - void setup_associated_types (); - - void setup_associated_types2 (const TyTy::BaseType *self, - const TyTy::TypeBoundPredicate &bound); + void setup_associated_types (const TyTy::BaseType *self, + const TyTy::TypeBoundPredicate &bound); void reset_associated_types (); - TyTy::BaseType *get_projected_type (const TraitItemReference *trait_item_ref, - TyTy::BaseType *reciever, HirId ref, - HIR::GenericArgs &trait_generics, - Location expr_locus); - private: TraitReference *trait; HIR::ImplBlock *impl; diff --git a/gcc/rust/typecheck/rust-hir-trait-resolve.cc b/gcc/rust/typecheck/rust-hir-trait-resolve.cc index 5681ebd..13edd8d 100644 --- a/gcc/rust/typecheck/rust-hir-trait-resolve.cc +++ b/gcc/rust/typecheck/rust-hir-trait-resolve.cc @@ -61,8 +61,214 @@ ResolveTraitItemToRef::visit (HIR::TraitItemFunc &fn) self, std::move (substitutions), locus); } +ResolveTraitItemToRef::ResolveTraitItemToRef ( + TyTy::BaseType *self, + std::vector<TyTy::SubstitutionParamMapping> &&substitutions) + : TypeCheckBase (), resolved (TraitItemReference::error ()), self (self), + substitutions (std::move (substitutions)) +{} + // TraitItemReference items +TraitReference * +TraitResolver::Resolve (HIR::TypePath &path) +{ + TraitResolver resolver; + return resolver.resolve_path (path); +} + +TraitReference * +TraitResolver::Resolve (HIR::Trait &trait) +{ + TraitResolver resolver; + return resolver.resolve_trait (&trait); +} + +TraitReference * +TraitResolver::Lookup (HIR::TypePath &path) +{ + TraitResolver resolver; + return resolver.lookup_path (path); +} + +TraitResolver::TraitResolver () + : TypeCheckBase (), resolved_trait_reference (nullptr) +{} + +TraitReference * +TraitResolver::resolve_path (HIR::TypePath &path) +{ + NodeId ref; + if (!resolver->lookup_resolved_type (path.get_mappings ().get_nodeid (), + &ref)) + { + rust_error_at (path.get_locus (), "Failed to resolve path to node-id"); + return &TraitReference::error_node (); + } + + HirId hir_node = UNKNOWN_HIRID; + if (!mappings->lookup_node_to_hir (mappings->get_current_crate (), ref, + &hir_node)) + { + rust_error_at (path.get_locus (), "Failed to resolve path to hir-id"); + return &TraitReference::error_node (); + } + + HIR::Item *resolved_item + = mappings->lookup_hir_item (mappings->get_current_crate (), hir_node); + + rust_assert (resolved_item != nullptr); + resolved_item->accept_vis (*this); + rust_assert (resolved_trait_reference != nullptr); + + return resolve_trait (resolved_trait_reference); +} + +TraitReference * +TraitResolver::resolve_trait (HIR::Trait *trait_reference) +{ + TraitReference *tref = &TraitReference::error_node (); + if (context->lookup_trait_reference ( + trait_reference->get_mappings ().get_defid (), &tref)) + { + return tref; + } + + TyTy::BaseType *self = nullptr; + std::vector<TyTy::SubstitutionParamMapping> substitutions; + for (auto &generic_param : trait_reference->get_generic_params ()) + { + switch (generic_param.get ()->get_kind ()) + { + case HIR::GenericParam::GenericKind::LIFETIME: + // Skipping Lifetime completely until better handling. + break; + + case HIR::GenericParam::GenericKind::TYPE: { + auto param_type + = TypeResolveGenericParam::Resolve (generic_param.get ()); + context->insert_type (generic_param->get_mappings (), param_type); + + auto &typaram = static_cast<HIR::TypeParam &> (*generic_param); + substitutions.push_back ( + TyTy::SubstitutionParamMapping (typaram, param_type)); + + if (typaram.get_type_representation ().compare ("Self") == 0) + { + self = param_type; + } + } + break; + } + } + rust_assert (self != nullptr); + + // Check if there is a super-trait, and apply this bound to the Self + // TypeParam + std::vector<TyTy::TypeBoundPredicate> specified_bounds; + + // copy the substitition mappings + std::vector<TyTy::SubstitutionParamMapping> self_subst_copy; + for (auto &sub : substitutions) + self_subst_copy.push_back (sub.clone ()); + + // They also inherit themselves as a bound this enables a trait item to + // reference other Self::trait_items + auto self_hrtb + = TyTy::TypeBoundPredicate (trait_reference->get_mappings ().get_defid (), + std::move (self_subst_copy), + trait_reference->get_locus ()); + specified_bounds.push_back (self_hrtb); + + // look for any + std::vector<const TraitReference *> super_traits; + if (trait_reference->has_type_param_bounds ()) + { + for (auto &bound : trait_reference->get_type_param_bounds ()) + { + if (bound->get_bound_type () + == HIR::TypeParamBound::BoundType::TRAITBOUND) + { + HIR::TraitBound *b + = static_cast<HIR::TraitBound *> (bound.get ()); + + // FIXME this might be recursive we need a check for that + auto predicate = get_predicate_from_bound (b->get_path ()); + specified_bounds.push_back (predicate); + super_traits.push_back (predicate.get ()); + } + } + } + self->inherit_bounds (specified_bounds); + + std::vector<TraitItemReference> item_refs; + for (auto &item : trait_reference->get_trait_items ()) + { + // make a copy of the substs + std::vector<TyTy::SubstitutionParamMapping> item_subst; + for (auto &sub : substitutions) + item_subst.push_back (sub.clone ()); + + TraitItemReference trait_item_ref + = ResolveTraitItemToRef::Resolve (*item.get (), self, + std::move (item_subst)); + item_refs.push_back (std::move (trait_item_ref)); + } + + TraitReference trait_object (trait_reference, item_refs, + std::move (super_traits), + std::move (substitutions)); + context->insert_trait_reference ( + trait_reference->get_mappings ().get_defid (), std::move (trait_object)); + + tref = &TraitReference::error_node (); + bool ok = context->lookup_trait_reference ( + trait_reference->get_mappings ().get_defid (), &tref); + rust_assert (ok); + + // hook to allow the trait to resolve its optional item blocks, we cant + // resolve the blocks of functions etc because it can end up in a recursive + // loop of trying to resolve traits as required by the types + tref->on_resolved (); + + return tref; +} + +TraitReference * +TraitResolver::lookup_path (HIR::TypePath &path) +{ + NodeId ref; + if (!resolver->lookup_resolved_type (path.get_mappings ().get_nodeid (), + &ref)) + { + rust_error_at (path.get_locus (), "Failed to resolve path to node-id"); + return &TraitReference::error_node (); + } + + HirId hir_node = UNKNOWN_HIRID; + if (!mappings->lookup_node_to_hir (mappings->get_current_crate (), ref, + &hir_node)) + { + rust_error_at (path.get_locus (), "Failed to resolve path to hir-id"); + return &TraitReference::error_node (); + } + + HIR::Item *resolved_item + = mappings->lookup_hir_item (mappings->get_current_crate (), hir_node); + + rust_assert (resolved_item != nullptr); + resolved_item->accept_vis (*this); + rust_assert (resolved_trait_reference != nullptr); + + TraitReference *tref = &TraitReference::error_node (); + if (context->lookup_trait_reference ( + resolved_trait_reference->get_mappings ().get_defid (), &tref)) + { + return tref; + } + return &TraitReference::error_node (); +} + void TraitItemReference::on_resolved () { @@ -154,29 +360,7 @@ TraitItemReference::associated_type_reset () const } void -AssociatedImplTrait::setup_associated_types () -{ - ImplTypeIterator iter (*impl, [&] (HIR::TypeAlias &type) { - TraitItemReference *resolved_trait_item = nullptr; - bool ok = trait->lookup_trait_item (type.get_new_type_name (), - &resolved_trait_item); - if (!ok) - return; - if (resolved_trait_item->get_trait_item_type () - != TraitItemReference::TraitItemType::TYPE) - return; - - TyTy::BaseType *lookup; - if (!context->lookup_type (type.get_mappings ().get_hirid (), &lookup)) - return; - - resolved_trait_item->associated_type_set (lookup); - }); - iter.go (); -} - -void -AssociatedImplTrait::setup_associated_types2 ( +AssociatedImplTrait::setup_associated_types ( const TyTy::BaseType *self, const TyTy::TypeBoundPredicate &bound) { // compute the constrained impl block generic arguments based on self and the @@ -390,46 +574,6 @@ TraitItemReference::is_object_safe () const return false; } -TyTy::BaseType * -AssociatedImplTrait::get_projected_type ( - const TraitItemReference *trait_item_ref, TyTy::BaseType *receiver, HirId ref, - HIR::GenericArgs &trait_generics, Location expr_locus) -{ - TyTy::BaseType *trait_item_tyty = trait_item_ref->get_tyty ()->clone (); - - // we can substitute the Self with the receiver here - if (trait_item_tyty->get_kind () == TyTy::TypeKind::FNDEF) - { - TyTy::FnType *fn = static_cast<TyTy::FnType *> (trait_item_tyty); - TyTy::SubstitutionParamMapping *param = nullptr; - for (auto ¶m_mapping : fn->get_substs ()) - { - const HIR::TypeParam &type_param = param_mapping.get_generic_param (); - if (type_param.get_type_representation ().compare ("Self") == 0) - { - param = ¶m_mapping; - break; - } - } - rust_assert (param != nullptr); - - std::vector<TyTy::SubstitutionArg> mappings; - mappings.push_back (TyTy::SubstitutionArg (param, receiver->clone ())); - - TyTy::SubstitutionArgumentMappings args (std::move (mappings), - expr_locus); - trait_item_tyty = SubstMapperInternal::Resolve (trait_item_tyty, args); - } - - if (!trait_generics.is_empty ()) - { - trait_item_tyty - = SubstMapper::Resolve (trait_item_tyty, expr_locus, &trait_generics); - } - - return trait_item_tyty; -} - // rust-hir-path-probe.h void diff --git a/gcc/rust/typecheck/rust-hir-trait-resolve.h b/gcc/rust/typecheck/rust-hir-trait-resolve.h index 651af9d..a73b67f 100644 --- a/gcc/rust/typecheck/rust-hir-trait-resolve.h +++ b/gcc/rust/typecheck/rust-hir-trait-resolve.h @@ -52,10 +52,7 @@ public: private: ResolveTraitItemToRef ( TyTy::BaseType *self, - std::vector<TyTy::SubstitutionParamMapping> &&substitutions) - : TypeCheckBase (), resolved (TraitItemReference::error ()), self (self), - substitutions (std::move (substitutions)) - {} + std::vector<TyTy::SubstitutionParamMapping> &&substitutions); TraitItemReference resolved; TyTy::BaseType *self; @@ -67,191 +64,25 @@ class TraitResolver : public TypeCheckBase using Rust::Resolver::TypeCheckBase::visit; public: - static TraitReference *Resolve (HIR::TypePath &path) - { - TraitResolver resolver; - return resolver.go (path); - } - - static TraitReference *Lookup (HIR::TypePath &path) - { - TraitResolver resolver; - return resolver.lookup_path (path); - } - -private: - TraitResolver () : TypeCheckBase () {} - - TraitReference *go (HIR::TypePath &path) - { - NodeId ref; - if (!resolver->lookup_resolved_type (path.get_mappings ().get_nodeid (), - &ref)) - { - rust_error_at (path.get_locus (), "Failed to resolve path to node-id"); - return &TraitReference::error_node (); - } - - HirId hir_node = UNKNOWN_HIRID; - if (!mappings->lookup_node_to_hir (mappings->get_current_crate (), ref, - &hir_node)) - { - rust_error_at (path.get_locus (), "Failed to resolve path to hir-id"); - return &TraitReference::error_node (); - } - - HIR::Item *resolved_item - = mappings->lookup_hir_item (mappings->get_current_crate (), hir_node); - - rust_assert (resolved_item != nullptr); - resolved_item->accept_vis (*this); - rust_assert (trait_reference != nullptr); - - TraitReference *tref = &TraitReference::error_node (); - if (context->lookup_trait_reference ( - trait_reference->get_mappings ().get_defid (), &tref)) - { - return tref; - } - - TyTy::BaseType *self = nullptr; - std::vector<TyTy::SubstitutionParamMapping> substitutions; - for (auto &generic_param : trait_reference->get_generic_params ()) - { - switch (generic_param.get ()->get_kind ()) - { - case HIR::GenericParam::GenericKind::LIFETIME: - // Skipping Lifetime completely until better handling. - break; - - case HIR::GenericParam::GenericKind::TYPE: { - auto param_type - = TypeResolveGenericParam::Resolve (generic_param.get ()); - context->insert_type (generic_param->get_mappings (), param_type); - - auto &typaram = static_cast<HIR::TypeParam &> (*generic_param); - substitutions.push_back ( - TyTy::SubstitutionParamMapping (typaram, param_type)); + static TraitReference *Resolve (HIR::TypePath &path); - if (typaram.get_type_representation ().compare ("Self") == 0) - { - self = param_type; - } - } - break; - } - } - rust_assert (self != nullptr); + static TraitReference *Resolve (HIR::Trait &trait); - // Check if there is a super-trait, and apply this bound to the Self - // TypeParam - std::vector<TyTy::TypeBoundPredicate> specified_bounds; + static TraitReference *Lookup (HIR::TypePath &path); - // copy the substitition mappings - std::vector<TyTy::SubstitutionParamMapping> self_subst_copy; - for (auto &sub : substitutions) - self_subst_copy.push_back (sub.clone ()); - - // They also inherit themselves as a bound this enables a trait item to - // reference other Self::trait_items - auto self_hrtb - = TyTy::TypeBoundPredicate (trait_reference->get_mappings ().get_defid (), - std::move (self_subst_copy), - trait_reference->get_locus ()); - specified_bounds.push_back (self_hrtb); - - // look for any - std::vector<const TraitReference *> super_traits; - if (trait_reference->has_type_param_bounds ()) - { - for (auto &bound : trait_reference->get_type_param_bounds ()) - { - if (bound->get_bound_type () - == HIR::TypeParamBound::BoundType::TRAITBOUND) - { - HIR::TraitBound *b - = static_cast<HIR::TraitBound *> (bound.get ()); - - // FIXME this might be recursive we need a check for that - auto predicate = get_predicate_from_bound (b->get_path ()); - specified_bounds.push_back (predicate); - super_traits.push_back (predicate.get ()); - } - } - } - self->inherit_bounds (specified_bounds); - - std::vector<TraitItemReference> item_refs; - for (auto &item : trait_reference->get_trait_items ()) - { - // make a copy of the substs - std::vector<TyTy::SubstitutionParamMapping> item_subst; - for (auto &sub : substitutions) - item_subst.push_back (sub.clone ()); - - TraitItemReference trait_item_ref - = ResolveTraitItemToRef::Resolve (*item.get (), self, - std::move (item_subst)); - item_refs.push_back (std::move (trait_item_ref)); - } - - TraitReference trait_object (trait_reference, item_refs, - std::move (super_traits), - std::move (substitutions)); - context->insert_trait_reference ( - trait_reference->get_mappings ().get_defid (), std::move (trait_object)); - - tref = &TraitReference::error_node (); - bool ok = context->lookup_trait_reference ( - trait_reference->get_mappings ().get_defid (), &tref); - rust_assert (ok); - - // hook to allow the trait to resolve its optional item blocks, we cant - // resolve the blocks of functions etc because it can end up in a recursive - // loop of trying to resolve traits as required by the types - tref->on_resolved (); - - return tref; - } - - TraitReference *lookup_path (HIR::TypePath &path) - { - NodeId ref; - if (!resolver->lookup_resolved_type (path.get_mappings ().get_nodeid (), - &ref)) - { - rust_error_at (path.get_locus (), "Failed to resolve path to node-id"); - return &TraitReference::error_node (); - } - - HirId hir_node = UNKNOWN_HIRID; - if (!mappings->lookup_node_to_hir (mappings->get_current_crate (), ref, - &hir_node)) - { - rust_error_at (path.get_locus (), "Failed to resolve path to hir-id"); - return &TraitReference::error_node (); - } +private: + TraitResolver (); - HIR::Item *resolved_item - = mappings->lookup_hir_item (mappings->get_current_crate (), hir_node); + TraitReference *resolve_path (HIR::TypePath &path); - rust_assert (resolved_item != nullptr); - resolved_item->accept_vis (*this); - rust_assert (trait_reference != nullptr); + TraitReference *resolve_trait (HIR::Trait *trait_reference); - TraitReference *tref = &TraitReference::error_node (); - if (context->lookup_trait_reference ( - trait_reference->get_mappings ().get_defid (), &tref)) - { - return tref; - } - return &TraitReference::error_node (); - } + TraitReference *lookup_path (HIR::TypePath &path); - HIR::Trait *trait_reference; + HIR::Trait *resolved_trait_reference; public: - void visit (HIR::Trait &trait) override { trait_reference = &trait; } + void visit (HIR::Trait &trait) override { resolved_trait_reference = &trait; } }; } // namespace Resolver diff --git a/gcc/rust/typecheck/rust-hir-type-check-item.h b/gcc/rust/typecheck/rust-hir-type-check-item.h index 9d3beae..71b6b81 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-item.h +++ b/gcc/rust/typecheck/rust-hir-type-check-item.h @@ -224,6 +224,8 @@ public: TypeCheckItem::Resolve (item.get ()); } + void visit (HIR::Trait &trait) override { TraitResolver::Resolve (trait); } + private: TypeCheckItem () : TypeCheckBase () {} }; diff --git a/gcc/rust/typecheck/rust-hir-type-check-path.cc b/gcc/rust/typecheck/rust-hir-type-check-path.cc index 9960e76..3823c57 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-path.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-path.cc @@ -67,41 +67,41 @@ TypeCheckExpr::visit (HIR::QualifiedPathInExpression &expr) // inherit the bound root->inherit_bounds ({specified_bound}); - // we need resolve to the impl block - NodeId impl_resolved_id = UNKNOWN_NODEID; - bool ok = resolver->lookup_resolved_name ( - qual_path_type.get_mappings ().get_nodeid (), &impl_resolved_id); - rust_assert (ok); - - HirId impl_block_id; - ok = mappings->lookup_node_to_hir (expr.get_mappings ().get_crate_num (), - impl_resolved_id, &impl_block_id); - rust_assert (ok); - - AssociatedImplTrait *lookup_associated = nullptr; - bool found_impl_trait - = context->lookup_associated_trait_impl (impl_block_id, &lookup_associated); - rust_assert (found_impl_trait); - + // lookup the associated item from the specified bound HIR::PathExprSegment &item_seg = expr.get_segments ().at (0); - - const TraitItemReference *trait_item_ref = nullptr; - ok = trait_ref->lookup_trait_item (item_seg.get_segment ().as_string (), - &trait_item_ref); - if (!ok) + HIR::PathIdentSegment item_seg_identifier = item_seg.get_segment (); + TyTy::TypeBoundPredicateItem item + = specified_bound.lookup_associated_item (item_seg_identifier.as_string ()); + if (item.is_error ()) { rust_error_at (item_seg.get_locus (), "unknown associated item"); return; } - HIR::GenericArgs trait_generics = qual_path_type.trait_has_generic_args () - ? qual_path_type.get_trait_generic_args () - : HIR::GenericArgs::create_empty (); + // infer the root type + infered = item.get_tyty_for_receiver (root); - lookup_associated->setup_associated_types (); - infered = lookup_associated->get_projected_type ( - trait_item_ref, root, item_seg.get_mappings ().get_hirid (), trait_generics, - item_seg.get_locus ()); + // we need resolve to the impl block + NodeId impl_resolved_id = UNKNOWN_NODEID; + bool have_associated_impl = resolver->lookup_resolved_name ( + qual_path_type.get_mappings ().get_nodeid (), &impl_resolved_id); + AssociatedImplTrait *lookup_associated = nullptr; + if (have_associated_impl) + { + HirId impl_block_id; + bool ok + = mappings->lookup_node_to_hir (expr.get_mappings ().get_crate_num (), + impl_resolved_id, &impl_block_id); + rust_assert (ok); + + bool found_impl_trait + = context->lookup_associated_trait_impl (impl_block_id, + &lookup_associated); + if (found_impl_trait) + { + lookup_associated->setup_associated_types (root, specified_bound); + } + } // turbo-fish segment path::<ty> if (item_seg.has_generic_args ()) @@ -119,6 +119,7 @@ TypeCheckExpr::visit (HIR::QualifiedPathInExpression &expr) } // continue on as a path-in-expression + const TraitItemReference *trait_item_ref = item.get_raw_item (); NodeId root_resolved_node_id = trait_item_ref->get_mappings ().get_nodeid (); bool fully_resolved = expr.get_segments ().size () <= 1; @@ -348,20 +349,6 @@ TypeCheckExpr::resolve_segments (NodeId root_resolved_node_id, 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); - - // setup associated mappings if possible we might be resolving a - // path within a default implementation of a trait function - // see: testsuite/rust/compile/torture/traits16.rs - if (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 ()); - // get the associated impl block associated_impl_block = impl; } diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.cc b/gcc/rust/typecheck/rust-hir-type-check-type.cc index 914bebb..bd40344 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-type.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-type.cc @@ -142,31 +142,35 @@ TypeCheckType::visit (HIR::QualifiedPathInType &path) return; } + // get the predicate for the bound + auto specified_bound + = get_predicate_from_bound (*qual_path_type.get_trait ().get ()); + if (specified_bound.is_error ()) + return; + + // inherit the bound + root->inherit_bounds ({specified_bound}); + + // lookup the associated item from the specified bound std::unique_ptr<HIR::TypePathSegment> &item_seg = path.get_associated_segment (); - const TraitItemReference *trait_item_ref = nullptr; - bool ok - = trait_ref->lookup_trait_item (item_seg->get_ident_segment ().as_string (), - &trait_item_ref); - if (!ok) + HIR::PathIdentSegment item_seg_identifier = item_seg->get_ident_segment (); + TyTy::TypeBoundPredicateItem item + = specified_bound.lookup_associated_item (item_seg_identifier.as_string ()); + if (item.is_error ()) { rust_error_at (item_seg->get_locus (), "unknown associated item"); return; } - // this will be the placeholder from the trait but we may be able to project - // it based on the impl block - translated = trait_item_ref->get_tyty (); - - // this is the associated generics we need to potentially apply - HIR::GenericArgs trait_generics = qual_path_type.trait_has_generic_args () - ? qual_path_type.get_trait_generic_args () - : HIR::GenericArgs::create_empty (); + // infer the root type + translated = item.get_tyty_for_receiver (root); // we need resolve to the impl block NodeId impl_resolved_id = UNKNOWN_NODEID; bool have_associated_impl = resolver->lookup_resolved_name ( qual_path_type.get_mappings ().get_nodeid (), &impl_resolved_id); + AssociatedImplTrait *lookup_associated = nullptr; if (have_associated_impl) { HirId impl_block_id; @@ -175,30 +179,16 @@ TypeCheckType::visit (HIR::QualifiedPathInType &path) impl_resolved_id, &impl_block_id); rust_assert (ok); - AssociatedImplTrait *lookup_associated = nullptr; bool found_impl_trait = context->lookup_associated_trait_impl (impl_block_id, &lookup_associated); - rust_assert (found_impl_trait); - - // project - lookup_associated->setup_associated_types (); - translated = lookup_associated->get_projected_type ( - trait_item_ref, root, item_seg->get_mappings ().get_hirid (), - trait_generics, item_seg->get_locus ()); - } - - if (translated->get_kind () == TyTy::TypeKind::PLACEHOLDER) - { - // lets grab the actual projection type - TyTy::PlaceholderType *p - = static_cast<TyTy::PlaceholderType *> (translated); - if (p->can_resolve ()) + if (found_impl_trait) { - translated = p->resolve (); + lookup_associated->setup_associated_types (root, specified_bound); } } + // turbo-fish segment path::<ty> if (item_seg->get_type () == HIR::TypePathSegment::SegmentType::GENERIC) { HIR::TypePathSegmentGeneric &generic_seg @@ -222,6 +212,7 @@ TypeCheckType::visit (HIR::QualifiedPathInType &path) } // continue on as a path-in-expression + const TraitItemReference *trait_item_ref = item.get_raw_item (); NodeId root_resolved_node_id = trait_item_ref->get_mappings ().get_nodeid (); bool fully_resolved = path.get_segments ().empty (); if (fully_resolved) @@ -448,22 +439,6 @@ TypeCheckType::resolve_segments ( { 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 && !reciever_is_generic) - { - 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 ()) diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc index 847ca88..7302b06 100644 --- a/gcc/rust/typecheck/rust-tyty.cc +++ b/gcc/rust/typecheck/rust-tyty.cc @@ -826,22 +826,23 @@ SubstitutionRef::monomorphize () bool found_impl_trait = context->lookup_associated_trait_impl (impl_block_id, &associated); - rust_assert (found_impl_trait); - - bool found_trait - = specified_bound_ref->is_equal (*bound_trait_ref); - bool found_self - = associated->get_self ()->can_eq (binding, false); - if (found_trait && found_self) + if (found_impl_trait) { - associated_impl_trait = associated; - break; + bool found_trait + = specified_bound_ref->is_equal (*bound_trait_ref); + bool found_self + = associated->get_self ()->can_eq (binding, false); + if (found_trait && found_self) + { + associated_impl_trait = associated; + break; + } } } if (associated_impl_trait != nullptr) { - associated_impl_trait->setup_associated_types2 (binding, bound); + associated_impl_trait->setup_associated_types (binding, bound); } } } @@ -1230,6 +1231,19 @@ FnType::is_equal (const BaseType &other) const { if (get_num_substitutions () != other2.get_num_substitutions ()) return false; + + const FnType &ofn = static_cast<const FnType &> (other); + for (size_t i = 0; i < get_num_substitutions (); i++) + { + const SubstitutionParamMapping &a = get_substs ().at (i); + const SubstitutionParamMapping &b = ofn.get_substs ().at (i); + + const ParamType *pa = a.get_param_ty (); + const ParamType *pb = b.get_param_ty (); + + if (!pa->is_equal (*pb)) + return false; + } } if (num_params () != other2.num_params ()) @@ -2961,6 +2975,7 @@ TypeCheckCallExpr::visit (ADTType &type) void TypeCheckCallExpr::visit (FnType &type) { + type.monomorphize (); if (call.num_params () != type.num_params ()) { if (type.is_varadic ()) diff --git a/gcc/testsuite/rust/compile/issue-1128.rs b/gcc/testsuite/rust/compile/issue-1128.rs new file mode 100644 index 0000000..462426b --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-1128.rs @@ -0,0 +1,6 @@ +pub trait Hasher { + fn write(&mut self, bytes: &[u8]); + fn write_u8(&mut self, i: u8) { + self.write(&[i]) + } +} |