[COMMITTED 63/83] gccrs: Fix return type leaking into other function contexts

arthur.cohen@opensrcsec.com arthur.cohen@opensrcsec.com
Wed Sep 16 12:30:22 GMT 2026


From: Philip Herron <herron.philip@googlemail.com>

We use this expected types to help with type unification hints in awkward
cases iirc it was for Try. But then when we have cases of return expressions
which are const position and end up needing to resolve into other blocks
which then bleeds these expected types into those chains.

Fixes Rust-GCC/gccrs#4860

gcc/rust/ChangeLog:

	* typecheck/rust-typecheck-context.cc (TypeCheckContext::pop_return_type):
	push expected null

gcc/testsuite/ChangeLog:

	* rust/compile/issue-4860.rs: New test.

Signed-off-by: Philip Herron <herron.philip@googlemail.com>
---
 gcc/rust/typecheck/rust-typecheck-context.cc |  4 +++
 gcc/testsuite/rust/compile/issue-4860.rs     | 29 ++++++++++++++++++++
 2 files changed, 33 insertions(+)
 create mode 100644 gcc/testsuite/rust/compile/issue-4860.rs

diff --git a/gcc/rust/typecheck/rust-typecheck-context.cc b/gcc/rust/typecheck/rust-typecheck-context.cc
index 404f8344331..a1f10ea29a1 100644
--- a/gcc/rust/typecheck/rust-typecheck-context.cc
+++ b/gcc/rust/typecheck/rust-typecheck-context.cc
@@ -173,12 +173,16 @@ TypeCheckContext::push_return_type (TypeCheckContextItem item,
 				    TyTy::BaseType *return_type)
 {
   return_type_stack.emplace_back (std::move (item), return_type);
+  // a query can check another function body while an expression in the
+  // caller has an expected type
+  push_expected_type (nullptr);
 }
 
 void
 TypeCheckContext::pop_return_type ()
 {
   rust_assert (!return_type_stack.empty ());
+  pop_expected_type ();
   return_type_stack.pop_back ();
 }
 
diff --git a/gcc/testsuite/rust/compile/issue-4860.rs b/gcc/testsuite/rust/compile/issue-4860.rs
new file mode 100644
index 00000000000..0d054dc78b2
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-4860.rs
@@ -0,0 +1,29 @@
+// { dg-options "-w" }
+#![feature(no_core, lang_items, intrinsics, staged_api)]
+#![no_core]
+
+#[lang = "sized"]
+pub trait Sized {}
+
+pub const FLAG: bool = check();
+
+pub const fn check() -> bool {
+    return 8i8.wrapping_shr(1) == 4;
+}
+
+extern "rust-intrinsic" {
+    #[rustc_const_stable(feature = "const_int_unchecked", since = "1.40.0")]
+    fn unchecked_shr<T>(x: T, y: T) -> T;
+}
+
+impl i8 {
+    pub const fn wrapping_shr(self, rhs: u32) -> Self {
+        unsafe { unchecked_shr(self, (rhs & 7) as i8) }
+    }
+}
+
+impl i16 {
+    pub const fn wrapping_shr(self, rhs: u32) -> Self {
+        unsafe { unchecked_shr(self, (rhs & 15) as i16) }
+    }
+}
-- 
2.50.1



More information about the Gcc-rust mailing list