aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust
diff options
context:
space:
mode:
authorPhilip Herron <philip.herron@embecosm.com>2021-09-10 12:14:33 +0100
committerPhilip Herron <philip.herron@embecosm.com>2021-09-10 13:47:51 +0100
commita1c87bfea6c5e2fd6b2d23b12b563fcaf5ec09a1 (patch)
tree1294bbc35cc86fffd2ef15e66f3b9fbce55eee06 /gcc/rust
parente68a772a4a3010b62dae7231b1d841654dbb66d3 (diff)
downloadgcc-a1c87bfea6c5e2fd6b2d23b12b563fcaf5ec09a1.zip
gcc-a1c87bfea6c5e2fd6b2d23b12b563fcaf5ec09a1.tar.gz
gcc-a1c87bfea6c5e2fd6b2d23b12b563fcaf5ec09a1.tar.bz2
Add initial support to specify Super Traits
Super Traits are simply TraitBounds upon the implict Self TypeParameter, such that a trait with a super trait bound almost ends up looking like this trait A : B { } -> trait A where Self: B { }
Diffstat (limited to 'gcc/rust')
-rw-r--r--gcc/rust/typecheck/rust-hir-trait-resolve.h36
-rw-r--r--gcc/rust/typecheck/rust-tyty.cc9
-rw-r--r--gcc/rust/typecheck/rust-tyty.h3
3 files changed, 43 insertions, 5 deletions
diff --git a/gcc/rust/typecheck/rust-hir-trait-resolve.h b/gcc/rust/typecheck/rust-hir-trait-resolve.h
index 49aa2fa..b0e2c0d 100644
--- a/gcc/rust/typecheck/rust-hir-trait-resolve.h
+++ b/gcc/rust/typecheck/rust-hir-trait-resolve.h
@@ -113,10 +113,6 @@ private:
return tref;
}
- // Check if there is a super-trait, and apply this bound to the Self
- // TypeParam
- // FIXME
-
TyTy::BaseType *self = nullptr;
std::vector<TyTy::SubstitutionParamMapping> substitutions;
for (auto &generic_param : trait_reference->get_generic_params ())
@@ -147,6 +143,38 @@ private:
rust_assert (self != nullptr);
+ // Check if there is a super-trait, and apply this bound to the Self
+ // TypeParam
+ std::vector<TyTy::TypeBoundPredicate> specified_bounds;
+
+ // They also inherit themselves as a bound this enables a trait item to
+ // reference other Self::trait_items
+ specified_bounds.push_back (
+ TyTy::TypeBoundPredicate (trait_reference->get_mappings ().get_defid (),
+ trait_reference->get_locus ()));
+
+ if (trait_reference->has_type_param_bounds ())
+ {
+ for (auto &bound : trait_reference->get_type_param_bounds ())
+ {
+ if (bound->get_bound_type ()
+ == HIR::TypeParamBound::BoundType::TRAITBOUND)
+ {
+ HIR::TraitBound *b
+ = static_cast<HIR::TraitBound *> (bound.get ());
+
+ // FIXME this might be recursive we need a check for that
+
+ TraitReference *trait = resolve_trait_path (b->get_path ());
+ TyTy::TypeBoundPredicate predicate (
+ trait->get_mappings ().get_defid (), bound->get_locus ());
+
+ specified_bounds.push_back (std::move (predicate));
+ }
+ }
+ }
+ self->inherit_bounds (specified_bounds);
+
std::vector<TraitItemReference> item_refs;
for (auto &item : trait_reference->get_trait_items ())
{
diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc
index 899ad59..398b531 100644
--- a/gcc/rust/typecheck/rust-tyty.cc
+++ b/gcc/rust/typecheck/rust-tyty.cc
@@ -99,7 +99,14 @@ BaseType::bounds_compatible (const BaseType &other, Location locus) const
void
BaseType::inherit_bounds (const BaseType &other)
{
- for (auto &bound : other.get_specified_bounds ())
+ inherit_bounds (other.get_specified_bounds ());
+}
+
+void
+BaseType::inherit_bounds (
+ const std::vector<TyTy::TypeBoundPredicate> &specified_bounds)
+{
+ for (auto &bound : specified_bounds)
{
add_bound (bound);
}
diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h
index 7f149a9..867dc37 100644
--- a/gcc/rust/typecheck/rust-tyty.h
+++ b/gcc/rust/typecheck/rust-tyty.h
@@ -257,6 +257,9 @@ public:
void inherit_bounds (const BaseType &other);
+ void inherit_bounds (
+ const std::vector<TyTy::TypeBoundPredicate> &specified_bounds);
+
virtual bool is_unit () const { return false; }
virtual bool is_concrete () const { return true; }