From: Philip Herron <[email protected]>
When we typecheck a trait impl block item, at the end we validate it
against the trait definition by doing a final unify but if the type check
fails on the the impl item it returns NULL here. The other issue was that
if we fail to resolve the specified lifetime we return error early, this
changes the typechecking to default to an anon lifetime so we can continue
typechecking.
Fixes Rust-GCC#4188
gcc/rust/ChangeLog:
* typecheck/rust-hir-type-check-implitem.cc
(TypeCheckImplItemWithTrait::visit): null guard
* typecheck/rust-hir-type-check.cc
(TraitItemReference::get_type_from_fn): default to anon
gcc/testsuite/ChangeLog:
* rust/compile/issue-4188.rs: New test.
Signed-off-by: Philip Herron <[email protected]>
---
gcc/rust/typecheck/rust-hir-type-check-implitem.cc | 2 ++
gcc/rust/typecheck/rust-hir-type-check.cc | 11 ++++++-----
gcc/testsuite/rust/compile/issue-4188.rs | 13 +++++++++++++
3 files changed, 21 insertions(+), 5 deletions(-)
create mode 100644 gcc/testsuite/rust/compile/issue-4188.rs
diff --git a/gcc/rust/typecheck/rust-hir-type-check-implitem.cc
b/gcc/rust/typecheck/rust-hir-type-check-implitem.cc
index 07fc010b087..83adf2ea761 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-implitem.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-implitem.cc
@@ -582,6 +582,8 @@ TypeCheckImplItemWithTrait::visit (HIR::Function &function)
// normal resolution of the item
TyTy::BaseType *lookup
= TypeCheckImplItem::Resolve (parent, function, self, substitutions);
+ if (lookup == nullptr)
+ return;
// map the impl item to the associated trait item
const auto tref = trait_reference.get ();
diff --git a/gcc/rust/typecheck/rust-hir-type-check.cc
b/gcc/rust/typecheck/rust-hir-type-check.cc
index 64f4314e315..3215f434804 100644
--- a/gcc/rust/typecheck/rust-hir-type-check.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check.cc
@@ -237,19 +237,20 @@ TraitItemReference::get_type_from_fn (/*const*/
HIR::TraitItemFunc &fn) const
: Mutability::Mut;
rust_assert (self_param.has_lifetime ());
+ auto region = TyTy::Region::make_anonymous ();
auto maybe_region = context->lookup_and_resolve_lifetime (
self_param.get_lifetime ());
-
- if (!maybe_region.has_value ())
+ if (maybe_region.has_value ())
+ region = maybe_region.value ();
+ else
{
rust_error_at (self_param.get_locus (),
"failed to resolve lifetime");
- return get_error ();
}
+
self_type = new TyTy::ReferenceType (
self_param.get_mappings ().get_hirid (),
- TyTy::TyVar (self->get_ref ()), mutability,
- maybe_region.value ());
+ TyTy::TyVar (self->get_ref ()), mutability, region);
}
break;
diff --git a/gcc/testsuite/rust/compile/issue-4188.rs
b/gcc/testsuite/rust/compile/issue-4188.rs
new file mode 100644
index 00000000000..32b175dbdb4
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-4188.rs
@@ -0,0 +1,13 @@
+trait MemoryUnit {
+ extern "C" fn read_dword(&'s self) -> u16 {}
+ // { dg-error {failed to resolve lifetime} "" { target *-*-* } .-1 }
+ // { dg-error {mismatched types} "" { target *-*-* } .-2 }
+}
+
+impl MemoryUnit for MemoryUnit {
+ extern "C" fn read_dword(&'s self) -> u16 {
+ let b16 = self.read_word() as u16;
+
+ b16 << 8
+ }
+}
--
2.50.1