Skip to content

Commit d06ce9f

Browse files
authored
Instantiate variant types as needed (#814)
* instantiate variant types as needed * changelog
1 parent f2b4644 commit d06ce9f

File tree

5 files changed

+69
-8
lines changed

5 files changed

+69
-8
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
- Fix JS syntax highlighting in single-line FFI extension points. https://github.com/rescript-lang/rescript-vscode/pull/807
3333
- Fix signature help in uncurried mode. https://github.com/rescript-lang/rescript-vscode/pull/809
3434
- Fix various issues in uncurried mode. https://github.com/rescript-lang/rescript-vscode/pull/810
35+
- Fixes a bug in pattern completion where for example `result` wouldn't complete, due to type variables getting lost/not being instantiated. https://github.com/rescript-lang/rescript-vscode/pull/814
3536

3637
## 1.18.0
3738

analysis/src/SharedTypes.ml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,8 @@ and completionType =
320320
constructors: Constructor.t list;
321321
variantDecl: Types.type_declaration;
322322
variantName: string;
323+
typeArgs: Types.type_expr list;
324+
typeParams: Types.type_expr list;
323325
}
324326
| Tpolyvariant of {
325327
env: QueryEnv.t;

analysis/src/TypeUtils.ml

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -128,14 +128,23 @@ let rec extractType ~env ~package (t : Types.type_expr) =
128128
| args, _tRet when args <> [] ->
129129
Some (Tfunction {env; args; typ = t; uncurried = true})
130130
| _args, _tRet -> None)
131-
| Tconstr (path, _, _) -> (
131+
| Tconstr (path, typeArgs, _) -> (
132132
match References.digConstructor ~env ~package path with
133-
| Some (env, {item = {decl = {type_manifest = Some t1}}}) ->
134-
extractType ~env ~package t1
135-
| Some (env, {name; item = {decl; kind = Type.Variant constructors}}) ->
133+
| Some (_env, {item = {decl = {type_manifest = Some t1; type_params}}}) ->
134+
t1
135+
|> instantiateType ~typeParams:type_params ~typeArgs
136+
|> extractType ~env ~package
137+
| Some (_env, {name; item = {decl; kind = Type.Variant constructors}}) ->
136138
Some
137139
(Tvariant
138-
{env; constructors; variantName = name.txt; variantDecl = decl})
140+
{
141+
env;
142+
constructors;
143+
variantName = name.txt;
144+
variantDecl = decl;
145+
typeArgs;
146+
typeParams = decl.type_params;
147+
})
139148
| Some (env, {item = {kind = Record fields}}) ->
140149
Some (Trecord {env; fields; definition = `TypeExpr t})
141150
| _ -> None)
@@ -280,7 +289,14 @@ let extractTypeFromResolvedType (typ : Type.t) ~env ~full =
280289
| Variant constructors ->
281290
Some
282291
(Tvariant
283-
{env; constructors; variantName = typ.name; variantDecl = typ.decl})
292+
{
293+
env;
294+
constructors;
295+
variantName = typ.name;
296+
variantDecl = typ.decl;
297+
typeParams = typ.decl.type_params;
298+
typeArgs = [];
299+
})
284300
| Abstract _ | Open -> (
285301
match typ.decl.type_manifest with
286302
| None -> None
@@ -345,8 +361,8 @@ let rec resolveNested ~env ~full ~nested ?ctx (typ : completionType) =
345361
typ
346362
|> extractType ~env ~package:full.package
347363
|> Utils.Option.flatMap (fun t -> t |> resolveNested ~env ~full ~nested)
348-
| NVariantPayload {constructorName; itemNum}, Tvariant {env; constructors}
349-
-> (
364+
| ( NVariantPayload {constructorName; itemNum},
365+
Tvariant {env; constructors; typeParams; typeArgs} ) -> (
350366
match
351367
constructors
352368
|> List.find_opt (fun (c : Constructor.t) ->
@@ -357,6 +373,7 @@ let rec resolveNested ~env ~full ~nested ?ctx (typ : completionType) =
357373
| None -> None
358374
| Some (typ, _) ->
359375
typ
376+
|> instantiateType ~typeParams ~typeArgs
360377
|> extractType ~env ~package:full.package
361378
|> Utils.Option.flatMap (fun typ ->
362379
typ |> resolveNested ~env ~full ~nested))

analysis/tests/src/CompletionPattern.res

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,3 +211,8 @@ let getThing = async () => One
211211

212212
// switch await getThing() { | }
213213
// ^com
214+
215+
let res: result<someVariant, somePolyVariant> = Ok(One)
216+
217+
// switch res { | Ok() }
218+
// ^com

analysis/tests/src/expected/CompletionPattern.res.txt

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1105,3 +1105,39 @@ Path getThing
11051105
"insertTextFormat": 2
11061106
}]
11071107

1108+
Complete src/CompletionPattern.res 216:21
1109+
posCursor:[216:21] posNoWhite:[216:20] Found pattern:[216:18->216:22]
1110+
Ppat_construct Ok:[216:18->216:20]
1111+
posCursor:[216:21] posNoWhite:[216:20] Found pattern:[216:20->216:22]
1112+
Ppat_construct ():[216:20->216:22]
1113+
Completable: Cpattern Value[res]->variantPayload::Ok($0)
1114+
Package opens Pervasives.JsxModules.place holder
1115+
Resolved opens 1 pervasives
1116+
ContextPath Value[res]
1117+
Path res
1118+
[{
1119+
"label": "One",
1120+
"kind": 4,
1121+
"tags": [],
1122+
"detail": "One\n\ntype someVariant = One | Two(bool) | Three(someRecord, bool)",
1123+
"documentation": null,
1124+
"insertText": "One",
1125+
"insertTextFormat": 2
1126+
}, {
1127+
"label": "Two(_)",
1128+
"kind": 4,
1129+
"tags": [],
1130+
"detail": "Two(bool)\n\ntype someVariant = One | Two(bool) | Three(someRecord, bool)",
1131+
"documentation": null,
1132+
"insertText": "Two(${1:_})",
1133+
"insertTextFormat": 2
1134+
}, {
1135+
"label": "Three(_, _)",
1136+
"kind": 4,
1137+
"tags": [],
1138+
"detail": "Three(someRecord, bool)\n\ntype someVariant = One | Two(bool) | Three(someRecord, bool)",
1139+
"documentation": null,
1140+
"insertText": "Three(${1:_}, ${2:_})",
1141+
"insertTextFormat": 2
1142+
}]
1143+

0 commit comments

Comments
 (0)