aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-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();
+}