@@ -290,7 +290,7 @@ let make_constructor env type_path type_params sargs sret_type =
290290*)
291291
292292
293- let transl_declaration env sdecl id =
293+ let transl_declaration ~ foundObject env sdecl id =
294294 (* Bind type parameters *)
295295 reset_type_variables() ;
296296 Ctype. begin_def () ;
@@ -358,9 +358,9 @@ let transl_declaration env sdecl id =
358358 unboxed_false_default_false
359359 in
360360 let unbox = unboxed_status.unboxed in
361- let (tkind, kind) =
361+ let (tkind, kind, sdecl ) =
362362 match sdecl.ptype_kind with
363- | Ptype_abstract -> Ttype_abstract , Type_abstract
363+ | Ptype_abstract -> Ttype_abstract , Type_abstract , sdecl
364364 | Ptype_variant scstrs ->
365365 assert (scstrs <> [] );
366366 if List. exists (fun cstr -> cstr.pcd_res <> None ) scstrs then begin
@@ -423,15 +423,15 @@ let transl_declaration env sdecl id =
423423 let tcstrs, cstrs = List. split (List. map make_cstr scstrs) in
424424 let isUntaggedDef = Ast_untagged_variants. has_untagged sdecl.ptype_attributes in
425425 Ast_untagged_variants. check_well_formed ~is UntaggedDef cstrs;
426- Ttype_variant tcstrs, Type_variant cstrs
427- | Ptype_record lbls ->
426+ Ttype_variant tcstrs, Type_variant cstrs, sdecl
427+ | Ptype_record lbls_ ->
428428 let has_optional attrs = Ext_list. exists attrs (fun ({txt } ,_ ) -> txt = " res.optional" ) in
429429 let optionalLabels =
430- Ext_list. filter_map lbls
430+ Ext_list. filter_map lbls_
431431 (fun lbl -> if has_optional lbl.pld_attributes then Some lbl.pld_name.txt else None ) in
432432 let lbls =
433- if optionalLabels = [] then lbls
434- else Ext_list. map lbls (fun lbl ->
433+ if optionalLabels = [] then lbls_
434+ else Ext_list. map lbls_ (fun lbl ->
435435 let typ = lbl.pld_type in
436436 let typ =
437437 if has_optional lbl.pld_attributes then
@@ -446,7 +446,7 @@ let transl_declaration env sdecl id =
446446 then Record_optional_labels optionalLabels
447447 else Record_regular
448448 in
449- let lbls, lbls' = match lbls, lbls' with
449+ let lbls_opt = match lbls, lbls' with
450450 | {ld_name = {txt = "..." } ; ld_type} :: _ , _ :: _ ->
451451 let rec extract t = match t.desc with
452452 | Tpoly (t , [] ) -> extract t
@@ -464,21 +464,36 @@ let transl_declaration env sdecl id =
464464 (_p0 , _p , {type_kind =Type_record (fields , _repr )} ) ->
465465 process_lbls (fst acc @ (fields |> List. map mkLbl), snd acc @ fields) rest rest'
466466 | _ -> assert false
467- | exception _ -> assert false )
467+ | exception _ -> None )
468468 | lbl ::rest , lbl' ::rest' -> process_lbls (fst acc @ [lbl], snd acc @ [lbl']) rest rest'
469- | _ -> acc
469+ | _ -> Some acc
470470 in
471471 process_lbls ([] , [] ) lbls lbls'
472- | _ -> lbls, lbls' in
472+ | _ -> Some ( lbls, lbls') in
473473 let rec check_duplicates (lbls : Typedtree.label_declaration list ) seen = match lbls with
474474 | [] -> ()
475475 | lbl ::rest ->
476476 let name = lbl.ld_id.name in
477477 if StringSet. mem name seen then raise(Error (lbl.ld_loc, Duplicate_label name));
478478 check_duplicates rest (StringSet. add name seen) in
479- check_duplicates lbls StringSet. empty;
480- Ttype_record lbls, Type_record (lbls', rep)
481- | Ptype_open -> Ttype_open , Type_open
479+ (match lbls_opt with
480+ | Some (lbls , lbls' ) ->
481+ check_duplicates lbls StringSet. empty;
482+ Ttype_record lbls, Type_record (lbls', rep), sdecl
483+ | None ->
484+ (* Could not fine type decl for ...t: assume t is an object type and this is syntax ambiguity *)
485+ foundObject := true ;
486+ let fields = Ext_list. map lbls_ (fun ld ->
487+ match ld.pld_name.txt with
488+ | "..." -> Parsetree. Oinherit ld.pld_type
489+ | _ -> Otag (ld.pld_name, ld.pld_attributes, ld.pld_type)) in
490+ let sdecl =
491+ {sdecl with
492+ ptype_kind = Ptype_abstract ;
493+ ptype_manifest = Some (Ast_helper.Typ. object_ ~loc: sdecl.ptype_loc fields Closed );
494+ } in
495+ (Ttype_abstract , Type_abstract , sdecl))
496+ | Ptype_open -> Ttype_open , Type_open , sdecl
482497 in
483498 let (tman, man) = match sdecl.ptype_manifest with
484499 None -> None , None
@@ -587,7 +602,7 @@ let check_constraints_labels env visited l pl =
587602 check_constraints_rec env (get_loc (Ident. name name) pl) visited ty)
588603 l
589604
590- let check_constraints env sdecl (_ , decl ) =
605+ let check_constraints ~ foundObject env sdecl (_ , decl ) =
591606 let visited = ref TypeSet. empty in
592607 begin match decl.type_kind with
593608 | Type_abstract -> ()
@@ -636,10 +651,12 @@ let check_constraints env sdecl (_, decl) =
636651 begin match decl.type_manifest with
637652 | None -> ()
638653 | Some ty ->
654+ if not ! foundObject then
639655 let sty =
640656 match sdecl.ptype_manifest with Some sty -> sty | _ -> assert false
641657 in
642658 check_constraints_rec env sty.ptyp_loc visited ty
659+
643660 end
644661
645662(*
@@ -1294,14 +1311,15 @@ let transl_type_decl env rec_flag sdecl_list =
12941311 | Asttypes. Recursive | Asttypes. Nonrecursive ->
12951312 id, None
12961313 in
1314+ let foundObject = ref false in
12971315 let transl_declaration name_sdecl (id , slot ) =
12981316 current_slot := slot;
12991317 Builtin_attributes. warning_scope
13001318 name_sdecl.ptype_attributes
13011319 (fun () -> transl_declaration temp_env name_sdecl id)
13021320 in
13031321 let tdecls =
1304- List. map2 transl_declaration sdecl_list (List. map id_slots id_list) in
1322+ List. map2 ( transl_declaration ~found Object) sdecl_list (List. map id_slots id_list) in
13051323 let decls =
13061324 List. map (fun tdecl -> (tdecl.typ_id, tdecl.typ_type)) tdecls in
13071325 current_slot := None ;
@@ -1349,7 +1367,7 @@ let transl_type_decl env rec_flag sdecl_list =
13491367 | None -> () )
13501368 sdecl_list tdecls;
13511369 (* Check that constraints are enforced *)
1352- List. iter2 (check_constraints newenv) sdecl_list decls;
1370+ List. iter2 (check_constraints ~found Object newenv) sdecl_list decls;
13531371 (* Name recursion *)
13541372 let decls =
13551373 List. map2 (fun sdecl (id , decl ) -> id, name_recursion sdecl id decl)
0 commit comments