Skip to content

Commit 6612840

Browse files
committed
Uniformize semantics of :> in class after deprecation phase of rocq-prover#16230
This ends the deprecation phases of rocq-prover#16230 and rocq-prover#15802 that introduced :: instead of :> for subclasses in Class declarations. Now :> means coercion in all record declarations (including typeclasses).
1 parent 7fec4bd commit 6612840

File tree

10 files changed

+93
-74
lines changed

10 files changed

+93
-74
lines changed

doc/sphinx/addendum/type-classes.rst

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -309,9 +309,8 @@ Command summary
309309
declared rigid during resolution so that the typeclass abstraction is
310310
maintained.
311311

312-
The `>` in
313-
:token:`record_definition` currently does nothing. In a future version, it will
314-
create coercions as it does when used in :cmd:`Record` commands.
312+
The `>` in :token:`record_definition`
313+
creates coercions as it does when used in :cmd:`Record` commands.
315314

316315
Like any command declaring a record, this command supports the
317316
:attr:`universes(polymorphic)`, :attr:`universes(template)`,
@@ -342,18 +341,9 @@ Command summary
342341

343342
This command has no effect when used on a typeclass.
344343

345-
.. _warn-future-coercion-class-field:
346-
347-
.. warn:: A coercion will be introduced instead of an instance in future versions when using ':>' in 'Class' declarations. Replace ':>' with '::' (or use '#[global] Existing Instance field.' for compatibility with Coq < 8.17).
348-
349-
In future versions, :g:`:>` in the :n:`@record_definition` or
350-
:n:`@constructor` will declare a :ref:`coercion<coercions>`, as
351-
it does for other :cmd:`Record` commands. To eliminate the warning, use
352-
:g:`::` instead.
353-
354344
.. warn:: Ignored instance declaration for “@ident”: “@term” is not a class
355345

356-
Using the ``::`` (or deprecated ``:>``) syntax in the :n:`@record_definition`
346+
Using the ``::`` syntax in the :n:`@record_definition`
357347
or :n:`@constructor` with a right-hand-side that
358348
is not itself a Class has no effect (apart from emitting this warning).
359349

doc/sphinx/language/core/records.rst

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,6 @@ Defining record types
9292
:n:`:>`
9393
If specified, the field is declared as a coercion from the record name
9494
to the class of the field type. See :ref:`coercions`.
95-
Note that this currently does something else in :cmd:`Class` commands.
9695

9796
:n:`::`
9897
If specified, the field is declared a typeclass instance of the class

test-suite/output/bug_16224.out

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
[reverse_coercion] : ReverseCoercionSource >-> ReverseCoercionTarget
2+
[cic] : Cic >-> A (reversible)
23
[rc] : Rc >-> A (reversible)
34
[ric] : Ric >-> A (reversible)
45
ric : Ric -> A
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
Module RecordNothing.
2+
Class B.
3+
Record A := { ab : B }.
4+
Parameter a : A.
5+
Fail Check a : B. (* no coercion *)
6+
Existing Class A.
7+
Existing Instance a.
8+
Fail Type _ : B. (* no typeclass instance *)
9+
End RecordNothing.
10+
11+
Module RecordCoercion.
12+
Class B.
13+
Record A := { ab :> B }.
14+
Parameter a : A.
15+
Check a : B. (* coercion *)
16+
Existing Class A.
17+
Existing Instance a.
18+
Fail Type _ : B. (* no typeclass instance *)
19+
End RecordCoercion.
20+
21+
Module RecordTC.
22+
Class B.
23+
Record A := { ab :: B }.
24+
Parameter a : A.
25+
Fail Check a : B. (* no coercion *)
26+
Existing Class A.
27+
Existing Instance a.
28+
Type _ : B. (* typeclass instance *)
29+
End RecordTC.
30+
31+
Module RecordCoercionTC.
32+
Class B.
33+
Record A := { ab ::> B }.
34+
Parameter a : A.
35+
Check a : B. (* coercion *)
36+
Existing Class A.
37+
Existing Instance a.
38+
Type _ : B. (* typeclass instance *)
39+
End RecordCoercionTC.
40+
41+
Module ClassNothing.
42+
Class B.
43+
Class A := { ab : B }.
44+
Parameter a : A.
45+
Fail Check a : B. (* no coercion *)
46+
Existing Instance a.
47+
Fail Type _ : B. (* no typeclass instance *)
48+
End ClassNothing.
49+
50+
Module ClassCoercion.
51+
Class B.
52+
Class A := { ab :> B }.
53+
Parameter a : A.
54+
Check a : B. (* coercion *)
55+
Existing Instance a.
56+
Fail Type _ : B. (* no typeclass instance *)
57+
End ClassCoercion.
58+
59+
Module ClassTC.
60+
Class B.
61+
Class A := { ab :: B }.
62+
Parameter a : A.
63+
Fail Check a : B. (* no coercion *)
64+
Existing Instance a.
65+
Type _ : B. (* typeclass instance *)
66+
End ClassTC.
67+
68+
Module ClassCoercionTC.
69+
Class B.
70+
Class A := { ab ::> B }.
71+
Parameter a : A.
72+
Check a : B. (* coercion *)
73+
Existing Instance a.
74+
Type _ : B. (* typeclass instance *)
75+
End ClassCoercionTC.

