Skip to content

Work around const item TypeOwnerId mismatch - #23174

Open
jix wants to merge 1 commit into
rust-lang:masterfrom
jix:fix-const-completion-panic
Open

Work around const item TypeOwnerId mismatch#23174
jix wants to merge 1 commit into
rust-lang:masterfrom
jix:fix-const-completion-panic

Conversation

@jix

@jix jix commented Aug 17, 2026

Copy link
Copy Markdown

For some time rust-analyzer started panicking regularly on the kind of code I tend to write, so today I decided to debug it and to try fixing it. I minimized it the following reproducer, which this PR also adds as a test:

pub struct Boo;
pub struct A(Boo);
impl A {
    const X: A = A(B$0);
}

Since I wasn't familiar with this codebase before I started debugging this, I was working backwards from the panic's backtrace. My current understanding of the issue is that const items do not introduce their own generic scope and when completing in the definition of a const, resolved completion candidates end up with a TypeOwnerId of the const item's container, the HasResolver implementation just skips the item scope, whereas expected types (from argument positions, the const type itself isn't used as expected type) end up with the const item itself as TypeOwnerId. This can make the Types non-unifiable triggering panics during completion.

This PR works around this by making Type::unify and Type::can_rebase_into normalize the TypeOwnerId of a Type to the innermost scope that actually can have generics for const and static items (or to NoParams if there is none).

I'm not at all confident that this is the best fix, it seems like it would be better to make sure that TypeOwnerIds are assigned consistently, but that would require a) ensuring no types end up with the const item as owner, and I don't have on overview of which places that would be, or b) changing the resolver, which I didn't really look into at all. Also without changing the representation or at least the exposed constructors to ensure consistent assignment, it would be easy to accidentally re-introduce new places that create inconsistent TypeOwnerIds. I thus opted for a work-around that is relatively localized and more robust, by forcing the TypeOwnerIds to be consistent around the parts that triggered the panic.

PS: The panic I got was the same as in #22659, but the regression test from #22858 still fails with this, so I believe what I fixed is not the same issue.

Const items do not introduce their own generic scope and when completing
in the definition of a const, resolved completion candidates end up with
a `TypeOwnerId` of the const item's container, the `HasResolver`
implementation just skips the item scope, whereas expected types (from
argument positions, the const type itself isn't used as expected type)
end up with the const item itself as TypeOwnerId. This can make the
`Type`s non-unifiable triggering panics during completion.

This works around this by making `Type::unify` and
`Type::can_rebase_into` normalize the `TypeOwnerId` of a `Type` to the
innermost scope that actually can have generics for const and static
items (or to `NoParams` if there is none).
@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Aug 17, 2026
@ChayimFriedman2

Copy link
Copy Markdown
Contributor

No that's not a correct fix. I'll create a PR for the correct fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-review Status: Awaiting review from the assignee but also interested parties.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants