aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/ast/rust-ast.h4
-rw-r--r--gcc/rust/ast/rust-stmt.h6
-rw-r--r--gcc/rust/ast/rust-type.h9
-rw-r--r--gcc/rust/backend/rust-compile-base.h10
-rw-r--r--gcc/rust/backend/rust-compile-context.h9
-rw-r--r--gcc/rust/backend/rust-compile-implitem.h24
-rw-r--r--gcc/rust/backend/rust-compile-item.h9
-rw-r--r--gcc/rust/backend/rust-compile.cc193
-rw-r--r--gcc/rust/hir/rust-ast-lower-type.h2
-rw-r--r--gcc/rust/hir/rust-ast-lower.cc38
-rw-r--r--gcc/rust/hir/tree/rust-hir-expr.h9
-rw-r--r--gcc/rust/hir/tree/rust-hir-full-decls.h1
-rw-r--r--gcc/rust/hir/tree/rust-hir-full-test.cc25
-rw-r--r--gcc/rust/hir/tree/rust-hir-item.h15
-rw-r--r--gcc/rust/hir/tree/rust-hir-stmt.h6
-rw-r--r--gcc/rust/hir/tree/rust-hir-type.h58
-rw-r--r--gcc/rust/hir/tree/rust-hir-visitor.h1
-rw-r--r--gcc/rust/hir/tree/rust-hir.h21
-rw-r--r--gcc/rust/lint/rust-lint-marklive-base.h1
-rw-r--r--gcc/rust/lint/rust-lint-marklive.h8
-rw-r--r--gcc/rust/parse/rust-parse-impl.h10
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-type.h2
-rw-r--r--gcc/rust/resolve/rust-ast-resolve.cc22
-rw-r--r--gcc/rust/rust-diagnostics.cc10
-rw-r--r--gcc/rust/rust-diagnostics.h13
-rw-r--r--gcc/rust/rust-gcc-diagnostics.cc10
-rw-r--r--gcc/rust/rust-system.h2
-rw-r--r--gcc/rust/typecheck/rust-hir-const-fold-base.h1
-rw-r--r--gcc/rust/typecheck/rust-hir-trait-ref.h4
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-base.h1
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-item.h24
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-type.cc46
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-type.h16
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-util.h1
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check.cc43
-rw-r--r--gcc/rust/typecheck/rust-tycheck-dump.h12
-rw-r--r--gcc/rust/typecheck/rust-tyty-bounds.cc11
-rw-r--r--gcc/rust/typecheck/rust-tyty.cc74
-rw-r--r--gcc/rust/typecheck/rust-tyty.h130
-rw-r--r--gcc/testsuite/rust/compile/torture/forward_decl_5.rs19
-rw-r--r--gcc/testsuite/rust/compile/traits10.rs1
-rw-r--r--gcc/testsuite/rust/compile/traits11.rs1
-rw-r--r--gcc/testsuite/rust/execute/torture/trait12.rs41
-rw-r--r--gcc/testsuite/rust/execute/torture/trait13.rs50
44 files changed, 744 insertions, 249 deletions
diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h
index 95e4738..72f2609 100644
--- a/gcc/rust/ast/rust-ast.h
+++ b/gcc/rust/ast/rust-ast.h
@@ -822,6 +822,8 @@ public:
virtual bool is_marked_for_strip () const = 0;
NodeId get_node_id () const { return node_id; }
+ virtual bool is_item () const = 0;
+
protected:
Stmt () : node_id (Analysis::Mappings::get ()->get_next_node_id ()) {}
@@ -847,6 +849,8 @@ public:
add_crate_name (std::vector<std::string> &names ATTRIBUTE_UNUSED) const
{}
+ bool is_item () const override final { return true; }
+
protected:
// Clone function implementation as pure virtual method
virtual Item *clone_item_impl () const = 0;
diff --git a/gcc/rust/ast/rust-stmt.h b/gcc/rust/ast/rust-stmt.h
index b83ca11..a1b4e57 100644
--- a/gcc/rust/ast/rust-stmt.h
+++ b/gcc/rust/ast/rust-stmt.h
@@ -46,6 +46,8 @@ public:
void mark_for_strip () override { marked_for_strip = true; }
bool is_marked_for_strip () const override { return marked_for_strip; }
+ bool is_item () const override final { return false; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -169,6 +171,8 @@ public:
return type;
}
+ bool is_item () const override final { return false; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -186,6 +190,8 @@ class ExprStmt : public Stmt
public:
Location get_locus () const override final { return locus; }
+ bool is_item () const override final { return false; }
+
protected:
ExprStmt (Location locus) : locus (locus) {}
};
diff --git a/gcc/rust/ast/rust-type.h b/gcc/rust/ast/rust-type.h
index b38837c..2414b60 100644
--- a/gcc/rust/ast/rust-type.h
+++ b/gcc/rust/ast/rust-type.h
@@ -162,10 +162,7 @@ public:
class TraitObjectType : public Type
{
bool has_dyn;
- // TypeParamBounds type_param_bounds;
- std::vector<std::unique_ptr<TypeParamBound> >
- type_param_bounds; // inlined form
-
+ std::vector<std::unique_ptr<TypeParamBound> > type_param_bounds;
Location locus;
protected:
@@ -179,7 +176,7 @@ protected:
public:
TraitObjectType (
std::vector<std::unique_ptr<TypeParamBound> > type_param_bounds,
- Location locus, bool is_dyn_dispatch = false)
+ Location locus, bool is_dyn_dispatch)
: has_dyn (is_dyn_dispatch),
type_param_bounds (std::move (type_param_bounds)), locus (locus)
{}
@@ -215,6 +212,8 @@ public:
void accept_vis (ASTVisitor &vis) override;
+ bool is_dyn () const { return has_dyn; }
+
// TODO: mutable getter seems kinda dodgy
std::vector<std::unique_ptr<TypeParamBound> > &get_type_param_bounds ()
{
diff --git a/gcc/rust/backend/rust-compile-base.h b/gcc/rust/backend/rust-compile-base.h
index d741598..3184e27 100644
--- a/gcc/rust/backend/rust-compile-base.h
+++ b/gcc/rust/backend/rust-compile-base.h
@@ -177,7 +177,6 @@ public:
virtual void visit (HIR::TraitObjectType &type) {}
virtual void visit (HIR::ParenthesisedType &type) {}
virtual void visit (HIR::ImplTraitTypeOneBound &type) {}
- virtual void visit (HIR::TraitObjectTypeOneBound &type) {}
virtual void visit (HIR::TupleType &type) {}
virtual void visit (HIR::NeverType &type) {}
virtual void visit (HIR::RawPointerType &type) {}
@@ -210,9 +209,12 @@ protected:
const TyTy::DynamicObjectType *ty,
Location locus);
- Bexpression *
- compute_address_for_trait_item (const Resolver::TraitItemReference *ref,
- const TyTy::BaseType *receiver);
+ Bexpression *compute_address_for_trait_item (
+ const Resolver::TraitItemReference *ref,
+ const TyTy::TypeBoundPredicate *predicate,
+ std::vector<std::pair<Resolver::TraitReference *, HIR::ImplBlock *>>
+ &receiver_bounds,
+ const TyTy::BaseType *receiver, const TyTy::BaseType *root, Location locus);
};
} // namespace Compile
diff --git a/gcc/rust/backend/rust-compile-context.h b/gcc/rust/backend/rust-compile-context.h
index 551e041..396cb10 100644
--- a/gcc/rust/backend/rust-compile-context.h
+++ b/gcc/rust/backend/rust-compile-context.h
@@ -367,6 +367,9 @@ public:
void visit (const TyTy::ParamType &param) override
{
+ recursion_count++;
+ rust_assert (recursion_count < kDefaultRecusionLimit);
+
param.resolve ()->accept_vis (*this);
}
@@ -670,12 +673,16 @@ public:
private:
TyTyResolveCompile (Context *ctx, bool trait_object_mode)
- : ctx (ctx), trait_object_mode (trait_object_mode), translated (nullptr)
+ : ctx (ctx), trait_object_mode (trait_object_mode), translated (nullptr),
+ recursion_count (0)
{}
Context *ctx;
bool trait_object_mode;
::Btype *translated;
+ size_t recursion_count;
+
+ static const size_t kDefaultRecusionLimit = 5;
};
} // namespace Compile
diff --git a/gcc/rust/backend/rust-compile-implitem.h b/gcc/rust/backend/rust-compile-implitem.h
index a78cf19..05c7910 100644
--- a/gcc/rust/backend/rust-compile-implitem.h
+++ b/gcc/rust/backend/rust-compile-implitem.h
@@ -46,12 +46,9 @@ public:
if (is_query_mode
&& ctx->get_backend ()->is_error_expression (compiler.reference))
- {
- rust_error_at (ref_locus, "failed to compile impl item: %s",
- item->as_string ().c_str ());
- rust_assert (
- !ctx->get_backend ()->is_error_expression (compiler.reference));
- }
+ rust_internal_error_at (ref_locus, "failed to compile impl item: %s",
+ item->as_string ().c_str ());
+
return compiler.reference;
}
@@ -331,7 +328,7 @@ class CompileTraitItem : public HIRCompileBase
using Rust::Compile::HIRCompileBase::visit;
public:
- static Bexpression *Compile (TyTy::BaseType *self, HIR::TraitItem *item,
+ static Bexpression *Compile (const TyTy::BaseType *self, HIR::TraitItem *item,
Context *ctx, TyTy::BaseType *concrete,
bool is_query_mode = false,
Location ref_locus = Location ())
@@ -341,12 +338,9 @@ public:
if (is_query_mode
&& ctx->get_backend ()->is_error_expression (compiler.reference))
- {
- rust_error_at (ref_locus, "failed to compile trait item: %s",
- item->as_string ().c_str ());
- rust_assert (
- !ctx->get_backend ()->is_error_expression (compiler.reference));
- }
+ rust_internal_error_at (ref_locus, "failed to compile trait item: %s",
+ item->as_string ().c_str ());
+
return compiler.reference;
}
@@ -575,14 +569,14 @@ public:
}
private:
- CompileTraitItem (TyTy::BaseType *self, Context *ctx,
+ CompileTraitItem (const TyTy::BaseType *self, Context *ctx,
TyTy::BaseType *concrete, Location ref_locus)
: HIRCompileBase (ctx), self (self), concrete (concrete),
reference (ctx->get_backend ()->error_expression ()),
ref_locus (ref_locus)
{}
- TyTy::BaseType *self;
+ const TyTy::BaseType *self;
TyTy::BaseType *concrete;
Bexpression *reference;
Location ref_locus;
diff --git a/gcc/rust/backend/rust-compile-item.h b/gcc/rust/backend/rust-compile-item.h
index b64f6f0..6691c2a 100644
--- a/gcc/rust/backend/rust-compile-item.h
+++ b/gcc/rust/backend/rust-compile-item.h
@@ -48,12 +48,9 @@ public:
if (is_query_mode
&& ctx->get_backend ()->is_error_expression (compiler.reference))
- {
- rust_error_at (ref_locus, "failed to compile item: %s",
- item->as_string ().c_str ());
- rust_assert (
- !ctx->get_backend ()->is_error_expression (compiler.reference));
- }
+ rust_internal_error_at (ref_locus, "failed to compile item: %s",
+ item->as_string ().c_str ());
+
return compiler.reference;
}
diff --git a/gcc/rust/backend/rust-compile.cc b/gcc/rust/backend/rust-compile.cc
index a5d32b1..e9aca2c 100644
--- a/gcc/rust/backend/rust-compile.cc
+++ b/gcc/rust/backend/rust-compile.cc
@@ -22,6 +22,7 @@
#include "rust-compile-struct-field-expr.h"
#include "rust-hir-trait-resolve.h"
#include "rust-hir-path-probe.h"
+#include "rust-hir-type-bounds.h"
#include "rust-hir-dot-operator.h"
namespace Rust {
@@ -243,8 +244,9 @@ CompileExpr::visit (HIR::MethodCallExpr &expr)
size_t offs = 0;
const Resolver::TraitItemReference *ref = nullptr;
- for (auto &item : dyn->get_object_items ())
+ for (auto &bound : dyn->get_object_items ())
{
+ const Resolver::TraitItemReference *item = bound.first;
auto t = item->get_tyty ();
rust_assert (t->get_kind () == TyTy::TypeKind::FNDEF);
auto ft = static_cast<TyTy::FnType *> (t);
@@ -790,18 +792,25 @@ HIRCompileBase::coerce_to_dyn_object (Bexpression *compiled_ref,
// __trait_object_ptr
// [list of function ptrs]
+ auto root = actual->get_root ();
+ std::vector<std::pair<Resolver::TraitReference *, HIR::ImplBlock *>>
+ probed_bounds_for_receiver = Resolver::TypeBoundsProbe::Probe (root);
+
std::vector<Bexpression *> vals;
vals.push_back (compiled_ref);
- for (auto &item : ty->get_object_items ())
+ for (auto &bound : ty->get_object_items ())
{
- // compute the address of each method item
- auto address = compute_address_for_trait_item (item, actual->get_root ());
+ const Resolver::TraitItemReference *item = bound.first;
+ const TyTy::TypeBoundPredicate *predicate = bound.second;
+
+ auto address = compute_address_for_trait_item (item, predicate,
+ probed_bounds_for_receiver,
+ actual, root, locus);
vals.push_back (address);
}
Bexpression *constructed_trait_object
= ctx->get_backend ()->constructor_expression (dynamic_object, vals, -1,
-
locus);
fncontext fnctx = ctx->peek_fn ();
@@ -851,44 +860,148 @@ HIRCompileBase::coerce_to_dyn_object (Bexpression *compiled_ref,
Bexpression *
HIRCompileBase::compute_address_for_trait_item (
- const Resolver::TraitItemReference *trait_item_ref,
- const TyTy::BaseType *receiver)
+ const Resolver::TraitItemReference *ref,
+ const TyTy::TypeBoundPredicate *predicate,
+ std::vector<std::pair<Resolver::TraitReference *, HIR::ImplBlock *>>
+ &receiver_bounds,
+ const TyTy::BaseType *receiver, const TyTy::BaseType *root, Location locus)
{
- TyTy::BaseType *item_type = trait_item_ref->get_tyty ();
- rust_assert (item_type->get_kind () == TyTy::TypeKind::FNDEF);
- TyTy::FnType *fntype = static_cast<TyTy::FnType *> (item_type);
-
- auto root = receiver->get_root ();
- HIR::PathIdentSegment segment_name (trait_item_ref->get_identifier ());
- std::vector<Resolver::PathProbeCandidate> candidates
- = Resolver::PathProbeType::Probe (root, segment_name, true, false, true);
-
- // FIXME for default trait item resolution
+ // There are two cases here one where its an item which has an implementation
+ // within a trait-impl-block. Then there is the case where there is a default
+ // implementation for this within the trait.
//
- // if (candidates.size () == 0)
- // {
- // rust_assert (trait_item_ref->is_optional ()); // has definition
+ // The awkward part here is that this might be a generic trait and we need to
+ // figure out the correct monomorphized type for this so we can resolve the
+ // address of the function , this is stored as part of the
+ // type-bound-predicate
//
- // CompileTraitItem::Compile (self_type,
- // trait_item_ref->get_hir_trait_item (), ctx,
- // fntype);
- // if (!ctx->lookup_function_decl (fntype->get_ty_ref (), &fn))
- // {
- // return ctx->get_backend ()->error_expression ();
- // }
- // }
-
- rust_assert (!candidates.empty ());
- rust_assert (candidates.size () == 1);
-
- Resolver::PathProbeCandidate *candidate = &candidates.at (0);
- rust_assert (candidate->is_impl_candidate ());
-
- HIR::ImplItem *impl_item = candidate->item.impl.impl_item;
-
- return CompileInherentImplItem::Compile (receiver->get_root (), impl_item,
- ctx, true, fntype, true,
- Location () /* FIXME */);
+ // Algo:
+ // check if there is an impl-item for this trait-item-ref first
+ // else assert that the trait-item-ref has an implementation
+
+ TyTy::TypeBoundPredicateItem predicate_item
+ = predicate->lookup_associated_item (ref->get_identifier ());
+ rust_assert (!predicate_item.is_error ());
+
+ // this is the expected end type
+ TyTy::BaseType *trait_item_type = predicate_item.get_tyty_for_receiver (root);
+ rust_assert (trait_item_type->get_kind () == TyTy::TypeKind::FNDEF);
+ TyTy::FnType *trait_item_fntype
+ = static_cast<TyTy::FnType *> (trait_item_type);
+
+ // find impl-block for this trait-item-ref
+ HIR::ImplBlock *associated_impl_block = nullptr;
+ const Resolver::TraitReference *predicate_trait_ref = predicate->get ();
+ for (auto &item : receiver_bounds)
+ {
+ Resolver::TraitReference *trait_ref = item.first;
+ HIR::ImplBlock *impl_block = item.second;
+ if (predicate_trait_ref->is_equal (*trait_ref))
+ {
+ associated_impl_block = impl_block;
+ break;
+ }
+ }
+
+ // FIXME this probably should just return error_mark_node but this helps
+ // debug for now since we are wrongly returning early on type-resolution
+ // failures, until we take advantage of more error types and error_mark_node
+ rust_assert (associated_impl_block != nullptr);
+
+ // lookup self for the associated impl
+ std::unique_ptr<HIR::Type> &self_type_path
+ = associated_impl_block->get_type ();
+ TyTy::BaseType *self = nullptr;
+ bool ok = ctx->get_tyctx ()->lookup_type (
+ self_type_path->get_mappings ().get_hirid (), &self);
+ rust_assert (ok);
+
+ // lookup the predicate item from the self
+ TyTy::TypeBoundPredicate *self_bound = nullptr;
+ for (auto &bound : self->get_specified_bounds ())
+ {
+ const Resolver::TraitReference *bound_ref = bound.get ();
+ const Resolver::TraitReference *specified_ref = predicate->get ();
+ if (bound_ref->is_equal (*specified_ref))
+ {
+ self_bound = &bound;
+ break;
+ }
+ }
+ rust_assert (self_bound != nullptr);
+
+ // lookup the associated item from the associated impl block
+ TyTy::TypeBoundPredicateItem associated_self_item
+ = self_bound->lookup_associated_item (ref->get_identifier ());
+ rust_assert (!associated_self_item.is_error ());
+
+ // apply any generic arguments from this predicate
+ TyTy::BaseType *mono1 = associated_self_item.get_tyty_for_receiver (self);
+ TyTy::BaseType *mono2 = nullptr;
+ if (predicate->has_generic_args ())
+ {
+ mono2 = associated_self_item.get_tyty_for_receiver (
+ self, predicate->get_generic_args ());
+ }
+ else
+ {
+ mono2 = associated_self_item.get_tyty_for_receiver (self);
+ }
+ rust_assert (mono1 != nullptr);
+ rust_assert (mono1->get_kind () == TyTy::TypeKind::FNDEF);
+ TyTy::FnType *assocated_item_ty1 = static_cast<TyTy::FnType *> (mono1);
+
+ rust_assert (mono2 != nullptr);
+ rust_assert (mono2->get_kind () == TyTy::TypeKind::FNDEF);
+ TyTy::FnType *assocated_item_ty2 = static_cast<TyTy::FnType *> (mono2);
+
+ // Lookup the impl-block for the associated impl_item if it exists
+ HIR::Function *associated_function = nullptr;
+ for (auto &impl_item : associated_impl_block->get_impl_items ())
+ {
+ bool is_function = impl_item->get_impl_item_type ()
+ == HIR::ImplItem::ImplItemType::FUNCTION;
+ if (!is_function)
+ continue;
+
+ HIR::Function *fn = static_cast<HIR::Function *> (impl_item.get ());
+ bool found_associated_item
+ = fn->get_function_name ().compare (ref->get_identifier ()) == 0;
+ if (found_associated_item)
+ associated_function = fn;
+ }
+
+ // we found an impl_item for this
+ if (associated_function != nullptr)
+ {
+ // lookup the associated type for this item
+ TyTy::BaseType *lookup = nullptr;
+ bool ok = ctx->get_tyctx ()->lookup_type (
+ associated_function->get_mappings ().get_hirid (), &lookup);
+ rust_assert (ok);
+ rust_assert (lookup->get_kind () == TyTy::TypeKind::FNDEF);
+ TyTy::FnType *lookup_fntype = static_cast<TyTy::FnType *> (lookup);
+
+ if (lookup_fntype->needs_substitution ())
+ {
+ TyTy::SubstitutionArgumentMappings mappings
+ = assocated_item_ty1->solve_missing_mappings_from_this (
+ *assocated_item_ty2, *lookup_fntype);
+ lookup_fntype = lookup_fntype->handle_substitions (mappings);
+ }
+
+ return CompileInherentImplItem::Compile (root, associated_function, ctx,
+ true, lookup_fntype, true,
+ locus);
+ }
+
+ // we can only compile trait-items with a body
+ bool trait_item_has_definition = ref->is_optional ();
+ rust_assert (trait_item_has_definition);
+
+ HIR::TraitItem *trait_item = ref->get_hir_trait_item ();
+ return CompileTraitItem::Compile (root, trait_item, ctx, trait_item_fntype,
+ true, locus);
}
} // namespace Compile
diff --git a/gcc/rust/hir/rust-ast-lower-type.h b/gcc/rust/hir/rust-ast-lower-type.h
index c667932..858984c 100644
--- a/gcc/rust/hir/rust-ast-lower-type.h
+++ b/gcc/rust/hir/rust-ast-lower-type.h
@@ -293,6 +293,8 @@ public:
void visit (AST::TraitObjectTypeOneBound &type) override;
+ void visit (AST::TraitObjectType &type) override;
+
private:
ASTLoweringType () : ASTLoweringBase (), translated (nullptr) {}
diff --git a/gcc/rust/hir/rust-ast-lower.cc b/gcc/rust/hir/rust-ast-lower.cc
index 5f269b1..d8d53eb 100644
--- a/gcc/rust/hir/rust-ast-lower.cc
+++ b/gcc/rust/hir/rust-ast-lower.cc
@@ -517,21 +517,43 @@ ASTLowerQualifiedPathInType::visit (AST::QualifiedPathInType &path)
void
ASTLoweringType::visit (AST::TraitObjectTypeOneBound &type)
{
- HIR::TypeParamBound *b
+ std::vector<std::unique_ptr<HIR::TypeParamBound> > bounds;
+ HIR::TypeParamBound *translated_bound
= ASTLoweringTypeBounds::translate (&type.get_trait_bound ());
- rust_assert (b->get_bound_type () == HIR::TypeParamBound::TRAITBOUND);
- HIR::TraitBound *bb = static_cast<HIR::TraitBound *> (b);
- HIR::TraitBound bound (*bb);
- delete bb;
+ bounds.push_back (std::unique_ptr<HIR::TypeParamBound> (translated_bound));
auto crate_num = mappings->get_current_crate ();
Analysis::NodeMapping mapping (crate_num, type.get_node_id (),
mappings->get_next_hir_id (crate_num),
mappings->get_next_localdef_id (crate_num));
- translated
- = new HIR::TraitObjectTypeOneBound (mapping, std::move (bound),
- type.get_locus (), type.is_dyn ());
+ translated = new HIR::TraitObjectType (mapping, std::move (bounds),
+ type.get_locus (), type.is_dyn ());
+
+ mappings->insert_hir_type (mapping.get_crate_num (), mapping.get_hirid (),
+ translated);
+}
+
+void
+ASTLoweringType::visit (AST::TraitObjectType &type)
+{
+ std::vector<std::unique_ptr<HIR::TypeParamBound> > bounds;
+
+ for (auto &bound : type.get_type_param_bounds ())
+ {
+ HIR::TypeParamBound *translated_bound
+ = ASTLoweringTypeBounds::translate (bound.get ());
+ bounds.push_back (
+ std::unique_ptr<HIR::TypeParamBound> (translated_bound));
+ }
+
+ auto crate_num = mappings->get_current_crate ();
+ Analysis::NodeMapping mapping (crate_num, type.get_node_id (),
+ mappings->get_next_hir_id (crate_num),
+ mappings->get_next_localdef_id (crate_num));
+
+ translated = new HIR::TraitObjectType (mapping, std::move (bounds),
+ type.get_locus (), type.is_dyn ());
mappings->insert_hir_type (mapping.get_crate_num (), mapping.get_hirid (),
translated);
diff --git a/gcc/rust/hir/tree/rust-hir-expr.h b/gcc/rust/hir/tree/rust-hir-expr.h
index c472cab..575d1f6 100644
--- a/gcc/rust/hir/tree/rust-hir-expr.h
+++ b/gcc/rust/hir/tree/rust-hir-expr.h
@@ -2007,15 +2007,6 @@ public:
void accept_vis (HIRVisitor &vis) override;
- void iterate_stmts (std::function<bool (Stmt *)> cb)
- {
- for (auto it = statements.begin (); it != statements.end (); it++)
- {
- if (!cb (it->get ()))
- return;
- }
- }
-
bool is_final_stmt (Stmt *stmt) { return statements.back ().get () == stmt; }
Location get_closing_locus ()
diff --git a/gcc/rust/hir/tree/rust-hir-full-decls.h b/gcc/rust/hir/tree/rust-hir-full-decls.h
index 384ddf5..3e9d8b2 100644
--- a/gcc/rust/hir/tree/rust-hir-full-decls.h
+++ b/gcc/rust/hir/tree/rust-hir-full-decls.h
@@ -218,7 +218,6 @@ class ImplTraitType;
class TraitObjectType;
class ParenthesisedType;
class ImplTraitTypeOneBound;
-class TraitObjectTypeOneBound;
class TupleType;
class NeverType;
class RawPointerType;
diff --git a/gcc/rust/hir/tree/rust-hir-full-test.cc b/gcc/rust/hir/tree/rust-hir-full-test.cc
index a7c2e9f9..bacef82 100644
--- a/gcc/rust/hir/tree/rust-hir-full-test.cc
+++ b/gcc/rust/hir/tree/rust-hir-full-test.cc
@@ -2893,25 +2893,6 @@ TypePathSegmentGeneric::as_string () const
}
std::string
-TraitObjectTypeOneBound::as_string () const
-{
- std::string str ("TraitObjectTypeOneBound: \n Has dyn dispatch: ");
-
- if (has_dyn)
- {
- str += "true";
- }
- else
- {
- str += "false";
- }
-
- str += "\n TraitBound: " + trait_bound.as_string ();
-
- return str;
-}
-
-std::string
TypePathFunction::as_string () const
{
std::string str ("(");
@@ -4462,12 +4443,6 @@ ImplTraitTypeOneBound::accept_vis (HIRVisitor &vis)
}
void
-TraitObjectTypeOneBound::accept_vis (HIRVisitor &vis)
-{
- vis.visit (*this);
-}
-
-void
TupleType::accept_vis (HIRVisitor &vis)
{
vis.visit (*this);
diff --git a/gcc/rust/hir/tree/rust-hir-item.h b/gcc/rust/hir/tree/rust-hir-item.h
index c5a8d06..0dd7ac8 100644
--- a/gcc/rust/hir/tree/rust-hir-item.h
+++ b/gcc/rust/hir/tree/rust-hir-item.h
@@ -1122,6 +1122,11 @@ public:
// Returns whether function has a where clause.
bool has_where_clause () const { return !where_clause.is_empty (); }
+ ImplItemType get_impl_item_type () const override final
+ {
+ return ImplItem::ImplItemType::FUNCTION;
+ }
+
// Mega-constructor with all possible fields
Function (Analysis::NodeMapping mappings, Identifier function_name,
FunctionQualifiers qualifiers,
@@ -1273,6 +1278,11 @@ public:
// Returns whether type alias has a where clause.
bool has_where_clause () const { return !where_clause.is_empty (); }
+ ImplItemType get_impl_item_type () const override final
+ {
+ return ImplItem::ImplItemType::TYPE_ALIAS;
+ }
+
// Mega-constructor with all possible fields
TypeAlias (Analysis::NodeMapping mappings, Identifier new_type_name,
std::vector<std::unique_ptr<GenericParam>> generic_params,
@@ -2075,6 +2085,11 @@ public:
return get_mappings ();
};
+ ImplItemType get_impl_item_type () const override final
+ {
+ return ImplItem::ImplItemType::CONSTANT;
+ }
+
protected:
/* Use covariance to implement clone function as returning this object
* rather than base */
diff --git a/gcc/rust/hir/tree/rust-hir-stmt.h b/gcc/rust/hir/tree/rust-hir-stmt.h
index cc61142..29e98fa 100644
--- a/gcc/rust/hir/tree/rust-hir-stmt.h
+++ b/gcc/rust/hir/tree/rust-hir-stmt.h
@@ -41,6 +41,8 @@ public:
void accept_vis (HIRVisitor &vis) override;
+ bool is_item () const override final { return false; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -119,6 +121,8 @@ public:
HIR::Pattern *get_pattern () { return variables_pattern.get (); }
+ bool is_item () const override final { return false; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -136,6 +140,8 @@ class ExprStmt : public Stmt
public:
Location get_locus () const override final { return locus; }
+ bool is_item () const override final { return false; }
+
protected:
ExprStmt (Analysis::NodeMapping mappings, Location locus)
: Stmt (std::move (mappings)), locus (locus)
diff --git a/gcc/rust/hir/tree/rust-hir-type.h b/gcc/rust/hir/tree/rust-hir-type.h
index 1a90b29..070b761 100644
--- a/gcc/rust/hir/tree/rust-hir-type.h
+++ b/gcc/rust/hir/tree/rust-hir-type.h
@@ -145,10 +145,7 @@ public:
class TraitObjectType : public Type
{
bool has_dyn;
- // TypeParamBounds type_param_bounds;
- std::vector<std::unique_ptr<TypeParamBound> >
- type_param_bounds; // inlined form
-
+ std::vector<std::unique_ptr<TypeParamBound> > type_param_bounds;
Location locus;
protected:
@@ -163,7 +160,7 @@ public:
TraitObjectType (
Analysis::NodeMapping mappings,
std::vector<std::unique_ptr<TypeParamBound> > type_param_bounds,
- Location locus, bool is_dyn_dispatch = false)
+ Location locus, bool is_dyn_dispatch)
: Type (mappings), has_dyn (is_dyn_dispatch),
type_param_bounds (std::move (type_param_bounds)), locus (locus)
{}
@@ -199,6 +196,17 @@ public:
Location get_locus () const { return locus; }
void accept_vis (HIRVisitor &vis) override;
+
+ std::vector<std::unique_ptr<TypeParamBound> > &get_type_param_bounds ()
+ {
+ return type_param_bounds;
+ }
+
+ const std::vector<std::unique_ptr<TypeParamBound> > &
+ get_type_param_bounds () const
+ {
+ return type_param_bounds;
+ }
};
// A type with parentheses around it, used to avoid ambiguity.
@@ -305,46 +313,6 @@ public:
void accept_vis (HIRVisitor &vis) override;
};
-/* A trait object with a single trait bound. The "trait bound" is really just
- * the trait. Basically like using an interface as a type in an OOP language. */
-class TraitObjectTypeOneBound : public TypeNoBounds
-{
- bool has_dyn;
- TraitBound trait_bound;
- Location locus;
-
-protected:
- /* Use covariance to implement clone function as returning this object rather
- * than base */
- TraitObjectTypeOneBound *clone_type_impl () const override
- {
- return new TraitObjectTypeOneBound (mappings, trait_bound, locus, has_dyn);
- }
-
- /* Use covariance to implement clone function as returning this object rather
- * than base */
- TraitObjectTypeOneBound *clone_type_no_bounds_impl () const override
- {
- return new TraitObjectTypeOneBound (mappings, trait_bound, locus, has_dyn);
- }
-
-public:
- TraitObjectTypeOneBound (Analysis::NodeMapping mappings,
- TraitBound trait_bound, Location locus,
- bool is_dyn_dispatch)
- : TypeNoBounds (mappings), has_dyn (is_dyn_dispatch),
- trait_bound (std::move (trait_bound)), locus (locus)
- {}
-
- std::string as_string () const override;
-
- Location get_locus () const { return locus; }
-
- void accept_vis (HIRVisitor &vis) override;
-
- TraitBound &get_trait_bound () { return trait_bound; }
-};
-
class TypePath; // definition moved to "rust-path.h"
/* A type consisting of the "product" of others (the tuple's elements) in a
diff --git a/gcc/rust/hir/tree/rust-hir-visitor.h b/gcc/rust/hir/tree/rust-hir-visitor.h
index 96ea4c3..0487446 100644
--- a/gcc/rust/hir/tree/rust-hir-visitor.h
+++ b/gcc/rust/hir/tree/rust-hir-visitor.h
@@ -149,7 +149,6 @@ public:
virtual void visit (TraitObjectType &type) = 0;
virtual void visit (ParenthesisedType &type) = 0;
virtual void visit (ImplTraitTypeOneBound &type) = 0;
- virtual void visit (TraitObjectTypeOneBound &type) = 0;
virtual void visit (TupleType &type) = 0;
virtual void visit (NeverType &type) = 0;
virtual void visit (RawPointerType &type) = 0;
diff --git a/gcc/rust/hir/tree/rust-hir.h b/gcc/rust/hir/tree/rust-hir.h
index d7977b4..e834553 100644
--- a/gcc/rust/hir/tree/rust-hir.h
+++ b/gcc/rust/hir/tree/rust-hir.h
@@ -104,6 +104,8 @@ public:
const Analysis::NodeMapping &get_mappings () const { return mappings; }
+ virtual bool is_item () const = 0;
+
protected:
Stmt (Analysis::NodeMapping mappings) : mappings (std::move (mappings)) {}
@@ -140,6 +142,8 @@ public:
AST::AttrVec &get_outer_attrs () { return outer_attrs; }
const AST::AttrVec &get_outer_attrs () const { return outer_attrs; }
+ bool is_item () const override final { return true; }
+
protected:
// Constructor
Item (Analysis::NodeMapping mappings,
@@ -642,11 +646,14 @@ public:
class ImplItem
{
-protected:
- // Clone function implementation as pure virtual method
- virtual ImplItem *clone_inherent_impl_item_impl () const = 0;
-
public:
+ enum ImplItemType
+ {
+ FUNCTION,
+ TYPE_ALIAS,
+ CONSTANT
+ };
+
virtual ~ImplItem () {}
// Unique pointer custom clone function
@@ -662,6 +669,12 @@ public:
virtual Analysis::NodeMapping get_impl_mappings () const = 0;
virtual Location get_locus () const = 0;
+
+ virtual ImplItemType get_impl_item_type () const = 0;
+
+protected:
+ // Clone function implementation as pure virtual method
+ virtual ImplItem *clone_inherent_impl_item_impl () const = 0;
};
// A crate HIR object - holds all the data for a single compilation unit
diff --git a/gcc/rust/lint/rust-lint-marklive-base.h b/gcc/rust/lint/rust-lint-marklive-base.h
index e7b0194..b67705b 100644
--- a/gcc/rust/lint/rust-lint-marklive-base.h
+++ b/gcc/rust/lint/rust-lint-marklive-base.h
@@ -172,7 +172,6 @@ public:
virtual void visit (HIR::TraitObjectType &) override {}
virtual void visit (HIR::ParenthesisedType &) override {}
virtual void visit (HIR::ImplTraitTypeOneBound &) override {}
- virtual void visit (HIR::TraitObjectTypeOneBound &) override {}
virtual void visit (HIR::TupleType &) override {}
virtual void visit (HIR::NeverType &) override {}
virtual void visit (HIR::RawPointerType &) override {}
diff --git a/gcc/rust/lint/rust-lint-marklive.h b/gcc/rust/lint/rust-lint-marklive.h
index 7b7b68f..ca5d894 100644
--- a/gcc/rust/lint/rust-lint-marklive.h
+++ b/gcc/rust/lint/rust-lint-marklive.h
@@ -97,10 +97,10 @@ public:
void visit (HIR::BlockExpr &expr) override
{
- expr.iterate_stmts ([&] (HIR::Stmt *s) mutable -> bool {
- s->accept_vis (*this);
- return true;
- });
+ for (auto &s : expr.get_statements ())
+ {
+ s->accept_vis (*this);
+ }
if (expr.has_expr ())
{
expr.get_final_expr ()->accept_vis (*this);
diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h
index 7f0db1b..f1d376a 100644
--- a/gcc/rust/parse/rust-parse-impl.h
+++ b/gcc/rust/parse/rust-parse-impl.h
@@ -9065,7 +9065,8 @@ Parser<ManagedTokenSource>::parse_type ()
= parse_type_param_bounds ();
return std::unique_ptr<AST::TraitObjectType> (
- new AST::TraitObjectType (std::move (bounds), t->get_locus ()));
+ new AST::TraitObjectType (std::move (bounds), t->get_locus (),
+ false));
}
case IDENTIFIER:
case SUPER:
@@ -9152,7 +9153,7 @@ Parser<ManagedTokenSource>::parse_type ()
}
return std::unique_ptr<AST::TraitObjectType> (
- new AST::TraitObjectType (std::move (bounds), locus));
+ new AST::TraitObjectType (std::move (bounds), locus, false));
}
default:
// assume that this is a type path and not an error
@@ -9422,7 +9423,8 @@ Parser<ManagedTokenSource>::parse_paren_prefixed_type ()
}
return std::unique_ptr<AST::TraitObjectType> (
- new AST::TraitObjectType (std::move (bounds), left_delim_locus));
+ new AST::TraitObjectType (std::move (bounds), left_delim_locus,
+ false));
}
else
{
@@ -9532,7 +9534,7 @@ Parser<ManagedTokenSource>::parse_for_prefixed_type ()
}
return std::unique_ptr<AST::TraitObjectType> (
- new AST::TraitObjectType (std::move (bounds), for_locus));
+ new AST::TraitObjectType (std::move (bounds), for_locus, false));
}
default:
// error
diff --git a/gcc/rust/resolve/rust-ast-resolve-type.h b/gcc/rust/resolve/rust-ast-resolve-type.h
index 4708bff..838d173 100644
--- a/gcc/rust/resolve/rust-ast-resolve-type.h
+++ b/gcc/rust/resolve/rust-ast-resolve-type.h
@@ -371,6 +371,8 @@ public:
void visit (AST::TraitObjectTypeOneBound &type) override;
+ void visit (AST::TraitObjectType &type) override;
+
private:
ResolveType (NodeId parent, bool canonicalize_type_with_generics)
: ResolverBase (parent),
diff --git a/gcc/rust/resolve/rust-ast-resolve.cc b/gcc/rust/resolve/rust-ast-resolve.cc
index 83a15a8..921b77c 100644
--- a/gcc/rust/resolve/rust-ast-resolve.cc
+++ b/gcc/rust/resolve/rust-ast-resolve.cc
@@ -349,7 +349,16 @@ ResolveExpr::visit (AST::BlockExpr &expr)
resolver->push_new_label_rib (resolver->get_type_scope ().peek ());
for (auto &s : expr.get_statements ())
- ResolveStmt::go (s.get (), s->get_node_id ());
+ {
+ if (s->is_item ())
+ ResolveStmt::go (s.get (), s->get_node_id ());
+ }
+
+ for (auto &s : expr.get_statements ())
+ {
+ if (!s->is_item ())
+ ResolveStmt::go (s.get (), s->get_node_id ());
+ }
if (expr.has_tail_expr ())
ResolveExpr::go (expr.get_tail_expr ().get (), expr.get_node_id ());
@@ -726,6 +735,17 @@ ResolveType::visit (AST::TraitObjectTypeOneBound &type)
ok = bound_resolved_id != UNKNOWN_NODEID;
}
+void
+ResolveType::visit (AST::TraitObjectType &type)
+{
+ ok = true;
+ for (auto &bound : type.get_type_param_bounds ())
+ {
+ /* NodeId bound_resolved_id = */
+ ResolveTypeBound::go (bound.get (), type.get_node_id ());
+ }
+}
+
// rust-ast-resolve-item.h
void
diff --git a/gcc/rust/rust-diagnostics.cc b/gcc/rust/rust-diagnostics.cc
index a82cac4..9982fa2 100644
--- a/gcc/rust/rust-diagnostics.cc
+++ b/gcc/rust/rust-diagnostics.cc
@@ -147,6 +147,16 @@ rust_close_quote ()
}
void
+rust_internal_error_at (const Location location, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start (ap, fmt);
+ rust_be_internal_error_at (location, expand_message (fmt, ap));
+ va_end (ap);
+}
+
+void
rust_error_at (const Location location, const char *fmt, ...)
{
va_list ap;
diff --git a/gcc/rust/rust-diagnostics.h b/gcc/rust/rust-diagnostics.h
index 93f8738..d9461f1 100644
--- a/gcc/rust/rust-diagnostics.h
+++ b/gcc/rust/rust-diagnostics.h
@@ -50,6 +50,10 @@
// simple location
extern void
+rust_internal_error_at (const Location, const char *fmt, ...)
+ RUST_ATTRIBUTE_GCC_DIAG (2, 3)
+ RUST_ATTRIBUTE_NORETURN;
+extern void
rust_error_at (const Location, const char *fmt, ...)
RUST_ATTRIBUTE_GCC_DIAG (2, 3);
extern void
@@ -57,7 +61,8 @@ rust_warning_at (const Location, int opt, const char *fmt, ...)
RUST_ATTRIBUTE_GCC_DIAG (3, 4);
extern void
rust_fatal_error (const Location, const char *fmt, ...)
- RUST_ATTRIBUTE_GCC_DIAG (2, 3);
+ RUST_ATTRIBUTE_GCC_DIAG (2, 3)
+ RUST_ATTRIBUTE_NORETURN;
extern void
rust_inform (const Location, const char *fmt, ...)
RUST_ATTRIBUTE_GCC_DIAG (2, 3);
@@ -82,13 +87,17 @@ rust_close_quote ();
// implement these routines.
extern void
+rust_be_internal_error_at (const Location, const std::string &errmsg)
+ RUST_ATTRIBUTE_NORETURN;
+extern void
rust_be_error_at (const Location, const std::string &errmsg);
extern void
rust_be_error_at (const RichLocation &, const std::string &errmsg);
extern void
rust_be_warning_at (const Location, int opt, const std::string &warningmsg);
extern void
-rust_be_fatal_error (const Location, const std::string &errmsg);
+rust_be_fatal_error (const Location, const std::string &errmsg)
+ RUST_ATTRIBUTE_NORETURN;
extern void
rust_be_inform (const Location, const std::string &infomsg);
extern void
diff --git a/gcc/rust/rust-gcc-diagnostics.cc b/gcc/rust/rust-gcc-diagnostics.cc
index db6372e..7106dd4 100644
--- a/gcc/rust/rust-gcc-diagnostics.cc
+++ b/gcc/rust/rust-gcc-diagnostics.cc
@@ -24,6 +24,16 @@
#include "options.h"
void
+rust_be_internal_error_at (const Location location, const std::string &errmsg)
+{
+ std::string loc_str = Linemap::location_to_string (location);
+ if (loc_str.empty ())
+ internal_error ("%s", errmsg.c_str ());
+ else
+ internal_error ("at %s, %s", loc_str.c_str (), errmsg.c_str ());
+}
+
+void
rust_be_error_at (const Location location, const std::string &errmsg)
{
location_t gcc_loc = location.gcc_location ();
diff --git a/gcc/rust/rust-system.h b/gcc/rust/rust-system.h
index e47fbdc..fa690d7 100644
--- a/gcc/rust/rust-system.h
+++ b/gcc/rust/rust-system.h
@@ -59,6 +59,8 @@
#include "diagnostic-core.h" /* For error_at and friends. */
#include "intl.h" /* For _(). */
+#define RUST_ATTRIBUTE_NORETURN ATTRIBUTE_NORETURN
+
// File separator to use based on whether or not the OS we're working with is
// DOS-based
#if defined(HAVE_DOS_BASED_FILE_SYSTEM)
diff --git a/gcc/rust/typecheck/rust-hir-const-fold-base.h b/gcc/rust/typecheck/rust-hir-const-fold-base.h
index 77c68c8..9cbf1ab 100644
--- a/gcc/rust/typecheck/rust-hir-const-fold-base.h
+++ b/gcc/rust/typecheck/rust-hir-const-fold-base.h
@@ -175,7 +175,6 @@ public:
virtual void visit (HIR::TraitObjectType &) override {}
virtual void visit (HIR::ParenthesisedType &) override {}
virtual void visit (HIR::ImplTraitTypeOneBound &) override {}
- virtual void visit (HIR::TraitObjectTypeOneBound &) override {}
virtual void visit (HIR::TupleType &) override {}
virtual void visit (HIR::NeverType &) override {}
virtual void visit (HIR::RawPointerType &) override {}
diff --git a/gcc/rust/typecheck/rust-hir-trait-ref.h b/gcc/rust/typecheck/rust-hir-trait-ref.h
index 0b64a36..31ebf8b 100644
--- a/gcc/rust/typecheck/rust-hir-trait-ref.h
+++ b/gcc/rust/typecheck/rust-hir-trait-ref.h
@@ -91,9 +91,7 @@ public:
TraitItemType get_trait_item_type () const { return type; }
- const HIR::TraitItem *get_hir_trait_item () const { return hir_trait_item; }
-
- HIR::TraitItem *get_hir_trait_item () { return hir_trait_item; }
+ HIR::TraitItem *get_hir_trait_item () const { return hir_trait_item; }
Location get_locus () const { return locus; }
diff --git a/gcc/rust/typecheck/rust-hir-type-check-base.h b/gcc/rust/typecheck/rust-hir-type-check-base.h
index b1e1050..eb96fd1 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-base.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-base.h
@@ -177,7 +177,6 @@ public:
virtual void visit (HIR::TraitObjectType &) override {}
virtual void visit (HIR::ParenthesisedType &) override {}
virtual void visit (HIR::ImplTraitTypeOneBound &) override {}
- virtual void visit (HIR::TraitObjectTypeOneBound &) override {}
virtual void visit (HIR::TupleType &) override {}
virtual void visit (HIR::NeverType &) override {}
virtual void visit (HIR::RawPointerType &) override {}
diff --git a/gcc/rust/typecheck/rust-hir-type-check-item.h b/gcc/rust/typecheck/rust-hir-type-check-item.h
index fe70035..706f649 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-item.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-item.h
@@ -70,12 +70,34 @@ public:
}
}
+ std::vector<TyTy::TypeBoundPredicate> specified_bounds;
TraitReference *trait_reference = &TraitReference::error_node ();
if (impl_block.has_trait_ref ())
{
std::unique_ptr<HIR::TypePath> &ref = impl_block.get_trait_ref ();
trait_reference = TraitResolver::Resolve (*ref.get ());
rust_assert (!trait_reference->is_error ());
+
+ // setup the bound
+ TyTy::TypeBoundPredicate predicate (
+ trait_reference->get_mappings ().get_defid (), ref->get_locus ());
+ auto &final_seg = ref->get_final_segment ();
+ if (final_seg->is_generic_segment ())
+ {
+ auto final_generic_seg
+ = static_cast<HIR::TypePathSegmentGeneric *> (final_seg.get ());
+ if (final_generic_seg->has_generic_args ())
+ {
+ HIR::GenericArgs &generic_args
+ = final_generic_seg->get_generic_args ();
+
+ // this is applying generic arguments to a trait
+ // reference
+ predicate.apply_generic_arguments (&generic_args);
+ }
+ }
+
+ specified_bounds.push_back (std::move (predicate));
}
TyTy::BaseType *self = nullptr;
@@ -86,6 +108,8 @@ public:
"failed to resolve Self for ImplBlock");
return;
}
+ // inherit the bounds
+ self->inherit_bounds (specified_bounds);
bool is_trait_impl_block = !trait_reference->is_error ();
diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.cc b/gcc/rust/typecheck/rust-hir-type-check-type.cc
index f2d5fe7..f1dbb6b 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-type.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-type.cc
@@ -95,7 +95,7 @@ TypeCheckType::visit (HIR::TypePath &path)
"TypePath %s declares generic arguments but "
"the type %s does not have any",
path.as_string ().c_str (),
- translated->as_string ().c_str ());
+ path_type->as_string ().c_str ());
}
else
{
@@ -525,22 +525,44 @@ TypeCheckType::resolve_segments (
}
void
-TypeCheckType::visit (HIR::TraitObjectTypeOneBound &type)
+TypeCheckType::visit (HIR::TraitObjectType &type)
{
std::vector<TyTy::TypeBoundPredicate> specified_bounds;
+ for (auto &bound : type.get_type_param_bounds ())
+ {
+ if (bound->get_bound_type ()
+ != HIR::TypeParamBound::BoundType::TRAITBOUND)
+ continue;
+
+ HIR::TypeParamBound &b = *bound.get ();
+ HIR::TraitBound &trait_bound = static_cast<HIR::TraitBound &> (b);
+
+ auto &type_path = trait_bound.get_path ();
+ TraitReference *trait = resolve_trait_path (type_path);
+ TyTy::TypeBoundPredicate predicate (trait->get_mappings ().get_defid (),
+ trait_bound.get_locus ());
+ auto &final_seg = type_path.get_final_segment ();
+ if (final_seg->is_generic_segment ())
+ {
+ auto final_generic_seg
+ = static_cast<HIR::TypePathSegmentGeneric *> (final_seg.get ());
+ if (final_generic_seg->has_generic_args ())
+ {
+ HIR::GenericArgs &generic_args
+ = final_generic_seg->get_generic_args ();
- HIR::TraitBound &trait_bound = type.get_trait_bound ();
- TraitReference *trait = resolve_trait_path (trait_bound.get_path ());
- TyTy::TypeBoundPredicate predicate (trait->get_mappings ().get_defid (),
- trait_bound.get_locus ());
+ // this is applying generic arguments to a trait
+ // reference
+ predicate.apply_generic_arguments (&generic_args);
+ }
+ }
- if (predicate.is_object_safe (true, type.get_locus ()))
- {
- specified_bounds.push_back (std::move (predicate));
- translated
- = new TyTy::DynamicObjectType (type.get_mappings ().get_hirid (),
- std::move (specified_bounds));
+ if (predicate.is_object_safe (true, type.get_locus ()))
+ specified_bounds.push_back (std::move (predicate));
}
+
+ translated = new TyTy::DynamicObjectType (type.get_mappings ().get_hirid (),
+ std::move (specified_bounds));
}
} // namespace Resolver
diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.h b/gcc/rust/typecheck/rust-hir-type-check-type.h
index c2b6d7c..08734ce 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-type.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-type.h
@@ -62,13 +62,9 @@ public:
std::vector<TyTy::SubstitutionParamMapping> *subst_mappings
= nullptr)
{
- TypeCheckType resolver (subst_mappings);
+ TypeCheckType resolver (type->get_mappings ().get_hirid (), subst_mappings);
type->accept_vis (resolver);
-
- if (resolver.translated == nullptr)
- resolver.translated
- = new TyTy::ErrorType (type->get_mappings ().get_hirid ());
-
+ rust_assert (resolver.translated != nullptr);
resolver.context->insert_type (type->get_mappings (), resolver.translated);
return resolver.translated;
}
@@ -147,11 +143,13 @@ public:
TyTy::InferType::InferTypeKind::GENERAL);
}
- void visit (HIR::TraitObjectTypeOneBound &type) override;
+ void visit (HIR::TraitObjectType &type) override;
private:
- TypeCheckType (std::vector<TyTy::SubstitutionParamMapping> *subst_mappings)
- : TypeCheckBase (), subst_mappings (subst_mappings), translated (nullptr)
+ TypeCheckType (HirId id,
+ std::vector<TyTy::SubstitutionParamMapping> *subst_mappings)
+ : TypeCheckBase (), subst_mappings (subst_mappings),
+ translated (new TyTy::ErrorType (id))
{}
void
diff --git a/gcc/rust/typecheck/rust-hir-type-check-util.h b/gcc/rust/typecheck/rust-hir-type-check-util.h
index 78d35a6..4595ca3 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-util.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-util.h
@@ -170,7 +170,6 @@ public:
virtual void visit (HIR::TraitObjectType &) override {}
virtual void visit (HIR::ParenthesisedType &) override {}
virtual void visit (HIR::ImplTraitTypeOneBound &) override {}
- virtual void visit (HIR::TraitObjectTypeOneBound &) override {}
virtual void visit (HIR::TupleType &) override {}
virtual void visit (HIR::NeverType &) override {}
virtual void visit (HIR::RawPointerType &) override {}
diff --git a/gcc/rust/typecheck/rust-hir-type-check.cc b/gcc/rust/typecheck/rust-hir-type-check.cc
index 5237082..ca4842a 100644
--- a/gcc/rust/typecheck/rust-hir-type-check.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check.cc
@@ -93,22 +93,37 @@ TypeResolution::Resolve (HIR::Crate &crate)
void
TypeCheckExpr::visit (HIR::BlockExpr &expr)
{
- expr.iterate_stmts ([&] (HIR::Stmt *s) mutable -> bool {
- auto resolved = TypeCheckStmt::Resolve (s, inside_loop);
- if (resolved == nullptr)
- {
- rust_error_at (s->get_locus (), "failure to resolve type");
- return false;
- }
+ for (auto &s : expr.get_statements ())
+ {
+ if (!s->is_item ())
+ continue;
- if (s->is_unit_check_needed () && !resolved->is_unit ())
- {
- auto unit = new TyTy::TupleType (s->get_mappings ().get_hirid ());
- resolved = unit->unify (resolved);
- }
+ auto resolved = TypeCheckStmt::Resolve (s.get (), inside_loop);
+ if (resolved == nullptr)
+ {
+ rust_error_at (s->get_locus (), "failure to resolve type");
+ return;
+ }
+ }
- return true;
- });
+ for (auto &s : expr.get_statements ())
+ {
+ if (s->is_item ())
+ continue;
+
+ auto resolved = TypeCheckStmt::Resolve (s.get (), inside_loop);
+ if (resolved == nullptr)
+ {
+ rust_error_at (s->get_locus (), "failure to resolve type");
+ return;
+ }
+
+ if (s->is_unit_check_needed () && !resolved->is_unit ())
+ {
+ auto unit = new TyTy::TupleType (s->get_mappings ().get_hirid ());
+ resolved = unit->unify (resolved);
+ }
+ }
if (expr.has_expr ())
infered
diff --git a/gcc/rust/typecheck/rust-tycheck-dump.h b/gcc/rust/typecheck/rust-tycheck-dump.h
index c0681b8..c305d48 100644
--- a/gcc/rust/typecheck/rust-tycheck-dump.h
+++ b/gcc/rust/typecheck/rust-tycheck-dump.h
@@ -94,12 +94,12 @@ public:
{
indentation_level++;
- expr.iterate_stmts ([&] (HIR::Stmt *s) mutable -> bool {
- dump += indent ();
- s->accept_vis (*this);
- dump += ";\n";
- return true;
- });
+ for (auto &s : expr.get_statements ())
+ {
+ dump += indent ();
+ s->accept_vis (*this);
+ dump += ";\n";
+ }
if (expr.has_expr ())
{
diff --git a/gcc/rust/typecheck/rust-tyty-bounds.cc b/gcc/rust/typecheck/rust-tyty-bounds.cc
index 88c94d2..cfb96bb 100644
--- a/gcc/rust/typecheck/rust-tyty-bounds.cc
+++ b/gcc/rust/typecheck/rust-tyty-bounds.cc
@@ -70,7 +70,10 @@ namespace TyTy {
std::string
TypeBoundPredicate::as_string () const
{
- return get ()->as_string ();
+ return get ()->as_string ()
+ + (has_generic_args ()
+ ? std::string ("<") + args->as_string () + std::string (">")
+ : "");
}
const Resolver::TraitReference *
@@ -135,7 +138,8 @@ TypeBoundPredicate::lookup_associated_item (const std::string &search) const
}
BaseType *
-TypeBoundPredicateItem::get_tyty_for_receiver (const TyTy::BaseType *receiver)
+TypeBoundPredicateItem::get_tyty_for_receiver (
+ const TyTy::BaseType *receiver, const HIR::GenericArgs *bound_args)
{
TyTy::BaseType *trait_item_tyty = get_raw_item ()->get_tyty ();
if (trait_item_tyty->get_kind () == TyTy::TypeKind::FNDEF)
@@ -166,7 +170,8 @@ TypeBoundPredicateItem::get_tyty_for_receiver (const TyTy::BaseType *receiver)
return trait_item_tyty;
// FIXME LEAK this should really be const
- const HIR::GenericArgs *args = parent->get_generic_args ();
+ const HIR::GenericArgs *args
+ = (bound_args != nullptr) ? bound_args : parent->get_generic_args ();
HIR::GenericArgs *generic_args = new HIR::GenericArgs (*args);
TyTy::BaseType *resolved
= Resolver::SubstMapper::Resolve (trait_item_tyty, parent->get_locus (),
diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc
index b3ceb06..378416f 100644
--- a/gcc/rust/typecheck/rust-tyty.cc
+++ b/gcc/rust/typecheck/rust-tyty.cc
@@ -334,6 +334,16 @@ StructFieldType::clone () const
}
bool
+SubstitutionParamMapping::need_substitution () const
+{
+ if (!param->can_resolve ())
+ return true;
+
+ auto resolved = param->resolve ();
+ return !resolved->is_concrete ();
+}
+
+bool
SubstitutionParamMapping::fill_param_ty (BaseType &type, Location locus)
{
auto context = Resolver::TypeCheckContext::get ();
@@ -575,6 +585,57 @@ SubstitutionRef::solve_mappings_from_receiver_for_self (
mappings.get_locus ());
}
+SubstitutionArgumentMappings
+SubstitutionRef::solve_missing_mappings_from_this (SubstitutionRef &ref,
+ SubstitutionRef &to)
+{
+ rust_assert (!ref.needs_substitution ());
+ rust_assert (needs_substitution ());
+ rust_assert (get_num_substitutions () == ref.get_num_substitutions ());
+
+ Location locus = used_arguments.get_locus ();
+ std::vector<SubstitutionArg> resolved_mappings;
+
+ std::map<HirId, std::pair<ParamType *, BaseType *>> substs;
+ for (size_t i = 0; i < get_num_substitutions (); i++)
+ {
+ SubstitutionParamMapping &a = substitutions.at (i);
+ SubstitutionParamMapping &b = ref.substitutions.at (i);
+
+ if (a.need_substitution ())
+ {
+ const BaseType *root = a.get_param_ty ()->resolve ()->get_root ();
+ rust_assert (root->get_kind () == TyTy::TypeKind::PARAM);
+ const ParamType *p = static_cast<const TyTy::ParamType *> (root);
+
+ substs[p->get_ty_ref ()] = {static_cast<ParamType *> (p->clone ()),
+ b.get_param_ty ()->resolve ()};
+ }
+ }
+
+ for (auto it = substs.begin (); it != substs.end (); it++)
+ {
+ HirId param_id = it->first;
+ BaseType *arg = it->second.second;
+
+ const SubstitutionParamMapping *associate_param = nullptr;
+ for (SubstitutionParamMapping &p : to.substitutions)
+ {
+ if (p.get_param_ty ()->get_ty_ref () == param_id)
+ {
+ associate_param = &p;
+ break;
+ }
+ }
+
+ rust_assert (associate_param != nullptr);
+ SubstitutionArg argument (associate_param, arg);
+ resolved_mappings.push_back (std::move (argument));
+ }
+
+ return SubstitutionArgumentMappings (resolved_mappings, locus);
+}
+
void
ADTType::accept_vis (TyVisitor &vis)
{
@@ -1978,7 +2039,7 @@ ParamType::as_string () const
bool ok = context->lookup_type (get_ty_ref (), &lookup);
rust_assert (ok);
- return lookup->as_string ();
+ return get_symbol () + "=" + lookup->as_string ();
}
std::string
@@ -2503,10 +2564,13 @@ DynamicObjectType::is_equal (const BaseType &other) const
return bounds_compatible (other, Location (), false);
}
-const std::vector<const Resolver::TraitItemReference *>
+const std::vector<
+ std::pair<const Resolver::TraitItemReference *, const TypeBoundPredicate *>>
DynamicObjectType::get_object_items () const
{
- std::vector<const Resolver::TraitItemReference *> items;
+ std::vector<
+ std::pair<const Resolver::TraitItemReference *, const TypeBoundPredicate *>>
+ items;
for (auto &bound : get_specified_bounds ())
{
const Resolver::TraitReference *trait = bound.get ();
@@ -2515,7 +2579,7 @@ DynamicObjectType::get_object_items () const
if (item.get_trait_item_type ()
== Resolver::TraitItemReference::TraitItemType::FN
&& item.is_object_safe ())
- items.push_back (&item);
+ items.push_back ({&item, &bound});
}
for (auto &super_trait : trait->get_super_traits ())
@@ -2525,7 +2589,7 @@ DynamicObjectType::get_object_items () const
if (item.get_trait_item_type ()
== Resolver::TraitItemReference::TraitItemType::FN
&& item.is_object_safe ())
- items.push_back (&item);
+ items.push_back ({&item, &bound});
}
}
}
diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h
index c26e193..ae9ff67 100644
--- a/gcc/rust/typecheck/rust-tyty.h
+++ b/gcc/rust/typecheck/rust-tyty.h
@@ -166,12 +166,16 @@ public:
return parent == nullptr || trait_item_ref == nullptr;
}
- BaseType *get_tyty_for_receiver (const TyTy::BaseType *receiver);
+ BaseType *get_tyty_for_receiver (const TyTy::BaseType *receiver,
+ const HIR::GenericArgs *bound_args
+ = nullptr);
const Resolver::TraitItemReference *get_raw_item () const;
bool needs_implementation () const;
+ const TypeBoundPredicate *get_parent () const { return parent; }
+
private:
const TypeBoundPredicate *parent;
const Resolver::TraitItemReference *trait_item_ref;
@@ -340,7 +344,7 @@ public:
virtual bool is_unit () const { return false; }
- virtual bool is_concrete () const { return true; }
+ virtual bool is_concrete () const = 0;
TypeKind get_kind () const { return kind; }
@@ -470,7 +474,7 @@ public:
bool default_type (BaseType **type) const;
- bool is_concrete () const final override { return false; }
+ bool is_concrete () const final override { return true; }
private:
InferTypeKind infer_kind;
@@ -503,6 +507,8 @@ public:
BaseType *clone () const final override;
std::string get_name () const override final { return as_string (); }
+
+ bool is_concrete () const final override { return false; }
};
class SubstitutionArgumentMappings;
@@ -559,6 +565,11 @@ public:
return true;
}
+ bool is_concrete () const override final
+ {
+ return !contains_type_parameters ();
+ }
+
ParamType *handle_substitions (SubstitutionArgumentMappings mappings);
private:
@@ -587,6 +598,8 @@ public:
StructFieldType *clone () const;
+ bool is_concrete () const { return ty->is_concrete (); }
+
void debug () const { rust_debug ("%s", as_string ().c_str ()); }
private:
@@ -710,6 +723,8 @@ public:
return var.get_tyty ();
}
+ bool need_substitution () const;
+
private:
const HIR::TypeParam &generic;
ParamType *param;
@@ -743,8 +758,13 @@ public:
bool is_conrete () const
{
- return argument != nullptr && argument->get_kind () != TyTy::TypeKind::ERROR
- && argument->get_kind () != TyTy::TypeKind::PARAM;
+ if (argument != nullptr)
+ return true;
+
+ if (argument->get_kind () == TyTy::TypeKind::PARAM)
+ return false;
+
+ return argument->is_concrete ();
}
std::string as_string () const
@@ -898,16 +918,12 @@ public:
bool needs_substitution () const
{
- if (!has_substitutions ())
- return false;
-
- if (used_arguments.is_error ())
- return true;
-
- if (used_arguments.size () != get_num_substitutions ())
- return true;
-
- return !used_arguments.is_concrete ();
+ for (auto &sub : substitutions)
+ {
+ if (sub.need_substitution ())
+ return true;
+ }
+ return false;
}
bool was_substituted () const { return !needs_substitution (); }
@@ -973,6 +989,11 @@ public:
SubstitutionArgumentMappings solve_mappings_from_receiver_for_self (
SubstitutionArgumentMappings &mappings) const;
+ // TODO comment
+ SubstitutionArgumentMappings
+ solve_missing_mappings_from_this (SubstitutionRef &ref, SubstitutionRef &to);
+
+ // TODO comment
BaseType *infer_substitions (Location locus)
{
std::vector<SubstitutionArg> args;
@@ -1217,6 +1238,19 @@ public:
return identifier + subst_as_string ();
}
+ bool is_concrete () const override final
+ {
+ for (auto &variant : variants)
+ {
+ for (auto &field : variant->get_fields ())
+ {
+ if (!field->is_concrete ())
+ return false;
+ }
+ }
+ return true;
+ }
+
BaseType *clone () const final override;
bool needs_generic_substitutions () const override final
@@ -1349,6 +1383,17 @@ public:
return param_at (0).second;
}
+ bool is_concrete () const override final
+ {
+ for (const auto &param : params)
+ {
+ const BaseType *p = param.second;
+ if (!p->is_concrete ())
+ return false;
+ }
+ return get_return_type ()->is_concrete ();
+ }
+
std::vector<std::pair<HIR::Pattern *, BaseType *>> &get_params ()
{
return params;
@@ -1446,6 +1491,16 @@ public:
}
}
+ bool is_concrete () const override final
+ {
+ for (auto &p : params)
+ {
+ if (!p.get_tyty ()->is_concrete ())
+ return false;
+ }
+ return result_type.get_tyty ()->is_concrete ();
+ }
+
private:
std::vector<TyVar> params;
TyVar result_type;
@@ -1498,6 +1553,17 @@ public:
BaseType *clone () const final override;
+ bool is_concrete () const override final
+ {
+ for (auto &param : parameter_types)
+ {
+ auto p = param.get_tyty ();
+ if (!p->is_concrete ())
+ return false;
+ }
+ return result_type.get_tyty ()->is_concrete ();
+ }
+
bool needs_generic_substitutions () const override final
{
return needs_substitution ();
@@ -1591,6 +1657,7 @@ public:
BaseType *cast (BaseType *other) override;
BaseType *clone () const final override;
+ bool is_concrete () const override final { return true; }
};
class IntType : public BaseType
@@ -1632,6 +1699,7 @@ public:
BaseType *clone () const final override;
bool is_equal (const BaseType &other) const override;
+ bool is_concrete () const override final { return true; }
private:
IntKind int_kind;
@@ -1676,6 +1744,7 @@ public:
BaseType *clone () const final override;
bool is_equal (const BaseType &other) const override;
+ bool is_concrete () const override final { return true; }
private:
UintKind uint_kind;
@@ -1718,6 +1787,7 @@ public:
BaseType *clone () const final override;
bool is_equal (const BaseType &other) const override;
+ bool is_concrete () const override final { return true; }
private:
FloatKind float_kind;
@@ -1748,6 +1818,7 @@ public:
BaseType *cast (BaseType *other) override;
BaseType *clone () const final override;
+ bool is_concrete () const override final { return true; }
};
class ISizeType : public BaseType
@@ -1775,6 +1846,7 @@ public:
BaseType *cast (BaseType *other) override;
BaseType *clone () const final override;
+ bool is_concrete () const override final { return true; }
};
class CharType : public BaseType
@@ -1802,6 +1874,7 @@ public:
BaseType *cast (BaseType *other) override;
BaseType *clone () const final override;
+ bool is_concrete () const override final { return true; }
};
class ReferenceType : public BaseType
@@ -1841,6 +1914,11 @@ public:
return get_base ()->contains_type_parameters ();
}
+ bool is_concrete () const override final
+ {
+ return !contains_type_parameters ();
+ }
+
ReferenceType *handle_substitions (SubstitutionArgumentMappings mappings);
Mutability mutability () const { return mut; }
@@ -1889,6 +1967,11 @@ public:
return get_base ()->contains_type_parameters ();
}
+ bool is_concrete () const override final
+ {
+ return !contains_type_parameters ();
+ }
+
PointerType *handle_substitions (SubstitutionArgumentMappings mappings);
Mutability mutability () const { return mut; }
@@ -1929,6 +2012,7 @@ public:
bool is_equal (const BaseType &other) const override;
BaseType *clone () const final override;
+ bool is_concrete () const override final { return true; }
};
// https://doc.rust-lang.org/std/primitive.never.html
@@ -1968,6 +2052,7 @@ public:
std::string get_name () const override final { return as_string (); }
bool is_unit () const override { return true; }
+ bool is_concrete () const override final { return true; }
};
// used at the type in associated types in traits
@@ -2027,6 +2112,11 @@ public:
return resolve ()->contains_type_parameters ();
}
+ bool is_concrete () const override final
+ {
+ return !contains_type_parameters ();
+ }
+
private:
std::string symbol;
};
@@ -2092,6 +2182,11 @@ public:
return base->contains_type_parameters ();
}
+ bool is_concrete () const override final
+ {
+ return !contains_type_parameters ();
+ }
+
ProjectionType *
handle_substitions (SubstitutionArgumentMappings mappings) override final;
@@ -2132,8 +2227,11 @@ public:
std::string get_name () const override final;
+ bool is_concrete () const override final { return true; }
+
// this returns a flat list of items including super trait bounds
- const std::vector<const Resolver::TraitItemReference *>
+ const std::vector<
+ std::pair<const Resolver::TraitItemReference *, const TypeBoundPredicate *>>
get_object_items () const;
};
diff --git a/gcc/testsuite/rust/compile/torture/forward_decl_5.rs b/gcc/testsuite/rust/compile/torture/forward_decl_5.rs
new file mode 100644
index 0000000..73a47fe
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/forward_decl_5.rs
@@ -0,0 +1,19 @@
+pub fn main() {
+ let a;
+ a = foo { a: 123, b: 456f32 };
+
+ let mut a = 123;
+ a = bar(a);
+
+ let mut b = 456f32;
+ b = bar(b);
+
+ fn bar<T>(x: T) -> T {
+ x
+ }
+
+ struct foo {
+ a: i32,
+ b: f32,
+ };
+}
diff --git a/gcc/testsuite/rust/compile/traits10.rs b/gcc/testsuite/rust/compile/traits10.rs
index a4622b2..f8f551b 100644
--- a/gcc/testsuite/rust/compile/traits10.rs
+++ b/gcc/testsuite/rust/compile/traits10.rs
@@ -12,5 +12,4 @@ pub fn main() {
let b: &dyn Bar = &a;
// { dg-error "trait bound is not object safe" "" { target *-*-* } .-1 }
- // { dg-error "expected" "" { target *-*-* } .-2 }
}
diff --git a/gcc/testsuite/rust/compile/traits11.rs b/gcc/testsuite/rust/compile/traits11.rs
index bf69ff0..d06e47d 100644
--- a/gcc/testsuite/rust/compile/traits11.rs
+++ b/gcc/testsuite/rust/compile/traits11.rs
@@ -16,5 +16,4 @@ pub fn main() {
let b: &dyn B = &a;
// { dg-error "trait bound is not object safe" "" { target *-*-* } .-1 }
- // { dg-error "expected" "" { target *-*-* } .-2 }
}
diff --git a/gcc/testsuite/rust/execute/torture/trait12.rs b/gcc/testsuite/rust/execute/torture/trait12.rs
new file mode 100644
index 0000000..f14a966
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/trait12.rs
@@ -0,0 +1,41 @@
+/* { dg-output "3\n" } */
+extern "C" {
+ fn printf(s: *const i8, ...);
+}
+
+trait FnLike<A, R> {
+ fn call(&self, arg: A) -> R;
+ // { dg-warning "unused name .self." "" { target *-*-* } .-1 }
+ // { dg-warning "unused name .arg." "" { target *-*-* } .-2 }
+}
+
+type FnObject<'b> = dyn for<'a> FnLike<&'a isize, &'a isize> + 'b;
+
+struct Identity;
+
+impl<'a, T> FnLike<&'a T, &'a T> for Identity {
+ fn call(&self, arg: &'a T) -> &'a T {
+ // { dg-warning "unused name .self." "" { target *-*-* } .-1 }
+ // { dg-warning "unused name" "" { target *-*-* } .-2 }
+ arg
+ }
+}
+
+fn call_repeatedly(f: &FnObject) {
+ let x = 3;
+ let y = f.call(&x);
+
+ unsafe {
+ let a = "%i\n\0";
+ let b = a as *const str;
+ let c = b as *const i8;
+
+ printf(c, *y);
+ }
+}
+
+fn main() -> i32 {
+ call_repeatedly(&Identity);
+
+ 0
+}
diff --git a/gcc/testsuite/rust/execute/torture/trait13.rs b/gcc/testsuite/rust/execute/torture/trait13.rs
new file mode 100644
index 0000000..76fb09c
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/trait13.rs
@@ -0,0 +1,50 @@
+/* { dg-output "123\n456\n" } */
+extern "C" {
+ fn printf(s: *const i8, ...);
+}
+
+struct Foo(i32);
+trait Bar {
+ fn baz(&self);
+ // { dg-warning "unused name" "" { target *-*-* } .-1 }
+
+ fn qux(&self) {
+ // { dg-warning "unused name" "" { target *-*-* } .-1 }
+ unsafe {
+ let a = "%i\n\0";
+ let b = a as *const str;
+ let c = b as *const i8;
+
+ printf(c, 456);
+ }
+ }
+}
+
+impl Bar for Foo {
+ fn baz(&self) {
+ // { dg-warning "unused name" "" { target *-*-* } .-1 }
+ unsafe {
+ let a = "%i\n\0";
+ let b = a as *const str;
+ let c = b as *const i8;
+
+ printf(c, self.0);
+ }
+ }
+}
+
+fn dynamic_dispatch(t: &dyn Bar) {
+ t.baz();
+ t.qux();
+}
+
+fn main() -> i32 {
+ let a;
+ a = Foo(123);
+
+ let b: &dyn Bar;
+ b = &a;
+ dynamic_dispatch(b);
+
+ 0
+}