change variance syntax
git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@3298 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02master
parent
4d30d52fb6
commit
5dfbff7f5e
24
.depend
24
.depend
|
@ -173,15 +173,15 @@ typing/typeclass.cmo: parsing/asttypes.cmi typing/btype.cmi utils/clflags.cmo \
|
|||
parsing/location.cmi parsing/longident.cmi utils/misc.cmi \
|
||||
typing/parmatch.cmi parsing/parsetree.cmi typing/path.cmi \
|
||||
typing/predef.cmi typing/printtyp.cmi typing/typecore.cmi \
|
||||
typing/typedtree.cmi typing/types.cmi typing/typetexp.cmi \
|
||||
utils/warnings.cmi typing/typeclass.cmi
|
||||
typing/typedecl.cmi typing/typedtree.cmi typing/types.cmi \
|
||||
typing/typetexp.cmi utils/warnings.cmi typing/typeclass.cmi
|
||||
typing/typeclass.cmx: parsing/asttypes.cmi typing/btype.cmx utils/clflags.cmx \
|
||||
typing/ctype.cmx typing/env.cmx typing/ident.cmx typing/includeclass.cmx \
|
||||
parsing/location.cmx parsing/longident.cmx utils/misc.cmx \
|
||||
typing/parmatch.cmx parsing/parsetree.cmi typing/path.cmx \
|
||||
typing/predef.cmx typing/printtyp.cmx typing/typecore.cmx \
|
||||
typing/typedtree.cmx typing/types.cmx typing/typetexp.cmx \
|
||||
utils/warnings.cmx typing/typeclass.cmi
|
||||
typing/typedecl.cmx typing/typedtree.cmx typing/types.cmx \
|
||||
typing/typetexp.cmx utils/warnings.cmx typing/typeclass.cmi
|
||||
typing/typecore.cmo: parsing/asttypes.cmi typing/btype.cmi utils/clflags.cmo \
|
||||
typing/ctype.cmi typing/env.cmi typing/ident.cmi parsing/location.cmi \
|
||||
parsing/longident.cmi utils/misc.cmi typing/parmatch.cmi \
|
||||
|
@ -194,17 +194,17 @@ typing/typecore.cmx: parsing/asttypes.cmi typing/btype.cmx utils/clflags.cmx \
|
|||
parsing/parsetree.cmi typing/path.cmx typing/predef.cmx \
|
||||
typing/printtyp.cmx typing/typedtree.cmx typing/types.cmx \
|
||||
typing/typetexp.cmx utils/warnings.cmx typing/typecore.cmi
|
||||
typing/typedecl.cmo: typing/btype.cmi utils/clflags.cmo utils/config.cmi \
|
||||
typing/ctype.cmi typing/env.cmi typing/ident.cmi typing/includecore.cmi \
|
||||
parsing/location.cmi parsing/longident.cmi utils/misc.cmi \
|
||||
parsing/parsetree.cmi typing/path.cmi typing/predef.cmi \
|
||||
typing/typedecl.cmo: parsing/asttypes.cmi typing/btype.cmi utils/clflags.cmo \
|
||||
utils/config.cmi typing/ctype.cmi typing/env.cmi typing/ident.cmi \
|
||||
typing/includecore.cmi parsing/location.cmi parsing/longident.cmi \
|
||||
utils/misc.cmi parsing/parsetree.cmi typing/path.cmi typing/predef.cmi \
|
||||
typing/primitive.cmi typing/printtyp.cmi typing/subst.cmi \
|
||||
typing/typedtree.cmi typing/types.cmi typing/typetexp.cmi \
|
||||
typing/typedecl.cmi
|
||||
typing/typedecl.cmx: typing/btype.cmx utils/clflags.cmx utils/config.cmx \
|
||||
typing/ctype.cmx typing/env.cmx typing/ident.cmx typing/includecore.cmx \
|
||||
parsing/location.cmx parsing/longident.cmx utils/misc.cmx \
|
||||
parsing/parsetree.cmi typing/path.cmx typing/predef.cmx \
|
||||
typing/typedecl.cmx: parsing/asttypes.cmi typing/btype.cmx utils/clflags.cmx \
|
||||
utils/config.cmx typing/ctype.cmx typing/env.cmx typing/ident.cmx \
|
||||
typing/includecore.cmx parsing/location.cmx parsing/longident.cmx \
|
||||
utils/misc.cmx parsing/parsetree.cmi typing/path.cmx typing/predef.cmx \
|
||||
typing/primitive.cmx typing/printtyp.cmx typing/subst.cmx \
|
||||
typing/typedtree.cmx typing/types.cmx typing/typetexp.cmx \
|
||||
typing/typedecl.cmi
|
||||
|
|
|
@ -144,8 +144,7 @@ let search_pos_type_decl td ~pos ~env =
|
|||
| None -> ()
|
||||
end;
|
||||
begin match td.ptype_kind with
|
||||
Ptype_abstract None -> ()
|
||||
| Ptype_abstract(Some t) -> search_pos_type t ~pos ~env
|
||||
Ptype_abstract -> ()
|
||||
| Ptype_variant dl ->
|
||||
List.iter dl
|
||||
~f:(fun (_, tl) -> List.iter tl ~f:(search_pos_type ~pos ~env))
|
||||
|
|
|
@ -292,8 +292,9 @@ rule token = parse
|
|||
| ">}" { GREATERRBRACE }
|
||||
|
||||
| "!=" { INFIXOP0 "!=" }
|
||||
| "-" { SUBTRACTIVE "-" }
|
||||
| "-." { SUBTRACTIVE "-." }
|
||||
| "+" { PLUS }
|
||||
| "-" { MINUS }
|
||||
| "-." { MINUSDOT }
|
||||
|
||||
| "!" symbolchar *
|
||||
{ PREFIXOP(Lexing.lexeme lexbuf) }
|
||||
|
|
|
@ -257,6 +257,8 @@ let bigarray_set arr arg newval =
|
|||
%token LPAREN
|
||||
%token MATCH
|
||||
%token METHOD
|
||||
%token MINUS
|
||||
%token MINUSDOT
|
||||
%token MINUSGREATER
|
||||
%token MODULE
|
||||
%token MUTABLE
|
||||
|
@ -267,6 +269,7 @@ let bigarray_set arr arg newval =
|
|||
%token <string> OPTLABEL
|
||||
%token OR
|
||||
%token PARSER
|
||||
%token PLUS
|
||||
%token <string> PREFIXOP
|
||||
%token PRIVATE
|
||||
%token QUESTION
|
||||
|
@ -283,7 +286,6 @@ let bigarray_set arr arg newval =
|
|||
%token STAR
|
||||
%token <string> STRING
|
||||
%token STRUCT
|
||||
%token <string> SUBTRACTIVE
|
||||
%token THEN
|
||||
%token TILDE
|
||||
%token TO
|
||||
|
@ -316,7 +318,7 @@ let bigarray_set arr arg newval =
|
|||
%left INFIXOP0 EQUAL LESS GREATER /* = < > etc */
|
||||
%right INFIXOP1 /* @ ^ etc */
|
||||
%right COLONCOLON /* :: */
|
||||
%left INFIXOP2 SUBTRACTIVE /* + - */
|
||||
%left INFIXOP2 PLUS MINUS MINUSDOT /* + - */
|
||||
%left INFIXOP3 STAR /* * / */
|
||||
%right INFIXOP4 /* ** */
|
||||
%right prec_unary_minus /* - unary */
|
||||
|
@ -504,7 +506,9 @@ class_declarations:
|
|||
;
|
||||
class_declaration:
|
||||
virtual_flag class_type_parameters LIDENT class_fun_binding
|
||||
{ {pci_virt = $1; pci_params = $2; pci_name = $3; pci_expr = $4;
|
||||
{ let params, variance = List.split (fst $2) in
|
||||
{pci_virt = $1; pci_params = params, snd $2;
|
||||
pci_name = $3; pci_expr = $4; pci_variance = variance;
|
||||
pci_loc = symbol_rloc ()} }
|
||||
;
|
||||
class_fun_binding:
|
||||
|
@ -689,7 +693,9 @@ class_descriptions:
|
|||
;
|
||||
class_description:
|
||||
virtual_flag class_type_parameters LIDENT COLON class_type
|
||||
{ {pci_virt = $1; pci_params = $2; pci_name = $3; pci_expr = $5;
|
||||
{ let params, variance = List.split (fst $2) in
|
||||
{pci_virt = $1; pci_params = params, snd $2;
|
||||
pci_name = $3; pci_expr = $5; pci_variance = variance;
|
||||
pci_loc = symbol_rloc ()} }
|
||||
;
|
||||
class_type_declarations:
|
||||
|
@ -698,7 +704,9 @@ class_type_declarations:
|
|||
;
|
||||
class_type_declaration:
|
||||
virtual_flag class_type_parameters LIDENT EQUAL class_signature
|
||||
{ {pci_virt = $1; pci_params = $2; pci_name = $3; pci_expr = $5;
|
||||
{ let params, variance = List.split (fst $2) in
|
||||
{pci_virt = $1; pci_params = params, snd $2;
|
||||
pci_name = $3; pci_expr = $5; pci_variance = variance;
|
||||
pci_loc = symbol_rloc ()} }
|
||||
;
|
||||
|
||||
|
@ -800,8 +808,12 @@ expr:
|
|||
{ mkinfix $1 $2 $3 }
|
||||
| expr INFIXOP4 expr
|
||||
{ mkinfix $1 $2 $3 }
|
||||
| expr SUBTRACTIVE expr
|
||||
{ mkinfix $1 $2 $3 }
|
||||
| expr PLUS expr
|
||||
{ mkinfix $1 "+" $3 }
|
||||
| expr MINUS expr
|
||||
{ mkinfix $1 "-" $3 }
|
||||
| expr MINUSDOT expr
|
||||
{ mkinfix $1 "-." $3 }
|
||||
| expr STAR expr
|
||||
{ mkinfix $1 "*" $3 }
|
||||
| expr EQUAL expr
|
||||
|
@ -820,7 +832,7 @@ expr:
|
|||
{ mkinfix $1 "&&" $3 }
|
||||
| expr COLONEQUAL expr
|
||||
{ mkinfix $1 ":=" $3 }
|
||||
| SUBTRACTIVE expr %prec prec_unary_minus
|
||||
| subtractive expr %prec prec_unary_minus
|
||||
{ mkuminus $1 $2 }
|
||||
| simple_expr DOT label_longident LESSMINUS expr
|
||||
{ mkexp(Pexp_setfield($1, $3, $5)) }
|
||||
|
@ -1144,11 +1156,13 @@ type_declarations:
|
|||
;
|
||||
type_declaration:
|
||||
type_parameters LIDENT type_kind constraints
|
||||
{ let (kind, manifest) = $3 in
|
||||
($2, {ptype_params = $1;
|
||||
{ let (params, variance) = List.split $1 in
|
||||
let (kind, manifest) = $3 in
|
||||
($2, {ptype_params = params;
|
||||
ptype_cstrs = List.rev $4;
|
||||
ptype_kind = kind;
|
||||
ptype_manifest = manifest;
|
||||
ptype_variance = variance;
|
||||
ptype_loc = symbol_rloc()}) }
|
||||
;
|
||||
constraints:
|
||||
|
@ -1157,11 +1171,9 @@ constraints:
|
|||
;
|
||||
type_kind:
|
||||
/*empty*/
|
||||
{ (Ptype_abstract None, None) }
|
||||
| AS core_type
|
||||
{ (Ptype_abstract (Some $2), None) }
|
||||
{ (Ptype_abstract, None) }
|
||||
| EQUAL core_type %prec prec_type_def
|
||||
{ (Ptype_abstract None, Some $2) }
|
||||
{ (Ptype_abstract, Some $2) }
|
||||
| EQUAL constructor_declarations
|
||||
{ (Ptype_variant(List.rev $2), None) }
|
||||
| EQUAL BAR constructor_declarations
|
||||
|
@ -1180,7 +1192,12 @@ type_parameters:
|
|||
| LPAREN type_parameter_list RPAREN { List.rev $2 }
|
||||
;
|
||||
type_parameter:
|
||||
QUOTE ident { $2 }
|
||||
type_variance QUOTE ident { $3, $1 }
|
||||
;
|
||||
type_variance:
|
||||
/* empty */ { false, false }
|
||||
| PLUS { true, false }
|
||||
| MINUS { false, true }
|
||||
;
|
||||
type_parameter_list:
|
||||
type_parameter { [$1] }
|
||||
|
@ -1213,10 +1230,12 @@ with_constraints:
|
|||
;
|
||||
with_constraint:
|
||||
TYPE type_parameters label_longident EQUAL core_type constraints
|
||||
{ ($3, Pwith_type {ptype_params = $2;
|
||||
{ let params, variance = List.split $2 in
|
||||
($3, Pwith_type {ptype_params = params;
|
||||
ptype_cstrs = List.rev $6;
|
||||
ptype_kind = Ptype_abstract None;
|
||||
ptype_kind = Ptype_abstract;
|
||||
ptype_manifest = Some $5;
|
||||
ptype_variance = variance;
|
||||
ptype_loc = symbol_rloc()}) }
|
||||
/* used label_longident instead of type_longident to disallow
|
||||
functor applications in type path */
|
||||
|
@ -1229,8 +1248,8 @@ with_constraint:
|
|||
core_type:
|
||||
core_type2
|
||||
{ $1 }
|
||||
| core_type2 AS type_parameter
|
||||
{ mktyp(Ptyp_alias($1, $3)) }
|
||||
| core_type2 AS QUOTE ident
|
||||
{ mktyp(Ptyp_alias($1, $4)) }
|
||||
;
|
||||
core_type2:
|
||||
simple_core_type_or_tuple
|
||||
|
@ -1351,8 +1370,8 @@ constant:
|
|||
;
|
||||
signed_constant:
|
||||
constant { $1 }
|
||||
| SUBTRACTIVE INT { Const_int(- $2) }
|
||||
| SUBTRACTIVE FLOAT { Const_float("-" ^ $2) }
|
||||
| MINUS INT { Const_int(- $2) }
|
||||
| subtractive FLOAT { Const_float("-" ^ $2) }
|
||||
;
|
||||
/* Identifiers and long identifiers */
|
||||
|
||||
|
@ -1376,7 +1395,9 @@ operator:
|
|||
| INFIXOP2 { $1 }
|
||||
| INFIXOP3 { $1 }
|
||||
| INFIXOP4 { $1 }
|
||||
| SUBTRACTIVE { $1 }
|
||||
| PLUS { "+" }
|
||||
| MINUS { "-" }
|
||||
| MINUSDOT { "-." }
|
||||
| STAR { "*" }
|
||||
| EQUAL { "=" }
|
||||
| LESS { "<" }
|
||||
|
@ -1481,4 +1502,8 @@ opt_semi:
|
|||
| /* empty */ { () }
|
||||
| SEMI { () }
|
||||
;
|
||||
subtractive:
|
||||
| MINUS { "-" }
|
||||
| MINUSDOT { "-." }
|
||||
;
|
||||
%%
|
||||
|
|
|
@ -48,6 +48,7 @@ type 'a class_infos =
|
|||
pci_params: string list * Location.t;
|
||||
pci_name: string;
|
||||
pci_expr: 'a;
|
||||
pci_variance: (bool * bool) list;
|
||||
pci_loc: Location.t }
|
||||
|
||||
(* Value expressions for the core language *)
|
||||
|
@ -114,10 +115,11 @@ and type_declaration =
|
|||
ptype_cstrs: (core_type * core_type * Location.t) list;
|
||||
ptype_kind: type_kind;
|
||||
ptype_manifest: core_type option;
|
||||
ptype_variance: (bool * bool) list;
|
||||
ptype_loc: Location.t }
|
||||
|
||||
and type_kind =
|
||||
Ptype_abstract of core_type option
|
||||
Ptype_abstract
|
||||
| Ptype_variant of (string * core_type list) list
|
||||
| Ptype_record of (string * mutable_flag * core_type) list
|
||||
|
||||
|
|
|
@ -286,9 +286,8 @@ and type_declaration i ppf x =
|
|||
|
||||
and type_kind i ppf x =
|
||||
match x with
|
||||
| Ptype_abstract (x) ->
|
||||
line i ppf "Ptype_abstract\n";
|
||||
option (i+1) core_type ppf x;
|
||||
| Ptype_abstract ->
|
||||
line i ppf "Ptype_abstract\n"
|
||||
| Ptype_variant (l) ->
|
||||
line i ppf "Ptype_variant\n";
|
||||
list (i+1) string_x_core_type_list ppf l;
|
||||
|
|
|
@ -64,7 +64,7 @@ let add_type_declaration bv td =
|
|||
td.ptype_cstrs;
|
||||
add_opt add_type bv td.ptype_manifest;
|
||||
match td.ptype_kind with
|
||||
Ptype_abstract _ -> ()
|
||||
Ptype_abstract -> ()
|
||||
| Ptype_variant cstrs ->
|
||||
List.iter (fun (c, args) -> List.iter (add_type bv) args) cstrs
|
||||
| Ptype_record lbls ->
|
||||
|
|
|
@ -163,12 +163,12 @@ let print_label ppf l =
|
|||
|
||||
let rec print_list_init pr sep ppf = function
|
||||
| [] -> ()
|
||||
| a :: l -> sep (); pr ppf a; print_list_init pr sep ppf l;;
|
||||
| a :: l -> sep ppf; pr ppf a; print_list_init pr sep ppf l;;
|
||||
|
||||
let rec print_list pr sep ppf = function
|
||||
| [] -> ()
|
||||
| [a] -> pr ppf a
|
||||
| a :: l -> pr ppf a; sep (); print_list pr sep ppf l;;
|
||||
| a :: l -> pr ppf a; sep ppf; print_list pr sep ppf l;;
|
||||
|
||||
let rec typexp sch prio0 ppf ty =
|
||||
let ty = repr ty in
|
||||
|
@ -217,7 +217,7 @@ let rec typexp sch prio0 ppf ty =
|
|||
let all_present = List.length present = List.length fields in
|
||||
let pr_present =
|
||||
print_list (fun ppf (s, _) -> fprintf ppf "`%s" s)
|
||||
(fun () -> fprintf ppf "@ ")
|
||||
(fun ppf -> fprintf ppf "@ ")
|
||||
in
|
||||
begin match row.row_name with
|
||||
| Some(p, tyl) when namable_row row ->
|
||||
|
@ -245,7 +245,7 @@ let rec typexp sch prio0 ppf ty =
|
|||
if not all_present then
|
||||
fprintf ppf "@;<1 -2>> @[<hov>%a@]" pr_present l in
|
||||
let print_fields =
|
||||
print_list (row_field sch) (fun () -> fprintf ppf "@;<1 -2>| ")
|
||||
print_list (row_field sch) (fun ppf -> fprintf ppf "@;<1 -2>| ")
|
||||
in
|
||||
|
||||
fprintf ppf "%s[%s@[<hv>@[<hv>%a@]%a]@]"
|
||||
|
@ -381,29 +381,29 @@ let rec type_decl kwd id ppf decl =
|
|||
let print_constraints ppf params =
|
||||
List.iter (constrain ppf) params in
|
||||
|
||||
let type_parameter ppf (ty,(co,cn)) =
|
||||
fprintf ppf "%s%a"
|
||||
(if not cn then "+" else if not co then "-" else "")
|
||||
type_expr ty
|
||||
in
|
||||
let type_defined ppf decl =
|
||||
if decl.type_kind = Type_abstract && decl.type_manifest = None
|
||||
&& List.exists (fun x -> x <> (true, true)) decl.type_variance then
|
||||
fprintf ppf "(@[%a)@]@ %a"
|
||||
(print_list type_parameter (fun ppf -> fprintf ppf ",@ "))
|
||||
(List.combine params decl.type_variance)
|
||||
ident id
|
||||
else
|
||||
type_expr ppf (Btype.newgenty (Tconstr(Pident id, params, ref Mnil)))
|
||||
in
|
||||
let print_manifest ppf decl =
|
||||
match decl.type_manifest with
|
||||
| None ->
|
||||
if decl.type_kind = Type_abstract
|
||||
&& List.exists (fun p -> p <> (true,true)) decl.type_variance then
|
||||
let select f l1 l2 =
|
||||
List.fold_right2 (fun x y l -> if f x then y :: l else l) l1 l2 []
|
||||
in
|
||||
let repres f =
|
||||
let l = select f decl.type_variance params in
|
||||
if l = [] then Predef.type_unit else Btype.newgenty (Ttuple l)
|
||||
in
|
||||
let covar = repres fst and convar = repres snd in
|
||||
let ty =
|
||||
if convar == Predef.type_unit then covar
|
||||
else Btype.newgenty (Tarrow ("", convar, covar))
|
||||
in
|
||||
fprintf ppf " as@ %a" type_expr ty
|
||||
| None -> ()
|
||||
| Some ty -> fprintf ppf " =@ %a" type_expr ty in
|
||||
|
||||
let print_name_args ppf decl =
|
||||
fprintf ppf "%s%a%a"
|
||||
kwd type_expr (Btype.newgenty (Tconstr(Pident id, params, ref Mnil)))
|
||||
kwd type_defined decl
|
||||
print_manifest decl in
|
||||
|
||||
begin match decl.type_kind with
|
||||
|
@ -415,12 +415,12 @@ let rec type_decl kwd id ppf decl =
|
|||
| Type_variant cstrs ->
|
||||
fprintf ppf "@[<2>@[<hv 2>%a =@;<1 2>%a@]%a@]"
|
||||
print_name_args decl
|
||||
(print_list constructor (fun () -> fprintf ppf "@ | ")) cstrs
|
||||
(print_list constructor (fun ppf -> fprintf ppf "@ | ")) cstrs
|
||||
print_constraints params
|
||||
| Type_record(lbls, rep) ->
|
||||
fprintf ppf "@[<2>@[<hv 2>%a = {%a@;<1 -2>}@]@ %a@]"
|
||||
print_name_args decl
|
||||
(print_list_init label (fun () -> fprintf ppf "@ ")) lbls
|
||||
(print_list_init label (fun ppf -> fprintf ppf "@ ")) lbls
|
||||
print_constraints params
|
||||
end
|
||||
|
||||
|
|
|
@ -1023,12 +1023,12 @@ let final_decl define_class
|
|||
end;
|
||||
|
||||
(id, clty, ty_id, cltydef, obj_id, obj_abbr, cl_id, cl_abbr,
|
||||
arity, pub_meths, expr)
|
||||
arity, pub_meths, expr, (cl.pci_variance, cl.pci_loc))
|
||||
|
||||
let extract_type_decls
|
||||
(id, clty, ty_id, cltydef, obj_id, obj_abbr, cl_id, cl_abbr,
|
||||
arity, pub_meths, expr) decls =
|
||||
(obj_id, obj_abbr) :: (cl_id, cl_abbr) :: decls
|
||||
arity, pub_meths, expr, required) decls =
|
||||
((obj_id, obj_abbr), required) :: ((cl_id, cl_abbr), required) :: decls
|
||||
|
||||
let rec compact = function
|
||||
[] -> []
|
||||
|
@ -1037,7 +1037,7 @@ let rec compact = function
|
|||
|
||||
let merge_type_decls
|
||||
(id, clty, ty_id, cltydef, _obj_id, _obj_abbr, _cl_id, _cl_abbr,
|
||||
arity, pub_meths, expr) ((obj_id, obj_abbr), (cl_id, cl_abbr)) =
|
||||
arity, pub_meths, expr, req) ((obj_id, obj_abbr), (cl_id, cl_abbr)) =
|
||||
(id, clty, ty_id, cltydef, obj_id, obj_abbr, cl_id, cl_abbr,
|
||||
arity, pub_meths, expr)
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ type error =
|
|||
| Unbound_type_var
|
||||
| Unbound_exception of Longident.t
|
||||
| Not_an_exception of Longident.t
|
||||
| Constructor_in_variance
|
||||
| Bad_variance
|
||||
|
||||
exception Error of Location.t * error
|
||||
|
||||
|
@ -96,7 +96,7 @@ let transl_declaration env (name, sdecl) id =
|
|||
type_arity = List.length params;
|
||||
type_kind =
|
||||
begin match sdecl.ptype_kind with
|
||||
Ptype_abstract _ ->
|
||||
Ptype_abstract ->
|
||||
Type_abstract
|
||||
| Ptype_variant cstrs ->
|
||||
let all_constrs = ref StringSet.empty in
|
||||
|
@ -143,15 +143,6 @@ let transl_declaration env (name, sdecl) id =
|
|||
end;
|
||||
type_variance = List.map (fun _ -> true, true) params;
|
||||
} in
|
||||
let variance =
|
||||
match sdecl.ptype_kind with
|
||||
Ptype_abstract(Some sty) ->
|
||||
begin try Some (transl_simple_type Env.initial true sty)
|
||||
with Typetexp.Error (loc, Unbound_type_constructor lid) ->
|
||||
raise (Error(loc, Constructor_in_variance))
|
||||
end
|
||||
| _ -> None
|
||||
in
|
||||
|
||||
(* Check constraints *)
|
||||
List.iter
|
||||
|
@ -163,7 +154,7 @@ let transl_declaration env (name, sdecl) id =
|
|||
raise(Error(loc, Unconsistent_constraint)))
|
||||
sdecl.ptype_cstrs;
|
||||
|
||||
((id, decl), variance)
|
||||
(id, decl)
|
||||
|
||||
(* Generalize a type declaration *)
|
||||
|
||||
|
@ -382,16 +373,17 @@ let compute_variance env tvl nega posi ty =
|
|||
if TypeSet.mem ty !nvisited then convar := true)
|
||||
tvl
|
||||
|
||||
let compute_variance_decl env decl abstract =
|
||||
let compute_variance_decl env decl (required, loc) =
|
||||
if decl.type_kind = Type_abstract && decl.type_manifest = None then
|
||||
List.map (fun (c, n) -> if c || n then (c, n) else (true, true)) required
|
||||
else
|
||||
let tvl = List.map (fun ty -> (Btype.repr ty, ref false, ref false))
|
||||
decl.type_params in
|
||||
begin match decl.type_kind with
|
||||
Type_abstract ->
|
||||
begin match decl.type_manifest, abstract with
|
||||
None, None -> List.iter (fun (_, co, cn) -> co := true; cn := true) tvl
|
||||
| Some ty, None -> compute_variance env tvl true false ty
|
||||
| None, Some ty -> compute_variance env tvl true false ty
|
||||
| _ -> assert false
|
||||
begin match decl.type_manifest with
|
||||
None -> assert false
|
||||
| Some ty -> compute_variance env tvl true false ty
|
||||
end
|
||||
| Type_variant tll ->
|
||||
List.iter
|
||||
|
@ -402,9 +394,13 @@ let compute_variance_decl env decl abstract =
|
|||
(fun (_, mut, ty) -> compute_variance env tvl true (mut = Mutable) ty)
|
||||
ftl
|
||||
end;
|
||||
List.map (fun (_, co, cn) -> (!co, !cn)) tvl
|
||||
List.map2
|
||||
(fun (_, co, cn) (c, n) ->
|
||||
if c && !cn || n && !co then raise (Error(loc, Bad_variance));
|
||||
(!co, !cn))
|
||||
tvl required
|
||||
|
||||
let rec compute_variance_fixpoint env decls abstract variances =
|
||||
let rec compute_variance_fixpoint env decls required variances =
|
||||
let new_decls =
|
||||
List.map2
|
||||
(fun (id, decl) variance -> id, {decl with type_variance = variance})
|
||||
|
@ -416,7 +412,7 @@ let rec compute_variance_fixpoint env decls abstract variances =
|
|||
in
|
||||
let new_variances =
|
||||
List.map2 (fun (_, decl) -> compute_variance_decl new_env decl)
|
||||
new_decls abstract
|
||||
new_decls required
|
||||
in
|
||||
let new_variances =
|
||||
List.map2 (List.map2 (fun (c1,n1) (c2,n2) -> (c1||c2), (n1||n2)))
|
||||
|
@ -424,16 +420,14 @@ let rec compute_variance_fixpoint env decls abstract variances =
|
|||
if new_variances = variances then
|
||||
new_decls, new_env
|
||||
else
|
||||
compute_variance_fixpoint env decls abstract new_variances
|
||||
compute_variance_fixpoint env decls required new_variances
|
||||
|
||||
(* for typeclass.ml *)
|
||||
let compute_variance_decls env decls =
|
||||
let decls, required = List.split decls in
|
||||
let variances =
|
||||
List.map
|
||||
(fun (_, decl) -> List.map (fun _ -> (false, false)) decl.type_params)
|
||||
decls
|
||||
and abstract = List.map (fun _ -> None) decls in
|
||||
fst (compute_variance_fixpoint env decls abstract variances)
|
||||
List.map (fun (l,_) -> List.map (fun _ -> false, false) l) required in
|
||||
fst (compute_variance_fixpoint env decls required variances)
|
||||
|
||||
(* Translate a set of mutually recursive type declarations *)
|
||||
let transl_type_decl env name_sdecl_list =
|
||||
|
@ -454,7 +448,6 @@ let transl_type_decl env name_sdecl_list =
|
|||
(* Translate each declaration. *)
|
||||
let decls =
|
||||
List.map2 (transl_declaration temp_env) name_sdecl_list id_list in
|
||||
let decls, abstract = List.split decls in
|
||||
(* Build the final env. *)
|
||||
let newenv =
|
||||
List.fold_right
|
||||
|
@ -491,8 +484,12 @@ let transl_type_decl env name_sdecl_list =
|
|||
in
|
||||
List.iter (check_expansion newenv (List.flatten id_loc_list)) decls;
|
||||
(* Add variances to the environment *)
|
||||
let required =
|
||||
List.map (fun (_, sdecl) -> sdecl.ptype_variance, sdecl.ptype_loc)
|
||||
name_sdecl_list
|
||||
in
|
||||
let final_decls, final_env =
|
||||
compute_variance_fixpoint env decls abstract
|
||||
compute_variance_fixpoint env decls required
|
||||
(List.map
|
||||
(fun (_,decl) -> List.map (fun _ -> (false, false)) decl.type_params)
|
||||
decls) in
|
||||
|
@ -567,7 +564,8 @@ let transl_with_constraint env sdecl =
|
|||
}
|
||||
in
|
||||
let decl =
|
||||
{decl with type_variance = compute_variance_decl env decl None} in
|
||||
{decl with type_variance =
|
||||
compute_variance_decl env decl (sdecl.ptype_variance, sdecl.ptype_loc)} in
|
||||
Ctype.end_def();
|
||||
generalize_decl decl;
|
||||
decl
|
||||
|
@ -627,5 +625,6 @@ let report_error ppf = function
|
|||
| Not_an_exception lid ->
|
||||
fprintf ppf "The constructor@ %a@ is not an exception"
|
||||
Printtyp.longident lid
|
||||
| Constructor_in_variance ->
|
||||
fprintf ppf "Type constructors are not allowed in variance declarations"
|
||||
| Bad_variance ->
|
||||
fprintf ppf
|
||||
"In this definition, expected parameter variances are not satisfied"
|
||||
|
|
|
@ -35,7 +35,8 @@ val transl_with_constraint:
|
|||
(* for typeclass.ml *)
|
||||
val compute_variance_decls:
|
||||
Env.t ->
|
||||
(Ident.t * type_declaration) list -> (Ident.t * type_declaration) list
|
||||
((Ident.t * type_declaration) * ((bool * bool) list * Location.t)) list ->
|
||||
(Ident.t * type_declaration) list
|
||||
|
||||
type error =
|
||||
Repeated_parameter
|
||||
|
@ -53,7 +54,7 @@ type error =
|
|||
| Unbound_type_var
|
||||
| Unbound_exception of Longident.t
|
||||
| Not_an_exception of Longident.t
|
||||
| Constructor_in_variance
|
||||
| Bad_variance
|
||||
|
||||
exception Error of Location.t * error
|
||||
|
||||
|
|
Loading…
Reference in New Issue