aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPhilip Herron <philip.herron@embecosm.com>2021-08-17 17:28:15 +0100
committerPhilip Herron <philip.herron@embecosm.com>2021-08-19 15:39:21 +0100
commit1dc718474044149ec1aa6bee9ea8e83d778f17f2 (patch)
tree688bcd5d3a550681afaa87b90c848f365d425bcb /gcc
parentc25cdc84600e81bfd4d1ae104ff9eb524f7c49f0 (diff)
downloadgcc-1dc718474044149ec1aa6bee9ea8e83d778f17f2.zip
gcc-1dc718474044149ec1aa6bee9ea8e83d778f17f2.tar.gz
gcc-1dc718474044149ec1aa6bee9ea8e83d778f17f2.tar.bz2
optional trait item with associated types
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/Make-lang.in1
-rw-r--r--gcc/rust/backend/rust-compile-context.h7
-rw-r--r--gcc/rust/backend/rust-compile-implitem.h8
-rw-r--r--gcc/rust/backend/rust-compile-resolve-path.cc49
-rw-r--r--gcc/rust/typecheck/rust-hir-path-probe.h47
-rw-r--r--gcc/rust/typecheck/rust-hir-trait-ref.h45
-rw-r--r--gcc/rust/typecheck/rust-hir-trait-resolve.cc75
-rw-r--r--gcc/rust/typecheck/rust-hir-type-bounds.h11
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-expr.h17
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-implitem.h3
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-item.h13
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-util.cc41
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-util.h216
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check.h71
-rw-r--r--gcc/rust/typecheck/rust-tyty-bounds.cc10
-rw-r--r--gcc/rust/typecheck/rust-tyty-cmp.h60
-rw-r--r--gcc/rust/typecheck/rust-tyty-rules.h41
-rw-r--r--gcc/rust/typecheck/rust-tyty.cc74
-rw-r--r--gcc/rust/typecheck/rust-tyty.h25
-rw-r--r--gcc/testsuite/rust/compile/torture/traits11.rs32
20 files changed, 756 insertions, 90 deletions
diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index 0d0ca1d..7ed380e 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -80,6 +80,7 @@ GRS_OBJS = \
rust/rust-tyty.o \
rust/rust-tyctx.o \
rust/rust-tyty-bounds.o \
+ rust/rust-hir-type-check-util.o \
rust/rust-hir-trait-resolve.o \
rust/rust-hir-const-fold.o \
rust/rust-lint-marklive.o \
diff --git a/gcc/rust/backend/rust-compile-context.h b/gcc/rust/backend/rust-compile-context.h
index 8a3d413..6356ccc 100644
--- a/gcc/rust/backend/rust-compile-context.h
+++ b/gcc/rust/backend/rust-compile-context.h
@@ -336,10 +336,13 @@ public:
void visit (TyTy::InferType &) override { gcc_unreachable (); }
- void visit (TyTy::PlaceholderType &) override { gcc_unreachable (); }
-
void visit (TyTy::ProjectionType &) override { gcc_unreachable (); }
+ void visit (TyTy::PlaceholderType &type) override
+ {
+ type.resolve ()->accept_vis (*this);
+ }
+
void visit (TyTy::ParamType &param) override
{
param.resolve ()->accept_vis (*this);
diff --git a/gcc/rust/backend/rust-compile-implitem.h b/gcc/rust/backend/rust-compile-implitem.h
index e446cf9..809cf56 100644
--- a/gcc/rust/backend/rust-compile-implitem.h
+++ b/gcc/rust/backend/rust-compile-implitem.h
@@ -319,15 +319,17 @@ public:
// 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.
Bfunction *lookup = nullptr;
- if (ctx->lookup_function_decl (fntype->get_ty_ref (), &lookup, fntype))
+ if (ctx->lookup_function_decl (fntype->get_ty_ref (), &lookup))
{
// has this been added to the list then it must be finished
if (ctx->function_completed (lookup))
{
Bfunction *dummy = nullptr;
if (!ctx->lookup_function_decl (fntype->get_ty_ref (), &dummy))
- ctx->insert_function_decl (fntype->get_ty_ref (), lookup, fntype);
-
+ {
+ ctx->insert_function_decl (fntype->get_ty_ref (), lookup,
+ fntype);
+ }
return;
}
}
diff --git a/gcc/rust/backend/rust-compile-resolve-path.cc b/gcc/rust/backend/rust-compile-resolve-path.cc
index 97ba15d..1b892d2 100644
--- a/gcc/rust/backend/rust-compile-resolve-path.cc
+++ b/gcc/rust/backend/rust-compile-resolve-path.cc
@@ -76,6 +76,7 @@ ResolvePathRef::visit (HIR::PathInExpression &expr)
&lookup);
rust_assert (ok);
rust_assert (lookup->get_kind () == TyTy::TypeKind::FNDEF);
+ TyTy::FnType *fntype = static_cast<TyTy::FnType *> (lookup);
Bfunction *fn = nullptr;
if (!ctx->lookup_function_decl (lookup->get_ty_ref (), &fn))
@@ -145,28 +146,32 @@ ResolvePathRef::visit (HIR::PathInExpression &expr)
rust_assert (
trait_item_ref->is_optional ()); // has definition
- // FIXME
- // TyTy::BaseType *self_type = nullptr;
- // if (!ctx->get_tyctx ()->lookup_type (
- // expr.get_receiver ()->get_mappings ().get_hirid (),
- // &self_type))
- // {
- // rust_error_at (expr.get_locus (),
- // "failed to resolve type for self param");
- // return;
- // }
-
- // CompileTraitItem::Compile (
- // self_type, trait_item_ref->get_hir_trait_item (), ctx,
- // fntype);
- // if (!ctx->lookup_function_decl (fntype->get_ty_ref (),
- // &fn))
- // {
- // translated = ctx->get_backend ()->error_expression ();
- // rust_error_at (expr.get_locus (),
- // "forward declaration was not compiled");
- // return;
- // }
+ Analysis::NodeMapping trait_mappings
+ = trait_item_ref->get_parent_trait_mappings ();
+ auto associated_impl_id
+ = ctx->get_tyctx ()
+ ->lookup_associated_impl_mapping_for_self (
+ trait_mappings.get_hirid (), receiver);
+ rust_assert (associated_impl_id != UNKNOWN_HIRID);
+
+ 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 ();
+
+ CompileTraitItem::Compile (
+ receiver, trait_item_ref->get_hir_trait_item (), ctx,
+ fntype);
+
+ if (!ctx->lookup_function_decl (fntype->get_ty_ref (), &fn))
+ {
+ resolved = ctx->get_backend ()->error_expression ();
+ rust_error_at (expr.get_locus (),
+ "forward declaration was not compiled");
+ return;
+ }
}
else
{
diff --git a/gcc/rust/typecheck/rust-hir-path-probe.h b/gcc/rust/typecheck/rust-hir-path-probe.h
index 22b1074..f737141 100644
--- a/gcc/rust/typecheck/rust-hir-path-probe.h
+++ b/gcc/rust/typecheck/rust-hir-path-probe.h
@@ -51,6 +51,7 @@ struct PathProbeCandidate
{
const TraitReference *trait_ref;
const TraitItemReference *item_ref;
+ HIR::ImplBlock *impl;
};
CandidateType type;
@@ -128,19 +129,22 @@ public:
if (!probe_bounds)
return probe.candidates;
- std::vector<TraitReference *> probed_bounds
+ std::vector<std::pair<TraitReference *, HIR::ImplBlock *>> probed_bounds
= TypeBoundsProbe::Probe (receiver);
- std::vector<const TraitReference *> specified_bounds;
+ std::vector<std::pair<const TraitReference *, HIR::ImplBlock *>>
+ specified_bounds;
for (const TyTy::TypeBoundPredicate &predicate :
receiver->get_specified_bounds ())
{
const TraitReference *trait_item = predicate.get ();
- specified_bounds.push_back (trait_item);
+
+ // FIXME lookup impl_block for this trait impl for this receiver
+ specified_bounds.push_back ({trait_item, nullptr});
}
- std::vector<const TraitReference *> union_type_bounds
- = probe.union_bounds (probed_bounds, specified_bounds);
+ std::vector<std::pair<const TraitReference *, HIR::ImplBlock *>>
+ union_type_bounds = probe.union_bounds (probed_bounds, specified_bounds);
probe.process_traits_for_candidates (union_type_bounds,
ignore_mandatory_trait_items);
return probe.candidates;
@@ -230,11 +234,15 @@ private:
}
void process_traits_for_candidates (
- const std::vector<const TraitReference *> traits,
+ const std::vector<std::pair<const TraitReference *, HIR::ImplBlock *>>
+ traits,
bool ignore_mandatory_trait_items)
{
- for (const TraitReference *trait_ref : traits)
+ for (auto &ref : traits)
{
+ const TraitReference *trait_ref = ref.first;
+ HIR::ImplBlock *impl = ref.second;
+
const TraitItemReference *trait_item_ref = nullptr;
if (!trait_ref->lookup_trait_item (search.as_string (),
&trait_item_ref))
@@ -296,7 +304,7 @@ private:
}
PathProbeCandidate::TraitItemCandidate trait_item_candidate{
- trait_ref, trait_item_ref};
+ trait_ref, trait_item_ref, impl};
PathProbeCandidate candidate{candidate_type,
trait_item_tyty,
trait_ref->get_locus (),
@@ -312,24 +320,27 @@ private:
current_impl (nullptr)
{}
- std::vector<const TraitReference *>
- union_bounds (const std::vector</*const*/ TraitReference *> a,
- const std::vector<const TraitReference *> b) const
+ std::vector<std::pair<const TraitReference *, HIR::ImplBlock *>>
+ union_bounds (
+ const std::vector<std::pair</*const*/ TraitReference *, HIR::ImplBlock *>>
+ a,
+ const std::vector<std::pair<const TraitReference *, HIR::ImplBlock *>> b)
+ const
{
- std::map<DefId, const TraitReference *> mapper;
- for (const TraitReference *ref : a)
+ std::map<DefId, std::pair<const TraitReference *, HIR::ImplBlock *>> mapper;
+ for (auto &ref : a)
{
- mapper.insert ({ref->get_mappings ().get_defid (), ref});
+ mapper.insert ({ref.first->get_mappings ().get_defid (), ref});
}
- for (const TraitReference *ref : b)
+ for (auto &ref : b)
{
- mapper.insert ({ref->get_mappings ().get_defid (), ref});
+ mapper.insert ({ref.first->get_mappings ().get_defid (), ref});
}
- std::vector<const TraitReference *> union_set;
+ std::vector<std::pair<const TraitReference *, HIR::ImplBlock *>> union_set;
for (auto it = mapper.begin (); it != mapper.end (); it++)
{
- union_set.push_back (it->second);
+ union_set.push_back ({it->second.first, it->second.second});
}
return union_set;
}
diff --git a/gcc/rust/typecheck/rust-hir-trait-ref.h b/gcc/rust/typecheck/rust-hir-trait-ref.h
index 718b3ce..2c7a0e8 100644
--- a/gcc/rust/typecheck/rust-hir-trait-ref.h
+++ b/gcc/rust/typecheck/rust-hir-trait-ref.h
@@ -21,6 +21,7 @@
#include "rust-hir-full.h"
#include "rust-tyty-visitor.h"
+#include "rust-hir-type-check-util.h"
namespace Rust {
namespace Resolver {
@@ -148,6 +149,8 @@ public:
return get_error ();
}
+ Analysis::NodeMapping get_parent_trait_mappings () const;
+
// this is called when the trait is completed resolution and gives the items a
// chance to run their specific type resolution passes. If we call their
// resolution on construction it can lead to a case where the trait being
@@ -155,6 +158,10 @@ public:
// the trait will not be stored in its own map yet
void on_resolved ();
+ void associated_type_set (TyTy::BaseType *ty);
+
+ void associated_type_reset ();
+
private:
TyTy::ErrorType *get_error () const
{
@@ -186,6 +193,7 @@ private:
Resolver::TypeCheckContext *context;
};
+// this wraps up the HIR::Trait so we can do analysis on it
class TraitReference
{
public:
@@ -316,11 +324,48 @@ public:
}
}
+ void clear_associated_types ()
+ {
+ for (auto &item : item_refs)
+ {
+ bool is_assoc_type = item.get_trait_item_type ()
+ == TraitItemReference::TraitItemType::TYPE;
+ if (is_assoc_type)
+ item.associated_type_reset ();
+ }
+ }
+
private:
const HIR::Trait *hir_trait_ref;
std::vector<TraitItemReference> item_refs;
};
+class AssociatedImplTrait
+{
+public:
+ AssociatedImplTrait (TraitReference *trait, HIR::ImplBlock *impl,
+ TyTy::BaseType *self,
+ Resolver::TypeCheckContext *context)
+ : trait (trait), impl (impl), self (self), context (context)
+ {}
+
+ TraitReference *get_trait () { return trait; }
+
+ HIR::ImplBlock *get_impl_block () { return impl; }
+
+ TyTy::BaseType *get_self () { return self; }
+
+ void setup_associated_types ();
+
+ void reset_associated_types ();
+
+private:
+ TraitReference *trait;
+ HIR::ImplBlock *impl;
+ TyTy::BaseType *self;
+ Resolver::TypeCheckContext *context;
+};
+
} // namespace Resolver
} // namespace Rust
diff --git a/gcc/rust/typecheck/rust-hir-trait-resolve.cc b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
index d760709..5d7c71e 100644
--- a/gcc/rust/typecheck/rust-hir-trait-resolve.cc
+++ b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
@@ -25,10 +25,6 @@ namespace Resolver {
void
ResolveTraitItemToRef::visit (HIR::TraitItemType &type)
{
- TyTy::BaseType *ty
- = new TyTy::PlaceholderType (type.get_mappings ().get_hirid ());
- context->insert_type (type.get_mappings (), ty);
-
// create trait-item-ref
Location locus = type.get_locus ();
bool is_optional = false;
@@ -92,7 +88,10 @@ TraitItemReference::on_resolved ()
void
TraitItemReference::resolve_item (HIR::TraitItemType &type)
{
- // TODO
+ TyTy::BaseType *ty
+ = new TyTy::PlaceholderType (type.get_name (),
+ type.get_mappings ().get_hirid ());
+ context->insert_type (type.get_mappings (), ty);
}
void
@@ -128,5 +127,71 @@ TraitItemReference::resolve_item (HIR::TraitItemFunc &func)
expected_ret_tyty->unify (block_expr_ty);
}
+void
+TraitItemReference::associated_type_set (TyTy::BaseType *ty)
+{
+ rust_assert (get_trait_item_type () == TraitItemType::TYPE);
+
+ TyTy::BaseType *item_ty = get_tyty ();
+ rust_assert (item_ty->get_kind () == TyTy::TypeKind::PLACEHOLDER);
+ TyTy::PlaceholderType *placeholder
+ = static_cast<TyTy::PlaceholderType *> (item_ty);
+
+ placeholder->set_associated_type (ty->get_ref ());
+}
+
+void
+TraitItemReference::associated_type_reset ()
+{
+ rust_assert (get_trait_item_type () == TraitItemType::TYPE);
+
+ TyTy::BaseType *item_ty = get_tyty ();
+ rust_assert (item_ty->get_kind () == TyTy::TypeKind::PLACEHOLDER);
+ TyTy::PlaceholderType *placeholder
+ = static_cast<TyTy::PlaceholderType *> (item_ty);
+
+ placeholder->clear_associated_type ();
+}
+
+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::reset_associated_types ()
+{
+ trait->clear_associated_types ();
+}
+
+Analysis::NodeMapping
+TraitItemReference::get_parent_trait_mappings () const
+{
+ auto mappings = Analysis::Mappings::get ();
+
+ HIR::Trait *trait
+ = mappings->lookup_trait_item_mapping (get_mappings ().get_hirid ());
+ rust_assert (trait != nullptr);
+
+ return trait->get_mappings ();
+}
+
} // namespace Resolver
} // namespace Rust
diff --git a/gcc/rust/typecheck/rust-hir-type-bounds.h b/gcc/rust/typecheck/rust-hir-type-bounds.h
index 2c06134..1ba6049 100644
--- a/gcc/rust/typecheck/rust-hir-type-bounds.h
+++ b/gcc/rust/typecheck/rust-hir-type-bounds.h
@@ -31,7 +31,8 @@ class TypeBoundsProbe : public TypeCheckBase
using Rust::Resolver::TypeCheckBase::visit;
public:
- static std::vector<TraitReference *> Probe (const TyTy::BaseType *receiver)
+ static std::vector<std::pair<TraitReference *, HIR::ImplBlock *>>
+ Probe (const TyTy::BaseType *receiver)
{
TypeBoundsProbe probe (receiver);
probe.scan ();
@@ -41,9 +42,11 @@ public:
static bool is_bound_satisfied_for_type (TyTy::BaseType *receiver,
TraitReference *ref)
{
- std::vector<TraitReference *> bounds = Probe (receiver);
- for (TraitReference *b : bounds)
+ std::vector<std::pair<TraitReference *, HIR::ImplBlock *>> bounds
+ = Probe (receiver);
+ for (auto &bound : bounds)
{
+ TraitReference *b = bound.first;
if (b == ref)
return true;
}
@@ -59,7 +62,7 @@ private:
{}
const TyTy::BaseType *receiver;
- std::vector<TraitReference *> trait_references;
+ std::vector<std::pair<TraitReference *, HIR::ImplBlock *>> trait_references;
};
} // namespace Resolver
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h
index d82b5c7..0ac60c2 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h
@@ -975,7 +975,6 @@ public:
}
// TODO self and generic arguments
-
infered = trait_item_ref->get_tyty ();
rust_debug_loc (expr.get_locus (), "resolved to:");
infered->debug ();
@@ -1370,6 +1369,22 @@ private:
{
resolved_node_id
= candidate.item.trait.item_ref->get_mappings ().get_nodeid ();
+
+ // lookup the associated-impl-trait
+ HIR::ImplBlock *impl = candidate.item.trait.impl;
+ if (impl != nullptr)
+ {
+ AssociatedImplTrait *lookup_associated = nullptr;
+ bool found_impl_trait = context->lookup_associated_trait_impl (
+ impl->get_mappings ().get_hirid (), &lookup_associated);
+ rust_assert (found_impl_trait);
+
+ lookup_associated->setup_associated_types ();
+
+ // we need a new ty_ref_id for this trait item
+ tyseg = tyseg->clone ();
+ tyseg->set_ty_ref (mappings->get_next_hir_id ());
+ }
}
if (seg.has_generic_args ())
diff --git a/gcc/rust/typecheck/rust-hir-type-check-implitem.h b/gcc/rust/typecheck/rust-hir-type-check-implitem.h
index 65088be..3d83523 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-implitem.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-implitem.h
@@ -383,8 +383,7 @@ public:
trait_reference.get_name ().c_str ());
}
- context->insert_type (resolved_trait_item.get_mappings (),
- lookup->clone ());
+ resolved_trait_item.associated_type_set (lookup);
}
void visit (HIR::Function &function) override
diff --git a/gcc/rust/typecheck/rust-hir-type-check-item.h b/gcc/rust/typecheck/rust-hir-type-check-item.h
index 372171f..72da26d 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-item.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-item.h
@@ -123,6 +123,19 @@ public:
trait_reference->get_name ().c_str ());
}
}
+
+ if (is_trait_impl_block)
+ {
+ trait_reference->clear_associated_types ();
+
+ AssociatedImplTrait associated (trait_reference, &impl_block, self,
+ context);
+ context->insert_associated_trait_impl (
+ impl_block.get_mappings ().get_hirid (), std::move (associated));
+ context->insert_associated_impl_mapping (
+ trait_reference->get_mappings ().get_hirid (), self,
+ impl_block.get_mappings ().get_hirid ());
+ }
}
void visit (HIR::Function &function) override
diff --git a/gcc/rust/typecheck/rust-hir-type-check-util.cc b/gcc/rust/typecheck/rust-hir-type-check-util.cc
new file mode 100644
index 0000000..82bd081
--- /dev/null
+++ b/gcc/rust/typecheck/rust-hir-type-check-util.cc
@@ -0,0 +1,41 @@
+// Copyright (C) 2021 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include "rust-hir-type-check-util.h"
+#include "rust-hir-full.h"
+
+namespace Rust {
+namespace Resolver {
+
+void
+ImplTypeIterator::go ()
+{
+ for (auto &item : impl.get_impl_items ())
+ {
+ item->accept_vis (*this);
+ }
+}
+
+void
+ImplTypeIterator::visit (HIR::TypeAlias &alias)
+{
+ cb (alias);
+}
+
+} // namespace Resolver
+} // namespace Rust
diff --git a/gcc/rust/typecheck/rust-hir-type-check-util.h b/gcc/rust/typecheck/rust-hir-type-check-util.h
new file mode 100644
index 0000000..0ba07a1
--- /dev/null
+++ b/gcc/rust/typecheck/rust-hir-type-check-util.h
@@ -0,0 +1,216 @@
+// Copyright (C) 2021 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#ifndef RUST_HIR_TYPE_CHECK_UTIL_H
+#define RUST_HIR_TYPE_CHECK_UTIL_H
+
+#include <functional>
+#include "rust-hir-visitor.h"
+
+namespace Rust {
+namespace Resolver {
+
+class SimpleHirVisitor : public HIR::HIRVisitor
+{
+public:
+ virtual ~SimpleHirVisitor () {}
+
+ virtual void visit (HIR::IdentifierExpr &) override {}
+ virtual void visit (HIR::Lifetime &) override {}
+ virtual void visit (HIR::LifetimeParam &) override {}
+ virtual void visit (HIR::PathInExpression &) override {}
+ virtual void visit (HIR::TypePathSegment &) override {}
+ virtual void visit (HIR::TypePathSegmentGeneric &) override {}
+ virtual void visit (HIR::TypePathSegmentFunction &) override {}
+ virtual void visit (HIR::TypePath &) override {}
+ virtual void visit (HIR::QualifiedPathInExpression &) override {}
+ virtual void visit (HIR::QualifiedPathInType &) override {}
+
+ virtual void visit (HIR::LiteralExpr &) override {}
+ virtual void visit (HIR::BorrowExpr &) override {}
+ virtual void visit (HIR::DereferenceExpr &) override {}
+ virtual void visit (HIR::ErrorPropagationExpr &) override {}
+ virtual void visit (HIR::NegationExpr &) override {}
+ virtual void visit (HIR::ArithmeticOrLogicalExpr &) override {}
+ virtual void visit (HIR::ComparisonExpr &) override {}
+ virtual void visit (HIR::LazyBooleanExpr &) override {}
+ virtual void visit (HIR::TypeCastExpr &) override {}
+ virtual void visit (HIR::AssignmentExpr &) override {}
+
+ virtual void visit (HIR::GroupedExpr &) override {}
+
+ virtual void visit (HIR::ArrayElemsValues &) override {}
+ virtual void visit (HIR::ArrayElemsCopied &) override {}
+ virtual void visit (HIR::ArrayExpr &) override {}
+ virtual void visit (HIR::ArrayIndexExpr &) override {}
+ virtual void visit (HIR::TupleExpr &) override {}
+ virtual void visit (HIR::TupleIndexExpr &) override {}
+ virtual void visit (HIR::StructExprStruct &) override {}
+
+ virtual void visit (HIR::StructExprFieldIdentifier &) override {}
+ virtual void visit (HIR::StructExprFieldIdentifierValue &) override {}
+
+ virtual void visit (HIR::StructExprFieldIndexValue &) override {}
+ virtual void visit (HIR::StructExprStructFields &) override {}
+ virtual void visit (HIR::StructExprStructBase &) override {}
+ virtual void visit (HIR::StructExprTuple &) override {}
+ virtual void visit (HIR::StructExprUnit &) override {}
+
+ virtual void visit (HIR::EnumExprFieldIdentifier &) override {}
+ virtual void visit (HIR::EnumExprFieldIdentifierValue &) override {}
+
+ virtual void visit (HIR::EnumExprFieldIndexValue &) override {}
+ virtual void visit (HIR::EnumExprStruct &) override {}
+ virtual void visit (HIR::EnumExprTuple &) override {}
+ virtual void visit (HIR::EnumExprFieldless &) override {}
+ virtual void visit (HIR::CallExpr &) override {}
+ virtual void visit (HIR::MethodCallExpr &) override {}
+ virtual void visit (HIR::FieldAccessExpr &) override {}
+ virtual void visit (HIR::ClosureExprInner &) override {}
+ virtual void visit (HIR::BlockExpr &) override {}
+ virtual void visit (HIR::ClosureExprInnerTyped &) override {}
+ virtual void visit (HIR::ContinueExpr &) override {}
+ virtual void visit (HIR::BreakExpr &) override {}
+ virtual void visit (HIR::RangeFromToExpr &) override {}
+ virtual void visit (HIR::RangeFromExpr &) override {}
+ virtual void visit (HIR::RangeToExpr &) override {}
+ virtual void visit (HIR::RangeFullExpr &) override {}
+ virtual void visit (HIR::RangeFromToInclExpr &) override {}
+ virtual void visit (HIR::RangeToInclExpr &) override {}
+ virtual void visit (HIR::ReturnExpr &) override {}
+ virtual void visit (HIR::UnsafeBlockExpr &) override {}
+ virtual void visit (HIR::LoopExpr &) override {}
+ virtual void visit (HIR::WhileLoopExpr &) override {}
+ virtual void visit (HIR::WhileLetLoopExpr &) override {}
+ virtual void visit (HIR::ForLoopExpr &) override {}
+ virtual void visit (HIR::IfExpr &) override {}
+ virtual void visit (HIR::IfExprConseqElse &) override {}
+ virtual void visit (HIR::IfExprConseqIf &) override {}
+ virtual void visit (HIR::IfExprConseqIfLet &) override {}
+ virtual void visit (HIR::IfLetExpr &) override {}
+ virtual void visit (HIR::IfLetExprConseqElse &) override {}
+ virtual void visit (HIR::IfLetExprConseqIf &) override {}
+ virtual void visit (HIR::IfLetExprConseqIfLet &) override {}
+
+ virtual void visit (HIR::MatchExpr &) override {}
+ virtual void visit (HIR::AwaitExpr &) override {}
+ virtual void visit (HIR::AsyncBlockExpr &) override {}
+
+ virtual void visit (HIR::TypeParam &) override {}
+
+ virtual void visit (HIR::LifetimeWhereClauseItem &) override {}
+ virtual void visit (HIR::TypeBoundWhereClauseItem &) override {}
+ virtual void visit (HIR::ModuleBodied &) override {}
+ virtual void visit (HIR::ModuleNoBody &) override {}
+ virtual void visit (HIR::ExternCrate &) override {}
+
+ virtual void visit (HIR::UseTreeGlob &) override {}
+ virtual void visit (HIR::UseTreeList &) override {}
+ virtual void visit (HIR::UseTreeRebind &) override {}
+ virtual void visit (HIR::UseDeclaration &) override {}
+ virtual void visit (HIR::Function &) override {}
+ virtual void visit (HIR::TypeAlias &) override {}
+ virtual void visit (HIR::StructStruct &) override {}
+ virtual void visit (HIR::TupleStruct &) override {}
+ virtual void visit (HIR::EnumItem &) override {}
+ virtual void visit (HIR::EnumItemTuple &) override {}
+ virtual void visit (HIR::EnumItemStruct &) override {}
+ virtual void visit (HIR::EnumItemDiscriminant &) override {}
+ virtual void visit (HIR::Enum &) override {}
+ virtual void visit (HIR::Union &) override {}
+ virtual void visit (HIR::ConstantItem &) override {}
+ virtual void visit (HIR::StaticItem &) override {}
+ virtual void visit (HIR::TraitItemFunc &) override {}
+ virtual void visit (HIR::TraitItemConst &) override {}
+ virtual void visit (HIR::TraitItemType &) override {}
+ virtual void visit (HIR::Trait &) override {}
+ virtual void visit (HIR::ImplBlock &) override {}
+
+ virtual void visit (HIR::ExternalStaticItem &) override {}
+ virtual void visit (HIR::ExternalFunctionItem &) override {}
+ virtual void visit (HIR::ExternBlock &) override {}
+
+ virtual void visit (HIR::LiteralPattern &) override {}
+ virtual void visit (HIR::IdentifierPattern &) override {}
+ virtual void visit (HIR::WildcardPattern &) override {}
+
+ virtual void visit (HIR::RangePatternBoundLiteral &) override {}
+ virtual void visit (HIR::RangePatternBoundPath &) override {}
+ virtual void visit (HIR::RangePatternBoundQualPath &) override {}
+ virtual void visit (HIR::RangePattern &) override {}
+ virtual void visit (HIR::ReferencePattern &) override {}
+
+ virtual void visit (HIR::StructPatternFieldTuplePat &) override {}
+ virtual void visit (HIR::StructPatternFieldIdentPat &) override {}
+ virtual void visit (HIR::StructPatternFieldIdent &) override {}
+ virtual void visit (HIR::StructPattern &) override {}
+
+ virtual void visit (HIR::TupleStructItemsNoRange &) override {}
+ virtual void visit (HIR::TupleStructItemsRange &) override {}
+ virtual void visit (HIR::TupleStructPattern &) override {}
+
+ virtual void visit (HIR::TuplePatternItemsMultiple &) override {}
+ virtual void visit (HIR::TuplePatternItemsRanged &) override {}
+ virtual void visit (HIR::TuplePattern &) override {}
+ virtual void visit (HIR::GroupedPattern &) override {}
+ virtual void visit (HIR::SlicePattern &) override {}
+
+ virtual void visit (HIR::EmptyStmt &) override {}
+ virtual void visit (HIR::LetStmt &) override {}
+ virtual void visit (HIR::ExprStmtWithoutBlock &) override {}
+ virtual void visit (HIR::ExprStmtWithBlock &) override {}
+
+ virtual void visit (HIR::TraitBound &) override {}
+ virtual void visit (HIR::ImplTraitType &) override {}
+ 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 {}
+ virtual void visit (HIR::ReferenceType &) override {}
+ virtual void visit (HIR::ArrayType &) override {}
+ virtual void visit (HIR::SliceType &) override {}
+ virtual void visit (HIR::InferredType &) override {}
+ virtual void visit (HIR::BareFunctionType &) override {}
+};
+
+class ImplTypeIterator : public SimpleHirVisitor
+{
+ using SimpleHirVisitor::visit;
+
+public:
+ ImplTypeIterator (HIR::ImplBlock &impl,
+ std::function<void (HIR::TypeAlias &alias)> cb)
+ : impl (impl), cb (cb)
+ {}
+
+ void go ();
+
+ void visit (HIR::TypeAlias &alias) override;
+
+private:
+ HIR::ImplBlock &impl;
+ std::function<void (HIR::TypeAlias &alias)> cb;
+};
+
+} // namespace Resolver
+} // namespace Rust
+
+#endif // RUST_HIR_TYPE_CHECK_UTIL_H
diff --git a/gcc/rust/typecheck/rust-hir-type-check.h b/gcc/rust/typecheck/rust-hir-type-check.h
index d834ad8..27b7f12 100644
--- a/gcc/rust/typecheck/rust-hir-type-check.h
+++ b/gcc/rust/typecheck/rust-hir-type-check.h
@@ -117,6 +117,70 @@ public:
return true;
}
+ void insert_associated_trait_impl (HirId id, AssociatedImplTrait &&associated)
+ {
+ rust_assert (associated_impl_traits.find (id)
+ == associated_impl_traits.end ());
+ associated_impl_traits.emplace (id, std::move (associated));
+ }
+
+ bool lookup_associated_trait_impl (HirId id, AssociatedImplTrait **associated)
+ {
+ auto it = associated_impl_traits.find (id);
+ if (it == associated_impl_traits.end ())
+ return false;
+
+ *associated = &it->second;
+ return true;
+ }
+
+ void insert_associated_type_mapping (HirId id, HirId mapping)
+ {
+ associated_type_mappings[id] = mapping;
+ }
+
+ void clear_associated_type_mapping (HirId id)
+ {
+ associated_type_mappings[id] = UNKNOWN_HIRID;
+ }
+
+ HirId lookup_associated_type_mapping (HirId id, HirId default_value)
+ {
+ auto it = associated_type_mappings.find (id);
+ if (it == associated_type_mappings.end ())
+ return default_value;
+
+ return it->second;
+ }
+
+ void insert_associated_impl_mapping (HirId trait_id,
+ const TyTy::BaseType *impl_type,
+ HirId impl_id)
+ {
+ auto it = associated_traits_to_impls.find (trait_id);
+ if (it == associated_traits_to_impls.end ())
+ {
+ associated_traits_to_impls[trait_id] = {};
+ }
+
+ associated_traits_to_impls[trait_id].push_back ({impl_type, impl_id});
+ }
+
+ HirId lookup_associated_impl_mapping_for_self (HirId trait_id,
+ const TyTy::BaseType *self)
+ {
+ auto it = associated_traits_to_impls.find (trait_id);
+ if (it == associated_traits_to_impls.end ())
+ return UNKNOWN_HIRID;
+
+ for (auto &item : it->second)
+ {
+ if (item.first->can_eq (self, false))
+ return item.second;
+ }
+ return UNKNOWN_HIRID;
+ }
+
private:
TypeCheckContext ();
@@ -127,6 +191,13 @@ private:
std::vector<TyTy::BaseType *> loop_type_stack;
std::map<DefId, TraitReference> trait_context;
std::map<HirId, TyTy::BaseType *> receiver_context;
+ std::map<HirId, AssociatedImplTrait> associated_impl_traits;
+
+ // trait-id -> list of < self-tyty:impl-id>
+ std::map<HirId, std::vector<std::pair<const TyTy::BaseType *, HirId>>>
+ associated_traits_to_impls;
+
+ std::map<HirId, HirId> associated_type_mappings;
};
class TypeResolution
diff --git a/gcc/rust/typecheck/rust-tyty-bounds.cc b/gcc/rust/typecheck/rust-tyty-bounds.cc
index 008dc19..1bd7865 100644
--- a/gcc/rust/typecheck/rust-tyty-bounds.cc
+++ b/gcc/rust/typecheck/rust-tyty-bounds.cc
@@ -25,7 +25,8 @@ namespace Resolver {
void
TypeBoundsProbe::scan ()
{
- std::vector<HIR::TypePath *> possible_trait_paths;
+ std::vector<std::pair<HIR::TypePath *, HIR::ImplBlock *>>
+ possible_trait_paths;
mappings->iterate_impl_blocks (
[&] (HirId id, HIR::ImplBlock *impl) mutable -> bool {
// we are filtering for trait-impl-blocks
@@ -42,16 +43,17 @@ TypeBoundsProbe::scan ()
if (!receiver->can_eq (impl_type, false))
return true;
- possible_trait_paths.push_back (impl->get_trait_ref ().get ());
+ possible_trait_paths.push_back ({impl->get_trait_ref ().get (), impl});
return true;
});
- for (auto &trait_path : possible_trait_paths)
+ for (auto &path : possible_trait_paths)
{
+ HIR::TypePath *trait_path = path.first;
TraitReference *trait_ref = TraitResolver::Resolve (*trait_path);
if (!trait_ref->is_error ())
- trait_references.push_back (trait_ref);
+ trait_references.push_back ({trait_ref, path.second});
}
}
diff --git a/gcc/rust/typecheck/rust-tyty-cmp.h b/gcc/rust/typecheck/rust-tyty-cmp.h
index 6801084..100e384 100644
--- a/gcc/rust/typecheck/rust-tyty-cmp.h
+++ b/gcc/rust/typecheck/rust-tyty-cmp.h
@@ -43,6 +43,16 @@ public:
return ok;
}
}
+ else if (other->get_kind () == TypeKind::PLACEHOLDER)
+ {
+ const PlaceholderType *p = static_cast<const PlaceholderType *> (other);
+ if (p->can_resolve ())
+ {
+ const BaseType *resolved = p->resolve ();
+ resolved->accept_vis (*this);
+ return ok;
+ }
+ }
other->accept_vis (*this);
return ok;
@@ -1165,43 +1175,55 @@ public:
: BaseCmp (base, emit_errors), base (base)
{}
- virtual void visit (const TupleType &) override { ok = true; }
+ bool can_eq (const BaseType *other) override
+ {
+ if (!base->can_resolve ())
+ return BaseCmp::can_eq (other);
+
+ BaseType *lookup = base->resolve ();
+ return lookup->can_eq (other, emit_error_flag);
+ }
+
+ void visit (const TupleType &) override { ok = true; }
- virtual void visit (const ADTType &) override { ok = true; }
+ void visit (const ADTType &) override { ok = true; }
- virtual void visit (const InferType &) override { ok = true; }
+ void visit (const InferType &) override { ok = true; }
- virtual void visit (const FnType &) override { ok = true; }
+ void visit (const FnType &) override { ok = true; }
- virtual void visit (const FnPtr &) override { ok = true; }
+ void visit (const FnPtr &) override { ok = true; }
- virtual void visit (const ArrayType &) override { ok = true; }
+ void visit (const ArrayType &) override { ok = true; }
- virtual void visit (const BoolType &) override { ok = true; }
+ void visit (const BoolType &) override { ok = true; }
- virtual void visit (const IntType &) override { ok = true; }
+ void visit (const IntType &) override { ok = true; }
- virtual void visit (const UintType &) override { ok = true; }
+ void visit (const UintType &) override { ok = true; }
- virtual void visit (const USizeType &) override { ok = true; }
+ void visit (const USizeType &) override { ok = true; }
- virtual void visit (const ISizeType &) override { ok = true; }
+ void visit (const ISizeType &) override { ok = true; }
- virtual void visit (const FloatType &) override { ok = true; }
+ void visit (const FloatType &) override { ok = true; }
- virtual void visit (const ErrorType &) override { ok = true; }
+ void visit (const ErrorType &) override { ok = true; }
- virtual void visit (const CharType &) override { ok = true; }
+ void visit (const CharType &) override { ok = true; }
- virtual void visit (const ReferenceType &) override { ok = true; }
+ void visit (const ReferenceType &) override { ok = true; }
- virtual void visit (const ParamType &) override { ok = true; }
+ void visit (const ParamType &) override { ok = true; }
- virtual void visit (const StrType &) override { ok = true; }
+ void visit (const StrType &) override { ok = true; }
- virtual void visit (const NeverType &) override { ok = true; }
+ void visit (const NeverType &) override { ok = true; }
- virtual void visit (const PlaceholderType &) override { ok = true; }
+ void visit (const PlaceholderType &type) override
+ {
+ ok = base->get_symbol ().compare (type.get_symbol ()) == 0;
+ }
private:
const BaseType *get_base () const override { return base; }
diff --git a/gcc/rust/typecheck/rust-tyty-rules.h b/gcc/rust/typecheck/rust-tyty-rules.h
index ca4849b..4d0b977 100644
--- a/gcc/rust/typecheck/rust-tyty-rules.h
+++ b/gcc/rust/typecheck/rust-tyty-rules.h
@@ -68,6 +68,14 @@ public:
other = p->resolve ();
}
}
+ else if (other->get_kind () == TypeKind::PLACEHOLDER)
+ {
+ PlaceholderType *p = static_cast<PlaceholderType *> (other);
+ if (p->can_resolve ())
+ {
+ other = p->resolve ();
+ }
+ }
other->accept_vis (*this);
if (resolved->get_kind () == TyTy::TypeKind::ERROR)
@@ -1249,7 +1257,7 @@ class NeverRules : public BaseRules
public:
NeverRules (NeverType *base) : BaseRules (base), base (base) {}
- virtual void visit (NeverType &type) override { resolved = type.clone (); }
+ void visit (NeverType &type) override { resolved = type.clone (); }
private:
BaseType *get_base () override { return base; }
@@ -1264,6 +1272,37 @@ class PlaceholderRules : public BaseRules
public:
PlaceholderRules (PlaceholderType *base) : BaseRules (base), base (base) {}
+ BaseType *unify (BaseType *other) override final
+ {
+ if (!base->can_resolve ())
+ return BaseRules::unify (other);
+
+ BaseType *lookup = base->resolve ();
+ return lookup->unify (other);
+ }
+
+ void visit (PlaceholderType &type) override
+ {
+ if (base->get_symbol ().compare (type.get_symbol ()) != 0)
+ {
+ BaseRules::visit (type);
+ return;
+ }
+
+ resolved = type.clone ();
+ }
+
+ void visit (InferType &type) override
+ {
+ if (type.get_infer_kind () != InferType::InferTypeKind::GENERAL)
+ {
+ BaseRules::visit (type);
+ return;
+ }
+
+ resolved = base->clone ();
+ }
+
private:
BaseType *get_base () override { return base; }
diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc
index ca4b3b8..18ccaee 100644
--- a/gcc/rust/typecheck/rust-tyty.cc
+++ b/gcc/rust/typecheck/rust-tyty.cc
@@ -49,10 +49,10 @@ BaseType::satisfies_bound (const TypeBoundPredicate &predicate) const
return true;
}
- std::vector<Resolver::TraitReference *> probed
- = Resolver::TypeBoundsProbe::Probe (this);
- for (const Resolver::TraitReference *bound : probed)
+ auto probed = Resolver::TypeBoundsProbe::Probe (this);
+ for (auto &b : probed)
{
+ const Resolver::TraitReference *bound = b.first;
bool found = bound->get_mappings ().get_defid ()
== query->get_mappings ().get_defid ();
if (found)
@@ -2032,7 +2032,8 @@ PlaceholderType::accept_vis (TyConstVisitor &vis) const
std::string
PlaceholderType::as_string () const
{
- return "<placeholder>";
+ return "<placeholder:" + (can_resolve () ? resolve ()->as_string () : "")
+ + ">";
}
BaseType *
@@ -2066,7 +2067,59 @@ PlaceholderType::can_eq (const BaseType *other, bool emit_errors) const
BaseType *
PlaceholderType::clone () const
{
- return new PlaceholderType (get_ref (), get_ty_ref (), get_combined_refs ());
+ return new PlaceholderType (get_symbol (), get_ref (), get_ty_ref (),
+ get_combined_refs ());
+}
+
+void
+PlaceholderType::set_associated_type (HirId ref)
+{
+ auto context = Resolver::TypeCheckContext::get ();
+ context->insert_associated_type_mapping (get_ty_ref (), ref);
+}
+
+void
+PlaceholderType::clear_associated_type ()
+{
+ auto context = Resolver::TypeCheckContext::get ();
+ context->clear_associated_type_mapping (get_ty_ref ());
+}
+
+bool
+PlaceholderType::can_resolve () const
+{
+ auto context = Resolver::TypeCheckContext::get ();
+ HirId val
+ = context->lookup_associated_type_mapping (get_ty_ref (), UNKNOWN_HIRID);
+ return val != UNKNOWN_HIRID;
+}
+
+BaseType *
+PlaceholderType::resolve () const
+{
+ auto context = Resolver::TypeCheckContext::get ();
+
+ rust_assert (can_resolve ());
+ HirId val
+ = context->lookup_associated_type_mapping (get_ty_ref (), UNKNOWN_HIRID);
+ rust_assert (val != UNKNOWN_HIRID);
+
+ return TyVar (val).get_tyty ();
+}
+
+bool
+PlaceholderType::is_equal (const BaseType &other) const
+{
+ if (get_kind () != other.get_kind ())
+ {
+ if (!can_resolve ())
+ return false;
+
+ return resolve ()->is_equal (other);
+ }
+
+ auto other2 = static_cast<const PlaceholderType &> (other);
+ return get_symbol ().compare (other2.get_symbol ()) == 0;
}
// Projection type
@@ -2243,6 +2296,17 @@ TypeCheckCallExpr::visit (FnType &type)
return;
}
+ if (type.get_return_type ()->get_kind () == TyTy::TypeKind::PLACEHOLDER)
+ {
+ const TyTy::PlaceholderType *p
+ = static_cast<const TyTy::PlaceholderType *> (type.get_return_type ());
+ if (p->can_resolve ())
+ {
+ resolved = p->resolve ()->clone ();
+ return;
+ }
+ }
+
resolved = type.get_return_type ()->clone ();
}
diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h
index f01d6f8..2fc6b53 100644
--- a/gcc/rust/typecheck/rust-tyty.h
+++ b/gcc/rust/typecheck/rust-tyty.h
@@ -1683,13 +1683,15 @@ public:
class PlaceholderType : public BaseType
{
public:
- PlaceholderType (HirId ref, std::set<HirId> refs = std::set<HirId> ())
- : BaseType (ref, ref, TypeKind::PLACEHOLDER, refs)
+ PlaceholderType (std::string symbol, HirId ref,
+ std::set<HirId> refs = std::set<HirId> ())
+ : BaseType (ref, ref, TypeKind::PLACEHOLDER, refs), symbol (symbol)
+
{}
- PlaceholderType (HirId ref, HirId ty_ref,
+ PlaceholderType (std::string symbol, HirId ref, HirId ty_ref,
std::set<HirId> refs = std::set<HirId> ())
- : BaseType (ref, ty_ref, TypeKind::PLACEHOLDER, refs)
+ : BaseType (ref, ty_ref, TypeKind::PLACEHOLDER, refs), symbol (symbol)
{}
void accept_vis (TyVisitor &vis) override;
@@ -1707,6 +1709,21 @@ public:
std::string get_name () const override final { return as_string (); }
bool is_unit () const override { return true; }
+
+ std::string get_symbol () const { return symbol; }
+
+ void set_associated_type (HirId ref);
+
+ void clear_associated_type ();
+
+ bool can_resolve () const;
+
+ BaseType *resolve () const;
+
+ bool is_equal (const BaseType &other) const override;
+
+private:
+ std::string symbol;
};
class ProjectionType : public BaseType
diff --git a/gcc/testsuite/rust/compile/torture/traits11.rs b/gcc/testsuite/rust/compile/torture/traits11.rs
new file mode 100644
index 0000000..b5fc023
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/traits11.rs
@@ -0,0 +1,32 @@
+trait Foo {
+ type A;
+ // { dg-warning "unused name" "" { target *-*-* } .-1 }
+
+ fn test(a: Self::A) -> Self::A {
+ a
+ }
+}
+
+struct Bar(i32);
+impl Foo for Bar {
+ type A = i32;
+}
+
+struct Baz(f32);
+impl Foo for Baz {
+ type A = f32;
+}
+
+fn main() {
+ let a;
+ a = Bar(123);
+
+ let b;
+ b = Bar::test(a.0);
+
+ let c;
+ c = Baz(123f32);
+
+ let d;
+ d = Baz::test(c.0);
+}