https://gcc.gnu.org/g:e494d53547e81b3761c1cf2f8ed215be787fa25b
commit r17-4340-ge494d53547e81b3761c1cf2f8ed215be787fa25b Author: Philip Herron <[email protected]> Date: Mon Sep 7 21:39:13 2026 +0100 gccrs: Fix return type leaking into other function contexts 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 <[email protected]> Diff: --- gcc/rust/typecheck/rust-typecheck-context.cc | 4 ++++ gcc/testsuite/rust/compile/issue-4860.rs | 29 ++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/gcc/rust/typecheck/rust-typecheck-context.cc b/gcc/rust/typecheck/rust-typecheck-context.cc index 404f83443311..a1f10ea29a1c 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 000000000000..0d054dc78b2e --- /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) } + } +}
