diff options
Diffstat (limited to 'gcc')
-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(); +} |