Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changes/stdlib-instanceof-annotations.fix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- An untagged variant with both `Blob` and `File` cases matches files as `File`, whatever the order of its cases. `File.t` is now a private abbreviation of `Blob.t`, and `JsError.t`, `Symbol.t` and the `Intl` classes can be untagged variant cases.
48 changes: 27 additions & 21 deletions compiler/ml/UntaggedVariants.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,8 +170,21 @@ through `globalThis` (#8785). The compiler trusts the annotations, as it
trusts the type of an external: a value that is not what its type declares is
recognized by what it is (rule 10).

The stdlib annotates the types of the classes it binds:

| Type | Annotation |
| --- | --- |
| `Date.t`, `RegExp.t`, `ArrayBuffer.t`, `DataView.t`, `Map.t`, `Set.t`, `WeakMap.t`, `WeakSet.t`, `Blob.t` | `@instanceOf` the class of the same name |
| `File.t`, a private abbreviation of `Blob.t` | `@instanceOf("File")`, a subclass of `Blob` |
| `JsError.t` | `@instanceOf("Error")` |
| `Intl.Collator.t`, `Intl.DateTimeFormat.t`, `Intl.ListFormat.t`, `Intl.Locale.t`, `Intl.NumberFormat.t`, `Intl.PluralRules.t`, `Intl.RelativeTimeFormat.t`, `Intl.Segmenter.t` | `@instanceOf("Intl.Collator")` and so on |
| `Int8Array.t` and the other typed arrays, public abbreviations of `TypedArray.t<_>` | `@instanceOf` the class of the same name |
| `Symbol.t` | `@typeOf("symbol")` |

Types without annotations are recognized from a fixed list of type names in
`ast_untagged_variants.ml:type_to_instanceof_backed_obj`. The predefined
`ast_untagged_variants.ml:type_to_instanceof_backed_obj`. Every listed stdlib
type is annotated, so the list only covers other types printed with one of
these paths. The predefined
`promise<_>` and `array<_>` are matched by path; the others by the printed
path of the type:

Expand All @@ -184,8 +197,8 @@ path of the type:
| `Int8Array.t`, `Uint8Array.t`, `Uint8ClampedArray.t`, `Int16Array.t`, `Uint16Array.t`, `Int32Array.t`, `Uint32Array.t`, `Float32Array.t`, `Float64Array.t`, `BigInt64Array.t`, `BigUint64Array.t` | the class of the same name |

The listed classes have no superclasses. The typed-array types are
abbreviations of one type, `TypedArray.t<_>`, and are told apart only by the
name as written.
abbreviations of one type, `TypedArray.t<_>`, and are told apart only by
their annotations, which are read on the name as written (Known bugs).

- Implementation: `variant_layout.ml:runtime_annotations`,
`declared_block_type`, `check_manifest_annotation`;
Expand All @@ -195,9 +208,10 @@ name as written.
`variant_runtime.ml:Instance`; `js_exp_make.ml:class_constructor`.
- Tests: `spec_test` rules 4 and 5;
`tests/tests/src/untagged_runtime_annotations_test.res`,
`untagged_runtime_annotations_shadow_test.res`; the fixtures above,
`untagged_runtime_annotations_shadow_test.res`,
`untagged_file_blob_test.res`; the fixtures above,
`UntaggedAtMostOneInstance.res`, `UntaggedTupleAndArray.res`.
- Shaped by #6296, #6383, #6396, #7788, #8009, #8950. Related: #7147.
- Shaped by #6296, #6383, #6396, #7788, #8009, #8950, #8948. Related: #7147.

### 6. Well-formedness

Expand Down Expand Up @@ -378,12 +392,13 @@ An `@as(null)` case does not prevent unboxing; `Some(N)` is `null`.
| `@as(null) WNull \| WString(string)` | `v` |
| `@as(undefined) WUndefined \| WUString(string)` | `Primitive_option.some(v)` |
| `@as("n") ONone \| OPaque(opaque)` | `Primitive_option.some(v)` |
| `BBlob(Blob.t) \| BString(string)` | `Primitive_option.some(v)` |
| `BBlob(Blob.t) \| BString(string)` | `v` |
| `DDate(Date.t) \| DString(string)` | `v` |

The stdlib marks `Date.t`, `RegExp.t`, `Map.t`, `Set.t`, `WeakMap.t`,
`WeakSet.t`, `ArrayBuffer.t`, `DataView.t`, the typed arrays and other
abstract types `@notUndefined`; `Blob.t` and `File.t` are not marked.
The stdlib's annotated types (rule 5) cannot hold `undefined`. It marks the
JSX element and component types, `Iterator.t`, `AsyncIterator.t`,
`TypedArray.t`, `Intl.Segments.t`, `Intl.NumberFormat.Grouping.t` and
`Lazy.t` with `@notUndefined`.

Rule 5 keeps an annotated abbreviation from claiming this of a type that can
hold `undefined`.
Expand Down Expand Up @@ -476,18 +491,9 @@ Console.log2(x == None, mk(U) == None) // true false
`Const_constructor`, including one whose literal is `undefined`; that this is
the cause is conjectured, not established.

**Overlapping instance classes follow declaration order** (#8938).

```rescript
@unboxed type b = B(Blob.t) | F(File.t)
let f = v => switch v { | B(_) => "blob" | F(_) => "file" }
Console.log(f(F(%raw(`new File(["x"], "a.txt")`)))) // blob
```

A `File` is a `Blob`, and the `Blob` check runs first.

**Typed arrays are classified by the name as written.** The typed-array types
are one type, so a value of one can be wrapped in the case of another.
**Typed arrays share one type** (#8955). The typed-array types are public
abbreviations of `TypedArray.t<_>`, each annotated with its class, so a value
of one can be wrapped in the case of another.

```rescript
@unboxed type ta = I8(Int8Array.t) | U8(Uint8Array.t)
Expand Down
2 changes: 1 addition & 1 deletion packages/@rescript/runtime/Stdlib_ArrayBuffer.res
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@notUndefined
@instanceOf("ArrayBuffer")
type t

@new external make: int => t = "ArrayBuffer"
Expand Down
2 changes: 1 addition & 1 deletion packages/@rescript/runtime/Stdlib_ArrayBuffer.resi
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ See: [`ArrayBuffer`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Ref
/**
Type representing an ArrayBuffer object used to represent a generic raw binary data buffer.
*/
@notUndefined
@instanceOf("ArrayBuffer")
type t

/**
Expand Down
2 changes: 1 addition & 1 deletion packages/@rescript/runtime/Stdlib_BigInt64Array.res
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/** The `BigInt64Array` typed array represents an array of 64-bit signed integers in platform byte order. See [BigInt64Array on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt64Array)
*/
@editor.completeFrom(Stdlib.TypedArray)
@editor.completeFrom(Stdlib.TypedArray) @instanceOf("BigInt64Array")
type t = Stdlib_TypedArray.t<bigint>

module Constants = {
Expand Down
2 changes: 1 addition & 1 deletion packages/@rescript/runtime/Stdlib_BigUint64Array.res
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/** The `BigUint64Array` typed array represents an array of 64-bit unsigned integers in platform byte order. See [BigUint64Array on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigUint64Array)
*/
@editor.completeFrom(Stdlib.TypedArray)
@editor.completeFrom(Stdlib.TypedArray) @instanceOf("BigUint64Array")
type t = Stdlib_TypedArray.t<bigint>

module Constants = {
Expand Down
1 change: 1 addition & 0 deletions packages/@rescript/runtime/Stdlib_Blob.res
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
/** JavaScript Blob API */
@instanceOf("Blob")
type t
2 changes: 1 addition & 1 deletion packages/@rescript/runtime/Stdlib_DataView.res
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@notUndefined
@instanceOf("DataView")
type t

@new
Expand Down
2 changes: 1 addition & 1 deletion packages/@rescript/runtime/Stdlib_DataView.resi
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ See [`DataView`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Referen
/**
Type representing a DataView.
*/
@notUndefined
@instanceOf("DataView")
type t

/**
Expand Down
2 changes: 1 addition & 1 deletion packages/@rescript/runtime/Stdlib_Date.res
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@notUndefined
@instanceOf("Date")
type t

type msSinceEpoch = float
Expand Down
2 changes: 1 addition & 1 deletion packages/@rescript/runtime/Stdlib_Date.resi
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
/**
A type representing a JavaScript date.
*/
@notUndefined
@instanceOf("Date")
type t

/**
Expand Down
5 changes: 3 additions & 2 deletions packages/@rescript/runtime/Stdlib_File.res
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
/** JavaScript File API */
type t
/** JavaScript File API. A file is a blob. */
@instanceOf("File")
type t = private Stdlib_Blob.t
2 changes: 1 addition & 1 deletion packages/@rescript/runtime/Stdlib_Float32Array.res
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/** The `Float32Array` typed array represents an array of 32-bit floating point numbers in platform byte order. See [Float32Array on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float32Array)
*/
@editor.completeFrom(Stdlib.TypedArray)
@editor.completeFrom(Stdlib.TypedArray) @instanceOf("Float32Array")
type t = Stdlib_TypedArray.t<float>

module Constants = {
Expand Down
2 changes: 1 addition & 1 deletion packages/@rescript/runtime/Stdlib_Float64Array.res
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/** The `Float64Array` typed array represents an array of 64-bit floating point numbers in platform byte order. See [Float64Array on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float64Array)
*/
@editor.completeFrom(Stdlib.TypedArray)
@editor.completeFrom(Stdlib.TypedArray) @instanceOf("Float64Array")
type t = Stdlib_TypedArray.t<float>

module Constants = {
Expand Down
2 changes: 1 addition & 1 deletion packages/@rescript/runtime/Stdlib_Int16Array.res
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/** The `Int16Array` typed array represents an array of twos-complement 16-bit signed integers in platform byte order. See [Int16Array on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Int16Array)
*/
@editor.completeFrom(Stdlib.TypedArray)
@editor.completeFrom(Stdlib.TypedArray) @instanceOf("Int16Array")
type t = Stdlib_TypedArray.t<int>

module Constants = {
Expand Down
2 changes: 1 addition & 1 deletion packages/@rescript/runtime/Stdlib_Int32Array.res
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/** The `Int32Array` typed array represents an array of twos-complemenet 32-bit signed integers in platform byte order. See [Int32Array on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Int32Array)
*/
@editor.completeFrom(Stdlib.TypedArray)
@editor.completeFrom(Stdlib.TypedArray) @instanceOf("Int32Array")
type t = Stdlib_TypedArray.t<int>

module Constants = {
Expand Down
2 changes: 1 addition & 1 deletion packages/@rescript/runtime/Stdlib_Int8Array.res
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/** The `Int8Array` typed array represents an array of twos-complement 8-bit signed integers. See [Int8Array on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Int8Array)
*/
@editor.completeFrom(Stdlib.TypedArray)
@editor.completeFrom(Stdlib.TypedArray) @instanceOf("Int8Array")
type t = Stdlib_TypedArray.t<int>

module Constants = {
Expand Down
2 changes: 1 addition & 1 deletion packages/@rescript/runtime/Stdlib_Intl_Collator.res
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@notUndefined
@instanceOf("Intl.Collator")
type t

type usage = [#sort | #search]
Expand Down
2 changes: 1 addition & 1 deletion packages/@rescript/runtime/Stdlib_Intl_DateTimeFormat.res
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Bindings to JavaScript's `Intl.DateTimeFormat`.
*/

@notUndefined
@instanceOf("Intl.DateTimeFormat")
type t

type dateStyle = [#full | #long | #medium | #short]
Expand Down
2 changes: 1 addition & 1 deletion packages/@rescript/runtime/Stdlib_Intl_ListFormat.res
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@notUndefined
@instanceOf("Intl.ListFormat")
type t

type listType = [
Expand Down
2 changes: 1 addition & 1 deletion packages/@rescript/runtime/Stdlib_Intl_Locale.res
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Bindings to JavaScript's `Intl.Locale`.
*/

@notUndefined
@instanceOf("Intl.Locale")
type t

type options = {
Expand Down
2 changes: 1 addition & 1 deletion packages/@rescript/runtime/Stdlib_Intl_NumberFormat.res
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module Grouping = Stdlib_Intl_NumberFormat_Grouping

@notUndefined
@instanceOf("Intl.NumberFormat")
type t

/**
Expand Down
2 changes: 1 addition & 1 deletion packages/@rescript/runtime/Stdlib_Intl_PluralRules.res
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@notUndefined
@instanceOf("Intl.PluralRules")
type t

type localeType = [#cardinal | #ordinal]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Bindings to JavaScript's `Intl.RelativeTimeFormat`.

See [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/RelativeTimeFormat) for API details.
*/
@notUndefined
@instanceOf("Intl.RelativeTimeFormat")
type t

type numeric = [#always | #auto]
Expand Down
2 changes: 1 addition & 1 deletion packages/@rescript/runtime/Stdlib_Intl_Segmenter.res
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Bindings to JavaScript's `Intl.Segmenter`.

See [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Segmenter) for API details.
*/
@notUndefined
@instanceOf("Intl.Segmenter")
type t

type granularity = [#grapheme | #word | #sentence]
Expand Down
2 changes: 1 addition & 1 deletion packages/@rescript/runtime/Stdlib_JsError.res
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@notUndefined
@instanceOf("Error")
type t

@get external stack: t => option<string> = "stack"
Expand Down
2 changes: 1 addition & 1 deletion packages/@rescript/runtime/Stdlib_JsError.resi
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ See [`Error`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/
*/

/** Represents a JavaScript error. */
@notUndefined
@instanceOf("Error")
type t

/**
Expand Down
2 changes: 1 addition & 1 deletion packages/@rescript/runtime/Stdlib_Map.res
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@notUndefined
@instanceOf("Map")
type t<'k, 'v>

external asIterable: t<'k, 'v> => Stdlib_Iterable.t<('k, 'v)> = "%identity"
Expand Down
2 changes: 1 addition & 1 deletion packages/@rescript/runtime/Stdlib_Map.resi
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ See [`Map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Gl
/**
Type representing an instance of `Map`.
*/
@notUndefined
@instanceOf("Map")
type t<'k, 'v>

/**
Expand Down
2 changes: 1 addition & 1 deletion packages/@rescript/runtime/Stdlib_RegExp.res
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@notUndefined
@instanceOf("RegExp")
type t

module Result = {
Expand Down
2 changes: 1 addition & 1 deletion packages/@rescript/runtime/Stdlib_RegExp.resi
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ See [`RegExp`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference
/**
Type representing an instantiated `RegExp`.
*/
@notUndefined
@instanceOf("RegExp")
type t

module Result: {
Expand Down
2 changes: 1 addition & 1 deletion packages/@rescript/runtime/Stdlib_Set.res
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@notUndefined
@instanceOf("Set")
type t<'a>

external asIterable: t<'a> => Stdlib_Iterable.t<'a> = "%identity"
Expand Down
2 changes: 1 addition & 1 deletion packages/@rescript/runtime/Stdlib_Set.resi
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ See [`Set`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Gl
/**
Type representing an instance of `Set`.
*/
@notUndefined
@instanceOf("Set")
type t<'a>

/**
Expand Down
2 changes: 1 addition & 1 deletion packages/@rescript/runtime/Stdlib_Symbol.res
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@notUndefined
@typeOf("symbol")
type t

@val external make: string => t = "Symbol"
Expand Down
2 changes: 1 addition & 1 deletion packages/@rescript/runtime/Stdlib_Symbol.resi
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Compiles to a regular JavaScript Symbol.
/**
Type representing a Symbol.
*/
@notUndefined
@typeOf("symbol")
type t

/**
Expand Down
2 changes: 1 addition & 1 deletion packages/@rescript/runtime/Stdlib_Uint16Array.res
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/** The `Uint16Array` typed array represents an array of 16-bit unsigned integers in platform byte order. See [Uint16Array on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint16Array)
*/
@editor.completeFrom(Stdlib.TypedArray)
@editor.completeFrom(Stdlib.TypedArray) @instanceOf("Uint16Array")
type t = Stdlib_TypedArray.t<int>

module Constants = {
Expand Down
2 changes: 1 addition & 1 deletion packages/@rescript/runtime/Stdlib_Uint32Array.res
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/** The `Uint32Array` typed array represents an array of 32-bit unsigned integers in platform byte order. See [Uint32Array on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint32Array)
*/
@editor.completeFrom(Stdlib.TypedArray)
@editor.completeFrom(Stdlib.TypedArray) @instanceOf("Uint32Array")
type t = Stdlib_TypedArray.t<int>

module Constants = {
Expand Down
2 changes: 1 addition & 1 deletion packages/@rescript/runtime/Stdlib_Uint8Array.res
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/** The `Uint8Array` typed array represents an array of 8-bit unsigned integers. See [Uint8Array on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array)
*/
@editor.completeFrom(Stdlib.TypedArray)
@editor.completeFrom(Stdlib.TypedArray) @instanceOf("Uint8Array")
type t = Stdlib_TypedArray.t<int>

module Constants = {
Expand Down
2 changes: 1 addition & 1 deletion packages/@rescript/runtime/Stdlib_Uint8ClampedArray.res
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/** The `Uint8ClampedArray` typed array represents an array of 8-bit unsigned integers clamped to 0-255. See [Uint8ClampedArray on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8ClampedArray)
*/
@editor.completeFrom(Stdlib.TypedArray)
@editor.completeFrom(Stdlib.TypedArray) @instanceOf("Uint8ClampedArray")
type t = Stdlib_TypedArray.t<int>

module Constants = {
Expand Down
2 changes: 1 addition & 1 deletion packages/@rescript/runtime/Stdlib_WeakMap.res
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Weak maps keep key/value pairs where keys must be objects and the references do
*/

/** Mutable weak map storing values of type `'v` with object keys `'k`. */
@notUndefined
@instanceOf("WeakMap")
type t<'k, 'v>

/**
Expand Down
2 changes: 1 addition & 1 deletion packages/@rescript/runtime/Stdlib_WeakSet.res
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Weak sets store references to objects without preventing those objects from bein
*/

/** Mutable weak set storing object references of type `'a`. */
@notUndefined
@instanceOf("WeakSet")
type t<'a>

/**
Expand Down
2 changes: 1 addition & 1 deletion tests/tests/src/UntaggedVariants.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -517,7 +517,7 @@ async function classifyAll(t) {
console.log(t.name);
return;
}
if (t instanceof Blob) {
if (t instanceof Blob && !(t instanceof File)) {
console.log(t.size);
return;
}
Expand Down
Loading
Loading