A regex literal that starts a statement is parsed as division, and the formatter removes the parentheses that prevent it
Les mainteneurs répondent en général sous 1 jour
Personne n'a encore pris cette issue.
Évaluation
- Difficulté
- 4/5
- Temps estimé
- 3-5 jours
- Accessibilité débutants
- 68/100
Piste de recherche
Start with compiler/syntax/src/res_core.ml, especially parse_binary_expr, and reproduce the issue with npx rescript format src/A.res followed by npx rescript build. Trace how a regex literal at the start of a statement is parsed and how its parentheses are formatted. Done means the shown source remains parseable after formatting and the build succeeds.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Description
Thank you for filing! Check list:
- Is it a bug? Usage questions should often be asked in the forum instead.
- Concise, focused, friendly issue title & description.
- A minimal, reproducible example.
- OS and browser versions, if relevant.
- Is it already fixed in master? Instructions
A regex literal at the start of a statement, on the line after another statement, is parsed as a division that continues the previous line, so the file does not parse.
rescript format produces exactly this form from code that parses: it removes the parentheses around the literal.
Snippet
src/A.res:
let f = s => {
let t = s
(/a/)->RegExp.test(t)
}
npx rescript format src/A.res
cat src/A.res
npx rescript build
Actual
let f = s => {
let t = s
/a/->RegExp.test(t)
}
Cleaned 0/0
Error in check:
Syntax error!
/path/to/check/src/A.res:3:6-7
1 │ let f = s => {
2 │ let t = s
3 │ /a/->RegExp.test(t)
4 │ }
5 │
Did you forget to write an expression here?
Incremental build failed. Error: Could not parse Source Files
The formatted form fails the same way when written by hand, and so does a regex literal after an expression statement (Console.log(s)) or after a top-level let.
The formatter gives the same result for the other spellings that parse:
;at the end of the line before the literal (let t = s;) is removed;- on 12.3.1,
%re("/a/")->RegExp.test(t)becomes/a/->RegExp.test(t).
These spellings parse and keep their form after formatting:
- the literal as the first statement of the block;
- the literal as a call argument:
RegExp.test(/a/, t); - the literal bound to a name first:
let r = /a/.
Expected
The file parses: / at the start of a statement starts a regex literal.
If that is not possible, the formatter keeps the parentheses (or the ;) in front of such a literal.
Possible cause: in parse_binary_expr (compiler/syntax/src/res_core.ml), Minus | MinusDot | LessThan | Percent on a new line with no whitespace after it is not taken as a binary operator.
Forwardslash has no such case, so / on a new line always continues the expression on the line before.
Worked in ReScript 11
ReScript 11.1.4 has no regex literals, and its formatter keeps %re:
let f = s => {
let t = s
%re("/a/")->Js.Re.test_(t)
}
The same commands print the file unchanged and build it:
let f = s => {
let t = s
%re("/a/")->Js.Re.test_(t)
}
>>>> Start compiling
Dependency Finished
rescript: [1/3] src/A.ast
rescript: [2/3] src/A.d
rescript: [3/3] src/A.cmj
>>>> Finish compiling 19 mseconds
Environment
- ReScript 12.3.1, 13.0.0-alpha.6, and master
58c6c89(from pkg.pr.new, reports13.0.0-alpha.7): the same result on all three. - Node.js 24.9.0
- Linux x86_64
Context
We hit it when rescript format 12.3.1 rewrote %re("/^[0-9\.,+-]*$/")->RegExp.test(str) ? Some(str) : None, which came right after a let line in a block.
Workaround
Pass the literal as an argument (RegExp.test(/a/, t)) or bind it with let first.
- Langage dominant
- OCaml
- Étoiles
- 7.5k
- Forks
- 485
- Merge moyen
- 1 j 6 h
- PR mergées (30 j)
- 52
Préparer son environnement
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
-
Difficulté 3/5 1-2 jours Accessibilité débutants 76/100
rescript-lang/rescript#8687 ·
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 5/5 Plus d'une semaine Accessibilité débutants 35/100
rescript-lang/rescript#8659 · 2 commentaires · 2 réactions ·
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 5/5 Plus d'une semaine Accessibilité débutants 35/100
rescript-lang/rescript#8647 ·
Les mainteneurs répondent en général sous 1 jour
-
Untagged variants: boolean literal/payload overlap is rejected while string, int, float and bigint overlap is allowedPeut-être pris @cknitt l’a pris il y a 22 jours. Ouverte
rescript-lang/rescript#8632 · 1 personne assignée ·
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 5/5 Plus d'une semaine Accessibilité débutants 28/100
rescript-lang/rescript#8624 · 1 commentaire ·
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 84/100
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 2/5 1-3 heures Accessibilité débutants 78/100
Les mainteneurs répondent en général sous 1 jour
-
bug
Difficulté 2/5 1-3 heures Accessibilité débutants 84/100
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 2/5 1-3 heures Accessibilité débutants 74/100
guybedford/es-module-lexer#255 ·
Les mainteneurs répondent en général sous 1 jour
-
bug
Difficulté 2/5 1-3 heures Accessibilité débutants 78/100