use types to disambiguate record access

git-svn-id: http://caml.inria.fr/svn/ocaml/branches/record-disambiguation@12934 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
master
Jacques Garrigue 2012-09-19 03:09:01 +00:00
parent 15ac0e835b
commit afa71dbea2
3 changed files with 90 additions and 0 deletions

View File

@ -27,3 +27,17 @@ end;;
(* path abbreviation is syntactic *) (* path abbreviation is syntactic *)
let f {M.x; y} = x+y;; (* fails *) let f {M.x; y} = x+y;; (* fails *)
let r = {M.x=1; y=2};; (* fails *) let r = {M.x=1; y=2};; (* fails *)
(* Use type information *)
let f (x:Complex.t) = x.re;;
let f x = ignore (x:Complex.t); x.re;; (* non principal *)
module M = struct
type t = {x:int}
module N = struct type s = t = {x:int} end
type u = { x:bool}
end;;
let f (r:M.u) = r.x;;
let f (r:M.t) = r.x;; (* fails *)
open M.N;;
let f r = r.x;;
let f (r:M.t) = r.x;; (* ok *)

View File

@ -0,0 +1,60 @@
# type t = { x : int; y : int; }
# Characters 5-6:
{x=3;z=2};;
^
Error: Unbound record field label z
# Characters 9-10:
fun {x=3;z=2} -> ();;
^
Error: Unbound record field label z
# Characters 26-34:
{x=3; contents=2};;
^^^^^^^^
Error: The record field label Pervasives.contents belongs to the type
'a ref but is mixed here with labels of type t
# type u = private { mutable u : int; }
# Characters 0-5:
{u=3};;
^^^^^
Error: Cannot create values of the private type u
# Characters 11-12:
fun x -> x.u <- 3;;
^
Error: Cannot assign field u of the private type u
# module M : sig type t = { x : int; y : int; } end
# val f : M.t -> int = <fun>
# val r : M.t = {M.x = 1; y = 2}
# val z : int = 3
# module M : sig type t = { x : int; y : int; } type u = { y : bool; } end
# Characters 43-51:
let f {M.x; y} = x+y;; (* fails *)
^^^^^^^^
Error: This pattern matches values of type M.u
but a pattern was expected which matches values of type M.t
# Characters 16-17:
let r = {M.x=1; y=2};; (* fails *)
^
Error: The record field label M.y belongs to the type M.u
but is mixed here with labels of type M.t
# val f : Complex.t -> float = <fun>
# Characters 32-36:
let f x = ignore (x:Complex.t); x.re;; (* non principal *)
^^^^
Warning 18: this type-based field selection is not principal.
val f : Complex.t -> float = <fun>
# module M :
sig
type t = { x : int; }
module N : sig type s = t = { x : int; } end
type u = { x : bool; }
end
# val f : M.u -> bool = <fun>
# Characters 16-17:
let f (r:M.t) = r.x;; (* fails *)
^
Error: This expression has type M.t but an expression was expected of type
M.u
# # val f : M.N.s -> int = <fun>
# val f : M.t -> int = <fun>
#

View File

@ -37,4 +37,20 @@ Error: This pattern matches values of type M.u
^ ^
Error: The record field label M.y belongs to the type M.u Error: The record field label M.y belongs to the type M.u
but is mixed here with labels of type M.t but is mixed here with labels of type M.t
# val f : Complex.t -> float = <fun>
# val f : Complex.t -> float = <fun>
# module M :
sig
type t = { x : int; }
module N : sig type s = t = { x : int; } end
type u = { x : bool; }
end
# val f : M.u -> bool = <fun>
# Characters 16-17:
let f (r:M.t) = r.x;; (* fails *)
^
Error: This expression has type M.t but an expression was expected of type
M.u
# # val f : M.N.s -> int = <fun>
# val f : M.t -> int = <fun>
# #