From: Philip Herron Date: Sun, 9 Nov 2025 22:05:58 +0000 (+0000) Subject: gccrs: Fix segv in errors in type checking an impl item X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=93430462afaee6bbb501174794fd060661f0f653;p=thirdparty%2Fgcc.git gccrs: Fix segv in errors in type checking an impl item 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 --- 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 + } +}