From a5d3586a9b159dd7c93992875b89605bedd0a60a Mon Sep 17 00:00:00 2001 From: Philip Herron Date: Wed, 5 Oct 2022 17:24:42 +0100 Subject: [PATCH] gccrs: Support looking up super traits for trait items When supporting calls to super traits we need to allow lookups based on the super traits as specified on the TraitReferences. Fixes #1555 gcc/rust/ChangeLog: * typecheck/rust-hir-trait-ref.h (lookup_trait_item): Add lookup in super_trait. gcc/testsuite/ChangeLog: * rust/compile/torture/issue-1555.rs: New test. --- gcc/rust/typecheck/rust-hir-trait-ref.h | 19 ++++++++++ gcc/testsuite/rust/compile/torture/issue-1555.rs | 48 ++++++++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 gcc/testsuite/rust/compile/torture/issue-1555.rs diff --git a/gcc/rust/typecheck/rust-hir-trait-ref.h b/gcc/rust/typecheck/rust-hir-trait-ref.h index f6a3328..7eeb330 100644 --- a/gcc/rust/typecheck/rust-hir-trait-ref.h +++ b/gcc/rust/typecheck/rust-hir-trait-ref.h @@ -336,6 +336,15 @@ public: return true; } } + + // lookup super traits + for (const auto &super_trait : super_traits) + { + bool found = super_trait->lookup_trait_item (ident, ref); + if (found) + return true; + } + return false; } @@ -351,6 +360,16 @@ public: if (ident.compare (item.get_identifier ()) == 0) return &item; } + + // lookup super traits + for (const auto &super_trait : super_traits) + { + const TraitItemReference *res + = super_trait->lookup_trait_item (ident, type); + if (!res->is_error ()) + return res; + } + return &TraitItemReference::error_node (); } diff --git a/gcc/testsuite/rust/compile/torture/issue-1555.rs b/gcc/testsuite/rust/compile/torture/issue-1555.rs new file mode 100644 index 0000000..adb4891 --- /dev/null +++ b/gcc/testsuite/rust/compile/torture/issue-1555.rs @@ -0,0 +1,48 @@ +extern "C" { + fn printf(s: *const i8, ...); +} + +struct Foo(i32); +trait Bar { + fn baz(&self); +} + +trait Baz: Bar { + fn qux(&self); +} + +impl Bar for Foo { + fn baz(&self) { + unsafe { + let a = "baz %i\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c, self.0); + } + } +} + +impl Baz for Foo { + fn qux(&self) { + unsafe { + let a = "qux %i\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c, self.0); + } + } +} + +fn static_dispatch(t: &T) { + t.baz(); + t.qux(); +} + +pub fn main() { + let a; + a = &Foo(123); + + static_dispatch(a); +} -- 2.7.4