Skip to content

Commit a7eeeb5

Browse files
committed
Add automatic parameter instantiation. Closes #45.
1 parent 8559a85 commit a7eeeb5

File tree

3 files changed

+43
-8
lines changed

3 files changed

+43
-8
lines changed

src/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,7 @@ TEST_XFAILS_LLVM := $(TASK_XFAILS) \
431431
argv.rs \
432432
autoderef-full-lval.rs \
433433
autoderef-objfn.rs \
434+
auto-instantiate.rs \
434435
basic.rs \
435436
basic-1.rs \
436437
basic-2.rs \

src/boot/me/type.ml

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,8 @@ let check_stmt (cx:Semant.ctxt) : (fn_ctx -> Ast.stmt -> unit) =
154154
| ty -> type_error "record" ty
155155
in
156156
let demand_fn
157-
?param_handler:(param_handler=demand)
157+
?param_handler:(param_handler=
158+
fun a idx effect -> demand a (Ast.TY_param (idx, effect)))
158159
(arg_tys:Ast.ty option array)
159160
(actual:Ast.ty)
160161
: Ast.ty =
@@ -179,7 +180,8 @@ let check_stmt (cx:Semant.ctxt) : (fn_ctx -> Ast.stmt -> unit) =
179180
let maybe_demand a_opt b =
180181
match a_opt, b with
181182
None, _ -> ()
182-
| Some a, Ast.TY_param _ -> param_handler a b
183+
| Some a, Ast.TY_param (idx, effect) ->
184+
param_handler a idx effect
183185
| Some a, _ -> demand a b
184186
in
185187
Common.arr_iter2 maybe_demand arg_tys in_slot_tys;
@@ -504,12 +506,33 @@ let check_stmt (cx:Semant.ctxt) : (fn_ctx -> Ast.stmt -> unit) =
504506
| TYPAT_fn arg_tys, LTYPE_mono actual ->
505507
ignore (demand_fn (Array.map (fun ty -> Some ty) arg_tys) actual);
506508
yield_ty actual
507-
| TYPAT_fn _, LTYPE_poly (_, _) ->
508-
(* FIXME: auto-instantiate *)
509-
Common.unimpl
510-
None
511-
"instantiation of polymorphic function types; please supply type \
512-
parameters explicitly, sorry"
509+
| TYPAT_fn arg_tys, (LTYPE_poly (ty_params, ty) as lty) ->
510+
(* Perform automatic instantiation of polymorphic types. *)
511+
let ty = fundamental_ty ty in
512+
let substs = Array.make (Array.length ty_params) None in
513+
let param_handler substituted_ty idx _ =
514+
match substs.(idx) with
515+
| None -> substs.(idx) <- Some substituted_ty
516+
| Some substituted_ty' -> demand substituted_ty substituted_ty'
517+
in
518+
let arg_ty_opts = Array.map (fun ty -> Some ty) arg_tys in
519+
ignore (demand_fn ~param_handler:param_handler arg_ty_opts ty);
520+
let get_subst subst_opt =
521+
match subst_opt with
522+
Some subst -> subst
523+
| None ->
524+
Common.bug ()
525+
"internal_check_outer_lval: subst not found"
526+
in
527+
let substs = Array.map get_subst substs in
528+
begin
529+
match beta_reduce (Semant.lval_base_id lval) lty substs with
530+
LTYPE_mono ty -> yield_ty ty
531+
| _ ->
532+
Common.bug ()
533+
"internal_check_outer_lval: beta reduction didn't yield \
534+
a monotype"
535+
end
513536
| TYPAT_wild, (LTYPE_poly _ as lty) ->
514537
Common.err
515538
None

src/test/run-pass/auto-instantiate.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// -*- rust -*-
2+
3+
fn f[T,U](&T x, &U y) -> tup(T,U) {
4+
ret tup(x, y);
5+
}
6+
7+
fn main() -> () {
8+
log f(tup(3, 4, 5), 4)._0._0;
9+
log f(5, 6)._0;
10+
}
11+

0 commit comments

Comments
 (0)