aboutsummaryrefslogtreecommitdiff
path: root/test-suite/success
diff options
context:
space:
mode:
authorGaëtan Gilbert2020-03-14 13:09:19 +0100
committerGaëtan Gilbert2020-03-14 13:09:19 +0100
commit1f984236f4bdc441b80f19bcc32424a45d8168f3 (patch)
tree36723e2bfcc13d7cf486404bd0cfdc26781f07bc /test-suite/success
parent5189661a3cc165d8f6cb943c07eb9d644f339102 (diff)
parent89d13a553d340ae2a49853597155ab45c0f5a0f4 (diff)
Merge PR #10858: Implementing postponed constraints in TC resolution
Reviewed-by: SkySkimmer Ack-by: Zimmi48 Ack-by: ejgallego
Diffstat (limited to 'test-suite/success')
-rw-r--r--test-suite/success/HintMode.v20
-rw-r--r--test-suite/success/Typeclasses.v61
2 files changed, 81 insertions, 0 deletions
diff --git a/test-suite/success/HintMode.v b/test-suite/success/HintMode.v
new file mode 100644
index 0000000000..decddb73d1
--- /dev/null
+++ b/test-suite/success/HintMode.v
@@ -0,0 +1,20 @@
+Module Postponing.
+
+Class In A T := { IsIn : A -> T -> Prop }.
+Class Empty T := { empty : T }.
+Class EmptyIn (A T : Type) `{In A T} `{Empty T} :=
+ { isempty : forall x, IsIn x empty -> False }.
+
+Hint Mode EmptyIn ! ! - - : typeclass_instances.
+Hint Mode Empty ! : typeclass_instances.
+Hint Mode In ! - : typeclass_instances.
+Existing Class IsIn.
+Goal forall A T `{In A T} `{Empty T} `{EmptyIn A T}, forall x : A, IsIn x empty -> False.
+ Proof.
+ intros.
+ eapply @isempty. (* Second goal needs to be solved first, to un-stuck the first one
+ (hence the Existing Class IsIn to allow finding the assumption of IsIn here) *)
+ all:typeclasses eauto.
+Qed.
+
+End Postponing.
diff --git a/test-suite/success/Typeclasses.v b/test-suite/success/Typeclasses.v
index 3f96bf2c35..66305dfefa 100644
--- a/test-suite/success/Typeclasses.v
+++ b/test-suite/success/Typeclasses.v
@@ -1,3 +1,64 @@
+Module applydestruct.
+ Class Foo (A : Type) :=
+ { bar : nat -> A;
+ baz : A -> nat }.
+ Hint Mode Foo + : typeclass_instances.
+
+ Class C (A : Type).
+ Hint Mode C + : typeclass_instances.
+
+ Variable fool : forall {A} {F : Foo A} (x : A), C A -> bar 0 = x.
+ (* apply leaves non-dependent subgoals of typeclass type
+ alone *)
+ Goal forall {A} {F : Foo A} (x : A), bar 0 = x.
+ Proof.
+ intros. apply fool.
+ match goal with
+ |[ |- C A ] => idtac
+ end.
+ Abort.
+
+ Variable fooli : forall {A} {F : Foo A} {c : C A} (x : A), bar 0 = x.
+ (* apply tries to resolve implicit argument typeclass
+ constraints. *)
+ Goal forall {A} {F : Foo A} (x : A), bar 0 = x.
+ Proof.
+ intros.
+ Fail apply fooli.
+ Fail unshelve eapply fooli; solve [typeclasses eauto].
+ eapply fooli.
+ Abort.
+
+ (* It applies resolution after unification of the goal *)
+ Goal forall {A} {F : Foo A} {C : C A} (x : A), bar 0 = x.
+ Proof.
+ intros. apply fooli.
+ Abort.
+ Set Typeclasses Debug Verbosity 2.
+
+ Inductive bazdestr {A} (F : Foo A) : nat -> Prop :=
+ | isbas : bazdestr F 1.
+
+ Variable fooinv : forall {A} {F : Foo A} (x : A),
+ bazdestr F (baz x).
+
+ (* Destruct applies resolution early, before finding
+ occurrences to abstract. *)
+ Goal forall {A} {F : Foo A} {C : C A} (x : A), baz x = 0.
+ Proof.
+ intros. Fail destruct (fooinv _).
+ destruct (fooinv x).
+ Abort.
+
+ Goal forall {A} {F : Foo A} (x y : A), x = y.
+ Proof.
+ intros. rewrite <- (fool x). rewrite <- (fool y). reflexivity.
+ match goal with
+ |[ |- C A ] => idtac
+ end.
+ Abort.
+End applydestruct.
+
Module onlyclasses.
(* In 8.6 we still allow non-class subgoals *)