https://gcc.gnu.org/g:e5382827c529a356b33b53a7e7f3695d34ee7b4f
commit r17-4316-ge5382827c529a356b33b53a7e7f3695d34ee7b4f Author: Philip Herron <[email protected]> Date: Mon Aug 31 19:48:48 2026 +0100 gccrs: Fix ambigious path resolution Rust checks regular impls first then only when candidates are empty it should iterate trait impls. Fixes Rust-GCC/gccrs#4823 gcc/rust/ChangeLog: * typecheck/rust-hir-path-probe-expr.cc (PathProbeExpr::probe_adt_impls): check impls first (PathProbeExpr::probe_fallback_impls): likewise gcc/testsuite/ChangeLog: * rust/compile/issue-4823.rs: New test. Signed-off-by: Philip Herron <[email protected]> Diff: --- gcc/rust/typecheck/rust-hir-path-probe-expr.cc | 29 ++++++++++++++++++++++++++ gcc/testsuite/rust/compile/issue-4823.rs | 23 ++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/gcc/rust/typecheck/rust-hir-path-probe-expr.cc b/gcc/rust/typecheck/rust-hir-path-probe-expr.cc index 4177e3760386..8307082af973 100644 --- a/gcc/rust/typecheck/rust-hir-path-probe-expr.cc +++ b/gcc/rust/typecheck/rust-hir-path-probe-expr.cc @@ -80,6 +80,21 @@ PathProbeExpr::probe_adt_impls (TyTy::ADTType *adt) mappings.iterate_adt_impl_items ( adt_node_id, [this] (HirId id, HIR::ImplItem *item, HIR::ImplBlock *impl) -> bool { + if (impl->has_trait_ref ()) + return true; + + return process_impl_item_candidate (id, item, impl); + }); + + if (!candidates.empty ()) + return; + + mappings.iterate_adt_impl_items ( + adt_node_id, + [this] (HirId id, HIR::ImplItem *item, HIR::ImplBlock *impl) -> bool { + if (!impl->has_trait_ref ()) + return true; + return process_impl_item_candidate (id, item, impl); }); } @@ -89,6 +104,20 @@ PathProbeExpr::probe_fallback_impls () { mappings.iterate_impl_items ( [this] (HirId id, HIR::ImplItem *item, HIR::ImplBlock *impl) -> bool { + if (impl->has_trait_ref ()) + return true; + + return process_impl_item_candidate (id, item, impl); + }); + + if (!candidates.empty ()) + return; + + mappings.iterate_impl_items ( + [this] (HirId id, HIR::ImplItem *item, HIR::ImplBlock *impl) -> bool { + if (!impl->has_trait_ref ()) + return true; + return process_impl_item_candidate (id, item, impl); }); } diff --git a/gcc/testsuite/rust/compile/issue-4823.rs b/gcc/testsuite/rust/compile/issue-4823.rs new file mode 100644 index 000000000000..5a0edd385428 --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-4823.rs @@ -0,0 +1,23 @@ +#![feature(no_core)] +#![no_core] + +pub struct S; + +trait T { + const VALUE: i32; +} + +impl T for S { + const VALUE: i32 = 1; + // { dg-warning "unused name" "" { target *-*-* } .-1 } +} + +impl S { + const VALUE: i32 = 2; +} + +const RESULT: i32 = S::VALUE; + +pub fn test() -> i32 { + RESULT +}
