Skip to content

Complete the constructors of extensible variants - #9085

Open
cknitt wants to merge 8 commits into
masterfrom
fix-9073-extensible-variant-completion
Open

cknitt wants to merge 8 commits into
masterfrom
fix-9073-extensible-variant-completion

Conversation

@cknitt

@cknitt cknitt commented Oct 27, 2026 •

Copy link
Copy Markdown
Member

Fixes #9073.

Analysis didn't record constructors added by type t += ..., so completion offered none for an extensible variant. They are now registered as constructors of an open type. Typed completion of an open type, in both expressions and patterns, offers the ones declared in the type's file and in the current file. The exhaustive-switch snippet for an open type ends with a _ case, since other files can extend it.

New analysis test: CompletionExtensibleVariant.

Constructors are named so that they are in scope where completion runs: unqualified inside their declaring module, Sub.Flag elsewhere in the file, and Module.Flag from another file, using source paths in namespaced projects.

Known limitation: an extension declared inside a module whose signature hides it (module Hidden: {} = { type attr += Flag }) is still offered. Filtering through the visible signature is left for a follow-up.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Kbf3gLMawVgtmiKy3TMBc3

@github-actions

github-actions Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

Changelog

🐛 Bug fix

  • Editor completion offers the constructors of an extensible variant declared in the current file or in the type's file, and the exhaustive switch snippet for one ends with a _ case.

Semantic Diff

8 commits · Full page

Complete the constructors of extensible variants

6144dd2 · cknitt + Claude · Oct 27, 2026, 13:06 UTC

Why

Editor analysis didn't record the constructors added by type t += ..., and an open type has none in its declaration, so completion offered no constructor where a value of the type was expected. They are now registered as constructors of an open type, and typed completion of an open type offers those declared in the type's file and in the current file. Since other files can extend the type, the exhaustive switch snippet for one adds a _ case.

Diagnostic modified (completion of an extensible variant)

type attr = ..
type attr += Str(string) | Num(int)

// let a: attr = Nu

text · tests/analysis_tests/tests/src/CompletionExtensibleVariant.res

-Nullable, Null
+Num(_), Nullable, Null

Diagnostic modified (exhaustive switch snippet)

let value: attr = Str("s")
// switch valu

rescript · After

switch value {
| Str(_) => %todo
| Num(_) => %todo
| Flag => %todo
| _ => %todo
}

Review

  • Which extensions are offered? Those in the file that declares the type and in the current file; an extension in a third file is not known to the current file's analysis.
Match extension constructors by type and name them by module path

ae2da18 · cknitt + Claude · Oct 27, 2026, 17:50 UTC

Codex review on #9085: extensions were matched to an open type by its last name only, so A.t got the constructors of B.t, and a constructor declared in a nested module was inserted without its module, which doesn't compile because an extension constructor can't be found from the expected type. An extension now records the type it extends and is matched by that type's file and stamp, and it is named by its module path, for example Sub.Flag; a prefix may match the last part.

Name extension constructors relative to where completion runs

b258851 · cknitt + Claude · Oct 27, 2026, 20:29 UTC

Codex review on #9085: extension constructors were named relative to the root of their file and to the file of the completed value. Inside the declaring module that inserted Sub.Flag, which is not in scope there, and for a value imported from another file the constructors were not qualified with its module, while extensions in the edited file were missed. A completion request now records the edited file and the module path at the cursor; constructors of that file drop the module path shared with the cursor, constructors of other files get their module's name, and extensions are collected from the edited file.

Qualify extension constructors of namespaced modules by source path

b9d5edc · cknitt + Claude · Oct 27, 2026, 21:45 UTC

Codex review on #9085: the module name of another file comes from its compiled name, which in a namespaced project is Base-MyNamespace, so completion inserted Base-MyNamespace.Flag. The name is turned into its source path MyNamespace.Base first.

Offer extensions in scope at the cursor and from interface modules

84e1386 · cknitt + Claude · Oct 28, 2026, 07:47 UTC

Codex review on #9085: an extension of the edited file declared after the cursor was offered although it isn't in scope there, and an extension inside a module of an interface (module Sub: { type attr += Flag }) was never registered, because only typed-tree extensions were. The completion scope now records the cursor position and skips later extensions of the edited file, and extensions in signatures are registered too.

Qualify extensions of nested interface modules and complete their payloads

3cb8834 · cknitt + Claude · Oct 29, 2026, 06:34 UTC

