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
2 changes: 2 additions & 0 deletions changes/typed-arrays-private.breaking.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- Typed arrays are distinct types: `Int8Array.t` and the others are private abbreviations of `TypedArray.t<_>`, so an untagged variant can no longer take one typed array for another. Use each module's own functions, such as `Int8Array.get`, or upcast with `(view :> TypedArray.t<int>)` to call the `TypedArray` functions.
- `@instanceOf` that introduces a class on an abbreviation of an abstract type requires a private abbreviation: write `@instanceOf("Element") type element = private node`.
13 changes: 12 additions & 1 deletion compiler/ml/UntaggedVariants.md
Original file line number Diff line number Diff line change
Expand Up @@ -181,13 +181,24 @@ type hierarchy (`type dogLike<'a> = private animalLike<_dog<'a>>`). A public
would `type dog = animal<int>` or `type dog = phantom<int>` with
`type phantom<'a> = animal`.

A class introduced on an abbreviation of a type the compiler does not see is
private too: `@instanceOf("Element") type element = private node`. A public
abbreviation would make every `node` an `element`, and a second one could
declare the same values instances of another class while the type checker
treats both as one type. The stdlib's typed arrays are such private
abbreviations of `TypedArray.t<_>`, so `Int8Array.t` and `Uint8Array.t` are
different types, upcast to `TypedArray.t<int>` with `:>`. Each typed array
module has the functions of `TypedArray` for its own type, through the
`TypedArray.Impl` functor.

| Declaration | Error | Fixture |
| --- | --- | --- |
| `@typeOf("string") type t = option<string>`, `type t<'a> = 'a`, an abbreviation of `unit`, `list<_>` or a variant | @typeOf on a type abbreviation must describe an abstract type, ... | `runtime_annotation_on_option.res`, `runtime_annotation_on_type_variable.res` |
| `@notUndefined type t = option<int>` | @notUndefined on a type abbreviation must describe an abstract type, ... | `not_undefined_on_option.res`, `tests/build_tests/not_undefined_attribute` |
| `@typeOf("number") type t = sym` with `@typeOf("symbol") type sym`, `@typeOf("string") type t = int`, or an abbreviation of a function type, a record or a tuple | This annotation, @typeOf("number"), contradicts the abbreviated type, whose values are recognized by @typeOf("symbol"). An array or tuple is recognized by Array.isArray. | `runtime_annotation_contradicts_manifest.res`, `runtime_annotation_contradicts_builtin.res`, `runtime_annotation_contradicts_function.res`, `runtime_annotation_contradicts_tuple.res` |
| `@instanceOf("Date") type date = X.t` in a functor of `X`, or over `(type a)`; `@notUndefined type t = X.t` | @instanceOf cannot describe the type of a functor parameter, ... | `instance_of_functor_parameter.res`, `type_of_locally_abstract_type.res`, `not_undefined_on_functor_parameter_type.res` |
| `@instanceOf("Dog") type dog = animal`, `= animal<int>`, or `= phantom<int>` with `type phantom<'a> = animal` | A subclass must be a private abbreviation ... | `instance_of_public_subclass.res`, `instance_of_public_subclass_instance.res`, `instance_of_public_subclass_through_alias.res` |
| `@instanceOf("Element") type element = node` with `type node` | A class must be declared on an abstract type or a private abbreviation ... | `instance_of_public_abbreviation.res`; `typed_array_cases_distinct.res` (typed arrays are distinct types) |
| `@instanceOf("Animal") type t = private dog` | Animal appears twice in this chain of abbreviations ... | `instance_of_class_twice_in_chain.res` |
| `@instanceOf("MyList") type t = private array<int>` | @instanceOf("MyList") cannot describe the values of an array type: ... subclasses of Array are not supported. | `instance_of_array_subclass.res` |
| any of the three on a record or variant | @instanceOf can only be used on abstract types and type abbreviations ... | `runtime_annotation_on_record.res`, `invalid_attribute_not_undefined.res` |
Expand Down Expand Up @@ -271,7 +282,7 @@ written (Known bugs).
`Cross_runtime_annotation_functor_argument`,
`Cross_not_undefined_option_implementation`.
- Shaped by #6296, #6383, #6396, #7458, #7464, #7788, #8009, #8950, #8948,
#8949, #8964. Related: #7147.
#8949, #8955, #8964. Related: #7147.

### 6. Well-formedness

Expand Down
8 changes: 8 additions & 0 deletions compiler/ml/ast_untagged_variants.ml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ type error =
| RuntimeAnnotationContradictsManifest of string * string
| SubclassOfArray of string
| SubclassOfPublicAbbreviation of string * string
| ClassOnPublicAbbreviation of string
| ClassTwiceInChain of string
exception Error of Location.t * error

