aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/backend/rust-compile-context.h6
-rw-r--r--gcc/rust/backend/rust-compile-expr.cc27
-rw-r--r--gcc/rust/backend/rust-compile-implitem.cc1
-rw-r--r--gcc/rust/backend/rust-compile-item.cc1
-rw-r--r--gcc/rust/backend/rust-compile-resolve-path.cc15
-rw-r--r--gcc/rust/rust-backend.h3
-rw-r--r--gcc/rust/rust-gcc.cc5
-rw-r--r--gcc/rust/typecheck/rust-hir-path-probe.h12
-rw-r--r--gcc/rust/typecheck/rust-hir-trait-ref.h11
-rw-r--r--gcc/rust/typecheck/rust-hir-trait-resolve.cc270
-rw-r--r--gcc/rust/typecheck/rust-hir-trait-resolve.h191
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-item.h2
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-path.cc71
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-type.cc67
-rw-r--r--gcc/rust/typecheck/rust-tyty.cc35
-rw-r--r--gcc/testsuite/rust/compile/issue-1128.rs6
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 &param_mapping : fn->get_substs ())
- {
- const HIR::TypeParam &type_param = param_mapping.get_generic_param ();
- if (type_param.get_type_representation ().compare ("Self") == 0)
- {
- param = &param_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])
+ }
+}