fix(semantic): don't ICE when an impl provides an associated item of the wrong kind#10206
Conversation
…the wrong kind
`impl_type_by_trait_type`, `impl_constant_by_trait_constant`, and
`impl_impl_by_trait_impl` looked up the impl item by name and then
`extract_matches!`'d it to the expected `ImplItemId` variant. When an impl
provides an item whose name matches a trait associated item but whose kind
differs (e.g. trait declares `type Foo` and the impl provides `const Foo`),
the extract panicked. These queries are on the mandatory resolution path
(reached via `MyImpl::Foo` in type/value/impl position), so the panic fired
before the separate trait-item-mismatch validation could surface its E2014.
Use `try_extract_matches!(...).ok_or_else(skip_diagnostic)` in all three, so
a wrong-kind item resolves to a skipped diagnostic and the existing E2014
("impl item ... is not a member of trait") is reported instead.
Adds an `expr/test_data/impl` golden covering all three query kinds: a trait
declaring a `type`/`const`/`impl` associated item, an impl providing each
with the wrong kind, referenced so every query runs.
This stack of pull requests is managed by Graphite. Learn more about stacking. |
PR SummaryLow Risk Overview In Adds a diagnostics test for cross-kind collisions ( Reviewed by Cursor Bugbot for commit 86292dc. Bugbot is set up for automated code reviews on this repo. Configure here. |

Summary
When an impl provides an associated item with the wrong kind (e.g., a
constwhere atypeis expected, or atypewhere animplis expected), the compiler previously panicked viaextract_matches!instead of emitting a proper diagnostic. This PR replaces those panickingextract_matches!calls withtry_extract_matches!inimpl_type_by_trait_type,impl_constant_by_trait_constant, andimpl_impl_by_trait_impl, so that a mismatched-kind item is treated as "not found" and a gracefulskip_diagnosticerror is returned instead.A new test case is added covering cross-kind collisions where
MyImplprovides aconst AsType,type AsConst, andtype AsImplagainst a trait expecting atype AsType,const AsConst, andimpl AsImpl, verifying that appropriateE2014diagnostics are emitted for each mismatched item.Type of change
Please check one:
Why is this change needed?
When an impl supplies an associated item under the correct name but the wrong kind (e.g., a
constinstead of atype), the lookup functions assumed the item would always match the expectedImplItemIdvariant and calledextract_matches!, which panics on a mismatch. This caused a compiler crash rather than a user-facing diagnostic.What was the behavior or documentation before?
The compiler panicked when an impl item's name matched a trait item but the kinds differed (e.g.,
const Fooprovided wheretype Foowas expected).What is the behavior or documentation after?
The compiler now emits an
E2014diagnostic ("Impl item<kind><name>is not a member of trait<trait>") for each cross-kind collision and continues compilation without crashing.Related issue or discussion (if any)
None.
Additional context
The refactor also simplifies the lookup logic by chaining
?,and_then, andok_or_elseinstead of nestedmatchblocks.