Skip to content

Conversation

@ShoyuVanilla
Copy link
Member

@ShoyuVanilla ShoyuVanilla commented Sep 11, 2025

Fixes #20582

Disclaimer: this code can effectively hang or stack-overflow your rust-analyzer!

trait DimMax<Other: Dimension> {
    type Output: Dimension;
}
trait Dimension: DimMax<<Self as Dimension>:: Smaller, Output = Self> {
    type Smaller: Dimension;
}

If we gonna normalize projection types related to the above traits, the current implementation endlessly elaborates implied bounds like

  • <T as DimMax>::Output: Dimension and we have Dimension: DimMax
  • <<T as DimMax>::Output as DimMax>::Output: DimMax
  • <<<T as DimMax>::Output as DimMax>::Output as DimMax>::Output: DimMax
  • ... 😵

Though this is not the best I can, I partially ported some implementation details from rustc to fix this infinite loop.

I think we should move overall lowering logic closer to that of rustc's, especially for those ones in here:
https://github.com/rust-lang/rust/blob/76c5ed2847cdb26ef2822a3a165d710f6b772217/compiler/rustc_hir_analysis/src/collect/predicates_of.rs

but maybe after migrating remaining things to next-solver.

@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Sep 11, 2025
);
}

// FIXME(next-solver): does this test make sense with fast path?
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing this in accordance with #20422 (comment)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’d keep this around and add an “expects a panic”. i think queries might be too expensive, but… i’d consider keeping it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of adding #[should_panic] I just updated the test output, as what was changed is just a single query name 😄


let interner = DbInterner::new_with(db, Some(krate), None);
// FIXME: We should use `explicit_predicates_of` here, which hasn't been implemented to
// rust-analyzer yet
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This causes a regression in the following test, though I think it's not a big deal for now, since having <Self> in type bounds is also reported as dyn-incompatible due to SelfRenferential but we should fix this eventually

U: Dimension,
{
let t: <T as DimMax<U>>::Output = loop {};
}
Copy link
Member Author

@ShoyuVanilla ShoyuVanilla Sep 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, this will blow up your rust-analyzer like in #20504 😨

I feel getting better on minimizing hangs/panics on real world projects 😄
These were actually monstrously large traits like in https://docs.rs/ndarray/0.16.1/ndarray/trait.Dimension.html

Copy link
Contributor

@davidbarsky davidbarsky left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

approving, modulo a nit.

);
}

// FIXME(next-solver): does this test make sense with fast path?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’d keep this around and add an “expects a panic”. i think queries might be too expensive, but… i’d consider keeping it.

@ShoyuVanilla
Copy link
Member Author

Merging this with David’s approval — without it, the issue might crop up quite often. I don’t think this should interfere with the ongoing coercion rewrite PR, but if it does, I’ll be ready to revert 😄

@ShoyuVanilla ShoyuVanilla added this pull request to the merge queue Sep 14, 2025
@ChayimFriedman2 ChayimFriedman2 removed this pull request from the merge queue due to a manual request Sep 14, 2025
@ChayimFriedman2
Copy link
Contributor

I actually rediscovered this issue from scratch in my coercion work just recently 😅

However, I stopped the merge due to one question - can't we just filter on generic_predicates_ns() in explicit_super_predicates_of(), no new query? I don't think lowering itself should be problematic.

@ShoyuVanilla
Copy link
Member Author

That sounds reasonable as more queries means more memory usage 😅 I think if we gonna move this closer to rustc, we might need separated queries as we need more control over recursive lowering but given the current simple implementation, I'll give it a try

@ShoyuVanilla ShoyuVanilla force-pushed the predicates branch 2 times, most recently from 3dd559b to 7cabe02 Compare September 14, 2025 10:42
Copy link
Contributor

@ChayimFriedman2 ChayimFriedman2 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for nudging you!

@ChayimFriedman2 ChayimFriedman2 added this pull request to the merge queue Sep 14, 2025
Merged via the queue into rust-lang:master with commit 760d378 Sep 14, 2025
15 checks passed
@rustbot rustbot removed the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Sep 14, 2025
@ShoyuVanilla
Copy link
Member Author

No worries at all

@ShoyuVanilla ShoyuVanilla deleted the predicates branch September 14, 2025 11:37
@lnicola
Copy link
Member

lnicola commented Sep 14, 2025

changelog fixup #20329

.iter()
.filter(|p| match p.kind().skip_binder() {
rustc_type_ir::ClauseKind::Trait(tr) => is_self_or_assoc(tr.self_ty()),
_ => true,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wait, that doesn't seem correct? E.g. if we got an AliasRelate we must filter it out if it's not constraining Self, otherwise trouble will happen.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I just found your comment by now. Yes, seems that I missed it.
To be clear, <T as Trait>::Assoc = Ty should be filtered out conditionally when T is not Self for both explicit_super_predicates_of and explicit_implied_predicates_of, unlike <T as Trait>::Assoc: Ty, which is always filtered out for explicit_super_predicates_of
https://github.com/rust-lang/rust/blob/52618eb338609df44978b0ca4451ab7941fd1c7a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs#L525-L608

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll open a followup for this once I'm back home from work 😅

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Runaway memory leak when viewing any file importing ndarray

5 participants