vernac/comInductive.ml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -735,8 +735,7 @@ let eq_params (up1,p1) (up2,p2) =
735735
let extract_coercions indl =
736736
let mkqid (_,({CAst.v=id},_)) = qualid_of_ident id in
737737
let iscoe (_, coe, inst) = match inst with
738-
(* remove BackInstanceWarning after deprecation phase *)
739-
| Vernacexpr.(NoInstance | BackInstanceWarning) -> coe = Vernacexpr.AddCoercion
738+
| Vernacexpr.NoInstance -> coe = Vernacexpr.AddCoercion
740739
| _ -> user_err (Pp.str "'::' not allowed in inductives.") in
741740
let extract lc = List.filter (fun (coe,_) -> iscoe coe) lc in
742741
List.map mkqid (List.flatten(List.map (fun (_,_,_,lc) -> extract lc) indl))

vernac/g_vernac.mlg

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -615,8 +615,8 @@ GRAMMAR EXTEND Gram
615615
| ":" -> { NoCoercion } ] ]
616616
;
617617
of_type_inst:
618-
[ [ ":>" -> { (AddCoercion, BackInstanceWarning) (* replace with NoInstance at end of deprecation phase *) }
619-
| ":"; ">" -> { (AddCoercion, BackInstanceWarning) (* replace with NoInstance at end of deprecation phase *) }
618+
[ [ ":>" -> { (AddCoercion, NoInstance) }
619+
| ":"; ">" -> { (AddCoercion, NoInstance) }
620620
| "::" -> { (NoCoercion, BackInstance) }
621621
| "::>" -> { (AddCoercion, BackInstance) }
622622
| ":" -> { (NoCoercion, NoInstance) } ] ]

vernac/ppvernac.ml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -566,7 +566,6 @@ let pr_oc coe ins = match coe, ins with
566566
| AddCoercion, NoInstance -> str" :>"
567567
| NoCoercion, BackInstance -> str" ::"
568568
| AddCoercion, BackInstance -> str" ::>"
569-
| _, BackInstanceWarning -> str" :>" (* remove this line at end of deprecation phase *)
570569

571570
let pr_record_field (x, { rfu_attrs = attr ; rfu_coercion = coe ; rfu_instance = ins ; rfu_priority = pri ; rfu_notation = ntn }) =
572571
let prx = match x with

vernac/record.ml

Lines changed: 8 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -391,10 +391,8 @@ let instantiate_possibly_recursive_type ind u ntypes paramdecls fields =
391391

392392
(** Declare projection [ref] over [from] a coercion
393393
or a typeclass instance according to [flags]. *)
394-
(* remove the last argument (it will become alway true) after deprecation phase
395-
(started in 8.17, c.f. https://github.com/coq/coq/pull/16230) *)
396-
let declare_proj_coercion_instance ~flags ref from ~with_coercion =
397-
if with_coercion && flags.Data.pf_coercion then begin
394+
let declare_proj_coercion_instance ~flags ref from =
395+
if flags.Data.pf_coercion then begin
398396
let cl = ComCoercion.class_of_global from in
399397
let local = flags.Data.pf_locality = Goptions.OptLocal in
400398
ComCoercion.try_add_new_coercion_with_source ref ~local ~reversible:flags.Data.pf_reversible ~source:cl
@@ -466,7 +464,7 @@ let build_named_proj ~primitive ~flags ~poly ~univs ~uinstance ~kind env paramde
466464
in
467465
let refi = GlobRef.ConstRef kn in
468466
Impargs.maybe_declare_manual_implicits false refi impls;
469-
declare_proj_coercion_instance ~flags refi (GlobRef.IndRef indsp) ~with_coercion:true;
467+
declare_proj_coercion_instance ~flags refi (GlobRef.IndRef indsp);
470468
let i = if is_local_assum decl then i+1 else i in
471469
(Some kn, i, Projection term::subst)
472470

@@ -683,38 +681,18 @@ let implicits_of_context ctx =
683681
| LocalAssum _ as d -> Some (RelDecl.get_name d))
684682
ctx)))
685683

