Record spread that copies a mutable field is generalized (unsound)
Les mainteneurs répondent en général sous 1 jour
Une pull request liée a déjà été fusionnée.
- #9158 par @cknitt — fusionnée
Évaluation
- Difficulté
- 4/5
- Temps estimé
- 3-5 jours
- Accessibilité débutants
- 38/100
- Type d'issue
- Bug
- Clarté
- Clairement spécifiée
- Activité
- Active
- Stack technique
- ocaml
- Domaine
- compilers
Piste de recherche
The unsound generalization comes from the value restriction in Typecore.is_nonexpansive, specifically how it handles record literals with a spread: written mutable fields are checked, but copied ones are not. Start there and compare with the handling of a plain record literal, then reproduce with the cell<'a> snippet from the issue using an external base. Done means a spread that copies a mutable field is treated as expansive, the example no longer type-checks, and existing type tests still pass.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Description
A record literal with a spread, {...base, field: value}, has its type generalized even when it copies a mutable field from base. The literal allocates a fresh record with that mutable field, so one binding can be written at one type and read at another:
type cell<'a> = {tag: int, mutable value: option<'a>}
@val external base: cell<'a> = "base"
let copy = {...base, tag: 1}
copy.value = Some(1)
let s: option<string> = copy.value
This compiles on master (8e26a9ca69) and generates:
let init = base;
let copy = {
tag: 1,
value: init.value
};
copy.value = 1;
let s = copy.value;
so s, typed option<string>, holds the number 1. The same happens with optional mutable fields ({tag?: int, mutable value?: 'a}).
Cause
The value restriction (Typecore.is_nonexpansive) checks a spread literal's written fields for mutability and requires the spread expression to be non-expansive, but treats the fields it copies from the spread as harmless. A spread literal allocates every field of the record, so a mutable field makes it expansive whether it is written or copied, just like a literal without a spread (#9149, #9152).
base has to be a polymorphic, non-expansive value of a record type with a mutable field. A record literal of such a type is itself expansive, so in practice base is an external, for example a binding to a default options object: @val external defaults: options<'a> followed by {...defaults, x: 1}.
- Langage dominant
- OCaml
- Étoiles
- 7.5k
- Forks
- 484
- Merge moyen
- 17 h 2 min
- PR mergées (30 j)
- 249
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
-
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
-
Issues from differential semantic drift analysis (b123b7c3 to c10223e8)Peut-être pris @cknitt l’a pris aujourd’hui. Ouverte
rescript-lang/rescript#9186 · 1 personne assignée ·
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 4/5 3-5 jours Accessibilité débutants 38/100
rescript-lang/rescript#9185 ·
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 4/5 3-5 jours Accessibilité débutants 28/100
rescript-lang/rescript#9184 ·
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 3/5 1-2 jours Accessibilité débutants 55/100
rescript-lang/rescript#9183 ·
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 72/100
JakeChampion/lang#14091 ·
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 2/5 1-3 heures Accessibilité débutants 72/100
Les mainteneurs répondent en général sous 1 jour
-
Won't Fix
Difficulté 2/5 1-3 heures Accessibilité débutants 62/100
microsoft/TypeScript#65107 · 1 commentaire ·
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 2/5 1-3 heures Accessibilité débutants 62/100
partiql/partiql-lang-kotlin#1987 ·
Les mainteneurs répondent en général sous 3 jours
-
`color-mix(var(--color-red-500))` crashes the build with `Cannot read properties of undefined (reading 'kind')`Peut-être pris @zerotohero3 l’a pris aujourd’hui. Ouverte
Difficulté 2/5 1-3 heures Accessibilité débutants 80/100
tailwindlabs/tailwindcss#20657 ·
Les mainteneurs répondent en général sous 1 jour