Skip to content

Commit c017b97

Browse files
committed
Hard failure on missing factories + better error message
1 parent ec1b16d commit c017b97

13 files changed

+105
-47
lines changed

HB/about.elpi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ main-located S (loc-gref (const C)) :- factory-constructor (const C) _, !,
2929
main-located S (loc-gref (const C)) :- exported-op M _ C, !,
3030
private.main-operation S M C.
3131

32-
main-located S (loc-gref GR) :- factory-alias->gref GR F, not (F = GR), !,
32+
main-located S (loc-gref GR) :- factory-alias->gref GR F ok, not (F = GR), !,
3333
main-located S (loc-gref F).
3434

3535
main-located S (loc-abbreviation A) :- phant-abbrev GR PhB A, factory-constructor (indt F) GR, !,

HB/builders.elpi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ declare-shadowed-located Id (loc-abbreviation Abbrev) :-
100100

101101
pred postulate-factory-abbrev i:term, i:list term, i:id, i:factoryname, o:term.
102102
postulate-factory-abbrev TheType Params Name Falias TheFactory :- std.do! [
103-
factory-alias->gref Falias F,
103+
std.assert-ok! (factory-alias->gref Falias F) "HB",
104104
phant-abbrev F _ Fabv,
105105
coq.notation.abbreviation Fabv {std.append Params [TheType]} Package,
106106
Msg is "Unable to declare factory " ^ Name,

HB/common/database.elpi

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ abbrev-to-export_name (abbrev-to-export _ N _) N.
6161
pred abbrev-to-export_body i:prop, o:term.
6262
abbrev-to-export_body (abbrev-to-export _ _ B) (global B).
6363

64+
pred clause-to-export_clause i:prop, o:prop.
65+
clause-to-export_clause (clause-to-export _ C) C.
66+
6467
pred extract-builder i:prop, o:builder.
6568
extract-builder (builder-decl B) B.
6669

@@ -77,7 +80,7 @@ sub-class? (class C1 _ ML1P) (class C2 _ ML2P) :-
7780
% [factory-provides F MLwP] computes the mixins MLwP generated by F
7881
pred factory-provides i:factoryname, o:mixins.
7982
factory-provides FactoryAlias MLwP :- std.do! [
80-
factory-alias->gref FactoryAlias Factory,
83+
std.assert-ok! (factory-alias->gref FactoryAlias Factory) "HB",
8184
gref-deps Factory RMLwP,
8285
w-params.map RMLwP (factory-provides.base Factory) MLwP
8386
].
@@ -107,11 +110,11 @@ factory-provides.one Params T B M (triple M PL T) :- std.do! [
107110
pred extract-conclusion-params i:term, i:term, o:list term.
108111
extract-conclusion-params TheType (prod _ S T) R :- !,
109112
@pi-decl _ S x\ extract-conclusion-params TheType (T x) R.
110-
extract-conclusion-params TheType (app [global GR|Args]) R :- !,
111-
factory-alias->gref GR Factory,
113+
extract-conclusion-params TheType (app [global GR|Args]) R :- !, std.do! [
114+
std.assert-ok! (factory-alias->gref GR Factory) "HB",
112115
factory-nparams Factory NP,
113116
std.map Args (copy-pack-holes TheType TheType) NewArgs,
114-
std.take NP NewArgs R.
117+
std.take NP NewArgs R].
115118
extract-conclusion-params TheType T R :- whd1 T T1, !, extract-conclusion-params TheType T1 R.
116119

117120

@@ -128,17 +131,17 @@ factories-provide FLwP MLwP :- std.do! [
128131

129132
pred undup-grefs i:list gref, o:list gref.
130133
undup-grefs L UL :- std.do! [
131-
coq.gref.list->set L S,
134+
coq.gref.list->set L S,
132135
coq.gref.set.elements S UL,
133136
].
134137

135138
pred undup-sorts i:list sort, o:list sort.
136139
undup-sorts L R :- std.do! [
137-
140+
138141
if (std.mem L prop) (R1 = [prop]) (R1 = []),
139142
if (std.mem L sprop) (R2 = [sprop]) (R2 = []),
140143
if (std.mem L (typ _)) (R3 = [typ _]) (R3 = []),
141-
144+
142145
std.flatten [R1, R2, R3] R,
143146
].
144147

@@ -352,17 +355,17 @@ mixin-src->has-mixin-instance (mixin-src (global GR) M I) (has-mixin-instance (
352355

353356
mixin-src->has-mixin-instance (mixin-src (app [global GR|_] ) M I) (has-mixin-instance (cs-gref GR) M IHd) :-
354357
term->gref I IHd.
355-
358+
356359
mixin-src->has-mixin-instance (mixin-src (prod _ _ _ ) M I) (has-mixin-instance cs-prod M IHd):-
357360
term->gref I IHd.
358361

359362
mixin-src->has-mixin-instance (mixin-src (sort U) M I) (has-mixin-instance (cs-sort U) M IHd):-
360363
term->gref I IHd.
361364

362365
% this auxiliary function iterates over the list of arguments of an application,
363-
% and create the necessary unify condition for each arguments
366+
% and create the necessary unify condition for each arguments
364367
% and at the end returns the mixin-src clause with all the conditions
365-
pred mixin-instance-type->mixin-src.aux
368+
pred mixin-instance-type->mixin-src.aux
366369
i:list term, % list of arguments
367370
i:term, % head of the original application
368371
i:mixinname, % name of mixin
@@ -434,7 +437,9 @@ structure-nparams Structure NParams :-
434437
pred factory? i:term, o:w-args factoryname.
435438
factory? S (triple F Params T) :-
436439
not (var S), !,
437-
safe-dest-app S (global GR) Args, factory-alias->gref GR F, factory-nparams F NP, !,
440+
safe-dest-app S (global GR) Args,
441+
factory-alias->gref GR F ok,
442+
factory-nparams F NP, !,
438443
std.split-at NP Args Params [T|_].
439444

440445
% [find-max-classes Mixins Classes] states that Classes is a list of classes

HB/common/synthesis.elpi

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ builder->term Ps T Src Tgt B :- !, std.do! [
240240
pred instantiate-all-these-mixin-args i:term, i:term, i:list mixinname, o:term.
241241
instantiate-all-these-mixin-args (fun _ Tm F) T ML R :-
242242
coq.safe-dest-app Tm (global TmGR) _,
243-
factory-alias->gref TmGR M,
243+
factory-alias->gref TmGR M ok,
244244
std.mem! ML M,
245245
!,
246246
if (mixin-for T M X) true (coq.error "HB: Unable to find mixin" {nice-gref->string M} "on subject" {coq.term->string T}), !,
@@ -252,7 +252,7 @@ instantiate-all-these-mixin-args F _ _ F.
252252
pred instantiate-all-args-let i:term, i:term, o:term, o:diagnostic.
253253
instantiate-all-args-let (fun N Tm F) T (let N Tm X R) Diag :- !, std.do! [
254254
coq.safe-dest-app Tm (global TmGR) _,
255-
factory-alias->gref TmGR M,
255+
factory-alias->gref TmGR M ok,
256256
if (mixin-for T M X)
257257
(@pi-def N Tm X m\ instantiate-all-args-let (F m) T (R m) Diag)
258258
(Diag = error Msg,

HB/export.elpi

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ export.abbrev NiceName GR :- !,
2525
coq.env.current-library File,
2626
acc-clause current (abbrev-to-export File NiceName GR).
2727

28+
pred export.clause i:prop.
29+
export.clause Clause :- !,
30+
coq.env.current-library File,
31+
acc-clauses current [Clause, clause-to-export File Clause].
32+
2833
pred export.reexport-all-modules-and-CS i:option string.
2934
export.reexport-all-modules-and-CS Filter :- std.do! [
3035
coq.env.current-library File,
@@ -57,6 +62,11 @@ export.reexport-all-modules-and-CS Filter :- std.do! [
5762
if-verbose (coq.say {header} "exporting Abbreviations" AbbNames),
5863
std.forall2 AbbNames AbbBodies (n\b\@global! => log.coq.notation.add-abbreviation n 0 b ff _),
5964

65+
std.findall (clause-to-export File Clause_) ClausesL,
66+
if-verbose (coq.say {header} "exporting Clauses" Clauses),
67+
std.map ClausesL clause-to-export_clause Clauses,
68+
acc-clauses current Clauses
69+
6070
].
6171

6272

HB/factory.elpi

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@ kind factory-abbrev type.
1313
type by-classname gref -> factory-abbrev.
1414
type by-phantabbrev abbreviation -> factory-abbrev.
1515

16-
pred declare-abbrev i:id, i:factory-abbrev.
17-
declare-abbrev Name (by-classname GR) :-
16+
pred declare-abbrev i:id, i:factory-abbrev, o:abbreviation.
17+
declare-abbrev Name (by-classname GR) Abbrev :-
1818
% looks fishy (the parameters are not taken into account)
19-
@global! => log.coq.notation.add-abbreviation Name 1 (fun _ _ t\ app[global GR,t]) tt _.
20-
declare-abbrev Name (by-phantabbrev Abbr) :- std.do! [
19+
@global! => log.coq.notation.add-abbreviation Name 1 (fun _ _ t\ app[global GR,t]) tt Abbrev.
20+
declare-abbrev Name (by-phantabbrev Abbr) Abbrev :- std.do! [
2121
coq.notation.abbreviation-body Abbr Nargs AbbrTrm,
22-
@global! => log.coq.notation.add-abbreviation Name Nargs AbbrTrm tt _,
22+
@global! => log.coq.notation.add-abbreviation Name Nargs AbbrTrm tt Abbrev,
2323
].
2424

2525
pred argument->w-mixins i:argument, o:w-mixins argument.
@@ -186,7 +186,7 @@ declare-id-builder.aux GR Params TheType (fun `x` Ty x\x) :-
186186
% FactAbbrev is the short name for the factory (either an alias of the class record)
187187
pred mk-factory-abbrev i:string, i:gref, o:list prop, o:factory-abbrev.
188188
mk-factory-abbrev Str GR Aliases FactAbbrev :- !, std.do! [
189-
if (factory-alias->gref GR _)
189+
if (factory-alias->gref GR _ ok)
190190
(Aliases = [],
191191
FactAbbrev = by-classname GR)
192192
(phant.of-gref ff GR [] PhTerm,
@@ -303,7 +303,7 @@ declare-mixin-or-factory MixinSrcClauses SectionCanonicalInstance
303303

304304
export.module {calc (Module ^ ".Exports")} Exports,
305305

306-
GRDepsClauses => declare-abbrev Module FactAbbrev,
306+
GRDepsClauses => declare-abbrev Module FactAbbrev _,
307307
].
308308

309309

@@ -319,7 +319,7 @@ declare-factory-alias MixinSrcClauses SectionCanonicalInstance
319319
log.coq.env.add-const-noimplicits "axioms_" Ty1Closed _ @transparent! C,
320320

321321
std.assert! (safe-dest-app Ty1 (global PhF) _Args) "Argument must be a factory",
322-
std.assert! (factory-alias->gref PhF F) "BUG: Factory alias declaration missing",
322+
std.assert-ok! (factory-alias->gref PhF F) "HB",
323323
std.assert! (factory-constructor F FK) "BUG: Factory constructor missing",
324324

325325
MixinSrcClauses => synthesis.infer-all-gref-deps TheParams TheType FK MFK,
@@ -375,7 +375,7 @@ declare-factory-alias MixinSrcClauses SectionCanonicalInstance
375375

376376
export.module {calc (Module ^ ".Exports")} Exports,
377377

378-
GRDepsClauses => declare-abbrev Module FactAbbrev,
378+
GRDepsClauses => declare-abbrev Module FactAbbrev _,
379379
].
380380

381381
% [build-deps-for-projections I ML CL] builds a [gref-dep] for each projection P

HB/instance.elpi

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ declare-existing T0 F0 :- std.do! [
1313
"HB: declare-existing illtyped factory instance",
1414
std.assert! (coq.safe-dest-app FTy (global FactoryAlias) _)
1515
"The type of the instance is not a factory",
16-
factory-alias->gref FactoryAlias Factory,
16+
std.assert-ok! (factory-alias->gref FactoryAlias Factory) "HB: ",
1717
private.declare-instance Factory T F Clauses _ _,
1818
acc-clauses current Clauses,
1919
].
@@ -43,8 +43,7 @@ declare-const Name BodySkel TyWPSkel CFL CSL :- std.do! [
4343

4444
% identify the factory
4545
std.assert! (coq.safe-dest-app SectionTy (global FactoryAlias) Args) "The type of the instance is not a factory",
46-
if (factory-alias->gref FactoryAlias Factory) true
47-
(coq.error "HB:" {coq.term->string (global FactoryAlias)} "is not a factory or its library was not correctly imported"),
46+
std.assert-ok! (factory-alias->gref FactoryAlias Factory) "HB",
4847
std.assert! (factory-nparams Factory NParams) "Not a factory synthesized by HB",
4948

5049
% declare the constant for the factory instance
@@ -221,7 +220,7 @@ pred context.declare i:factories, o:mixins, o:list term, o:term, o:list prop, o:
221220

222221
pred mk-factory-sort-deps i:gref, o:list (pair id constant).
223222
mk-factory-sort-deps AliasGR CSL :- std.do! [
224-
factory-alias->gref AliasGR GR,
223+
std.assert-ok! (factory-alias->gref AliasGR GR) "HB: mk-factory-sort-deps",
225224
gref-deps GR MLwPRaw,
226225
context.declare MLwPRaw MLwP SortParams SortKey SortMSL _,
227226
SortMSL => synthesis.infer-all-gref-deps SortParams SortKey GR FSort,
@@ -246,7 +245,7 @@ mk-factory-sort-deps AliasGR CSL :- std.do! [
246245

247246
pred mk-factory-sort-factory i:gref, o:list (pair id constant), o:list (pair id constant).
248247
mk-factory-sort-factory AliasGR CFL CSL :- std.do! [
249-
factory-alias->gref AliasGR GR,
248+
std.assert-ok! (factory-alias->gref AliasGR GR) "HB",
250249
gref-deps GR MLwPRaw,
251250
context.declare MLwPRaw MLwP SortParams SortKey SortMSL _,
252251
SortMSL => synthesis.infer-all-gref-deps SortParams SortKey GR FSort,
@@ -321,7 +320,7 @@ add-mixin T FGR MakeCanon MissingMixin [MixinSrcCl, BuilderDeclCl] CSL :- std.do
321320

322321
std.assert-ok! (coq.typecheck Bo Ty) "declare-instances: mixin illtyped",
323322
safe-dest-app Ty (global MixinNameAlias) _,
324-
factory-alias->gref MixinNameAlias MixinName,
323+
std.assert-ok! (factory-alias->gref MixinNameAlias MixinName) "HB",
325324

326325
std.assert! (MissingMixin = MixinName) "HB: anomaly: we built the wrong mixin",
327326

HB/structure.elpi

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ declare Module BSkel Sort :- std.do! [
4141
ClassName Structure SortProjection ClassProjection Factories StructKeyClause,
4242

4343
w-params.map MLwP (_\_\_\ mk-nil) NilwP,
44-
ClassAlias = (factory-alias->gref ClassName ClassName),
44+
ClassAlias = (factory-alias->gref ClassName ClassName ok),
4545
CurrentClass = (class ClassName Structure MLwP),
4646
ClassName = indt ClassInd, coq.env.indt ClassInd _ _ _ _ [ClassK] _,
4747
GRDepsClauses =
@@ -124,7 +124,7 @@ declare Module BSkel Sort :- std.do! [
124124

125125
if-verbose (coq.say {header} "accumulating various props"),
126126
std.flatten [
127-
Factories, [ClassAlias], [is-structure Structure],
127+
Factories, [is-structure Structure],
128128
NewJoins, [class-def CurrentClass], GRDepsClauses,
129129
[gref-deps GRPack MLwP], MixinMems, [StructKeyClause]
130130
]
@@ -177,7 +177,8 @@ declare Module BSkel Sort :- std.do! [
177177

178178
if-verbose (coq.say {header} "abbreviation factory-by-classname"),
179179

180-
NewClauses => factory.declare-abbrev Module (factory.by-classname ClassName),
180+
ClassAlias => NewClauses => factory.declare-abbrev Module (factory.by-classname ClassName) ClassAbbrev,
181+
export.clause (phant-abbrev ClassName ClassName ClassAbbrev),
181182

182183
NewClauses => if-MC-compat (private.mc-compat-structure Module ModulePath MLToExport
183184
{w-params.nparams MLwP} ClassProjection GRPack),

HB/structures.v

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -129,9 +129,14 @@ pred phant-abbrev o:gref, o:gref, o:abbreviation.
129129
% [factory-alias->gref X GR] when X is already a factory X = GR
130130
% however, when X is a phantom abbreviated gref, we find the underlying
131131
% factory gref GR associated to it.
132-
pred factory-alias->gref i:gref, o:gref.
133-
factory-alias->gref PhGR GR :- phant-abbrev GR PhGR _, !.
134-
factory-alias->gref GR GR :- phant-abbrev GR _ _, !.
132+
pred factory-alias->gref i:gref, o:gref, o: diagnostic.
133+
factory-alias->gref PhGR GR ok :- phant-abbrev GR PhGR _, !.
134+
factory-alias->gref GR GR ok :- phant-abbrev GR _ _, !.
135+
factory-alias->gref GR _ (error Msg) :- !,
136+
Msg is {coq.term->string (global GR)} ^
137+
" is not a factory or its library (" ^
138+
{ std.string.concat "." {std.drop-last 1 {coq.gref->path GR} } } ^
139+
") was not correctly imported".
135140

136141
%%%%% Cache of known facts %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
137142

@@ -230,6 +235,7 @@ pred current-mode o:declaration.
230235
pred module-to-export o:string, o:id, o:modpath.
231236
pred instance-to-export o:string, o:id, o:constant.
232237
pred abbrev-to-export o:string, o:id, o:gref.
238+
pred clause-to-export o:string, o:prop.
233239

234240
%% database for HB.locate and HB.about %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
235241

@@ -268,7 +274,7 @@ Elpi Accumulate lp:{{
268274
main [str S] :- !,
269275
if (decl-location {coq.locate S} Loc)
270276
(coq.say "HB: synthesized in file" Loc)
271-
(coq.say "HB:" S "not synthesized by HB").
277+
(coq.say "HB" S "not synthesized by HB").
272278

273279
main _ :- coq.error "Usage: HB.locate <name>.".
274280
}}.
@@ -482,7 +488,7 @@ actions N :-
482488
coq.elpi.accumulate current "export.db" (clause _ _ (module-to-export File E)).
483489

484490
main [indt-decl D] :- record-decl->id D N, with-attributes (actions N).
485-
491+
486492
main _ :-
487493
coq.error "Usage: HB.mixin Record <MixinName> T of F A & … := { … }.".
488494
}}.
@@ -495,7 +501,7 @@ Elpi Export HB.mixin.
495501

496502
(** [HB.pack] and [HB.pack_for] are tactic-in-term synthesizing a structure
497503
instance.
498-
504+
499505
In the middle of a term, in a context expecting a [Structure.type],
500506
you can write [HB.pack T F] to use factory [F] to equip type [T] with
501507
[Structure]. If [T] is already a rich type, eg [T : OtherStructure.type]
@@ -504,7 +510,7 @@ Elpi Export HB.mixin.
504510
505511
If the context does not impose a [Structure.type] typing constraint, then
506512
you can use [HB.pack_for Structure.type T F].
507-
513+
508514
You can pass zero or more factories like [F] but they must all typecheck
509515
in the current context (the type is not enriched progressively).
510516
Structure instances are projected to their class in order to obtain a
@@ -645,7 +651,7 @@ Elpi Accumulate lp:{{
645651
main [const-decl N (some B) Arity] :- std.do! [
646652
% compute the universe for the structure (default )
647653
prod-last {coq.arity->term Arity} Ty,
648-
if (ground_term Ty) (Sort = Ty) (Sort = {{Type}}), sort Univ = Sort,
654+
if (ground_term Ty) (Sort = Ty) (Sort = {{Type}}), sort Univ = Sort,
649655
with-attributes (with-logging (structure.declare N B Univ)),
650656
].
651657

@@ -686,7 +692,7 @@ actions-compat ModuleName :-
686692
true.
687693

688694
main [const-decl N _ _] :- !, with-attributes (actions N).
689-
695+
690696
main _ :- coq.error "Usage: HB.structure Definition <ModuleName> := { A of <Factory1> A & … & <FactoryN> A }".
691697
}}.
692698
Elpi Typecheck.
@@ -839,7 +845,7 @@ actions N :-
839845

840846
main [indt-decl D] :- record-decl->id D N, with-attributes (actions N).
841847
main [const-decl N _ _] :- with-attributes (actions N).
842-
848+
843849
main _ :-
844850
coq.error "Usage: HB.factory Record <FactoryName> T of F A & … := { … }.\nUsage: HB.factory Definition <FactoryName> T of F A := t.".
845851
}}.
@@ -916,7 +922,7 @@ actions N :-
916922
begin-section N.
917923

918924
main [ctx-decl _] :- !, with-attributes (actions {calc ("Builders_" ^ {std.any->string {new_int} })}).
919-
925+
920926
main _ :- coq.error "Usage: HB.builders Context A (f : F1 A).".
921927
}}.
922928
Elpi Typecheck.
@@ -1208,5 +1214,5 @@ Notation "`Error_cannot_unify: t1 'with' t2" := (unify t1 t2 None)
12081214
Notation "`Error: t msg T" := (unify t _ (Some (msg%string, T)))
12091215
(at level 0, msg, T at level 0, format "`Error: t msg T", only printing) :
12101216
form_scope.
1211-
1217+
12121218
Global Open Scope string_scope.

_CoqProject.test-suite

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,9 @@ tests/saturate_on.v
9999
tests/bug_435.v
100100
tests/bug_447.v
101101

102+
tests/unimported_relevant_class.v
103+
tests/unimported_irrelevant_class.v
104+
102105
-R tests HB.tests
103106
-R examples HB.examples
104107

0 commit comments

Comments
 (0)