Hacktoberfest 2026 : les issues que les mainteneurs ont marquées pour octobre, ouvertes et accessibles aux débutants. Parcourir les issues Hacktoberfest

Untagged variant switch with a default arm matches instances and literals in the wrong case

Ouverte
#8,995 0 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Les mainteneurs répondent en général sous 1 jour

Personne n'a encore pris cette issue.

Évaluation

Difficulté
4/5
Temps estimé
1-2 jours
Accessibilité débutants
55/100
Type d'issue
Bug
Clarté
Plutôt claire
Activité
Active
Stack technique
javascript, ocaml
Domaine
compilers

Piste de recherche

Start with compiler/ml/lam_compile.ml, especially compile_untagged_cases and compile_general_cases, then compare the behavior with rules 7 and 8 in compiler/ml/UntaggedVariants.md. Run or add compiler cases for the instance and literal examples in the issue; done means both produce other for the shown inputs while preserving the documented matching rules.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Description

A switch on an untagged variant with a _ arm can match a value in the wrong case. This happens when the default survives into the untagged dispatch, which takes a variant with several cases; with fewer cases the match compiler expands _ into the remaining cases and the result is correct.

An instance lands in the object case.

@unboxed type t = D(Date.t) | R(RegExp.t) | O({x: int}) | S(string) | I(int) | F(int => int)
@inline(never) let id = (x: t) => x
let f = v => switch v { | O(_) => "O" | S(_) => "S" | _ => "other" }
Console.log(f(id(D(Date.make()))))
function f(v) {
  switch (typeof v) {
    case "object" :
      return "O";
    case "string" :
      return "S";
    default:
      return "other";
  }
}

Output: O; expected other. The case "object" lacks the !(v instanceof Date) && !(v instanceof RegExp) exclusion that the object check gets elsewhere.

A literal lands in the string case.

@unboxed type t = | @as("lit") Lit | S(string) | I(int) | B(bool) | O({x: int}) | F(int => int)
@inline(never) let id = (x: t) => x
let f = v => switch v { | S(_) => "S" | O(_) => "O" | _ => "other" }
Console.log(f(id(Lit)))
function f(v) {
  switch (typeof v) {
    case "string" :
      return "S";
    case "object" :
      return "O";
    default:
      return "other";
  }
}

Output: S; expected other. No test for the literal "lit" is emitted before the typeof switch.

Both contradict compiler/ml/UntaggedVariants.md: rule 7 ("A value equal to a literal therefore belongs to the literal's case") and rule 8 ("In both forms a value of an instance case never lands in the object case"). The cause is presumably in lam_compile.ml:compile_untagged_cases / compile_general_cases when the switch keeps a Default and the instance and literal cases it would need to exclude have no arm of their own (not yet confirmed).

Langage dominant
OCaml
Étoiles
7.5k
Forks
483
Merge moyen
21 h 8 min
PR mergées (30 j)
183

Préparer son environnement

Ouvrir dans Codespaces

Lance le conteneur de développement du projet dans votre navigateur, avec votre propre compte GitHub.

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Autres issues de rescript-lang/rescript

Toutes les issues de rescript-lang/rescript

Issues similaires

Plus d'issues Compilers

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.