@@ -11,6 +11,12 @@ type ltype =
11
11
| LTYPE_poly of Ast .ty_param array * Ast .ty (* "big lambda" *)
12
12
| LTYPE_module of Ast .mod_items (* type of a module *)
13
13
14
+ (* A "type pattern" used for inference. *)
15
+ type ty_pat =
16
+ TYPAT_wild (* matches any type *)
17
+ | TYPAT_ty of Ast .ty (* matches only the given type *)
18
+ | TYPAT_fn of Ast .ty array (* matches a function with some arg types *)
19
+
14
20
type fn_ctx = {
15
21
fnctx_return_type : Ast .ty ;
16
22
fnctx_is_iter : bool ;
@@ -231,7 +237,7 @@ let check_stmt (cx:Semant.ctxt) : (fn_ctx -> Ast.stmt -> unit) =
231
237
232
238
(* Here the actual inference happens. *)
233
239
let internal_check_slot
234
- (infer :Ast.ty option )
240
+ (infer :ty_pat )
235
241
(defn_id :Common.node_id )
236
242
: Ast.ty =
237
243
let slot =
@@ -243,10 +249,10 @@ let check_stmt (cx:Semant.ctxt) : (fn_ctx -> Ast.stmt -> unit) =
243
249
" internal_check_slot: supplied defn wasn't a slot at all"
244
250
in
245
251
match infer, slot.Ast. slot_ty with
246
- Some expected , Some actual ->
252
+ TYPAT_ty expected , Some actual ->
247
253
demand expected actual;
248
254
actual
249
- | Some inferred , None ->
255
+ | TYPAT_ty inferred , None ->
250
256
iflog cx
251
257
(fun _ ->
252
258
log cx " setting auto slot #%d = %a to type %a"
@@ -258,9 +264,11 @@ let check_stmt (cx:Semant.ctxt) : (fn_ctx -> Ast.stmt -> unit) =
258
264
Hashtbl. replace cx.Semant. ctxt_all_defns defn_id
259
265
(Semant. DEFN_slot new_slot);
260
266
inferred
261
- | None , Some actual -> actual
262
- | None , None ->
267
+ | TYPAT_wild , Some actual -> actual
268
+ | TYPAT_wild , None ->
263
269
Common. err None " can't infer any type for this slot"
270
+ | TYPAT_fn _ , _ ->
271
+ Common. unimpl None " sorry, fn type patterns aren't implemented"
264
272
in
265
273
266
274
let internal_check_mod_item_decl
@@ -281,7 +289,7 @@ let check_stmt (cx:Semant.ctxt) : (fn_ctx -> Ast.stmt -> unit) =
281
289
in
282
290
283
291
let rec internal_check_base_lval
284
- (infer :Ast.ty option )
292
+ (infer :ty_pat )
285
293
(nbi :Ast.name_base Common.identified )
286
294
: ltype =
287
295
let lval_id = nbi.Common. id in
@@ -302,7 +310,7 @@ let check_stmt (cx:Semant.ctxt) : (fn_ctx -> Ast.stmt -> unit) =
302
310
(comp :Ast.lval_component )
303
311
: ltype =
304
312
let base_ity =
305
- match internal_check_lval None base with
313
+ match internal_check_lval TYPAT_wild base with
306
314
LTYPE_poly (_ , ty ) ->
307
315
Common. err None " can't index the polymorphic type '%a'"
308
316
Ast. sprintf_ty ty
@@ -459,7 +467,7 @@ let check_stmt (cx:Semant.ctxt) : (fn_ctx -> Ast.stmt -> unit) =
459
467
in
460
468
typecheck base_ity
461
469
462
- and internal_check_lval (infer :Ast.ty option ) (lval :Ast.lval ) : ltype =
470
+ and internal_check_lval (infer :ty_pat ) (lval :Ast.lval ) : ltype =
463
471
match lval with
464
472
Ast. LVAL_base nbi -> internal_check_base_lval infer nbi
465
473
| Ast. LVAL_ext (base , comp ) -> internal_check_ext_lval base comp
@@ -473,43 +481,50 @@ let check_stmt (cx:Semant.ctxt) : (fn_ctx -> Ast.stmt -> unit) =
473
481
and internal_check_outer_lval
474
482
~mut :(mut :Ast.mutability )
475
483
~deref :(deref :bool )
476
- ~fn_args :(fn_args :(Ast.ty array) option )
477
- (infer :Ast.ty option )
484
+ (infer :ty_pat )
478
485
(lval :Ast.lval )
479
486
: (Ast.ty * int) =
480
487
let yield_ty ty =
481
488
let (ty, n_boxes) = if deref then unbox ty else (ty, 0 ) in
482
489
(maybe_mutable mut ty, n_boxes)
483
490
in
484
491
match infer, internal_check_lval infer lval with
485
- | None , LTYPE_mono ty -> yield_ty ty
486
- | Some expected , LTYPE_mono actual ->
492
+ | TYPAT_wild , LTYPE_mono ty -> yield_ty ty
493
+ | TYPAT_ty expected , LTYPE_mono actual ->
487
494
demand expected actual;
488
495
yield_ty actual
489
- | None , (LTYPE_poly _ as lty ) ->
490
- begin
491
- match fn_args with
492
- None ->
493
- Common. err None
494
- " can't auto-instantiate %a" sprintf_ltype lty
495
- | Some args ->
496
- Common. err None " can't auto-instantiate %a on %d args"
497
- sprintf_ltype lty (Array. length args)
498
- end
499
- | Some _ , (LTYPE_poly _ ) ->
496
+ | TYPAT_fn _ , LTYPE_mono _ ->
497
+ (* FIXME: typecheck *)
498
+ Common. unimpl
499
+ None
500
+ " sorry, function type patterns aren't typechecked yet"
501
+ | TYPAT_wild , (LTYPE_poly _ as lty ) ->
502
+ Common. err
503
+ None
504
+ " not enough context to automatically instantiate the polymorphic \
505
+ type '%a'; supply type parameters explicitly"
506
+ sprintf_ltype lty
507
+ | TYPAT_ty expected , (LTYPE_poly _ as lty ) ->
508
+ (* FIXME: auto-instantiate *)
509
+ Common. unimpl
510
+ None
511
+ " sorry, automatic polymorphic instantiation of %a to %a isn't \
512
+ supported yet; please supply type parameters explicitly"
513
+ sprintf_ltype lty
514
+ Ast. sprintf_ty expected
515
+ | TYPAT_fn _ , (LTYPE_poly _ ) ->
500
516
(* FIXME: auto-instantiate *)
501
517
Common. unimpl
502
518
None
503
- " sorry, automatic polymorphic instantiation isn't supported yet; \
504
- please supply type parameters explicitly"
519
+ " sorry, automatic polymorphic instantiation of function types \
520
+ isn't supported yet; please supply type parameters explicitly"
505
521
| _ , LTYPE_module _ ->
506
522
Common. err None " can't refer to a module as a first-class value"
507
523
508
524
and generic_check_lval
509
525
~mut :(mut :Ast.mutability )
510
526
~deref :(deref :bool )
511
- ~fn_args :(fn_args :(Ast.ty array) option )
512
- (infer :Ast.ty option )
527
+ (infer :ty_pat )
513
528
(lval :Ast.lval )
514
529
: Ast.ty =
515
530
(* The lval we got is an impostor (it may contain unresolved TY_nameds).
@@ -524,11 +539,12 @@ let check_stmt (cx:Semant.ctxt) : (fn_ctx -> Ast.stmt -> unit) =
524
539
(if mut = Ast. MUT_mutable then " mutable" else " immutable" )
525
540
(if deref then " true" else " false" )
526
541
(match infer with
527
- None -> " <none>"
528
- | Some t -> Fmt. fmt_to_str Ast. fmt_ty t))
542
+ TYPAT_wild -> " _"
543
+ | TYPAT_ty t -> Fmt. fmt_to_str Ast. fmt_ty t
544
+ | TYPAT_fn _ -> " <fn>" (* FIXME *) ))
529
545
in
530
546
let (lval_ty, n_boxes) =
531
- internal_check_outer_lval ~mut ~deref ~fn_args infer lval
547
+ internal_check_outer_lval ~mut: mut ~deref: deref infer lval
532
548
in
533
549
let _ =
534
550
iflog cx
@@ -570,10 +586,9 @@ let check_stmt (cx:Semant.ctxt) : (fn_ctx -> Ast.stmt -> unit) =
570
586
and check_lval
571
587
?mut :(mut = Ast. MUT_immutable )
572
588
?deref:(deref= false )
573
- ?fn_args:(fn_args= None )
574
589
(lval:Ast.lval )
575
590
: Ast. ty =
576
- generic_check_lval ~fn_args ~ mut ~deref None lval
591
+ generic_check_lval ~mut: mut ~deref: deref TYPAT_wild lval
577
592
578
593
and check_atom ?deref :(deref = false ) (atom:Ast.atom ) : Ast. ty =
579
594
match atom with
@@ -582,16 +597,16 @@ let check_stmt (cx:Semant.ctxt) : (fn_ctx -> Ast.stmt -> unit) =
582
597
in
583
598
584
599
let infer_slot (ty :Ast.ty ) (slot_id :Common.node_id ) : unit =
585
- ignore (internal_check_slot (Some ty) slot_id)
600
+ ignore (internal_check_slot (TYPAT_ty ty) slot_id)
586
601
in
587
602
588
603
let infer_lval
589
604
?mut :(mut = Ast. MUT_immutable )
590
605
(ty:Ast.ty )
591
606
(lval:Ast.lval )
592
607
: unit =
593
- ignore (generic_check_lval ~ mut ~deref: false ~fn_args: None
594
- (Some (Ast. TY_mutable ty)) lval)
608
+ ignore (generic_check_lval ? mut:mut ~deref: false
609
+ (TYPAT_ty (Ast. TY_mutable ty)) lval)
595
610
in
596
611
597
612
(*
@@ -646,7 +661,7 @@ let check_stmt (cx:Semant.ctxt) : (fn_ctx -> Ast.stmt -> unit) =
646
661
* returns the return type. *)
647
662
let check_fn (callee :Ast.lval ) (args :Ast.atom array ) : Ast.ty =
648
663
let arg_tys = Array. map check_atom args in
649
- let callee_ty = check_lval callee ~fn_args: ( Some arg_tys) in
664
+ let callee_ty = check_lval callee in
650
665
demand_fn (Array. map (fun ty -> Some ty) arg_tys) callee_ty
651
666
in
652
667
0 commit comments