Skip to content

Remove the unreachable Longident.Lapply constructor#8469

Merged
JonoPrest merged 4 commits into
rescript-lang:masterfrom
JonoPrest:jono/remove-longident-lapply
Jun 12, 2026
Merged

Remove the unreachable Longident.Lapply constructor#8469
JonoPrest merged 4 commits into
rescript-lang:masterfrom
JonoPrest:jono/remove-longident-lapply

Conversation

@JonoPrest

Copy link
Copy Markdown
Contributor

Follow up to #8459

@cknitt suggested that we should remove Longident.Lapply constructor since it's not reachable from ReScript's grammar.
#8459 (comment)

ppxs could technically produce this AST but in practice it's not usable in ReScript

Longident.Lapply is the parsetree form of OCaml's applicative-functor
path syntax (F(X).t), where a functor is applied inline inside an
identifier path. ReScript's grammar has no such production: functor
application is only a module expression (module M = F(X)), which the
type checker resolves to Path.Papply, never a Longident.Lapply. The
parser never builds Lapply, so every match on it was dead (assert false
/ fatal_error / raise Not_found / defensive printer fallbacks).

Remove the constructor and all its handling across the type checker,
printers, depend, and analysis. The sole construction site was
Ctype.lid_of_path (Path.Papply -> Longident.Lapply); since no Papply
flows into that type-path conversion, replace it with assert false,
matching the existing Papply -> assert false invariants. Removing the
Env.lookup_module Lapply arms also left functor_components.fcomp_arg
write-only, so drop that field too.

Add a super_errors fixture exercising functor application plus a
type-path error, confirming the functor machinery and error printing
are unchanged.
@JonoPrest

Copy link
Copy Markdown
Contributor 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: 8a11e0c9f4

ℹ️ 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 compiler/ml/longident.ml
(**************************************************************************)

type t = Lident of string | Ldot of t * string | Lapply of t * t
type t = Lident of string | Ldot of t * string

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 Longident.Lapply for frozen PPX ASTs

In this repository parsetree0.ml still exposes Longident.t in the frozen v0 PPX AST (for example Ptyp_constr of Longident.t loc * ...), and the AGENTS.md guidance says existing PPXs rely on that frozen version. Removing the Lapply constructor from the shared Longident.t type breaks any existing PPX that was compiled against or constructs the v0 AST with applicative-functor paths, even though the ReScript parser itself never produces them. Please keep the v0-facing shape compatible (or introduce a mapped v0 longident) instead of deleting the constructor from the shared type.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This is not really true.

It only breaks if the ppx tries to construct Lapply, it can never read this variant from ReScript code. There should be no real world ReScript ppxs that hit this.

@codecov

codecov Bot commented Jun 11, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 92.85714% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 74.42%. Comparing base (b8a6089) to head (11f6a61).

Files with missing lines Patch % Lines
compiler/frontend/ast_util.ml 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #8469      +/-   ##
==========================================
+ Coverage   74.34%   74.42%   +0.08%     
==========================================
  Files         450      451       +1     
  Lines       61518    61459      -59     
==========================================
+ Hits        45736    45743       +7     
+ Misses      15782    15716      -66     
Files with missing lines Coverage Δ
analysis/src/completion_front_end.ml 81.53% <ø> (+0.10%) ⬆️
analysis/src/process_extra.ml 86.53% <ø> (+0.35%) ⬆️
analysis/src/semantic_tokens.ml 88.07% <ø> (+0.40%) ⬆️
analysis/src/utils.ml 53.89% <ø> (+0.63%) ⬆️
compiler/ml/ctype.ml 57.70% <100.00%> (+0.19%) ⬆️
compiler/ml/depend.ml 82.02% <ø> (+0.79%) ⬆️
compiler/ml/env.ml 74.33% <100.00%> (+1.72%) ⬆️
compiler/ml/longident.ml 68.18% <ø> (+16.45%) ⬆️
compiler/ml/pprintast.ml 91.46% <ø> (+0.12%) ⬆️
compiler/ml/printast.ml 0.00% <ø> (ø)
... and 9 more

... and 1 file 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 Jun 11, 2026

Copy link
Copy Markdown

Open in StackBlitz

rescript

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

@rescript/darwin-arm64

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

@rescript/darwin-x64

npm i https://pkg.pr.new/@rescript/darwin-x64@8469

@rescript/linux-arm64

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

@rescript/linux-x64

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

@rescript/runtime

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

@rescript/win32-x64

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

commit: 11f6a61

@JonoPrest JonoPrest force-pushed the jono/remove-longident-lapply branch from 7bd4d4e to 4731ede Compare June 11, 2026 16:40
@JonoPrest JonoPrest marked this pull request as ready for review June 11, 2026 16:43
@JonoPrest JonoPrest requested a review from cristianoc June 11, 2026 16:43

@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: 4731eded6f

ℹ️ 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 compiler/ml/ctype.ml Outdated
(* Functor-application paths (Path.Papply) only arise from applicative
functors, which ReScript's surface syntax cannot express as a path; no
such path reaches this type-path conversion. *)
| Path.Papply _ -> assert false

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Handle Papply paths instead of asserting

Applicative functor paths are still produced internally even if users cannot write F(X).t directly: Typemod.path_of_module returns Papply for module App = F(Arg), and Mtype.strengthen records abstract result types under Papply paths. When later diagnostics call Ctype.lid_of_path for one of those strengthened paths (for example while printing or disambiguating an error involving an abstract type from a functor application), this new assertion aborts the compiler instead of reporting the type error; the previous Longident.Lapply branch handled exactly that internal path shape.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

If true, this is an issue.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@cristianoc, I couldn't find a way to hit this from ReScript source. Tried to get codex to hit this path unsuccessfully as well. But either way I've now added a way to handle it and added an internal unit test for this branch.

Applicative functors are on by default, so Path.Papply paths are
produced internally (typemod path_of_module, Mtype.strengthen) even
though ReScript source cannot reference such a path directly. Replace the
assert false in Ctype.lid_of_path's Papply arm (introduced when removing
Longident.Lapply) with a graceful Lident rendering via Path.name, so any
diagnostic that ever reaches it degrades to a readable name (e.g. F(Arg))
instead of aborting the compiler.

Add an ounit test that calls Ctype.lid_of_path on a synthetic Papply path
(unreachable from source, so exercised directly) to lock in the graceful
behavior.
@JonoPrest JonoPrest force-pushed the jono/remove-longident-lapply branch from ca2c07a to 11f6a61 Compare June 12, 2026 07:43
@JonoPrest JonoPrest merged commit 516e650 into rescript-lang:master Jun 12, 2026
30 checks passed
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.

2 participants