@@ -23,7 +23,7 @@ type fn_ctx = {
23
23
mutable fnctx_just_saw_ret : bool
24
24
}
25
25
26
- exception Type_error of string * Ast. ty
26
+ exception Type_error of string * string
27
27
28
28
let log cx =
29
29
Session. log
@@ -37,7 +37,159 @@ let iflog cx thunk =
37
37
else ()
38
38
;;
39
39
40
- let type_error expected actual = raise (Type_error (expected, actual))
40
+ let head_only ty =
41
+ match ty with
42
+
43
+ Ast. TY_tup _ -> " tup(...)"
44
+ | Ast. TY_rec _ -> " rec(...)"
45
+
46
+ | Ast. TY_fn _ -> " fn (...) -> ..."
47
+
48
+ | Ast. TY_vec _ -> " vec[...]"
49
+ | Ast. TY_chan _ -> " chan[...]"
50
+ | Ast. TY_port _ -> " port[...]"
51
+
52
+ | Ast. TY_obj _ -> " obj { ... }"
53
+ | Ast. TY_box _ -> " @(...)"
54
+ | Ast. TY_mutable _ -> " (mutable ...)"
55
+ | Ast. TY_constrained _ -> " (... : <constrained>)"
56
+
57
+ | _ -> Printf. sprintf " %a" Ast. sprintf_ty ty
58
+ ;;
59
+
60
+
61
+ let rec rec_diff
62
+ (a :Ast.ty_rec ) (b :Ast.ty_rec )
63
+ (abuf :Buffer.t ) (bbuf :Buffer.t )
64
+ : unit =
65
+
66
+ Buffer. add_string abuf " rec(" ;
67
+ Buffer. add_string bbuf " rec(" ;
68
+
69
+ let rec append_first_diff buf a b i =
70
+ let alen = Array. length a in
71
+ let blen = Array. length b in
72
+ if i > = alen
73
+ then
74
+ Buffer. add_string buf " ...)"
75
+ else
76
+ if i > = blen
77
+ then
78
+ Printf. bprintf buf
79
+ " ... <%d elements>)" (blen - i)
80
+ else
81
+ let (alab, aty) = a.(i) in
82
+ let (blab, bty) = b.(i) in
83
+ if alab <> blab
84
+ then
85
+ Printf. bprintf buf " ... <ty> %s ...)" alab
86
+ else
87
+ if aty <> bty
88
+ then
89
+ let (a,_) = summarize_difference aty bty in
90
+ Printf. bprintf buf " ... %s %s ...)" a alab
91
+ else
92
+ append_first_diff buf a b (i+ 1 )
93
+ in
94
+ append_first_diff abuf a b 0 ;
95
+ append_first_diff bbuf b a 0 ;
96
+ Buffer. add_string abuf " )" ;
97
+ Buffer. add_string bbuf " )" ;
98
+
99
+
100
+ and tup_diff
101
+ (a :Ast.ty_tup ) (b :Ast.ty_tup )
102
+ (abuf :Buffer.t ) (bbuf :Buffer.t )
103
+ : unit =
104
+
105
+ Buffer. add_string abuf " tup(" ;
106
+ Buffer. add_string bbuf " tup(" ;
107
+
108
+ let rec append_first_diff buf a b i =
109
+ let alen = Array. length a in
110
+ let blen = Array. length b in
111
+ if i > = alen
112
+ then
113
+ Buffer. add_string buf " ...)"
114
+ else
115
+ if i > = blen
116
+ then
117
+ Printf. bprintf buf
118
+ " ... <%d elements>)" (blen - i)
119
+ else
120
+ let (aty) = a.(i) in
121
+ let (bty) = b.(i) in
122
+ if aty <> bty
123
+ then
124
+ let (a,_) = summarize_difference aty bty in
125
+ Printf. bprintf buf " ... %s ...)" a
126
+ else
127
+ append_first_diff buf a b (i+ 1 )
128
+ in
129
+ append_first_diff abuf a b 0 ;
130
+ append_first_diff bbuf b a 0 ;
131
+ Buffer. add_string abuf " )" ;
132
+ Buffer. add_string bbuf " )" ;
133
+
134
+
135
+ and summarize_difference (expected :Ast.ty ) (actual :Ast.ty )
136
+ : (string * string) =
137
+ if expected = actual
138
+ then (" _" , " _" )
139
+ else
140
+ begin
141
+ let ebuf = Buffer. create 10 in
142
+ let abuf = Buffer. create 10 in
143
+
144
+ let p s =
145
+ Buffer. add_string ebuf s;
146
+ Buffer. add_string abuf s
147
+ in
148
+
149
+ let sub e a =
150
+ let (e, a) = summarize_difference e a in
151
+ Printf. bprintf ebuf " %s" e;
152
+ Printf. bprintf abuf " %s" a;
153
+ in
154
+
155
+ begin
156
+ match expected, actual with
157
+ (Ast. TY_tup etys , Ast. TY_tup atys ) ->
158
+ tup_diff etys atys ebuf abuf
159
+
160
+ | (Ast. TY_rec eelts , Ast. TY_rec aelts ) ->
161
+ rec_diff eelts aelts ebuf abuf
162
+
163
+ | (Ast. TY_vec e , Ast. TY_vec a ) ->
164
+ p " vec[" ; sub e a; p " ]" ;
165
+
166
+ | (Ast. TY_chan e , Ast. TY_port a ) ->
167
+ p " chan[" ; sub e a; p " ]" ;
168
+
169
+ | (Ast. TY_port e , Ast. TY_port a ) ->
170
+ p " port[" ; sub e a; p " ]" ;
171
+
172
+ | (Ast. TY_box e , Ast. TY_box a ) ->
173
+ p " @" ; sub e a;
174
+
175
+ | (Ast. TY_mutable e , Ast. TY_mutable a ) ->
176
+ p " mutable " ; sub e a;
177
+
178
+ | (e , a ) ->
179
+ Buffer. add_string ebuf (head_only e);
180
+ Buffer. add_string abuf (head_only a)
181
+ end ;
182
+ (Buffer. contents ebuf, Buffer. contents abuf)
183
+ end
184
+ ;;
185
+
186
+ let type_error_full expected actual =
187
+ raise (Type_error (expected, actual))
188
+ ;;
189
+
190
+ let type_error expected actual =
191
+ type_error_full expected (head_only actual)
192
+ ;;
41
193
42
194
(* We explicitly curry [cx] like this to avoid threading it through all the
43
195
* inner functions. *)
@@ -101,7 +253,8 @@ let check_stmt (cx:Semant.ctxt) : (fn_ctx -> Ast.stmt -> unit) =
101
253
let demand (expected :Ast.ty ) (actual :Ast.ty ) : unit =
102
254
let expected, actual = fundamental_ty expected, fundamental_ty actual in
103
255
if expected <> actual then
104
- type_error (Printf. sprintf " %a" Ast. sprintf_ty expected) actual
256
+ let (e,a) = summarize_difference expected actual in
257
+ type_error_full e a
105
258
in
106
259
let demand_integer (actual :Ast.ty ) : unit =
107
260
if not (is_integer (fundamental_ty actual)) then
@@ -982,9 +1135,9 @@ let check_stmt (cx:Semant.ctxt) : (fn_ctx -> Ast.stmt -> unit) =
982
1135
with Type_error (expected , actual ) ->
983
1136
Common. err
984
1137
(Some stmt.Common. id)
985
- " mismatched types: expected %s but found %a "
1138
+ " mismatched types: expected %s but found %s "
986
1139
expected
987
- Ast. sprintf_ty actual
1140
+ actual
988
1141
in
989
1142
check_stmt'
990
1143
in
0 commit comments