8000 `('a : value mod non_float) or_null` is `non_float` by dkalinichenko-js · Pull Request #4158 · oxcaml/oxcaml · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

('a : value mod non_float) or_null is non_float #4158

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
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: 1 addition & 1 deletion otherlibs/stdlib_stable/or_null.ml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
(* *)
(**************************************************************************)

type 'a t : immediate_or_null with 'a = 'a or_null [@@or_null_reexport]
type 'a t : value_or_null = 'a or_null [@@or_null_reexport]

let null = Null
let this v = This v
Expand Down
4 changes: 2 additions & 2 deletions otherlibs/stdlib_stable/or_null.mli
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@
(* CR layouts: enable ocamlformat for this module when it starts supporting
jkind annotations. *)

type 'a t : immediate_or_null with 'a = 'a or_null [@@or_null_reexport]
type 'a t : value_or_null = 'a or_null [@@or_null_reexport]
(** The type of nullable values. Either [Null] or a value [This v].
['a or_null] has a non-standard [immediate_or_null with 'a] layout,
['a or_null] has a non-standard [value_or_null] layout,
preventing the type constructor from being nested. *)
Comment on lines 28 to 30
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not new in this patch, but I don't understand this comment.


val null : 'a t
Expand Down
11 changes: 6 additions & 5 deletions testsuite/tests/typing-layouts-or-null/containers.ml
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ Line 1, characters 21-25:
^^^^
Error: This expression has type "'a or_null"
but an expression was expected of type "('b : value)"
The kind of 'a or_null is immediate_or_null with 'a
because it is the primitive immediate_or_null type or_null.
The kind of 'a or_null is value_or_null
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the change from immediate_or_null with 'a? I think immediate_or_null with 'a is more accurate. Is the kind of 'a getting defaulted to value?

because it is the primitive value_or_null type or_null.
But the kind of 'a or_null must be a subkind of value
because it's the type of an array element,
chosen to have kind value.
Expand Down Expand Up @@ -129,8 +129,8 @@ Line 1, characters 28-32:
^^^^
Error: This expression has type "'a or_null"
but an expression was expected of type "('b : value)"
The kind of 'a or_null is immediate_or_null with 'a
because it is the primitive immediate_or_null type or_null.
The kind of 'a or_null is value_or_null
because it is the primitive value_or_null type or_null.
But the kind of 'a or_null must be a subkind of value
because it's the type of an array element,
chosen to have kind value.
Expand Down Expand Up @@ -260,7 +260,8 @@ let should_work_option3 = None

[%%expect{|
val should_work_option1 : float or_null option = Some (This 3.4)
val should_work_option2 : 'a or_null option = Some Null
val should_work_option2 :
('a : value_or_null mod non_null). 'a or_null option = Some Null
val should_work_option3 : 'a option = None
|}]

Expand Down
35 changes: 11 additions & 24 deletions testsuite/tests/typing-layouts-or-null/immediate.ml
8000
Original file line number Diff line number Diff line change
Expand Up @@ -85,21 +85,9 @@ type should_work = int_or_null accept_immediate_or_null
type should_work = int_or_null accept_immediate_or_null
|}]

(* CR layouts v2.8: this is a bug in principal inference with with-kinds. *)

type should_work = int or_null accept_immediate_or_null
[%%expect{|
type should_work = int or_null accept_immediate_or_null
|}, Principal{|
Line 1, characters 19-30:
1 | type should_work = int or_null accept_immediate_or_null
^^^^^^^^^^^
Error: This type "int or_null" should be an instance of type
"('a : immediate_or_null)"
The kind of int or_null is immediate_or_null with int
because it is the primitive immediate_or_null type or_null.
But the kind of int or_null must be a subkind of immediate_or_null
because of the definition of accept_immediate_or_null at line 1, characters 0-54.
|}]

(* Values. *)
Expand All @@ -118,8 +106,6 @@ external write_imm : ('a : immediate_or_null). 'a myref -> 'a -> unit
external equal : ('a : immediate_or_null). 'a -> 'a -> bool = "%equal"
|}]

(* CR layouts v2.8: this is a bug in principal inference with with-kinds. *)

let () =
let r = { v = (Null : int or_null) } in
let x = read_imm r in
Expand All @@ -129,14 +115,15 @@ let () =
;;

[%%expect{|
|}, Principal{|
Line 2, characters 16-36:
2 | let r = { v = (Null : int or_null) } in
^^^^^^^^^^^^^^^^^^^^
Error: This expression has type "int or_null"
but an expression was expected of type "('a : immediate_or_null)"
The kind of int or_null is immediate_or_null with int
because it is the primitive immediate_or_null type or_null.
But the kind of int or_null must be a subkind of immediate_or_null
because of the definition of myref at line 1, characters 0-56.
|}]

(* [immediate_or_null] is [non_float]: *)

type ('a : value_or_null mod non_float) accepts_nonfloat

type succeeds = t_immediate_or_null accepts_nonfloat

[%%expect{|
type ('a : value_or_null mod non_float) accepts_nonfloat
type succeeds = t_immediate_or_null accepts_nonfloat
|}]
49 changes: 27 additions & 22 deletions testsuite/tests/typing-layouts-or-null/reexport.ml
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,23 @@
(* CR layouts v3.5: ['a or_null] can't be re- 9E12 exported normally,
because users can't define their own [Null]-like constructors. *)
module Or_null = struct
type ('a : value) t : immediate_or_null with 'a = 'a or_null =
type ('a : value) t : value_or_null = 'a or_null =
| Null
| This of 'a
end
[%%expect{|
Lines 2-4, characters 2-16:
2 | ..type ('a : value) t : immediate_or_null with 'a = 'a or_null =
2 | ..type ('a : value) t : value_or_null = 'a or_null =
3 | | Null
4 | | This of 'a
Error: The kind of type "t" is immutable_data with 'a
because it's a boxed variant type.
But the kind of type "t" must be a subkind of immediate_or_null with 'a
because of the annotation on the declaration of the type t.
Error: This variant or record definition does not match that of type
"'a or_null"
Their internal representations differ:
the original definition has a null constructor.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a terrible error message. Let's at least leave a CR to return.

|}]

module Or_null = struct
type ('a : value) t : immediate_or_null with 'a = 'a or_null
type ('a : value) t : value_or_null = 'a or_null
end
[%%expect{|
module Or_null : sig type 'a t = 'a or_null end
Expand Down Expand Up @@ -50,7 +50,7 @@ Error: Unbound constructor "Or_null.This"
(* [@@or_null_reexport] re-exports those constructors. *)

module Or_null = struct
type ('a : value) t : immediate_or_null with 'a = 'a or_null [@@or_null_reexport]
type ('a : value) t : value_or_null with 'a = 'a or_null [@@or_null_reexport]
end
let n = Or_null.Null
let t v = Or_null.This v
Expand All @@ -70,10 +70,10 @@ Line 1, characters 24-40:
^^^^^^^^^^^^^^^^
Error: This expression has type "'a Or_null.t" = "'a or_null"
but an expression was expected of type "('b : value)"
The kind of 'a Or_null.t is immediate_or_null with 'a
because it is the primitive immediate_or_null type or_null.
The kind of 'a Or_null.t is value_or_null
because it is the primitive value_or_null type or_null.
But the kind of 'a Or_null.t must be a subkind of value
because of the definition of t at line 2, characters 2-83.
because of the definition of t at line 2, characters 2-79.
|}]

(* Type annotations are not required. *)
Expand All @@ -91,8 +91,8 @@ Line 4, characters 24-40:
^^^^^^^^^^^^^^^^
Error: This expression has type "'a Or_null.t" = "'a or_null"
but an expression was expected of type "('b : value)"
The kind of 'a Or_null.t is immediate_or_null with 'a
because it is the primitive immediate_or_null type or_null.
The kind of 'a Or_null.t is value_or_null
because it is the primitive value_or_null type or_null.
But the kind of 'a Or_null.t must be a subkind of value
because of the definition of t at line 2, characters 2-45.
|}]
Expand All @@ -105,8 +105,8 @@ type 'a t : value = 'a or_null [@@or_null_reexport]
Line 1, characters 0-51:
1 | type 'a t : value = 'a or_null [@@or_null_reexport]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error: The kind of type "'a or_null" is immediate_or_null with 'a
because it is the primitive immediate_or_null type or_null.
Error: The kind of type "'a or_null" is value_or_null
because it is the primitive value_or_null type or_null.
But the kind of type "'a or_null" must be a subkind of value
because of the definition of t at line 1, characters 0-51.
|}]
Expand All @@ -118,7 +118,7 @@ Line 1, characters 0-53:
1 | type 'a t : float64 = 'a or_null [@@or_null_reexport]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error: The layout of type "'a or_null" is value
because it is the primitive immediate_or_null type or_null.
because it is the primitive value_or_null type or_null.
But the layout of type "'a or_null" must be a sublayout of float64
because of the definition of t at line 1, characters 0-53.
|}]
Expand All @@ -129,7 +129,8 @@ type ('a : float64) t = 'a or_null [@@or_null_reexport]
Line 1, characters 24-26:
1 | type ('a : float64) t = 'a or_null [@@or_null_reexport]
^^
Error: This type "('a : float64)" should be an instance of type "('b : value)"
Error: This type "('a : float64)" should be an instance of type
"('b : value_or_null mod non_null)"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is very strange.

The layout of 'a is float64
because of the annotation on 'a in the declaration of the type t.
But the layout of 'a must overlap with value
Expand All @@ -146,15 +147,19 @@ let fail = Or_null.This (Or_null.This 5)

[%%expect{|
module Or_null :
sig type 'a t = 'a or_null = Null | This of 'a [@@or_null_reexport] end
sig
type ('a : value_or_null mod non_null) t = 'a or_null = Null | This of 'a [@@or_null_reexport]
end
Line 4, characters 24-40:
4 | let fail = Or_null.This (Or_null.This 5)
^^^^^^^^^^^^^^^^
Error: This expression has type "'a Or_null.t" = "'a or_null"
but an expression was expected of type "('b : value)"
The kind of 'a Or_null.t is immediate_or_null with 'a
because it is the primitive immediate_or_null type or_null.
But the kind of 'a Or_null.t must be a subkind of value
but an expression was expected of type
"('b : value_or_null mod non_null)"
The kind of 'a Or_null.t is value_or_null
because it is the primitive value_or_null type or_null.
But the kind of 'a Or_null.t must be a subkind of
value_or_null mod non_null
because of the definition of t at line 2, characters 2-63.
|}]

Expand Down
Loading
0