diff options
author | Philip Herron <philip.herron@embecosm.com> | 2021-06-05 16:37:29 +0100 |
---|---|---|
committer | Philip Herron <philip.herron@embecosm.com> | 2021-06-05 16:40:19 +0100 |
commit | 1c0f8d6d2a22ce498ef3f1bfd60a3867a90c8130 (patch) | |
tree | 4ac87f4d6dc73a876525a3dc3c280283f9baa1ea | |
parent | 69b3e488803f684d9d956223a7f410d219cced24 (diff) | |
download | gcc-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.h | 8 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-item.h | 16 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-implitem.h | 14 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-item.h | 15 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-toplevel.h | 41 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/torture/traits1.rs | 17 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/torture/traits2.rs | 17 |
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(); +} |