aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGraydon Hoare <[email protected]>2010-10-07 13:15:38 -0700
committerGraydon Hoare <[email protected]>2010-10-07 13:15:38 -0700
commite553ab9fc05dcaef7d92d801f1ab20bd58fe5d87 (patch)
treeec7aae820fb7cbf6873af8dceef177872097601e /src
parentAdd the beginnings of an ast folder plus an empty module for resolve. (diff)
downloadrust-e553ab9fc05dcaef7d92d801f1ab20bd58fe5d87.tar.xz
rust-e553ab9fc05dcaef7d92d801f1ab20bd58fe5d87.zip
Simplify type-mismatch messages.
Diffstat (limited to 'src')
-rw-r--r--src/boot/me/type.ml163
1 files changed, 158 insertions, 5 deletions
diff --git a/src/boot/me/type.ml b/src/boot/me/type.ml
index 782d2e27..d2d01f0a 100644
--- a/src/boot/me/type.ml
+++ b/src/boot/me/type.ml
@@ -23,7 +23,7 @@ type fn_ctx = {
mutable fnctx_just_saw_ret: bool
}
-exception Type_error of string * Ast.ty
+exception Type_error of string * string
let log cx =
Session.log
@@ -37,7 +37,159 @@ let iflog cx thunk =
else ()
;;
-let type_error expected actual = raise (Type_error (expected, actual))
+let head_only ty =
+ match ty with
+
+ Ast.TY_tup _ -> "tup(...)"
+ | Ast.TY_rec _ -> "rec(...)"
+
+ | Ast.TY_fn _ -> "fn (...) -> ..."
+
+ | Ast.TY_vec _ -> "vec[...]"
+ | Ast.TY_chan _ -> "chan[...]"
+ | Ast.TY_port _ -> "port[...]"
+
+ | Ast.TY_obj _ -> "obj { ... }"
+ | Ast.TY_box _ -> "@(...)"
+ | Ast.TY_mutable _ -> "(mutable ...)"
+ | Ast.TY_constrained _ -> "(... : <constrained>)"
+
+ | _ -> Printf.sprintf "%a" Ast.sprintf_ty ty
+;;
+
+
+let rec rec_diff
+ (a:Ast.ty_rec) (b:Ast.ty_rec)
+ (abuf:Buffer.t) (bbuf:Buffer.t)
+ : unit =
+
+ Buffer.add_string abuf "rec(";
+ Buffer.add_string bbuf "rec(";
+
+ let rec append_first_diff buf a b i =
+ let alen = Array.length a in
+ let blen = Array.length b in
+ if i >= alen
+ then
+ Buffer.add_string buf "...)"
+ else
+ if i >= blen
+ then
+ Printf.bprintf buf
+ "... <%d elements>)" (blen - i)
+ else
+ let (alab, aty) = a.(i) in
+ let (blab, bty) = b.(i) in
+ if alab <> blab
+ then
+ Printf.bprintf buf "... <ty> %s ...)" alab
+ else
+ if aty <> bty
+ then
+ let (a,_) = summarize_difference aty bty in
+ Printf.bprintf buf "... %s %s ...)" a alab
+ else
+ append_first_diff buf a b (i+1)
+ in
+ append_first_diff abuf a b 0;
+ append_first_diff bbuf b a 0;
+ Buffer.add_string abuf ")";
+ Buffer.add_string bbuf ")";
+
+
+and tup_diff
+ (a:Ast.ty_tup) (b:Ast.ty_tup)
+ (abuf:Buffer.t) (bbuf:Buffer.t)
+ : unit =
+
+ Buffer.add_string abuf "tup(";
+ Buffer.add_string bbuf "tup(";
+
+ let rec append_first_diff buf a b i =
+ let alen = Array.length a in
+ let blen = Array.length b in
+ if i >= alen
+ then
+ Buffer.add_string buf "...)"
+ else
+ if i >= blen
+ then
+ Printf.bprintf buf
+ "... <%d elements>)" (blen - i)
+ else
+ let (aty) = a.(i) in
+ let (bty) = b.(i) in
+ if aty <> bty
+ then
+ let (a,_) = summarize_difference aty bty in
+ Printf.bprintf buf "... %s ...)" a
+ else
+ append_first_diff buf a b (i+1)
+ in
+ append_first_diff abuf a b 0;
+ append_first_diff bbuf b a 0;
+ Buffer.add_string abuf ")";
+ Buffer.add_string bbuf ")";
+
+
+and summarize_difference (expected:Ast.ty) (actual:Ast.ty)
+ : (string * string) =
+ if expected = actual
+ then ("_", "_")
+ else
+ begin
+ let ebuf = Buffer.create 10 in
+ let abuf = Buffer.create 10 in
+
+ let p s =
+ Buffer.add_string ebuf s;
+ Buffer.add_string abuf s
+ in
+
+ let sub e a =
+ let (e, a) = summarize_difference e a in
+ Printf.bprintf ebuf "%s" e;
+ Printf.bprintf abuf "%s" a;
+ in
+
+ begin
+ match expected, actual with
+ (Ast.TY_tup etys, Ast.TY_tup atys) ->
+ tup_diff etys atys ebuf abuf
+
+ | (Ast.TY_rec eelts, Ast.TY_rec aelts) ->
+ rec_diff eelts aelts ebuf abuf
+
+ | (Ast.TY_vec e, Ast.TY_vec a) ->
+ p "vec["; sub e a; p "]";
+
+ | (Ast.TY_chan e, Ast.TY_port a) ->
+ p "chan["; sub e a; p "]";
+
+ | (Ast.TY_port e, Ast.TY_port a) ->
+ p "port["; sub e a; p "]";
+
+ | (Ast.TY_box e, Ast.TY_box a) ->
+ p "@"; sub e a;
+
+ | (Ast.TY_mutable e, Ast.TY_mutable a) ->
+ p "mutable "; sub e a;
+
+ | (e, a) ->
+ Buffer.add_string ebuf (head_only e);
+ Buffer.add_string abuf (head_only a)
+ end;
+ (Buffer.contents ebuf, Buffer.contents abuf)
+ end
+;;
+
+let type_error_full expected actual =
+ raise (Type_error (expected, actual))
+;;
+
+let type_error expected actual =
+ type_error_full expected (head_only actual)
+;;
(* We explicitly curry [cx] like this to avoid threading it through all the
* inner functions. *)
@@ -101,7 +253,8 @@ let check_stmt (cx:Semant.ctxt) : (fn_ctx -> Ast.stmt -> unit) =
let demand (expected:Ast.ty) (actual:Ast.ty) : unit =
let expected, actual = fundamental_ty expected, fundamental_ty actual in
if expected <> actual then
- type_error (Printf.sprintf "%a" Ast.sprintf_ty expected) actual
+ let (e,a) = summarize_difference expected actual in
+ type_error_full e a
in
let demand_integer (actual:Ast.ty) : unit =
if not (is_integer (fundamental_ty actual)) then
@@ -982,9 +1135,9 @@ let check_stmt (cx:Semant.ctxt) : (fn_ctx -> Ast.stmt -> unit) =
with Type_error (expected, actual) ->
Common.err
(Some stmt.Common.id)
- "mismatched types: expected %s but found %a"
+ "mismatched types: expected %s but found %s"
expected
- Ast.sprintf_ty actual
+ actual
in
check_stmt'
in