]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: Fix segv in errors in type checking an impl item
authorPhilip Herron <herron.philip@googlemail.com>
Sun, 9 Nov 2025 22:05:58 +0000 (22:05 +0000)
committerArthur Cohen <arthur.cohen@embecosm.com>
Mon, 17 Nov 2025 14:58:19 +0000 (15:58 +0100)
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 <herron.philip@googlemail.com>
gcc/rust/typecheck/rust-hir-type-check-implitem.cc
gcc/rust/typecheck/rust-hir-type-check.cc
gcc/testsuite/rust/compile/issue-4188.rs [new file with mode: 0644]

index 07fc010b087289a701218bc24bd3e459bb497041..83adf2ea761b50d350f7abd9cd4f1f7b280baf8b 100644 (file)
@@ -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 ();
index 64f4314e31516f84759fff1edb50f27385456121..3215f4348048f2abd97dc15d3966860b99c60fbd 100644 (file)
@@ -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 (file)
index 0000000..32b175d
--- /dev/null
@@ -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
+    }
+}