diff options
-rw-r--r-- | gcc/rust/typecheck/rust-hir-path-probe.h | 4 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/torture/issue-862.rs | 74 |
2 files changed, 76 insertions, 2 deletions
diff --git a/gcc/rust/typecheck/rust-hir-path-probe.h b/gcc/rust/typecheck/rust-hir-path-probe.h index caacc2a..50d660c 100644 --- a/gcc/rust/typecheck/rust-hir-path-probe.h +++ b/gcc/rust/typecheck/rust-hir-path-probe.h @@ -280,8 +280,8 @@ protected: current_impl = impl; HirId impl_ty_id = impl->get_type ()->get_mappings ().get_hirid (); TyTy::BaseType *impl_block_ty = nullptr; - bool ok = context->lookup_type (impl_ty_id, &impl_block_ty); - rust_assert (ok); + if (!context->lookup_type (impl_ty_id, &impl_block_ty)) + return; if (!receiver->can_eq (impl_block_ty, false)) return; diff --git a/gcc/testsuite/rust/compile/torture/issue-862.rs b/gcc/testsuite/rust/compile/torture/issue-862.rs new file mode 100644 index 0000000..c1a4609 --- /dev/null +++ b/gcc/testsuite/rust/compile/torture/issue-862.rs @@ -0,0 +1,74 @@ +// { dg-additional-options "-w" } +extern "C" { + fn printf(s: *const i8, ...); +} + +#[lang = "deref"] +pub trait Deref { + type Target; + + fn deref(&self) -> &Self::Target; +} + +impl<T> Deref for &T { + type Target = T; + + fn deref(&self) -> &T { + unsafe { + let a = "imm_deref\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c); + } + + *self + } +} + +impl<T> Deref for &mut T { + type Target = T; + + fn deref(&self) -> &T { + unsafe { + let a = "mut_deref\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c); + } + + *self + } +} + +struct Foo<T>(T); +impl<T> Deref for Foo<T> { + type Target = T; + + fn deref(&self) -> &Self::Target { + unsafe { + let a = "foo_deref\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c); + } + + &self.0 + } +} + +struct Bar(i32); +impl Bar { + fn cake(self) -> i32 { + self.0 + 1 + } +} + +pub fn main() { + let foo: Foo<Bar> = Foo(Bar(123)); + let bar: Bar = *foo; + + let cake_result: i32 = foo.cake(); +} |