diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d0ef88301..90aca5bf13 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ - Add missing check that the runtime representation of variants matches implementation and interface. https://github.com/rescript-lang/rescript-compiler/pull/6513/files - GenType: only export types (not values) from module types. https://github.com/rescript-lang/rescript-compiler/pull/6516 - Fix compiler crash with unboxed variant definition with only 1 constructor. https://github.com/rescript-lang/rescript-compiler/pull/6523 +- GenType: support mutual recursive types inside modules. https://github.com/rescript-lang/rescript-compiler/pull/6528 # 11.0.0-rc.7 diff --git a/jscomp/gentype/TranslateTypeDeclarations.ml b/jscomp/gentype/TranslateTypeDeclarations.ml index 5999d4b4fa..64e103fce7 100644 --- a/jscomp/gentype/TranslateTypeDeclarations.ml +++ b/jscomp/gentype/TranslateTypeDeclarations.ml @@ -313,13 +313,12 @@ let hasSomeGADTLeaf constructorDeclarations = (fun declaration -> declaration.Types.cd_res != None) constructorDeclarations -let translateTypeDeclaration ~config ~outputFileRelative ~recursive ~resolver - ~typeEnv +let translateTypeDeclaration ~config ~outputFileRelative ~resolver ~typeEnv ({typ_attributes; typ_id; typ_loc; typ_manifest; typ_params; typ_type} : Typedtree.type_declaration) : CodeItem.typeDeclaration list = if !Debug.translation then Log_.item "Translate Type Declaration %s\n" (typ_id |> Ident.name); - if recursive then typeEnv |> TypeEnv.newType ~name:(typ_id |> Ident.name); + let typeName = Ident.name typ_id in let typeVars = typ_params @@ -335,19 +334,27 @@ let translateTypeDeclaration ~config ~outputFileRelative ~recursive ~resolver | Type_abstract -> GeneralDeclaration typ_manifest | _ -> NoDeclaration in - let res = - declarationKind - |> traslateDeclarationKind ~config ~loc:typ_loc ~outputFileRelative - ~resolver ~typeAttributes:typ_attributes ~typeEnv ~typeName ~typeVars - in - if not recursive then typeEnv |> TypeEnv.newType ~name:(typ_id |> Ident.name); - res + declarationKind + |> traslateDeclarationKind ~config ~loc:typ_loc ~outputFileRelative ~resolver + ~typeAttributes:typ_attributes ~typeEnv ~typeName ~typeVars + +let addTypeDeclarationIdToTypeEnv ~typeEnv + ({typ_id} : Typedtree.type_declaration) = + typeEnv |> TypeEnv.newType ~name:(typ_id |> Ident.name) let translateTypeDeclarations ~config ~outputFileRelative ~recursive ~resolver ~typeEnv (typeDeclarations : Typedtree.type_declaration list) : CodeItem.typeDeclaration list = + if recursive then + typeDeclarations |> List.iter (addTypeDeclarationIdToTypeEnv ~typeEnv); typeDeclarations - |> List.map - (translateTypeDeclaration ~config ~outputFileRelative ~recursive - ~resolver ~typeEnv) + |> List.map (fun typeDeclaration -> + let res = + typeDeclaration + |> translateTypeDeclaration ~config ~outputFileRelative ~resolver + ~typeEnv + in + if not recursive then + typeDeclaration |> addTypeDeclarationIdToTypeEnv ~typeEnv; + res) |> List.concat diff --git a/jscomp/gentype_tests/typescript-react-example/package-lock.json b/jscomp/gentype_tests/typescript-react-example/package-lock.json index c02269dfe5..2dd8fbba05 100644 --- a/jscomp/gentype_tests/typescript-react-example/package-lock.json +++ b/jscomp/gentype_tests/typescript-react-example/package-lock.json @@ -22,26 +22,6 @@ "typescript": "^5.2.2" } }, - "../../..": { - "name": "rescript", - "version": "11.0.0-rc.8", - "dev": true, - "hasInstallScript": true, - "license": "SEE LICENSE IN LICENSE", - "bin": { - "bsc": "bsc", - "bstracing": "lib/bstracing", - "rescript": "rescript" - }, - "devDependencies": { - "mocha": "10.1.0", - "nyc": "15.0.0", - "prettier": "2.7.1" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@aashutoshrathi/word-wrap": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", @@ -1419,8 +1399,19 @@ } }, "node_modules/rescript": { - "resolved": "../../..", - "link": true + "version": "11.0.0-rc.8", + "resolved": "file:../../..", + "dev": true, + "hasInstallScript": true, + "license": "SEE LICENSE IN LICENSE", + "bin": { + "bsc": "bsc", + "bstracing": "lib/bstracing", + "rescript": "rescript" + }, + "engines": { + "node": ">=10" + } }, "node_modules/resolve-from": { "version": "4.0.0", diff --git a/jscomp/gentype_tests/typescript-react-example/src/NonrecursiveTypes.gen.tsx b/jscomp/gentype_tests/typescript-react-example/src/NonrecursiveTypes.gen.tsx index 51366a0640..9842501a0a 100644 --- a/jscomp/gentype_tests/typescript-react-example/src/NonrecursiveTypes.gen.tsx +++ b/jscomp/gentype_tests/typescript-react-example/src/NonrecursiveTypes.gen.tsx @@ -8,3 +8,7 @@ export type notRecursive = number; export type M_notRecursive = notRecursive[]; export type M_recursive = { readonly self: M_recursive }; + +export type M_mutualRecursive = { readonly a: M_a }; + +export type M_a = { readonly self: M_mutualRecursive }; diff --git a/jscomp/gentype_tests/typescript-react-example/src/NonrecursiveTypes.res b/jscomp/gentype_tests/typescript-react-example/src/NonrecursiveTypes.res index 1fc81532d3..9c76dc27e7 100644 --- a/jscomp/gentype_tests/typescript-react-example/src/NonrecursiveTypes.res +++ b/jscomp/gentype_tests/typescript-react-example/src/NonrecursiveTypes.res @@ -7,4 +7,8 @@ module M = { @genType type rec recursive = {self: recursive} + + @genType + type rec mutualRecursive = {a: a} + and a = {self: mutualRecursive} }