Expand Down Expand Up @@ -169,6 +170,13 @@ let report_error ppf =
are recognized by Array.isArray, and subclasses of Array are not \
supported."
name
| ClassOnPublicAbbreviation name ->
fprintf ppf
"A class must be declared on an abstract type or a private abbreviation: \
write `= private ...`, so that values of the abbreviated type are not \
instances of %s without a coercion, and another abbreviation cannot \
declare them instances of another class."
name
| SubclassOfPublicAbbreviation (name, ancestor) ->
fprintf ppf
"A subclass must be a private abbreviation: write `= private ...` so \
Expand Down
9 changes: 8 additions & 1 deletion compiler/ml/typedecl.ml
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,14 @@ let check_manifest_annotation ~loc ~env (decl : Types.type_declaration) =
| Can_be_undefined -> unrelated ())
| (Instance_of _ | Type_of _), None -> (
match Typeopt.abstractness env manifest with
| Opaque -> ()
| Opaque -> (
(* Two public abbreviations of one type would declare its values
instances of two classes, and the type checker would not tell
them apart *)
match outer with
| Instance_of name when decl.type_private = Public ->
error (ClassOnPublicAbbreviation name)
| Not_undefined | Instance_of _ | Type_of _ -> ())
| Stands_for_another -> stands_for_another ()
| Not_abstract -> unrelated ())
| Type_of block_type, Some inner when block_type = inner -> ()
Expand Down
9 changes: 7 additions & 2 deletions packages/@rescript/runtime/Stdlib_BigInt64Array.res
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
/** 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) @instanceOf("BigInt64Array")
type t = Stdlib_TypedArray.t<bigint>
@instanceOf("BigInt64Array")
type t = private Stdlib_TypedArray.t<bigint>

include Stdlib_TypedArray.Impl({
type t = t
type elt = bigint
})

module Constants = {
/**`bytesPerElement` returns the element size. See [BYTES_PER_ELEMENT on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/BYTES_PER_ELEMENT)
Expand Down
9 changes: 7 additions & 2 deletions packages/@rescript/runtime/Stdlib_BigUint64Array.res
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
/** 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) @instanceOf("BigUint64Array")
type t = Stdlib_TypedArray.t<bigint>
@instanceOf("BigUint64Array")
type t = private Stdlib_TypedArray.t<bigint>

include Stdlib_TypedArray.Impl({
type t = t
type elt = bigint
})

module Constants = {
/**`bytesPerElement` returns the element size. See [BYTES_PER_ELEMENT on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/BYTES_PER_ELEMENT)
Expand Down
9 changes: 7 additions & 2 deletions packages/@rescript/runtime/Stdlib_Float32Array.res
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
/** 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) @instanceOf("Float32Array")
type t = Stdlib_TypedArray.t<float>
@instanceOf("Float32Array")
type t = private Stdlib_TypedArray.t<float>

include Stdlib_TypedArray.Impl({
type t = t
type elt = float
})

module Constants = {
/**`bytesPerElement` returns the element size. See [BYTES_PER_ELEMENT on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/BYTES_PER_ELEMENT)
Expand Down
9 changes: 7 additions & 2 deletions packages/@rescript/runtime/Stdlib_Float64Array.res
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
/** 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) @instanceOf("Float64Array")
type t = Stdlib_TypedArray.t<float>
@instanceOf("Float64Array")
type t = private Stdlib_TypedArray.t<float>

include Stdlib_TypedArray.Impl({
type t = t
type elt = float
})

module Constants = {
/**`bytesPerElement` returns the element size. See [BYTES_PER_ELEMENT on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/BYTES_PER_ELEMENT)
Expand Down
9 changes: 7 additions & 2 deletions packages/@rescript/runtime/Stdlib_Int16Array.res
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
/** 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) @instanceOf("Int16Array")
type t = Stdlib_TypedArray.t<int>
@instanceOf("Int16Array")
type t = private Stdlib_TypedArray.t<int>

include Stdlib_TypedArray.Impl({
type t = t
type elt = int
})

module Constants = {
/**`bytesPerElement` returns the element size. See [BYTES_PER_ELEMENT on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/BYTES_PER_ELEMENT)
Expand Down
9 changes: 7 additions & 2 deletions packages/@rescript/runtime/Stdlib_Int32Array.res
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
/** 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) @instanceOf("Int32Array")
type t = Stdlib_TypedArray.t<int>
@instanceOf("Int32Array")
type t = private Stdlib_TypedArray.t<int>

include Stdlib_TypedArray.Impl({
type t = t
type elt = int
})

module Constants = {
/**`bytesPerElement` returns the element size. See [BYTES_PER_ELEMENT on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/BYTES_PER_ELEMENT)
Expand Down
9 changes: 7 additions & 2 deletions packages/@rescript/runtime/Stdlib_Int8Array.res
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
/** 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) @instanceOf("Int8Array")
type t = Stdlib_TypedArray.t<int>
@instanceOf("Int8Array")
type t = private Stdlib_TypedArray.t<int>

include Stdlib_TypedArray.Impl({
type t = t
type elt = int
})

module Constants = {
/**`bytesPerElement` returns the element size. See [BYTES_PER_ELEMENT on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/BYTES_PER_ELEMENT)
Expand Down
Loading
Loading