aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Herron <philip.herron@embecosm.com>2021-06-05 16:37:29 +0100
committerPhilip Herron <philip.herron@embecosm.com>2021-06-05 16:40:19 +0100
commit1c0f8d6d2a22ce498ef3f1bfd60a3867a90c8130 (patch)
tree4ac87f4d6dc73a876525a3dc3c280283f9baa1ea
parent69b3e488803f684d9d956223a7f410d219cced24 (diff)
downloadgcc-1c0f8d6d2a22ce498ef3f1bfd60a3867a90c8130.zip
gcc-1c0f8d6d2a22ce498ef3f1bfd60a3867a90c8130.tar.gz
gcc-1c0f8d6d2a22ce498ef3f1bfd60a3867a90c8130.tar.bz2
This is the initial building blocks for Traits
We can compile TraitImpls, since before we can actually start checking trait obligations we need to be able to implement the trait first. More desugaring is needed in HIR to make TraitImpls contain normal impl items to avoid seperation in how impl blocks are handled. Fixes #395 #472
-rw-r--r--gcc/rust/backend/rust-compile-implitem.h8
-rw-r--r--gcc/rust/backend/rust-compile-item.h16
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-implitem.h14
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-item.h15
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-toplevel.h41
-rw-r--r--gcc/testsuite/rust/compile/torture/traits1.rs17
-rw-r--r--gcc/testsuite/rust/compile/torture/traits2.rs17
7 files changed, 128 insertions, 0 deletions
diff --git a/gcc/rust/backend/rust-compile-implitem.h b/gcc/rust/backend/rust-compile-implitem.h
index a5ca13b..a4fb6d1 100644
--- a/gcc/rust/backend/rust-compile-implitem.h
+++ b/gcc/rust/backend/rust-compile-implitem.h
@@ -42,6 +42,14 @@ public:
item->accept_vis (compiler);
}
+ static void Compile (TyTy::BaseType *self, HIR::TraitImplItem *item,
+ Context *ctx, bool compile_fns,
+ TyTy::BaseType *concrete = nullptr)
+ {
+ CompileInherentImplItem compiler (self, ctx, compile_fns, concrete);
+ item->accept_vis (compiler);
+ }
+
void visit (HIR::ConstantItem &constant) override
{
TyTy::BaseType *resolved_type = nullptr;
diff --git a/gcc/rust/backend/rust-compile-item.h b/gcc/rust/backend/rust-compile-item.h
index e3b6d0f..e681652 100644
--- a/gcc/rust/backend/rust-compile-item.h
+++ b/gcc/rust/backend/rust-compile-item.h
@@ -290,6 +290,22 @@ public:
compile_fns);
}
+ void visit (HIR::TraitImpl &impl_block) override
+ {
+ TyTy::BaseType *self_lookup = nullptr;
+ if (!ctx->get_tyctx ()->lookup_type (
+ impl_block.get_type ()->get_mappings ().get_hirid (), &self_lookup))
+ {
+ rust_error_at (impl_block.get_locus (),
+ "failed to resolve type of impl");
+ return;
+ }
+
+ for (auto &impl_item : impl_block.get_impl_items ())
+ CompileInherentImplItem::Compile (self_lookup, impl_item.get (), ctx,
+ compile_fns);
+ }
+
private:
CompileItem (Context *ctx, bool compile_fns, TyTy::BaseType *concrete)
: HIRCompileBase (ctx), compile_fns (compile_fns), concrete (concrete)
diff --git a/gcc/rust/typecheck/rust-hir-type-check-implitem.h b/gcc/rust/typecheck/rust-hir-type-check-implitem.h
index 2f54d0c..bed89b8 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-implitem.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-implitem.h
@@ -41,6 +41,14 @@ public:
item->accept_vis (resolver);
}
+ static void
+ Resolve (HIR::TraitImplItem *item, TyTy::BaseType *self,
+ std::vector<TyTy::SubstitutionParamMapping> substitutions)
+ {
+ TypeCheckTopLevelImplItem resolver (self, substitutions);
+ item->accept_vis (resolver);
+ }
+
void visit (HIR::ConstantItem &constant) override
{
TyTy::BaseType *type = TypeCheckType::Resolve (constant.get_type ());
@@ -219,6 +227,12 @@ public:
item->accept_vis (resolver);
}
+ static void Resolve (HIR::TraitImplItem *item, TyTy::BaseType *self)
+ {
+ TypeCheckImplItem resolver (self);
+ item->accept_vis (resolver);
+ }
+
void visit (HIR::Function &function) override
{
TyTy::BaseType *lookup;
diff --git a/gcc/rust/typecheck/rust-hir-type-check-item.h b/gcc/rust/typecheck/rust-hir-type-check-item.h
index 1205dce..47d9a8a 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-item.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-item.h
@@ -55,6 +55,21 @@ public:
TypeCheckImplItem::Resolve (impl_item.get (), self);
}
+ void visit (HIR::TraitImpl &impl_block) override
+ {
+ TyTy::BaseType *self = nullptr;
+ if (!context->lookup_type (
+ impl_block.get_type ()->get_mappings ().get_hirid (), &self))
+ {
+ rust_error_at (impl_block.get_locus (),
+ "failed to resolve Self for TraitImpl");
+ return;
+ }
+
+ for (auto &impl_item : impl_block.get_impl_items ())
+ TypeCheckImplItem::Resolve (impl_item.get (), self);
+ }
+
void visit (HIR::Function &function) override
{
TyTy::BaseType *lookup;
diff --git a/gcc/rust/typecheck/rust-hir-type-check-toplevel.h b/gcc/rust/typecheck/rust-hir-type-check-toplevel.h
index e01b46f..3ec231f 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-toplevel.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-toplevel.h
@@ -273,6 +273,47 @@ public:
substitutions);
}
+ void visit (HIR::TraitImpl &impl_block) override
+ {
+ std::vector<TyTy::SubstitutionParamMapping> substitutions;
+ if (impl_block.has_generics ())
+ {
+ for (auto &generic_param : impl_block.get_generic_params ())
+ {
+ switch (generic_param.get ()->get_kind ())
+ {
+ case HIR::GenericParam::GenericKind::LIFETIME:
+ // Skipping Lifetime completely until better handling.
+ break;
+
+ case HIR::GenericParam::GenericKind::TYPE: {
+ auto param_type
+ = TypeResolveGenericParam::Resolve (generic_param.get ());
+ context->insert_type (generic_param->get_mappings (),
+ param_type);
+
+ substitutions.push_back (TyTy::SubstitutionParamMapping (
+ static_cast<HIR::TypeParam &> (*generic_param),
+ param_type));
+ }
+ break;
+ }
+ }
+ }
+
+ // TODO
+ // resolve the trait and check all items implemented
+
+ auto self
+ = TypeCheckType::Resolve (impl_block.get_type ().get (), &substitutions);
+ if (self == nullptr || self->get_kind () == TyTy::TypeKind::ERROR)
+ return;
+
+ for (auto &impl_item : impl_block.get_impl_items ())
+ TypeCheckTopLevelImplItem::Resolve (impl_item.get (), self,
+ substitutions);
+ }
+
private:
TypeCheckTopLevel () : TypeCheckBase () {}
};
diff --git a/gcc/testsuite/rust/compile/torture/traits1.rs b/gcc/testsuite/rust/compile/torture/traits1.rs
new file mode 100644
index 0000000..18e2779
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/traits1.rs
@@ -0,0 +1,17 @@
+trait Foo {
+ fn bar() -> i32;
+ // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
+
+struct Test(i32, f32);
+
+impl Foo for Test {
+ fn bar() -> i32 {
+ 123
+ }
+}
+
+fn main() {
+ let a: i32;
+ a = Test::bar();
+}
diff --git a/gcc/testsuite/rust/compile/torture/traits2.rs b/gcc/testsuite/rust/compile/torture/traits2.rs
new file mode 100644
index 0000000..6df369d
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/traits2.rs
@@ -0,0 +1,17 @@
+trait Foo {
+ fn bar() -> i32;
+ // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
+
+struct Test<T>(T);
+
+impl<T> Foo for Test<T> {
+ fn bar() -> i32 {
+ 123
+ }
+}
+
+fn main() {
+ let a: i32;
+ a = Test::<i32>::bar();
+}