686-
(* deprecated in 8.16, to be removed at the end of the deprecation phase
687-
(c.f., https://github.com/coq/coq/pull/15802 ) *)
688-
let warn_future_coercion_class_constructor =
689-
CWarnings.create ~name:"future-coercion-class-constructor" ~category:Deprecation.Version.v8_16
690-
~default:CWarnings.AsError
691-
Pp.(fun () -> str "'Class >' currently does nothing. Use 'Class' instead.")
692-
693-
(* deprecated in 8.17, to be removed at the end of the deprecation phase
694-
(c.f., https://github.com/coq/coq/pull/16230 ) *)
695-
let warn_future_coercion_class_field =
696-
CWarnings.create ~name:"future-coercion-class-field" ~category:Deprecation.Version.v8_17
697-
~default:CWarnings.AsError
698-
Pp.(fun definitional ->
699-
strbrk "A coercion will be introduced instead of an instance in future versions when using ':>' in 'Class' declarations. "
700-
++ strbrk "Replace ':>' with '::' (or use '#[global] Existing Instance field.' for compatibility with Coq < 8.18). Beware that the default locality for '::' is #[export], as opposed to #[global] for ':>' currently."
701-
++ strbrk (if definitional then " Add an explicit #[global] attribute if you need to keep the current behavior. For example: \"Class foo := #[global] baz :: bar.\""
702-
else " Add an explicit #[global] attribute to the field if you need to keep the current behavior. For example: \"Class foo := { #[global] field :: bar }.\""))
703-
704684
let check_proj_flags kind rf =
705685
let open Vernacexpr in
706686
let pf_coercion, pf_reversible =
707687
match rf.rf_coercion with
708-
(* replace "kind_class kind = NotClass" with true after deprecation phase *)
709-
| AddCoercion -> kind_class kind = NotClass, Option.default true rf.rf_reversible
688+
| AddCoercion -> true, Option.default true rf.rf_reversible
710689
| NoCoercion ->
711690
if rf.rf_reversible <> None then
712691
Attributes.(unsupported_attributes
713692
[CAst.make ("reversible (without :>)",VernacFlagEmpty)]);
714693
false, false in
715694
let pf_instance =
716-
match rf.rf_instance with NoInstance -> false | BackInstance -> true
717-
| BackInstanceWarning -> kind_class kind <> NotClass in
695+
match rf.rf_instance with NoInstance -> false | BackInstance -> true in
718696
let pf_priority = rf.rf_priority in
719697
let pf_locality =
720698
begin match rf.rf_coercion, rf.rf_instance with
@@ -728,19 +706,10 @@ let check_proj_flags kind rf =
728706
[CAst.make ("export (without ::)",VernacFlagEmpty)])
729707
| _ -> ()
730708
end; rf.rf_locality in
731-
(* remove following let after deprecation phase (started in 8.17,
732-
c.f., https://github.com/coq/coq/pull/16230 ) *)
733-
let pf_locality =
734-
match rf.rf_instance, rf.rf_locality with
735-
| BackInstanceWarning, Goptions.OptDefault -> Goptions.OptGlobal
736-
| _ -> pf_locality in
737709
let pf_canonical = rf.rf_canonical in
738710
Data.{ pf_coercion; pf_reversible; pf_instance; pf_priority; pf_locality; pf_canonical }
739711

740-
(* remove the definitional argument at the end of the deprecation phase
741-
(started in 8.17)
742-
(c.f., https://github.com/coq/coq/pull/16230 ) *)
743-
let pre_process_structure ?(definitional=false) ~auto_prop_lowering udecl kind ~poly (records : Ast.t list) =
712+
let pre_process_structure ~auto_prop_lowering udecl kind ~poly (records : Ast.t list) =
744713
let indlocs = check_unique_names records in
745714
let () = check_priorities kind records in
746715
let ps, data = extract_record_data records in
@@ -767,11 +736,6 @@ let pre_process_structure ?(definitional=false) ~auto_prop_lowering udecl kind ~
767736
Namegen.next_ident_away canonical_inhabitant_id (bound_names_rdata rdata)
768737
in
769738
let is_coercion = match is_coercion with AddCoercion -> true | NoCoercion -> false in
770-
if kind_class kind <> NotClass then begin
771-
if is_coercion then warn_future_coercion_class_constructor ();
772-
if List.exists (function (_, Vernacexpr.{ rf_instance = BackInstanceWarning; _ }) -> true | _ -> false) cfs then
773-
warn_future_coercion_class_field definitional
774-
end;
775739
{ Data.id = name.CAst.v; idbuild; rdata; is_coercion; proj_flags; inhabitant_id }
776740
in
777741
let data = List.map2 map data records in
@@ -920,7 +884,7 @@ let declare_class_constant ~univs paramimpls params data =
920884
Classes.set_typeclass_transparency ~locality:Hints.SuperGlobal
921885
[Evaluable.EvalConstRef cst] false;
922886
let () =
923-
declare_proj_coercion_instance ~flags:proj_flags (GlobRef.ConstRef proj_cst) cref ~with_coercion:false in
887+
declare_proj_coercion_instance ~flags:proj_flags (GlobRef.ConstRef proj_cst) cref in
924888
let m = {
925889
meth_name = Name proj_name;
926890
meth_info = None;
@@ -1086,16 +1050,11 @@ let definition_structure ~flags udecl kind ~primitive_proj (records : Ast.t list
10861050
finite;
10871051
} = flags in
10881052
let impargs, params, univs, variances, projections_kind, data, indlocs =
1089-
let definitional = kind_class kind = DefClass in
1090-
pre_process_structure ~auto_prop_lowering ~definitional udecl kind ~poly records
1053+
pre_process_structure ~auto_prop_lowering udecl kind ~poly records
10911054
in
10921055
let inds, def = match kind_class kind with
10931056
| DefClass -> declare_class_constant ~univs impargs params data
10941057
| RecordClass | NotClass ->
1095-
(* remove the following block after deprecation phase
1096-
(started in 8.16, c.f., https://github.com/coq/coq/pull/15802 ) *)
1097-
let data = if kind_class kind = NotClass then data else
1098-
List.map (fun d -> { d with Data.is_coercion = false }) data in
10991058
let structure =
11001059
interp_structure_core
11011060
~cumulative finite ~univs ~variances ~primitive_proj

vernac/vernacentries.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -918,7 +918,7 @@ let preprocess_inductive_decl ~atts kind indl =
918918
user_err Pp.(str "Definitional classes do not support the \">\" syntax.");
919919
let ((attr, rf_coercion, rf_instance), (lid, ce)) = l in
920920
let rf_locality = match rf_coercion, rf_instance with
921-
| AddCoercion, _ | _, (BackInstance | BackInstanceWarning) -> parse option_locality attr
921+
| AddCoercion, _ | _, BackInstance -> parse option_locality attr
922922
| _ -> let () = unsupported_attributes attr in Goptions.OptDefault in
923923
let f = AssumExpr ((make ?loc:lid.loc @@ Name lid.v), [], ce),
924924
{ rf_coercion ; rf_reversible = None ; rf_instance ; rf_priority = None ;
@@ -946,7 +946,7 @@ let preprocess_inductive_decl ~atts kind indl =
946946
| AddCoercion -> reversible
947947
| NoCoercion -> Notations.return None in
948948
let loc = match f.rfu_coercion, f.rfu_instance with
949-
| AddCoercion, _ | _, (BackInstance | BackInstanceWarning) -> option_locality
949+
| AddCoercion, _ | _, BackInstance -> option_locality
950950
| _ -> Notations.return Goptions.OptDefault in
951951
Notations.(rev ++ loc ++ canonical_field) in
952952
let (rf_reversible, rf_locality), rf_canonical = parse attr f.rfu_attrs in

vernac/vernacexpr.mli

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,10 +110,7 @@ type 'a search_restriction =
110110

111111
type verbose_flag = bool (* true = Verbose; false = Silent *)
112112
type coercion_flag = AddCoercion | NoCoercion
113-
(* Remove BackInstanceWarning at end of deprecation phase
114-
(this is just to print a warning when :> is used instead of ::
115-
to declare instances in classes) *)
116-
type instance_flag = BackInstance | BackInstanceWarning | NoInstance
113+
type instance_flag = BackInstance | NoInstance
117114

118115
type export_flag = Lib.export_flag = Export | Import
119116

0 commit comments

Comments
 (0)