Codex review on #9085: an extension two modules deep in an interface got only the outer module in its path, because the signature walk didn't extend the module path when entering a module, and completion inside the payload of a qualified constructor such as Sub.Toggle(...) found no constructor, because the payload position keeps only Toggle. Signature modules now extend the path, and payload lookup also matches the last part of a qualified constructor name.

Type extension payloads in their own file and match qualified constructors

462f92c · cknitt + Claude · Oct 29, 2026, 10:10 UTC

Codex review on #9085: a payload type declared next to the extension, as in type Base.attr += Color(color) with a local color, was resolved in the open type's file, so payload completion lost it; and of two same-named extensions, B.Value(...) completed the payload of the first one, A.Value, because the payload position kept only Value. Each extension constructor now carries the environment of its file, and the payload position keeps the written path: the constructor sharing the longest suffix with it is meant, ties going to the most recent open, then to the last declared one.

✨ Look up unqualified extension payloads in the scope at the cursor

b119166 · cknitt + Claude · Oct 29, 2026, 10:33 UTC · new

Codex review on #9085: ranking same-named extension constructors let an open outrank a local extension declared after it, so after open A and a later local Value(...), completion used A.Value's payload; and an extension inside a module type, module type S = { type attr += Phantom }, was offered as S.Phantom and added to exhaustive switches. A qualified constructor is now the one its written path names, and an unqualified one is looked up in the completion scope as the compiler does, which now records extension constructors, the most recent declaration or open winning. Extensions in module types are skipped.

@codecov

codecov Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 90.06211% with 16 lines in your changes missing coverage. Please review.
✅ Project coverage is 81.51%. Comparing base (beb423d) to head (b119166).
⚠️ Report is 13 commits behind head on master.

Files with missing lines Patch % Lines
analysis/src/type_utils.ml 85.14% 15 Missing ⚠️
analysis/src/completion_back_end.ml 96.42% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #9085      +/-   ##
==========================================
+ Coverage   81.45%   81.51%   +0.05%     
==========================================
  Files         460      460              
  Lines       64645    64862     +217     
==========================================
+ Hits        52657    52871     +214     
- Misses      11988    11991       +3     
Files with missing lines Coverage Δ
analysis/src/completion_expressions.ml 86.88% <100.00%> (+0.33%) ⬆️
analysis/src/completion_front_end.ml 81.83% <100.00%> (+0.22%) ⬆️
analysis/src/completion_patterns.ml 88.88% <100.00%> (+0.31%) ⬆️
analysis/src/process_cmt.ml 85.36% <100.00%> (+1.27%) ⬆️
analysis/src/shared_types.ml 80.68% <ø> (ø)
analysis/src/completion_back_end.ml 81.83% <96.42%> (+0.34%) ⬆️
analysis/src/type_utils.ml 68.32% <85.14%> (+2.05%) ⬆️

... and 30 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@pkg-pr-new

pkg-pr-new Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

rescript

npm i https://pkg.pr.new/rescript@9085

@rescript/belt

npm i https://pkg.pr.new/@rescript/belt@9085

@rescript/darwin-arm64

npm i https://pkg.pr.new/@rescript/darwin-arm64@9085

@rescript/linux-arm64

npm i https://pkg.pr.new/@rescript/linux-arm64@9085

@rescript/linux-x64

npm i https://pkg.pr.new/@rescript/linux-x64@9085

@rescript/runtime

npm i https://pkg.pr.new/@rescript/runtime@9085

@rescript/win32-x64

npm i https://pkg.pr.new/@rescript/win32-x64@9085

commit: b119166

@github-actions

Copy link
Copy Markdown

@cknitt
cknitt marked this pull request as ready for review October 27, 2026 14:20
@cknitt

cknitt commented Oct 27, 2026

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-29T10:40:04.669494Z b119166 Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 98ecc79d93

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread analysis/src/type_utils.ml Outdated
Comment thread analysis/src/type_utils.ml Outdated
cknitt added a commit that referenced this pull request Oct 27, 2026
Codex review on #9085: extensions were matched to an open type by its
last name only, so `A.t` got the constructors of `B.t`, and a constructor
declared in a nested module was inserted without its module, which
doesn't compile because an extension constructor can't be found from
the expected type. An extension now records the type it extends and is
matched by that type's file and stamp, and it is named by its module
path, for example `Sub.Flag`; a prefix may match the last part.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kbf3gLMawVgtmiKy3TMBc3
Signed-off-by: Christoph Knittel <ck@cca.io>
@cknitt

