@@ -14,6 +14,7 @@ open Common;;
14
14
*
15
15
*)
16
16
17
+ exception Resolution_failure of (Ast. name * Ast. name) list
17
18
18
19
let log cx = Session. log " resolve"
19
20
(should_log cx cx.ctxt_sess.Session. sess_log_resolve)
@@ -228,14 +229,6 @@ let all_item_collecting_visitor
228
229
Walk. visit_stmt_pre = visit_stmt_pre; }
229
230
;;
230
231
231
- let report_error (full_name :Ast.name ) (unbound_name :Ast.name ) =
232
- if full_name = unbound_name then
233
- err None " unbound name '%a'" Ast. sprintf_name full_name
234
- else
235
- err None " unbound name '%a' in name '%a'" Ast. sprintf_name unbound_name
236
- Ast. sprintf_name full_name
237
- ;;
238
-
239
232
let lookup_type_node_by_name
240
233
(cx :ctxt )
241
234
(scopes :scope list )
@@ -245,7 +238,7 @@ let lookup_type_node_by_name
245
238
log cx " lookup_simple_type_by_name %a"
246
239
Ast. sprintf_name name);
247
240
match lookup_by_name cx [] scopes name with
248
- RES_failed name' -> report_error name name'
241
+ RES_failed name' -> raise ( Resolution_failure [ name', name ])
249
242
| RES_ok (_ , id ) ->
250
243
match htab_search cx.ctxt_all_defns id with
251
244
Some (DEFN_item { Ast. decl_item = Ast. MOD_ITEM_type _ ;
@@ -270,6 +263,24 @@ let push_node r n =
270
263
{ recur_all_nodes = n :: r .recur_all_nodes }
271
264
272
265
266
+ let report_resolution_failure type_names =
267
+ let rec recur type_names str =
268
+ let stringify_pair (part , whole ) =
269
+ if part = whole then
270
+ Printf. sprintf " '%a'" Ast. sprintf_name part
271
+ else
272
+ Printf. sprintf " '%a' in name '%a'" Ast. sprintf_name part
273
+ Ast. sprintf_name whole
274
+ in
275
+ match type_names with
276
+ [] -> bug () " no name in resolution failure"
277
+ | [ pair ] -> err None " unbound name %s%s" (stringify_pair pair) str
278
+ | pair ::pairs ->
279
+ recur pairs
280
+ (Printf. sprintf " while resolving %s" (stringify_pair pair))
281
+ in
282
+ recur type_names " "
283
+
273
284
let rec lookup_type_by_name
274
285
?loc :loc
275
286
(cx :ctxt )
@@ -281,7 +292,7 @@ let rec lookup_type_by_name
281
292
log cx " +++ lookup_type_by_name %a"
282
293
Ast. sprintf_name name);
283
294
match lookup_by_name cx [] scopes name with
284
- RES_failed name' -> report_error name name'
295
+ RES_failed name' -> raise ( Resolution_failure [ name', name ])
285
296
| RES_ok (scopes' , id ) ->
286
297
let ty, params =
287
298
match htab_search cx.ctxt_all_defns id with
@@ -358,15 +369,19 @@ and resolve_type
358
369
in
359
370
iflog cx (fun _ ->
360
371
log cx " resolved type name '%a' to item %d with ty %a"
361
- Ast. sprintf_name name (int_of_node node) Ast. sprintf_ty t);
372
+ Ast. sprintf_name name (int_of_node node)
373
+ Ast. sprintf_ty t);
362
374
if List. mem node recur.recur_all_nodes
363
375
then (err (Some node) " infinite recursive type definition: '%a'"
364
376
Ast. sprintf_name name)
365
377
else
366
378
let recur = push_node recur node in
367
379
iflog cx (fun _ -> log cx " recursively resolving type %a"
368
380
Ast. sprintf_ty t);
369
- resolve_type ?loc:loc cx scopes recur t
381
+ try
382
+ resolve_type ?loc:loc cx scopes recur t
383
+ with Resolution_failure names ->
384
+ raise (Resolution_failure ((name, name)::names))
370
385
in
371
386
let fold =
372
387
{ base with
@@ -388,9 +403,11 @@ let type_resolving_visitor
388
403
389
404
let tinfos = Hashtbl. create 0 in
390
405
391
- let resolve_ty (t :Ast.ty ) : Ast.ty =
392
- resolve_type ~loc: (id_of_scope (List. hd (! scopes)))
393
- cx (! scopes) empty_recur_info t
406
+ let resolve_ty ?(loc =id_of_scope (List. hd (! scopes))) (t :Ast.ty ) : Ast.ty =
407
+ try
408
+ resolve_type ~loc: loc cx (! scopes) empty_recur_info t
409
+ with Resolution_failure pairs ->
410
+ report_resolution_failure pairs
394
411
in
395
412
396
413
let resolve_slot (s :Ast.slot ) : Ast.slot =
@@ -422,19 +439,15 @@ let type_resolving_visitor
422
439
let visit_mod_item_pre id params item =
423
440
let resolve_and_store_type _ =
424
441
let t = ty_of_mod_item item in
425
- let ty =
426
- resolve_type ~loc: item.id cx (! scopes) empty_recur_info t
427
- in
442
+ let ty = resolve_ty ~loc: item.id t in
428
443
log cx " resolved item %s, type as %a" id Ast. sprintf_ty ty;
429
444
htab_put cx.ctxt_all_item_types item.id ty;
430
445
in
431
446
begin
432
447
try
433
448
match item.node.Ast. decl_item with
434
449
Ast. MOD_ITEM_type (_ , ty ) ->
435
- let ty =
436
- resolve_type ~loc: item.id cx (! scopes) empty_recur_info ty
437
- in
450
+ let ty = resolve_ty ~loc: item.id ty in
438
451
log cx " resolved item %s, defining type %a"
439
452
id Ast. sprintf_ty ty;
440
453
htab_put cx.ctxt_all_type_items item.id ty;
@@ -478,10 +491,7 @@ let type_resolving_visitor
478
491
in
479
492
480
493
let visit_obj_fn_pre obj ident fn =
481
- let fty =
482
- resolve_type ~loc: fn.id cx (! scopes)
483
- empty_recur_info (Ast. TY_fn (ty_fn_of_fn fn.node))
484
- in
494
+ let fty = resolve_ty ~loc: fn.id (Ast. TY_fn (ty_fn_of_fn fn.node)) in
485
495
log cx " resolved obj fn %s as %a" ident Ast. sprintf_ty fty;
486
496
htab_put cx.ctxt_all_item_types fn.id fty;
487
497
inner.Walk. visit_obj_fn_pre obj ident fn
0 commit comments