await in a functor body compiles to invalid JavaScript
Les mainteneurs répondent en général sous 1 jour
Évaluation
- Difficulté
- 4/5
- Temps estimé
- 3-5 jours
- Accessibilité débutants
- 25/100
- Type d'issue
- Bug
- Clarté
- Clairement spécifiée
- Activité
- À l'abandon
- Stack technique
- javascript
- Domaine
- compilers
Piste de recherche
The issue points to compiler/frontend/bs_builtin_ppx.ml, especially expr_mapper, module_expr_mapper, and structure_mapper. Read the await context handling around Pexp_fun, Pmod_functor, and structure-level module bindings, then check the existing cases described for functors and module M = await List. Done means those forms are rejected outside async contexts and accepted where allowed, without generating invalid JavaScript.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Description
await in the body of a functor passes the compiler's check, and the generated JavaScript has await in the function that the functor compiles to, which is not async:
module type Source = {
let value: promise<int>
}
module Make = (Source: Source) => {
let value = await Source.value
}
function Make(Source) {
let value = await Source.value;
return {
value: value
};
}
Loading the module fails with SyntaxError: Unexpected reserved word (with CommonJS output, SyntaxError: await is only valid in async functions and the top level bodies of modules); node --check reports the same.
A functor in a plain function is rejected with Await on expression not in an async context, but in an async function it is accepted. A first-class functor returned by an async function compiles to a plain arrow:
module type Make = (Source: Source) => {let value: int}
let make = async () => module((Source: Source) => {
let value = await Source.value
}: Make)
async function make() {
return Source => {
let value = await Source.value;
return {
value: value
};
};
}
The same happens with for await and module M = await List in a functor body, with a generative functor, a functor with several parameters, and a functor defined in the body of another functor.
The JavaScript is valid only where the optimizer inlines every application of the functor and then drops the functor: a functor defined and applied in an async function, a top-level functor that an interface (.resi) or a module signature hides, and a functor applied where it is written, as in module M = ((X: S) => {...})({...}). This depends on the optimization, not on the code: after module Alias = Make, Alias({...}) is not inlined and Make stays a function with await in it, and an application in a plain function inside the async function moves the await into that plain function.
A dynamic import at the top level of a module that is nested in a plain function is accepted as well, while module L = await List directly in the function body is rejected:
let length = values => {
module M = {
module L = await List
let length = L.length(values)
}
M.length
}
function length(values) {
let L = await import("@rescript/runtime/lib/es6/Stdlib_List.mjs");
let length$1 = L.length(values);
return length$1;
}
The await check is in compiler/frontend/bs_builtin_ppx.ml. expr_mapper sets the async context at every Pexp_fun to whether that function is async, which #9169, the fix for #9168, made exact for functions. A functor is a Pmod_functor module expression, and module_expr_mapper leaves the context unchanged, so the functor body keeps the context around the functor: true at the top level of a file, where top-level await is allowed (#5925), and in an async function. In addition, structure_mapper rewrites module M = await List in a structure without checking the context, which expr_mapper checks only for the Pexp_letmodule form in an expression.
Reproduced with 11.1.4, 12.0.0-alpha.1, 12.0.0-alpha.6, 12.3.1, 13.0.0-alpha.6 and master (c10223e80).
Related: #9168, #9169, #5925, #8815.
- Langage dominant
- OCaml
- Étoiles
- 7.5k
- Forks
- 484
- Merge moyen
- 16 h 57 min
- PR mergées (30 j)
- 258
Préparer son environnement
Lance le conteneur de développement du projet dans votre navigateur, avec votre propre compte GitHub.
- Aucun Dockerfile ni fichier Docker Compose
- Propose un modèle de pull request
- Lire le guide de contribution
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Autres issues de rescript-lang/rescript
-
Exception analysis does not know the Temporal `fromStringOrThrow` functionsPeut-être pris @cknitt l’a pris il y a 1 jour. Ouverte
Difficulté 2/5 1-3 heures Accessibilité débutants 72/100
rescript-lang/rescript#9182 ·
Les mainteneurs répondent en général sous 1 jour
-
`(() :> string)` compiles, and other coercions and variant spreads treat `bool` and `unit` as variantsPeut-être pris @mununki l’a pris il y a 1 jour. Ouverte
Difficulté 4/5 3-5 jours Accessibilité débutants 35/100
rescript-lang/rescript#9216 ·
Les mainteneurs répondent en général sous 1 jour
-
A polymorphic variant argument of an external is evaluated twice, or inside a generated functionPeut-être pris @mununki l’a pris il y a 1 jour. Ouverte
Difficulté 4/5 3-5 jours Accessibilité débutants 20/100
rescript-lang/rescript#9215 ·
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 4/5 3-5 jours Accessibilité débutants 48/100
rescript-lang/rescript#9212 ·
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 4/5 3-5 jours Accessibilité débutants 55/100
rescript-lang/rescript#9197 ·
Les mainteneurs répondent en général sous 1 jour
Toutes les issues de rescript-lang/rescript
Issues similaires
-
Difficulté 2/5 1-3 heures Accessibilité débutants 65/100
paradigmxyz/solar#2436 ·
Les mainteneurs répondent en général sous 1 jour
-
bug bulk-filed needs triage
Difficulté 2/5 1-3 heures Accessibilité débutants 76/100
Les mainteneurs répondent en général sous 2 jours
-
Difficulté 1/5 Moins d'une heure Accessibilité débutants 87/100
gleam-lang/gleam#6491 ·
Les mainteneurs répondent en général sous 1 jour
-
clang:frontend
Difficulté 2/5 1-3 heures Accessibilité débutants 67/100
llvm/llvm-project#238916 · 6 commentaires ·
Les mainteneurs répondent en général sous 1 jour
-
good first issue priority:low scope:syntax
Difficulté 1/5 Moins d'une heure Accessibilité débutants 92/100
Les mainteneurs répondent en général sous 1 jour