cknitt commented Oct 27, 2026

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f678bb32e5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread analysis/src/type_utils.ml Outdated
Comment thread analysis/src/type_utils.ml
cknitt added a commit that referenced this pull request Oct 27, 2026
Codex review on #9085: extension constructors were named relative to the
root of their file and to the file of the completed value. Inside the
declaring module that inserted `Sub.Flag`, which is not in scope there,
and for a value imported from another file the constructors were not
qualified with its module, while extensions in the edited file were
missed. A completion request now records the edited file and the module
path at the cursor; constructors of that file drop the module path shared
with the cursor, constructors of other files get their module's name,
and extensions are collected from the edited file.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kbf3gLMawVgtmiKy3TMBc3
Signed-off-by: Christoph Knittel <ck@cca.io>
@cknitt

cknitt commented Oct 27, 2026

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 56cff12ba2

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread analysis/src/type_utils.ml Outdated
Comment thread analysis/src/type_utils.ml
cknitt added a commit that referenced this pull request Oct 27, 2026
Codex review on #9085: the module name of another file comes from its
compiled name, which in a namespaced project is `Base-MyNamespace`, so
completion inserted `Base-MyNamespace.Flag`. The name is turned into its
source path `MyNamespace.Base` first.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kbf3gLMawVgtmiKy3TMBc3
Signed-off-by: Christoph Knittel <ck@cca.io>
@cknitt

cknitt commented Oct 28, 2026

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3408b27a6e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread analysis/src/type_utils.ml
Comment thread analysis/src/process_cmt.ml
cknitt and others added 5 commits October 28, 2026 07:48
Why:
    Editor analysis didn't record the constructors added by `type t += ...`,
    and an open type has none in its declaration, so completion offered no
    constructor where a value of the type was expected. They are now
    registered as constructors of an open type, and typed completion of an
    open type offers those declared in the type's file and in the current
    file. Since other files can extend the type, the exhaustive switch
    snippet for one adds a `_` case.

Diagnostic modified (completion of an extensible variant):
Example:
    type attr = ..
    type attr += Str(string) | Num(int)

    // let a: attr = Nu
Before (text): tests/analysis_tests/tests/src/CompletionExtensibleVariant.res
    Nullable, Null
After (text): tests/analysis_tests/tests/src/CompletionExtensibleVariant.res
    Num(_), Nullable, Null

Diagnostic modified (exhaustive switch snippet):
Example:
    let value: attr = Str("s")
    // switch valu
After (rescript):
    switch value {
    | Str(_) => %todo
    | Num(_) => %todo
    | Flag => %todo
    | _ => %todo
    }

Review: Which extensions are offered?
    Those in the file that declares the type and in the current file;
    an extension in a third file is not known to the current file's
    analysis.

Fixes: #9073
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kbf3gLMawVgtmiKy3TMBc3
Signed-off-by: Christoph Knittel <ck@cca.io>
Codex review on #9085: extensions were matched to an open type by its
last name only, so `A.t` got the constructors of `B.t`, and a constructor
declared in a nested module was inserted without its module, which
doesn't compile because an extension constructor can't be found from
the expected type. An extension now records the type it extends and is
matched by that type's file and stamp, and it is named by its module
path, for example `Sub.Flag`; a prefix may match the last part.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kbf3gLMawVgtmiKy3TMBc3
Signed-off-by: Christoph Knittel <ck@cca.io>
Codex review on #9085: extension constructors were named relative to the
root of their file and to the file of the completed value. Inside the
declaring module that inserted `Sub.Flag`, which is not in scope there,
and for a value imported from another file the constructors were not
qualified with its module, while extensions in the edited file were
missed. A completion request now records the edited file and the module
path at the cursor; constructors of that file drop the module path shared
with the cursor, constructors of other files get their module's name,
and extensions are collected from the edited file.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kbf3gLMawVgtmiKy3TMBc3
Signed-off-by: Christoph Knittel <ck@cca.io>
Codex review on #9085: the module name of another file comes from its
compiled name, which in a namespaced project is `Base-MyNamespace`, so
completion inserted `Base-MyNamespace.Flag`. The name is turned into its
source path `MyNamespace.Base` first.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kbf3gLMawVgtmiKy3TMBc3
Signed-off-by: Christoph Knittel <ck@cca.io>
Codex review on #9085: an extension of the edited file declared after the
cursor was offered although it isn't in scope there, and an extension
inside a module of an interface (`module Sub: { type attr += Flag }`) was
never registered, because only typed-tree extensions were. The completion
scope now records the cursor position and skips later extensions of the
edited file, and extensions in signatures are registered too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kbf3gLMawVgtmiKy3TMBc3
Signed-off-by: Christoph Knittel <ck@cca.io>
@cknitt
cknitt force-pushed the fix-9073-extensible-variant-completion branch from 3408b27 to 84e1386 Compare October 28, 2026 08:10
@cknitt

