Improve `iSpecialize ("H" $! x1 .. xn)`.
Instead of doing all the instantiations by invoking a single type class search, it now performs the instantiations by invoking individual type class searches. This a.) gives better error messages and b.) works when `xj` depends on `xi`.

Owner
Thanks :)
Do you think we should have dedicated testcases for things like this? LambdaRust may stop using this feature at some point; also, it'd be nice to notice such regressions before lambdaRust is updated to a new Iris.

Maintainer
I don't think these things break arbitrarily, but I can put something involving a dependent type in
tests/proofmode.v
. 
Maintainer
I'm quite suspicious for this change, given that the default behavior of Coq tactics is to do a single typeclass (isn't it?). For example, it seems like it would prevent using mutually dependent type classes.

Maintainer
I don't understand what you mean. You could give an example of "mutually dependent type classes."

Maintainer
I don't have a specific example in mind, but imagine you have two typeclasses
A
andB
with one parameter each. Consider the typeclass search problemA ?x
,B ?x
. I.e., the search algorithm has to find an instance forA
and an instance forB
, such that the value of the parameter coincides. The only way to solve this problem properly is to consider bothA
andB
at the same time. If you consider them one after the other, you will potentially find a instance forA
that leaves no possibility forB
. 
Maintainer
Alright, in your problem this would be problematic when you have
Class C (x : A) := c : A x > B x > C x.
Then if you infer
C ?x
, it would backtrack on different instantiations ofA ?x
, but that would not happen when you inferA ?x
andB ?x
separately.In the code concerning this commit this problem does not apply: there is no nondeterminism when instantiating a universal quantifier (and hence no backtracking).

Maintainer
By the way, I initially implemented the idea of instantiating a list of universal quantifiers in one to improve performance. But as shown here, this optimization did not work out well with dependent types.

Maintainer
there is no nondeterminism when instantiating a universal quantifier (and hence no backtracking).
I don't see why there would be no nondeterminism, given that there is a typeclass search.

Maintainer
Because the instances of
IntoForall
are unique 
Maintainer
Right, but what if the expression I am using for instantiating triggers a typeclass search?

Maintainer
Alright, I see the problem, but this did not work with the old
iSpecialize
either, for example:From iris.proofmode Require Import tactics. Class A := a : nat. Class B := b : nat. Class C (x : A) (y : B). Instance a1 : A := 1. Instance a2 : A := 2. Instance b1 : B := 1. Instance c11 : C a1 b1. Goal ∀ M : ucmraT, (∀ (x : A) (y : B) (z : C x y), False) ∗ (False : uPred M). iIntros (M) "H". iPoseProof ("H" $! a1 b1) as "Hfoo". (* picks a1 b1 *) iSpecialize ("H" $! a1 b1 _). (* already failed work with the old iSpecialize *)

Maintainer
I was thinking of a situation like this:
From iris.proofmode Require Import tactics. Class A (n : nat) := a : True. Class B (n : nat) := b : n = 1. Instance a1 : A 1 := I. Instance a2 : A 2 := I. Instance b1 : B 1 := eq_refl. Goal ∀ M : ucmraT, (∀ n (x : A n) (y : B n), False) ∗ (False: uPred M). iIntros (M) "H". iPoseProof ("H" $! _) as "Hfoo". iSpecialize ("Hfoo" $! _ _). done.
It used to work, but no longer now. But now that I see an actual example, I am figuring out that this might not be THAT important.

Maintainer
It would be interesting to figure out how to make that AND the actual example work. I don't know.
Also, in the old setting I would not know how to achieve something like f1b30a2e.

mentioned in commit 0e1825e2

Maintainer
but I can put something involving a dependent type in tests/proofmode.v.
Done, see 0e1825e2.

Owner
Thanks :)