Open detrumi opened 3 years ago
rust-analyzer#7680 might also be related, as that keeps expanding nested queries with dyn/AliasEq, again inside a closure substitution.
I'm still having trouble creating a chalk test case that repros this. @detrumi do you think you could capture a CHALK_DEBUG
log up to a couple rounds of expansion?
I have a feeling this might be caused by the difference in representation between the chalk-integration closure substs and rust-analyzer/rustc closure substs
@jackh726 Sure! It's a lot of output, but I think this shows the first few repeats:
The full ist of solve queries that happened before might also be useful:
Full output for completeness, which also shows chalk programs: https://gist.github.com/detrumi/a7112751e901bbbd864a83e011f93cae
For reference, this was output from the following:
RA_LOG=hir_ty=info CHALK_DEBUG=3 CHALK_PRINT=1 cargo run --release -p rust-analyzer -- analysis-stats ../tryout
I think the difference that's likely the source of problems is that rust-analyzer (and I think I got this from rustc) puts the closure signature in a function pointer type in the substs. (rustc puts some more stuff in there, we currently only have the signature.)
Especially the fact that it's in a function pointer may be relevant, since that's caused problems because of variance already.
It's also worth noting that rust-analyzer never passes any lifetimes except 'static
to Chalk.
@detrumi so the output there only shows chalk_recursive
tracing output, which isn't super helpful. Haven't looked into how rust-analyzer enables the logging, but I would expect to also see chalk_solve
output.
@flodiebold yeah, I'm wondering if we're relating all the substs somewhere that we should only be relating the "function substitution"
Yeah, actually, I bet this is happening because we call generalize_substitution
on the whole closure substitution
After #733 this reproduces as
#[test]
fn chalk_688() {
test! {
program {
#[lang(fn_once)]
trait FnOnce<Args> {
type Output;
}
struct Ordering {}
closure foo<F>(self,) {}
impl<A, B, U> FnOnce<(A, B)> for foo<fn(A, B) -> U> {
type Output = U;
}
}
goal {
exists <R, S, T, U> {
<
foo<fn(&'static (R, &'static S), &'static (T, S)) -> Ordering>
as
FnOnce<(&'static (T, U), &'static (T, U))>
>::Output
= Ordering
}
} yields {
"Ambiguous; no inference guidance"
}
}
}
on the recursive solver only
@JakobDegen just now finding some time to look at this and #733. Sorry for the delay. Shouldn't the repro for this end up with a hang, instead of an answer?
@JakobDegen just now finding some time to look at this and #733. Sorry for the delay. Shouldn't the repro for this end up with a hang, instead of an answer?
Yeah should have clarified, that test does hang on the recursive solver on my branch; the answer in the test is needed so that this passes the SLG solver, as otherwise the recursive solver doesn't even run.
Ah okay. For future reference, you can use } yields[SolverChoice::recursive_default()] {
to restrict to only the recursive solver!
Are you up for trying to fix this? (The work done in #733 is great, but I need to go through it more thoroughly; can definitely work on fixing the actual problem concurrently though). If so, feel free to reach out on Zulip if you have questions or run into problems :)
Ah okay. For future reference, you can use
} yields[SolverChoice::recursive_default()] {
to restrict to only the recursive solver!
That's good to know, thanks!
Are you up for trying to fix this?
I am definitely interested in it, but time is currently a bit of an issue for me. I'm hoping to get around to looking at chalk more within the next two weeks; I'll claim the issue at that point if no one else has gotten started before then.
Found in rust-analyzer#7796: When trying to solve this goal:
Chalk keeps expanding the query when trying to normalize this:
It's tricky to translate the rust-analyzer example to a chalk test case because closures are involved, but hopefully this should be enough info to make the problem clear.