cknitt commented Oct 28, 2026

Copy link
Copy Markdown
Member Author

@codex review

@cknitt cknitt mentioned this pull request Oct 28, 2026
5 of 12 tasks

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 84e1386175

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread analysis/src/process_cmt.ml
Comment thread analysis/src/type_utils.ml Outdated
…loads

Codex review on #9085: an extension two modules deep in an interface got
only the outer module in its path, because the signature walk didn't
extend the module path when entering a module, and completion inside the
payload of a qualified constructor such as `Sub.Toggle(...)` found no
constructor, because the payload position keeps only `Toggle`. Signature
modules now extend the path, and payload lookup also matches the last
part of a qualified constructor name.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kbf3gLMawVgtmiKy3TMBc3
Signed-off-by: Christoph Knittel <ck@cca.io>
@cknitt

cknitt commented Oct 29, 2026

Copy link
Copy Markdown
Member Author

@codex review

1 similar comment
@cknitt

cknitt commented Oct 29, 2026

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3cb8834566

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread analysis/src/type_utils.ml Outdated
Comment thread analysis/src/type_utils.ml Outdated
…ctors

Codex review on #9085: a payload type declared next to the extension, as
in `type Base.attr += Color(color)` with a local `color`, was resolved in
the open type's file, so payload completion lost it; and of two
same-named extensions, `B.Value(...)` completed the payload of the first
one, `A.Value`, because the payload position kept only `Value`. Each
extension constructor now carries the environment of its file, and the
payload position keeps the written path: the constructor sharing the
longest suffix with it is meant, ties going to the most recent open, then
to the last declared one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kbf3gGkPma9LAZimuQjnrP
Signed-off-by: Christoph Knittel <ck@cca.io>
@cknitt

cknitt commented Oct 29, 2026

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 462f92c4a4

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread analysis/src/type_utils.ml
Comment thread analysis/src/type_utils.ml Outdated
Codex review on #9085: ranking same-named extension constructors let an
open outrank a local extension declared after it, so after `open A` and a
later local `Value(...)`, completion used `A.Value`'s payload; and an
extension inside a module type, `module type S = { type attr += Phantom }`,
was offered as `S.Phantom` and added to exhaustive switches. A qualified
constructor is now the one its written path names, and an unqualified one
is looked up in the completion scope as the compiler does, which now
records extension constructors, the most recent declaration or open
winning. Extensions in module types are skipped.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kbf3gGkPma9LAZimuQjnrP
Signed-off-by: Christoph Knittel <ck@cca.io>
@cknitt

cknitt commented Oct 29, 2026

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b1191669a3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +646 to +650
( Tvariant
{
env = env_from_item;
constructors = List.map fst extension_envs;
extension_envs;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve catch-all cases in open-variant refactors

Returning Tvariant for open types also enables Xform.Expand_catch_all_for_variants.xform, which replaces the wildcard with only the listed constructors. For example, after type attr = ..; type attr += Known, applying “Expand catch-all” to switch value { | _ => ... } now removes the fallback and handles only Known. Valid constructors added elsewhere then cause a match failure. Unlike the completion snippet updated in this commit, this code-action consumer does not check Type_open. Preserve the wildcard when expanding an open variant, or exclude open variants from this refactor.

Useful? React with 👍 / 👎.

Comment on lines +429 to +431
match last (named (opened @ path)) with
| Some c -> Some c
| None -> lookup scope)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Restrict opened payload lookup to the opened module

With A.Value(bool) declared first, a local Value(option<int>) declared next, and then open A, payload completion inside unqualified Value(...) selects the local option constructor instead of the opened boolean constructor. The fresh counterexample reverses the covered local-after-open ordering: the open occurs last and should win. Here, named ["A"; "Value"] accepts both constructors because the reverse suffix comparison also matches the bare local name; last then selects the later local declaration. This affects expression and pattern payload completion. Resolve the opened module's constructor rather than allowing an unrelated bare constructor to match its qualified path.

Useful? React with 👍 / 👎.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

No completion for extensible variant constructors

1 participant