From 6f5a0a3b3ba6fc444ce722049cadcfb26a96dc35 Mon Sep 17 00:00:00 2001 From: Lenny222 Date: Wed, 21 Dec 2011 21:36:43 +0100 Subject: [PATCH 1/8] json: add "null" --- src/libstd/json.rs | 11 +++++++++++ src/test/stdtest/json.rs | 7 +++++++ 2 files changed, 18 insertions(+) diff --git a/src/libstd/json.rs b/src/libstd/json.rs index e0b559ec7471..2adfbca70cf7 100644 --- a/src/libstd/json.rs +++ b/src/libstd/json.rs @@ -34,6 +34,8 @@ tag json { list(@[json]); /* Variant: dict */ dict(map::hashmap); + /* Variant: null */ + null; } /* @@ -233,6 +235,14 @@ fn from_str_bool(s: str) -> (option::t, str) { } } +fn from_str_null(s: str) -> (option::t, str) { + if (str::starts_with(s, "null")) { + (some(null), str::slice(s, 4u, str::byte_len(s))) + } else { + (none, s) + } +} + fn from_str_helper(s: str) -> (option::t, str) { let s = str::trim_left(s); if str::is_empty(s) { ret (none, s); } @@ -243,6 +253,7 @@ fn from_str_helper(s: str) -> (option::t, str) { '{' { from_str_dict(s) } '0' to '9' | '-' | '+' | '.' { from_str_float(s) } 't' | 'f' { from_str_bool(s) } + 'n' { from_str_null(s) } _ { ret (none, s); } } } diff --git a/src/test/stdtest/json.rs b/src/test/stdtest/json.rs index db65b223ff78..41031b2e16a4 100644 --- a/src/test/stdtest/json.rs +++ b/src/test/stdtest/json.rs @@ -5,6 +5,11 @@ import option; import std::json::*; import option::{none, some}; +#[test] +fn test_from_str_null() { + assert(from_str("null") == some(null)); +} + #[test] fn test_from_str_num() { assert(from_str("3") == some(num(3f))); @@ -31,6 +36,7 @@ fn test_from_str_bool() { fn test_from_str_list() { assert(from_str("[]") == some(list(@[]))); assert(from_str("[true]") == some(list(@[boolean(true)]))); + assert(from_str("[null]") == some(list(@[null]))); assert(from_str("[3, 1]") == some(list(@[num(3f), num(1f)]))); assert(from_str("[2, [4, 1]]") == some(list(@[num(2f), list(@[num(4f), num(1f)])]))); @@ -44,6 +50,7 @@ fn test_from_str_list() { fn test_from_str_dict() { assert(from_str("{}") != none); assert(from_str("{\"a\": 3}") != none); + assert(from_str("{\"a\": null}") != none); assert(from_str("{\"a\": }") == none); assert(from_str("{\"a\" }") == none); assert(from_str("{\"a\"") == none); From 341e4151d6721d53be1408a2ab4cf8198ea8c9be Mon Sep 17 00:00:00 2001 From: Lenny222 Date: Wed, 21 Dec 2011 22:21:11 +0100 Subject: [PATCH 2/8] json: to_str() also for "null" --- src/libstd/json.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libstd/json.rs b/src/libstd/json.rs index 2adfbca70cf7..64ce2794bb44 100644 --- a/src/libstd/json.rs +++ b/src/libstd/json.rs @@ -65,6 +65,7 @@ fn to_str(j: json) -> str { }); str::concat(["{ ", str::connect(parts, ", "), " }"]) } + null { "null" } } } From 7beb21c6e33bdc474c10f443035856e9d30c69d6 Mon Sep 17 00:00:00 2001 From: Lenny222 Date: Wed, 21 Dec 2011 22:57:57 +0100 Subject: [PATCH 3/8] tests: add corner case (empty list) --- src/test/stdtest/list.rs | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/src/test/stdtest/list.rs b/src/test/stdtest/list.rs index da1643e92749..227e8ad299de 100644 --- a/src/test/stdtest/list.rs +++ b/src/test/stdtest/list.rs @@ -15,6 +15,12 @@ fn test_from_vec() { assert (head(tail(tail(l))) == 2); } +#[test] +fn test_from_vec_empty() { + let empty : list::list = from_vec([]); + assert (empty == list::nil::); +} + #[test] fn test_from_vec_mut() { let l = from_vec([mutable 0, 1, 2]); @@ -25,10 +31,11 @@ fn test_from_vec_mut() { #[test] fn test_foldl() { - let l = from_vec([0, 1, 2, 3, 4]); fn add(&&a: uint, &&b: int) -> uint { ret a + (b as uint); } - let rs = list::foldl(l, 0u, add); - assert (rs == 10u); + let l = from_vec([0, 1, 2, 3, 4]); + let empty = list::nil::; + assert (list::foldl(l, 0u, add) == 10u); + assert (list::foldl(empty, 0u, add) == 0u); } #[test] @@ -37,26 +44,25 @@ fn test_foldl2() { a - b } let l = from_vec([1, 2, 3, 4]); - let sum = list::foldl(l, 0, sub); - assert sum == -10; + assert (list::foldl(l, 0, sub) == -10); } #[test] fn test_find_success() { - let l = from_vec([0, 1, 2]); fn match(&&i: int) -> option::t { ret if i == 2 { option::some(i) } else { option::none:: }; } - let rs = list::find(l, match); - assert (rs == option::some(2)); + let l = from_vec([0, 1, 2]); + assert (list::find(l, match) == option::some(2)); } #[test] fn test_find_fail() { - let l = from_vec([0, 1, 2]); fn match(&&_i: int) -> option::t { ret option::none::; } - let rs = list::find(l, match); - assert (rs == option::none::); + let l = from_vec([0, 1, 2]); + let empty = list::nil::; + assert (list::find(l, match) == option::none::); + assert (list::find(empty, match) == option::none::); } #[test] @@ -72,6 +78,8 @@ fn test_has() { #[test] fn test_len() { let l = from_vec([0, 1, 2]); + let empty = list::nil::; assert (list::len(l) == 3u); + assert (list::len(empty) == 0u); } From e31983a02eb5476dbfc84c71af037ddde3492fb5 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Thu, 22 Dec 2011 09:38:03 +0100 Subject: [PATCH 4/8] Add Lennart Kudling to AUTHORS --- AUTHORS.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS.txt b/AUTHORS.txt index c6f4240a32cb..c07ef5b37a0b 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -27,6 +27,7 @@ Jesse Ruderman Josh Matthews Joshua Wise Kelly Wilson +Lennart Kudling Lindsey Kuper Marijn Haverbeke Matt Brubeck From e2e077c831b5ef43780d18631170807ba0623270 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Thu, 22 Dec 2011 13:47:30 +0100 Subject: [PATCH 5/8] Remove trivial cast checker I consider the added complexity not justified at this point, and it interacts badly with the patches for issue #828. Feel free to discuss. --- src/comp/middle/check_const.rs | 1 - src/comp/middle/trans.rs | 22 ++------- src/comp/middle/ty.rs | 48 -------------------- src/comp/middle/typeck.rs | 28 +++--------- src/comp/syntax/ast_util.rs | 17 ------- src/comp/syntax/parse/parser.rs | 2 +- src/libcore/float.rs | 54 +++++++++++------------ src/test/compile-fail/non-triv-cast-be.rs | 17 ------- src/test/run-pass/triv-cast-be.rs | 28 ------------ src/test/run-pass/triv-cast-const.rs | 13 ------ 10 files changed, 36 insertions(+), 194 deletions(-) delete mode 100644 src/test/compile-fail/non-triv-cast-be.rs delete mode 100644 src/test/run-pass/triv-cast-be.rs delete mode 100644 src/test/run-pass/triv-cast-const.rs diff --git a/src/comp/middle/check_const.rs b/src/comp/middle/check_const.rs index 81d41b06e49f..1a34fe631e95 100644 --- a/src/comp/middle/check_const.rs +++ b/src/comp/middle/check_const.rs @@ -43,7 +43,6 @@ fn check_expr(sess: session, e: @expr, &&is_const: bool, v: visit::vt) { "disallowed operator in constant expression"); ret; } - expr_cast(_, _) { } expr_lit(@{node: lit_str(_), _}) { sess.span_err(e.span, "string constants are not supported"); diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index c163ac9871b0..cc2259d6e0d0 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -3581,12 +3581,7 @@ fn trans_expr(bcx: @block_ctxt, e: @ast::expr, dest: dest) -> @block_ctxt { } else { ret lval_to_dps(bcx, a, dest); } } - ast::expr_cast(val, _) { - alt tcx.cast_map.find(e.id) { - some(ty::triv_cast.) { ret trans_expr(bcx, val, dest); } - _ { ret trans_cast(bcx, val, e.id, dest); } - } - } + ast::expr_cast(val, _) { ret trans_cast(bcx, val, e.id, dest); } ast::expr_anon_obj(anon_obj) { ret trans_anon_obj(bcx, e.span, anon_obj, e.id, dest); } @@ -3615,7 +3610,7 @@ fn trans_expr(bcx: @block_ctxt, e: @ast::expr, dest: dest) -> @block_ctxt { // that is_call_expr(ex) -- but we don't support that // yet // FIXME - check (ast_util::is_tail_call_expr(ex)); + check (ast_util::is_call_expr(ex)); ret trans_be(bcx, ex); } ast::expr_fail(expr) { @@ -3952,8 +3947,7 @@ fn trans_ret(bcx: @block_ctxt, e: option::t<@ast::expr>) -> @block_ctxt { fn build_return(bcx: @block_ctxt) { Br(bcx, bcx_fcx(bcx).llreturn); } // fn trans_be(cx: &@block_ctxt, e: &@ast::expr) -> result { -fn trans_be(cx: @block_ctxt, e: @ast::expr) : -ast_util::is_tail_call_expr(e) -> +fn trans_be(cx: @block_ctxt, e: @ast::expr) : ast_util::is_call_expr(e) -> @block_ctxt { // FIXME: Turn this into a real tail call once // calling convention issues are settled @@ -4728,16 +4722,6 @@ fn trans_impl(cx: @local_ctxt, name: ast::ident, methods: [@ast::method], // that does so later on? fn trans_const_expr(cx: @crate_ctxt, e: @ast::expr) -> ValueRef { alt e.node { - ast::expr_cast(e1, _) { - alt ccx_tcx(cx).cast_map.find(e.id) { - some(ty::triv_cast.) { trans_const_expr(cx, e1) } - _ { - cx.sess.span_err(e.span, - "non-trivial cast in constant expression"); - fail; - } - } - } ast::expr_lit(lit) { ret trans_crate_lit(cx, *lit); } ast::expr_binary(b, e1, e2) { let te1 = trans_const_expr(cx, e1); diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index ca63fdb6dd85..ef6177822e37 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -31,7 +31,6 @@ export ast_constr_to_constr; export bind_params_in_type; export block_ty; export constr; -export cast_type; export constr_general; export constr_table; export count_ty_params; @@ -106,8 +105,6 @@ export substitute_type_params; export t; export tag_variants; export tag_variant_with_id; -export triv_cast; -export triv_eq_ty; export ty_param_substs_opt_and_ty; export ty_param_kinds_and_ty; export ty_native_fn; @@ -133,7 +130,6 @@ export ty_param; export ty_ptr; export ty_rec; export ty_tag; -export ty_to_machine_ty; export ty_tup; export ty_type; export ty_send_type; @@ -214,17 +210,10 @@ type creader_cache = hashmap<{cnum: int, pos: uint, len: uint}, ty::t>; type tag_var_cache = @smallintmap::smallintmap<@mutable [variant_info]>; -tag cast_type { - /* cast may be ignored after substituting primitive with machine types - since expr already has the right type */ - triv_cast; -} - type ctxt = @{ts: @type_store, sess: session::session, def_map: resolve::def_map, - cast_map: hashmap, node_types: node_type_table, items: ast_map::map, freevars: freevars::freevar_map, @@ -420,7 +409,6 @@ fn mk_ctxt(s: session::session, dm: resolve::def_map, amap: ast_map::map, @{ts: ts, sess: s, def_map: dm, - cast_map: ast_util::new_node_hash(), node_types: ntt, items: amap, freevars: freevars, @@ -1423,42 +1411,6 @@ fn eq_raw_ty(&&a: @raw_t, &&b: @raw_t) -> bool { // the types are interned. fn eq_ty(&&a: t, &&b: t) -> bool { a == b } - -// Convert type to machine type -// (i.e. replace uint, int, float with target architecture machine types) -// -// FIXME somewhat expensive but this should only be called rarely -fn ty_to_machine_ty(cx: ctxt, ty: t) -> t { - fn sub_fn(cx: ctxt, uint_ty: t, int_ty: t, float_ty: t, in: t) -> t { - alt struct(cx, in) { - ty_uint(ast::ty_u.) { ret uint_ty; } - ty_int(ast::ty_i.) { ret int_ty; } - ty_float(ast::ty_f.) { ret float_ty; } - _ { ret in; } - } - } - - let cfg = cx.sess.get_targ_cfg(); - let uint_ty = mk_mach_uint(cx, cfg.uint_type); - let int_ty = mk_mach_int(cx, cfg.int_type); - let float_ty = mk_mach_float(cx, cfg.float_type); - let fold_m = fm_general(bind sub_fn(cx, uint_ty, int_ty, float_ty, _)); - - ret fold_ty(cx, fold_m, ty); -} - -// Two types are trivially equal if they are either -// equal or if they are equal after substituting all occurences of -// machine independent primitive types by their machine type equivalents -// for the current target architecture -fn triv_eq_ty(cx: ctxt, &&a: t, &&b: t) -> bool { - let a = alt interner::get(*cx.ts, a).struct - { ty_named(t, _) { t } _ { a } }; - let b = alt interner::get(*cx.ts, b).struct - { ty_named(t, _) { t } _ { b } }; - a == b || ty_to_machine_ty(cx, a) == ty_to_machine_ty(cx, b) -} - // Type lookups fn node_id_to_ty_param_substs_opt_and_ty(cx: ctxt, id: ast::node_id) -> ty_param_substs_opt_and_ty { diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs index 1de1457b76a0..d37482f0f1e8 100644 --- a/src/comp/middle/typeck.rs +++ b/src/comp/middle/typeck.rs @@ -1850,21 +1850,8 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier, } ast::expr_be(e) { // FIXME: prove instead of assert - assert (ast_util::is_tail_call_expr(e)); + assert (ast_util::is_call_expr(e)); check_expr_with(fcx, e, fcx.ret_ty); - - alt e.node { - ast::expr_cast(_, _) { - alt tcx.cast_map.find(e.id) { - option::some(ty::triv_cast.) { } - _ { tcx.sess.span_err(expr.span, - "non-trivial cast of tail-call return value"); - } - } - } - _ { /* regular tail call */ } - } - bot = true; write::nil_ty(tcx, id); } @@ -2066,19 +2053,19 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier, ast::expr_cast(e, t) { bot = check_expr(fcx, e); let t_1 = ast_ty_to_ty_crate(fcx.ccx, t); - let t_e = expr_ty(tcx, e); + let t_e = ty::expr_ty(tcx, e); if ty::type_is_nil(tcx, t_e) { tcx.sess.span_err(expr.span, "cast from nil: " + - ty_to_str(tcx, expr_ty(tcx, e)) + " as " + + ty_to_str(tcx, t_e) + " as " + ty_to_str(tcx, t_1)); } if ty::type_is_nil(tcx, t_1) { tcx.sess.span_err(expr.span, "cast to nil: " + - ty_to_str(tcx, expr_ty(tcx, e)) + " as " + + ty_to_str(tcx, t_e) + " as " + ty_to_str(tcx, t_1)); } @@ -2087,14 +2074,9 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier, && type_is_scalar(fcx, expr.span, t_1)) { tcx.sess.span_err(expr.span, "non-scalar cast: " + - ty_to_str(tcx, expr_ty(tcx, e)) + " as " + + ty_to_str(tcx, t_e) + " as " + ty_to_str(tcx, t_1)); } - - // mark as triv_cast for later dropping in trans - if ty::triv_eq_ty(tcx, t_1, t_e) - { tcx.cast_map.insert(expr.id, ty::triv_cast); } - write::ty_only_fixup(fcx, id, t_1); } ast::expr_vec(args, mut) { diff --git a/src/comp/syntax/ast_util.rs b/src/comp/syntax/ast_util.rs index ea3ca0bd5041..f32b4f7aa930 100644 --- a/src/comp/syntax/ast_util.rs +++ b/src/comp/syntax/ast_util.rs @@ -1,5 +1,3 @@ -import core::{str, option, int}; -import std::map; import codemap::span; import ast::*; @@ -7,13 +5,6 @@ fn respan(sp: span, t: T) -> spanned { ret {node: t, span: sp}; } -fn new_node_hash() -> map::hashmap { - fn node_id_hash(&&i: node_id) -> uint { ret int::hash(i as int); } - fn node_id_eq(&&a: node_id, &&b: node_id) -> bool - { ret int::eq(a as int, b as int); } - ret map::mk_hashmap(node_id_hash, node_id_eq); -} - /* assuming that we're not in macro expansion */ fn mk_sp(lo: uint, hi: uint) -> span { ret {lo: lo, hi: hi, expanded_from: codemap::os_none}; @@ -198,14 +189,6 @@ pure fn is_call_expr(e: @expr) -> bool { alt e.node { expr_call(_, _, _) { true } _ { false } } } -pure fn is_tail_call_expr(e: @expr) -> bool { - alt e.node { - expr_call(_, _, _) { true } - expr_cast(inner_e, _) { is_call_expr(inner_e) } - _ { false } - } -} - fn is_constraint_arg(e: @expr) -> bool { alt e.node { expr_lit(_) { ret true; } diff --git a/src/comp/syntax/parse/parser.rs b/src/comp/syntax/parse/parser.rs index d12943202c76..cf02c4ea31e3 100644 --- a/src/comp/syntax/parse/parser.rs +++ b/src/comp/syntax/parse/parser.rs @@ -958,7 +958,7 @@ fn parse_bottom_expr(p: parser) -> @ast::expr { let e = parse_expr(p); // FIXME: Is this the right place for this check? - if /*check*/ ast_util::is_tail_call_expr(e) { + if /*check*/ast_util::is_call_expr(e) { hi = e.span.hi; ex = ast::expr_be(e); } else { p.fatal("Non-call expression in tail call"); } diff --git a/src/libcore/float.rs b/src/libcore/float.rs index ab27b938b53f..fdc5dda996d1 100644 --- a/src/libcore/float.rs +++ b/src/libcore/float.rs @@ -482,7 +482,7 @@ Function: acos Returns the arccosine of an angle (measured in rad) */ pure fn acos(x: float) -> float - { be m_float::acos(x as m_float) as float } + { ret m_float::acos(x as m_float) as float } /* Function: asin @@ -490,7 +490,7 @@ Function: asin Returns the arcsine of an angle (measured in rad) */ pure fn asin(x: float) -> float - { be m_float::asin(x as m_float) as float } + { ret m_float::asin(x as m_float) as float } /* Function: atan @@ -498,7 +498,7 @@ Function: atan Returns the arctangents of an angle (measured in rad) */ pure fn atan(x: float) -> float - { be m_float::atan(x as m_float) as float } + { ret m_float::atan(x as m_float) as float } /* @@ -507,7 +507,7 @@ Function: atan2 Returns the arctangent of an angle (measured in rad) */ pure fn atan2(y: float, x: float) -> float - { be m_float::atan2(y as m_float, x as m_float) as float } + { ret m_float::atan2(y as m_float, x as m_float) as float } /* Function: ceil @@ -515,7 +515,7 @@ Function: ceil Returns the smallest integral value less than or equal to `n` */ pure fn ceil(n: float) -> float - { be m_float::ceil(n as m_float) as float } + { ret m_float::ceil(n as m_float) as float } /* Function: cos @@ -523,7 +523,7 @@ Function: cos Returns the cosine of an angle `x` (measured in rad) */ pure fn cos(x: float) -> float - { be m_float::cos(x as m_float) as float } + { ret m_float::cos(x as m_float) as float } /* Function: cosh @@ -532,7 +532,7 @@ Returns the hyperbolic cosine of `x` */ pure fn cosh(x: float) -> float - { be m_float::cosh(x as m_float) as float } + { ret m_float::cosh(x as m_float) as float } /* @@ -541,7 +541,7 @@ Function: exp Returns `consts::e` to the power of `n* */ pure fn exp(n: float) -> float - { be m_float::exp(n as m_float) as float } + { ret m_float::exp(n as m_float) as float } /* Function: abs @@ -549,7 +549,7 @@ Function: abs Returns the absolute value of `n` */ pure fn abs(n: float) -> float - { be m_float::abs(n as m_float) as float } + { ret m_float::abs(n as m_float) as float } /* Function: floor @@ -557,7 +557,7 @@ Function: floor Returns the largest integral value less than or equal to `n` */ pure fn floor(n: float) -> float - { be m_float::floor(n as m_float) as float } + { ret m_float::floor(n as m_float) as float } /* Function: fmod @@ -565,7 +565,7 @@ Function: fmod Returns the floating-point remainder of `x/y` */ pure fn fmod(x: float, y: float) -> float - { be m_float::fmod(x as m_float, y as m_float) as float } + { ret m_float::fmod(x as m_float, y as m_float) as float } /* Function: ln @@ -573,7 +573,7 @@ Function: ln Returns the natural logaritm of `n` */ pure fn ln(n: float) -> float - { be m_float::ln(n as m_float) as float } + { ret m_float::ln(n as m_float) as float } /* Function: ldexp @@ -581,7 +581,7 @@ Function: ldexp Returns `x` multiplied by 2 to the power of `n` */ pure fn ldexp(n: float, i: int) -> float - { be m_float::ldexp(n as m_float, i as c_int) as float } + { ret m_float::ldexp(n as m_float, i as c_int) as float } /* Function: ln1p @@ -590,7 +590,7 @@ Returns the natural logarithm of `1+n` accurately, even for very small values of `n` */ pure fn ln1p(n: float) -> float - { be m_float::ln1p(n as m_float) as float } + { ret m_float::ln1p(n as m_float) as float } /* Function: log10 @@ -598,7 +598,7 @@ Function: log10 Returns the logarithm to base 10 of `n` */ pure fn log10(n: float) -> float - { be m_float::log10(n as m_float) as float } + { ret m_float::log10(n as m_float) as float } /* Function: log2 @@ -606,7 +606,7 @@ Function: log2 Returns the logarithm to base 2 of `n` */ pure fn log2(n: float) -> float - { be m_float::log2(n as m_float) as float } + { ret m_float::log2(n as m_float) as float } /* Function: modf @@ -622,7 +622,7 @@ The fractional part of `n` */ #[no(warn_trivial_casts)] // FIXME Implement pure fn modf(n: float, &iptr: float) -> float { unsafe { - be m_float::modf(n as m_float, ptr::addr_of(iptr) as *m_float) as float + ret m_float::modf(n as m_float, ptr::addr_of(iptr) as *m_float) as float } } /* @@ -640,13 +640,13 @@ Returns: The fractional part of `n` */ pure fn frexp(n: float, &exp: c_int) -> float - { be m_float::frexp(n as m_float, exp) as float } + { ret m_float::frexp(n as m_float, exp) as float } /* Function: pow */ pure fn pow(v: float, e: float) -> float - { be m_float::pow(v as m_float, e as m_float) as float } + { ret m_float::pow(v as m_float, e as m_float) as float } /* @@ -656,7 +656,7 @@ Returns the integral value nearest to `x` (according to the prevailing rounding mode) in floating-point format */ pure fn rint(x: float) -> float - { be m_float::rint(x as m_float) as float } + { ret m_float::rint(x as m_float) as float } /* Function: round @@ -666,7 +666,7 @@ Return the integral value nearest to `x` rounding half-way cases away from zero, regardless of the current rounding direction. */ pure fn round(x: float) -> float - { be m_float::round(x as m_float) as float } + { ret m_float::round(x as m_float) as float } /* Function: sin @@ -674,7 +674,7 @@ Function: sin Returns the sine of an angle `x` (measured in rad) */ pure fn sin(x: float) -> float - { be m_float::sin(x as m_float) as float } + { ret m_float::sin(x as m_float) as float } /* Function: sinh @@ -682,7 +682,7 @@ Function: sinh Returns the hyperbolic sine of an angle `x` (measured in rad) */ pure fn sinh(x: float) -> float - { be m_float::sinh(x as m_float) as float } + { ret m_float::sinh(x as m_float) as float } /* Function: sqrt @@ -690,7 +690,7 @@ Function: sqrt Returns the square root of `x` */ pure fn sqrt(x: float) -> float - { be m_float::sqrt(x as m_float) as float } + { ret m_float::sqrt(x as m_float) as float } /* Function: tan @@ -699,7 +699,7 @@ Returns the tangent of an angle `x` (measured in rad) */ pure fn tan(x: float) -> float - { be m_float::tan(x as m_float) as float } + { ret m_float::tan(x as m_float) as float } /* Function: tanh @@ -708,7 +708,7 @@ Returns the hyperbolic tangent of an angle `x` (measured in rad) */ pure fn tanh(x: float) -> float - { be m_float::tanh(x as m_float) as float } + { ret m_float::tanh(x as m_float) as float } /* Function: trunc @@ -717,7 +717,7 @@ Returns the integral value nearest to but no larger in magnitude than `x` */ pure fn trunc(x: float) -> float - { be m_float::trunc(x as m_float) as float } + { ret m_float::trunc(x as m_float) as float } // // Local Variables: diff --git a/src/test/compile-fail/non-triv-cast-be.rs b/src/test/compile-fail/non-triv-cast-be.rs deleted file mode 100644 index 458013a912c9..000000000000 --- a/src/test/compile-fail/non-triv-cast-be.rs +++ /dev/null @@ -1,17 +0,0 @@ -// error-pattern: non-trivial cast of tail-call return value -import core::mtypes::*; - -fn foo_float() -> m_float { ret 0.0 as m_float; } -fn bar_float() -> bool { be foo_float() as bool; } - -fn foo_int() -> m_int { ret 0 as m_int; } -fn bar_int() -> bool { be foo_int() as bool; } - -fn foo_uint() -> m_uint { ret 0u as m_uint; } -fn bar_uint() -> bool { be foo_uint() as bool; } - -fn main() { - assert bar_float() == 0.0; - assert bar_int() == 0.0; - assert bar_uint() == 0.0; -} \ No newline at end of file diff --git a/src/test/run-pass/triv-cast-be.rs b/src/test/run-pass/triv-cast-be.rs deleted file mode 100644 index 0fbb1ad28300..000000000000 --- a/src/test/run-pass/triv-cast-be.rs +++ /dev/null @@ -1,28 +0,0 @@ -import core::ctypes::*; - -import core::mtypes::m_float; -import core::mtypes::m_int; -import core::mtypes::m_uint; - -fn foo_float() -> m_float { ret 0.0 as m_float; } -fn bar_float() -> float { be foo_float() as float; } - -fn foo_int() -> m_int { ret 0 as m_int; } -fn bar_int() -> int { be foo_int() as int; } - -fn foo_uint() -> m_uint { ret 0u as m_uint; } -fn bar_uint() -> uint { be foo_uint() as uint; } - -fn foo_long() -> long { ret 0 as long; } -fn bar_long() -> int { be foo_long() as int; } - -fn foo_ulong() -> ulong { ret 0u as ulong; } -fn bar_ulong() -> uint { be foo_uint() as uint; } - -fn main() { - assert bar_float() == 0.0; - assert bar_int() == 0; - assert bar_uint() == 0u; - assert bar_long() == 0; - assert bar_ulong() == 0u; -} \ No newline at end of file diff --git a/src/test/run-pass/triv-cast-const.rs b/src/test/run-pass/triv-cast-const.rs deleted file mode 100644 index 0880fc82c48d..000000000000 --- a/src/test/run-pass/triv-cast-const.rs +++ /dev/null @@ -1,13 +0,0 @@ -import core::mtypes::m_int; - -// This will be more interesting once there is support -// for consts that refer to other consts, i.e. math_f64::consts::pi as m_float -#[cfg(target_arch="x86")] -const foo: m_int = 0i32 as m_int; - -#[cfg(target_arch="x86_64")] -const foo: m_int = 0i64 as m_int; - -fn main() { - assert foo == 0 as m_int; -} \ No newline at end of file From 3ee630bbee1e35933b6296e4749fcdd882a81f90 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Thu, 22 Dec 2011 14:24:36 +0100 Subject: [PATCH 6/8] Add ty::new_ty_hash, clean up comparing of ty::t's --- src/comp/metadata/encoder.rs | 2 +- src/comp/middle/debuginfo.rs | 7 +++-- src/comp/middle/trans.rs | 19 +++++--------- src/comp/middle/ty.rs | 51 ++++++++++++++---------------------- 4 files changed, 30 insertions(+), 49 deletions(-) diff --git a/src/comp/metadata/encoder.rs b/src/comp/metadata/encoder.rs index 1e844d39bca5..169a1354f986 100644 --- a/src/comp/metadata/encoder.rs +++ b/src/comp/metadata/encoder.rs @@ -653,7 +653,7 @@ fn encode_hash(ebml_w: ebml::writer, hash: str) { fn encode_metadata(cx: @crate_ctxt, crate: @crate) -> str { - let abbrevs = map::mk_hashmap(ty::hash_ty, ty::eq_ty); + let abbrevs = ty::new_ty_hash(); let ecx = @{ccx: cx, type_abbrevs: abbrevs}; let string_w = io::string_writer(); diff --git a/src/comp/middle/debuginfo.rs b/src/comp/middle/debuginfo.rs index 96868cd0bf03..19b1578b29af 100644 --- a/src/comp/middle/debuginfo.rs +++ b/src/comp/middle/debuginfo.rs @@ -267,8 +267,7 @@ fn create_basic_type(cx: @crate_ctxt, t: ty::t, ty: @ast::ty) let cache = get_cache(cx); let tg = BasicTypeDescriptorTag; alt cached_metadata::<@metadata>( - cache, tg, - {|md| ty::hash_ty(t) == ty::hash_ty(md.data.hash)}) { + cache, tg, {|md| t == md.data.hash}) { option::some(md) { ret md; } option::none. {} } @@ -311,7 +310,7 @@ fn create_basic_type(cx: @crate_ctxt, t: ty::t, ty: @ast::ty) lli32(0), //XXX flags? lli32(encoding)]; let llnode = llmdnode(lldata); - let mdval = @{node: llnode, data: {hash: ty::hash_ty(t)}}; + let mdval = @{node: llnode, data: {hash: t}}; update_cache(cache, tg, tydesc_metadata(mdval)); add_named_metadata(cx, "llvm.dbg.ty", llnode); ret mdval; @@ -333,7 +332,7 @@ fn create_pointer_type(cx: @crate_ctxt, t: ty::t, span: codemap::span, //let cu_node = create_compile_unit(cx, fname); let llnode = create_derived_type(tg, file_node.node, "", 0, size * 8, align * 8, 0, pointee.node); - let mdval = @{node: llnode, data: {hash: ty::hash_ty(t)}}; + let mdval = @{node: llnode, data: {hash: t}}; //update_cache(cache, tg, tydesc_metadata(mdval)); add_named_metadata(cx, "llvm.dbg.ty", llnode); ret mdval; diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index cc2259d6e0d0..786ab1886c86 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -4348,7 +4348,7 @@ fn new_fn_ctxt_w_id(cx: @local_ctxt, sp: span, llfndecl: ValueRef, lllocals: new_int_hash::(), llupvars: new_int_hash::(), mutable lltydescs: [], - derived_tydescs: map::mk_hashmap(ty::hash_ty, ty::eq_ty), + derived_tydescs: ty::new_ty_hash(), id: id, ret_style: rstyle, sp: sp, @@ -5642,13 +5642,6 @@ fn trans_crate(sess: session::session, crate: @ast::crate, tcx: ty::ctxt, tn.associate("taskptr", taskptr_type); let tydesc_type = T_tydesc(targ_cfg); tn.associate("tydesc", tydesc_type); - let hasher = ty::hash_ty; - let eqer = ty::eq_ty; - let tag_sizes = map::mk_hashmap::(hasher, eqer); - let tydescs = map::mk_hashmap::(hasher, eqer); - let lltypes = map::mk_hashmap::(hasher, eqer); - let sha1s = map::mk_hashmap::(hasher, eqer); - let short_names = map::mk_hashmap::(hasher, eqer); let crate_map = decl_crate_map(sess, link_meta.name, llmod); let dbg_cx = if sess.get_opts().debuginfo { option::some(@{llmetadata: map::new_int_hash(), @@ -5669,18 +5662,18 @@ fn trans_crate(sess: session::session, crate: @ast::crate, tcx: ty::ctxt, item_symbols: new_int_hash::(), mutable main_fn: none::, link_meta: link_meta, - tag_sizes: tag_sizes, + tag_sizes: ty::new_ty_hash(), discrims: ast_util::new_def_id_hash::(), discrim_symbols: new_int_hash::(), consts: new_int_hash::(), obj_methods: new_int_hash::<()>(), - tydescs: tydescs, + tydescs: ty::new_ty_hash(), module_data: new_str_hash::(), - lltypes: lltypes, + lltypes: ty::new_ty_hash(), names: namegen(0), sha: sha, - type_sha1s: sha1s, - type_short_names: short_names, + type_sha1s: ty::new_ty_hash(), + type_short_names: ty::new_ty_hash(), tcx: tcx, mut_map: mut_map, copy_map: copy_map, diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index ef6177822e37..a1cb5cd371b6 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -36,7 +36,6 @@ export constr_table; export count_ty_params; export ctxt; export def_has_ty_params; -export eq_ty; export expr_has_ty_params; export expr_ty; export expr_ty_params_and_ty; @@ -47,7 +46,6 @@ export field_idx; export get_field; export fm_general; export get_element_type; -export hash_ty; export idx_nil; export is_binopable; export is_pred_ty; @@ -103,6 +101,7 @@ export stmt_node_id; export sty; export substitute_type_params; export t; +export new_ty_hash; export tag_variants; export tag_variant_with_id; export ty_param_substs_opt_and_ty; @@ -398,12 +397,16 @@ fn mk_rcache() -> creader_cache { ret map::mk_hashmap(hash_cache_entry, eq_cache_entries); } +fn new_ty_hash() -> map::hashmap { map::new_uint_hash() } fn mk_ctxt(s: session::session, dm: resolve::def_map, amap: ast_map::map, freevars: freevars::freevar_map) -> ctxt { let ntt: node_type_table = @smallintmap::mk::(); let tcache = new_def_hash::(); + fn eq_raw_ty(&&a: @raw_t, &&b: @raw_t) -> bool { + ret a.hash == b.hash && a.struct == b.struct; + } let ts = @interner::mk::<@raw_t>(hash_raw_ty, eq_raw_ty); let cx = @{ts: ts, @@ -414,9 +417,9 @@ fn mk_ctxt(s: session::session, dm: resolve::def_map, amap: ast_map::map, freevars: freevars, tcache: tcache, rcache: mk_rcache(), - short_names_cache: map::mk_hashmap(ty::hash_ty, ty::eq_ty), - needs_drop_cache: map::mk_hashmap(ty::hash_ty, ty::eq_ty), - kind_cache: map::mk_hashmap(ty::hash_ty, ty::eq_ty), + short_names_cache: new_ty_hash(), + needs_drop_cache: new_ty_hash(), + kind_cache: new_ty_hash(), ast_ty_to_ty_cache: map::mk_hashmap(ast_util::hash_ty, ast_util::eq_ty), tag_var_cache: @smallintmap::mk()}; @@ -1233,8 +1236,7 @@ fn type_autoderef(cx: ctxt, t: ty::t) -> ty::t { ret t1; } -// Type hashing. This function is private to this module (and slow); external -// users should use `hash_ty()` instead. +// Type hashing. fn hash_type_structure(st: sty) -> uint { fn hash_uint(id: uint, n: uint) -> uint { let h = id; @@ -1249,7 +1251,7 @@ fn hash_type_structure(st: sty) -> uint { } fn hash_subty(id: uint, subty: t) -> uint { let h = id; - h += (h << 5u) + hash_ty(subty); + h += (h << 5u) + subty; ret h; } fn hash_subtys(id: uint, subtys: [t]) -> uint { @@ -1284,8 +1286,8 @@ fn hash_type_structure(st: sty) -> uint { fn hash_fn(id: uint, args: [arg], rty: t) -> uint { let h = id; - for a: arg in args { h += (h << 5u) + hash_ty(a.ty); } - h += (h << 5u) + hash_ty(rty); + for a: arg in args { h += (h << 5u) + a.ty; } + h += (h << 5u) + rty; ret h; } alt st { @@ -1308,14 +1310,14 @@ fn hash_type_structure(st: sty) -> uint { ty_str. { ret 17u; } ty_tag(did, tys) { let h = hash_def(18u, did); - for typ: t in tys { h += (h << 5u) + hash_ty(typ); } + for typ: t in tys { h += (h << 5u) + typ; } ret h; } ty_box(mt) { ret hash_subty(19u, mt.ty); } ty_vec(mt) { ret hash_subty(21u, mt.ty); } ty_rec(fields) { let h = 26u; - for f: field in fields { h += (h << 5u) + hash_ty(f.mt.ty); } + for f: field in fields { h += (h << 5u) + f.mt.ty; } ret h; } ty_tup(ts) { ret hash_subtys(25u, ts); } @@ -1354,13 +1356,6 @@ fn hash_type_structure(st: sty) -> uint { fn hash_raw_ty(&&rt: @raw_t) -> uint { ret rt.hash; } -fn hash_ty(&&typ: t) -> uint { ret typ; } - - -// Type equality. This function is private to this module (and slow); external -// users should use `eq_ty()` instead. -fn eq_int(&&x: uint, &&y: uint) -> bool { ret x == y; } - fn arg_eq(eq: fn(T, T) -> bool, a: @sp_constr_arg, b: @sp_constr_arg) -> bool { alt a.node { @@ -1389,6 +1384,7 @@ fn args_eq(eq: fn(T, T) -> bool, a: [@sp_constr_arg], } fn constr_eq(c: @constr, d: @constr) -> bool { + fn eq_int(&&x: uint, &&y: uint) -> bool { ret x == y; } ret path_to_str(c.node.path) == path_to_str(d.node.path) && // FIXME: hack args_eq(eq_int, c.node.args, d.node.args); @@ -1401,16 +1397,6 @@ fn constrs_eq(cs: [@constr], ds: [@constr]) -> bool { ret true; } -// This function is private to this module. -fn eq_raw_ty(&&a: @raw_t, &&b: @raw_t) -> bool { - ret a.hash == b.hash && a.struct == b.struct; -} - - -// This is the equality function the public should use. It works as long as -// the types are interned. -fn eq_ty(&&a: t, &&b: t) -> bool { a == b } - // Type lookups fn node_id_to_ty_param_substs_opt_and_ty(cx: ctxt, id: ast::node_id) -> ty_param_substs_opt_and_ty { @@ -2088,12 +2074,15 @@ mod unify { fn unify_step(cx: @ctxt, expected: t, actual: t, variance: variance) -> result { - // TODO: rewrite this using tuple pattern matching when available, to + // FIXME: rewrite this using tuple pattern matching when available, to // avoid all this rightward drift and spikiness. + // NOTE: we have tuple matching now, but that involves copying the + // matched elements into a tuple first, which is expensive, since sty + // holds vectors, which are currently unique // Fast path. + if expected == actual { ret ures_ok(expected); } - if eq_ty(expected, actual) { ret ures_ok(expected); } // Stage 1: Handle the cases in which one side or another is a type // variable. From 44f921c8a9573df6bc13df4beb175762a2575f5f Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Thu, 22 Dec 2011 14:52:30 +0100 Subject: [PATCH 7/8] Do not use == and != to compare ty::t values Issue #828 --- src/comp/middle/ty.rs | 61 +++++++++++++++++++++++++-------------- src/comp/middle/typeck.rs | 11 +++---- 2 files changed, 45 insertions(+), 27 deletions(-) diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index a1cb5cd371b6..070123439adc 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -136,6 +136,7 @@ export ty_uint; export ty_uniq; export ty_var; export ty_named; +export same_type, same_method; export ty_var_id; export ty_param_substs_opt_and_ty_to_monotype; export ty_fn_args; @@ -1683,7 +1684,7 @@ mod unify { type var_bindings = {sets: ufind::ufind, types: smallintmap::smallintmap}; - type ctxt = {vb: @var_bindings, tcx: ty_ctxt}; + type ctxt = {vb: option::t<@var_bindings>, tcx: ty_ctxt}; fn mk_var_bindings() -> @var_bindings { ret @{sets: ufind::make(), types: smallintmap::mk::()}; @@ -1692,31 +1693,32 @@ mod unify { // Unifies two sets. fn union(cx: @ctxt, set_a: uint, set_b: uint, variance: variance) -> union_result { - ufind::grow(cx.vb.sets, float::max(set_a, set_b) + 1u); - let root_a = ufind::find(cx.vb.sets, set_a); - let root_b = ufind::find(cx.vb.sets, set_b); + let vb = option::get(cx.vb); + ufind::grow(vb.sets, float::max(set_a, set_b) + 1u); + let root_a = ufind::find(vb.sets, set_a); + let root_b = ufind::find(vb.sets, set_b); let replace_type = - bind fn (cx: @ctxt, t: t, set_a: uint, set_b: uint) { - ufind::union(cx.vb.sets, set_a, set_b); - let root_c: uint = ufind::find(cx.vb.sets, set_a); - smallintmap::insert::(cx.vb.types, root_c, t); + bind fn (vb: @var_bindings, t: t, set_a: uint, set_b: uint) { + ufind::union(vb.sets, set_a, set_b); + let root_c: uint = ufind::find(vb.sets, set_a); + smallintmap::insert::(vb.types, root_c, t); }(_, _, set_a, set_b); - alt smallintmap::find(cx.vb.types, root_a) { + alt smallintmap::find(vb.types, root_a) { none. { - alt smallintmap::find(cx.vb.types, root_b) { - none. { ufind::union(cx.vb.sets, set_a, set_b); ret unres_ok; } - some(t_b) { replace_type(cx, t_b); ret unres_ok; } + alt smallintmap::find(vb.types, root_b) { + none. { ufind::union(vb.sets, set_a, set_b); ret unres_ok; } + some(t_b) { replace_type(vb, t_b); ret unres_ok; } } } some(t_a) { - alt smallintmap::find(cx.vb.types, root_b) { - none. { replace_type(cx, t_a); ret unres_ok; } + alt smallintmap::find(vb.types, root_b) { + none. { replace_type(vb, t_a); ret unres_ok; } some(t_b) { alt unify_step(cx, t_a, t_b, variance) { - ures_ok(t_c) { replace_type(cx, t_c); ret unres_ok; } + ures_ok(t_c) { replace_type(vb, t_c); ret unres_ok; } ures_err(terr) { ret unres_err(terr); } } } @@ -1741,10 +1743,11 @@ mod unify { fn record_var_binding( cx: @ctxt, key: int, typ: t, variance: variance) -> result { - ufind::grow(cx.vb.sets, (key as uint) + 1u); - let root = ufind::find(cx.vb.sets, key as uint); + let vb = option::get(cx.vb); + ufind::grow(vb.sets, (key as uint) + 1u); + let root = ufind::find(vb.sets, key as uint); let result_type = typ; - alt smallintmap::find::(cx.vb.types, root) { + alt smallintmap::find(vb.types, root) { some(old_type) { alt unify_step(cx, old_type, typ, variance) { ures_ok(unified_type) { result_type = unified_type; } @@ -1753,7 +1756,7 @@ mod unify { } none. {/* fall through */ } } - smallintmap::insert::(cx.vb.types, root, result_type); + smallintmap::insert::(vb.types, root, result_type); ret ures_ok(typ); } @@ -2090,6 +2093,7 @@ mod unify { // If the RHS is a variable type, then just do the // appropriate binding. ty::ty_var(actual_id) { + assert option::is_some(cx.vb); let actual_n = actual_id as uint; alt struct(cx.tcx, expected) { ty::ty_var(expected_id) { @@ -2114,8 +2118,8 @@ mod unify { } alt struct(cx.tcx, expected) { ty::ty_var(expected_id) { + assert option::is_some(cx.vb); // Add a binding. (`actual` can't actually be a var here.) - alt record_var_binding_for_expected( cx, expected_id, actual, variance) { @@ -2431,8 +2435,8 @@ mod unify { } } } - fn unify(expected: t, actual: t, vb: @var_bindings, tcx: ty_ctxt) -> - result { + fn unify(expected: t, actual: t, vb: option::t<@var_bindings>, + tcx: ty_ctxt) -> result { let cx = @{vb: vb, tcx: tcx}; ret unify_step(cx, expected, actual, covariant); } @@ -2505,6 +2509,19 @@ mod unify { } } +fn same_type(cx: ctxt, a: t, b: t) -> bool { + alt unify::unify(a, b, none, cx) { + unify::ures_ok(_) { true } + _ { false } + } +} +fn same_method(cx: ctxt, a: method, b: method) -> bool { + a.proto == b.proto && a.ident == b.ident && + vec::all2(a.inputs, b.inputs, + {|a, b| a.mode == b.mode && same_type(cx, a.ty, b.ty) }) && + same_type(cx, a.output, b.output) && a.cf == b.cf +} + fn type_err_to_str(err: ty::type_err) -> str { alt err { terr_mismatch. { ret "types differ"; } diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs index d37482f0f1e8..400411fa68ab 100644 --- a/src/comp/middle/typeck.rs +++ b/src/comp/middle/typeck.rs @@ -791,7 +791,8 @@ mod collect { mod unify { fn unify(fcx: @fn_ctxt, expected: ty::t, actual: ty::t) -> ty::unify::result { - ret ty::unify::unify(expected, actual, fcx.var_bindings, fcx.ccx.tcx); + ret ty::unify::unify(expected, actual, some(fcx.var_bindings), + fcx.ccx.tcx); } } @@ -1106,7 +1107,7 @@ fn gather_locals(ccx: @crate_ctxt, alt ty_opt { none. {/* nothing to do */ } some(typ) { - ty::unify::unify(ty::mk_var(tcx, var_id), typ, vb, tcx); + ty::unify::unify(ty::mk_var(tcx, var_id), typ, some(vb), tcx); } } }; @@ -1198,8 +1199,8 @@ fn check_pat(fcx: @fn_ctxt, map: ast_util::pat_id_map, pat: @ast::pat, check_expr_with(fcx, end, expected); let b_ty = resolve_type_vars_if_possible(fcx, expr_ty(fcx.ccx.tcx, begin)); - if b_ty != resolve_type_vars_if_possible(fcx, expr_ty(fcx.ccx.tcx, - end)) { + if !ty::same_type(fcx.ccx.tcx, b_ty, resolve_type_vars_if_possible( + fcx, expr_ty(fcx.ccx.tcx, end))) { fcx.ccx.tcx.sess.span_err(pat.span, "mismatched types in range"); } else if !ty::type_is_numeric(fcx.ccx.tcx, b_ty) { fcx.ccx.tcx.sess.span_err(pat.span, @@ -2324,7 +2325,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier, // We'd better be overriding with one of the same // type. Check to make sure. let new_type = ty_of_method(ccx.tcx, m_check, om); - if new_type != m { + if !ty::same_method(ccx.tcx, new_type, m) { ccx.tcx.sess.span_fatal (om.span, "attempted to override method " + m.ident + " with one of a different type"); From 07d7f828cd858bed67855e5a5ba24369625a981e Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Thu, 22 Dec 2011 16:23:49 +0100 Subject: [PATCH 8/8] Fix tag_var_cache to cache crate-external tags And to not return a bogus mutable box. --- src/comp/middle/ty.rs | 67 +++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 41 deletions(-) diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index 070123439adc..25c8d948a40b 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -207,9 +207,6 @@ type mt = {ty: t, mut: ast::mutability}; // the types of AST nodes. type creader_cache = hashmap<{cnum: int, pos: uint, len: uint}, ty::t>; -type tag_var_cache = - @smallintmap::smallintmap<@mutable [variant_info]>; - type ctxt = @{ts: @type_store, sess: session::session, @@ -223,7 +220,7 @@ type ctxt = needs_drop_cache: hashmap, kind_cache: hashmap, ast_ty_to_ty_cache: hashmap<@ast::ty, option::t>, - tag_var_cache: tag_var_cache}; + tag_var_cache: hashmap}; type ty_ctxt = ctxt; @@ -404,7 +401,6 @@ fn mk_ctxt(s: session::session, dm: resolve::def_map, amap: ast_map::map, freevars: freevars::freevar_map) -> ctxt { let ntt: node_type_table = @smallintmap::mk::(); - let tcache = new_def_hash::(); fn eq_raw_ty(&&a: @raw_t, &&b: @raw_t) -> bool { ret a.hash == b.hash && a.struct == b.struct; } @@ -416,14 +412,14 @@ fn mk_ctxt(s: session::session, dm: resolve::def_map, amap: ast_map::map, node_types: ntt, items: amap, freevars: freevars, - tcache: tcache, + tcache: new_def_hash(), rcache: mk_rcache(), short_names_cache: new_ty_hash(), needs_drop_cache: new_ty_hash(), kind_cache: new_ty_hash(), ast_ty_to_ty_cache: map::mk_hashmap(ast_util::hash_ty, ast_util::eq_ty), - tag_var_cache: @smallintmap::mk()}; + tag_var_cache: new_def_hash()}; populate_type_store(cx); ret cx; } @@ -2627,45 +2623,34 @@ fn def_has_ty_params(def: ast::def) -> bool { // Tag information type variant_info = @{args: [ty::t], ctor_ty: ty::t, id: ast::def_id}; -fn tag_variants(cx: ctxt, id: ast::def_id) -> @mutable [variant_info] { - if ast::local_crate != id.crate { - ret @mutable csearch::get_tag_variants(cx, id); - } - assert (id.node >= 0); - alt smallintmap::find(*cx.tag_var_cache, id.node as uint) { - option::some(variants) { ret variants; } +fn tag_variants(cx: ctxt, id: ast::def_id) -> @[variant_info] { + alt cx.tag_var_cache.find(id) { + some(variants) { ret variants; } _ { /* fallthrough */ } } - let item = - alt cx.items.find(id.node) { - some(i) { i } - none. { cx.sess.bug("expected to find cached node_item") } - }; - alt item { - ast_map::node_item(item) { - alt item.node { - ast::item_tag(variants, _) { - let result: @mutable [variant_info] = @mutable []; - for variant: ast::variant in variants { - let ctor_ty = node_id_to_monotype(cx, variant.node.id); - let arg_tys: [t] = []; - if vec::len(variant.node.args) > 0u { - for a: arg in ty_fn_args(cx, ctor_ty) { - arg_tys += [a.ty]; - } - } - let did = variant.node.id; - *result += - [@{args: arg_tys, - ctor_ty: ctor_ty, - id: ast_util::local_def(did)}]; + let result = if ast::local_crate != id.crate { + @csearch::get_tag_variants(cx, id) + } else { + alt cx.items.get(id.node) { + ast_map::node_item(item) { + alt item.node { + ast::item_tag(variants, _) { + @vec::map(variants, {|variant| + let ctor_ty = node_id_to_monotype(cx, variant.node.id); + let arg_tys = if vec::len(variant.node.args) > 0u { + vec::map(ty_fn_args(cx, ctor_ty), {|a| a.ty}) + } else { [] }; + @{args: arg_tys, + ctor_ty: ctor_ty, + id: ast_util::local_def(variant.node.id)} + }) + } } - smallintmap::insert(*cx.tag_var_cache, id.node as uint, result); - ret result; } } - } - } + }; + cx.tag_var_cache.insert(id, result); + result }