@@ -1521,9 +1521,24 @@ fn require_pure_call(ccx: @crate_ctxt, caller_purity: &ast::purity,
1521
1521
}
1522
1522
}
1523
1523
1524
+ type unifier = fn ( fcx : & @fn_ctxt , sp : & span ,
1525
+ expected : & ty:: t , actual : & ty:: t ) -> ty:: t ;
1526
+
1524
1527
fn check_expr ( fcx : & @fn_ctxt , expr : & @ast:: expr ) -> bool {
1525
- // fcx.ccx.tcx.sess.span_warn(expr.span, "typechecking expr " +
1526
- // syntax::print::pprust::expr_to_str(expr));
1528
+ fn dummy_unify ( fcx : & @fn_ctxt , sp : & span ,
1529
+ expected : & ty:: t , actual : & ty:: t ) -> ty:: t {
1530
+ actual
1531
+ }
1532
+ ret check_expr_with_unifier ( fcx, expr, dummy_unify, 0 u) ;
1533
+ }
1534
+ fn check_expr_with ( fcx : & @fn_ctxt , expr : & @ast:: expr , expected : & ty:: t )
1535
+ -> bool {
1536
+ ret check_expr_with_unifier ( fcx, expr, demand:: simple, expected) ;
1537
+ }
1538
+
1539
+ fn check_expr_with_unifier ( fcx : & @fn_ctxt , expr : & @ast:: expr ,
1540
+ unify : & unifier , expected : & ty:: t ) -> bool {
1541
+ //log_err "typechecking expr " + syntax::print::pprust::expr_to_str(expr);
1527
1542
1528
1543
// A generic function to factor out common logic from call and bind
1529
1544
// expressions.
@@ -1594,14 +1609,14 @@ fn check_expr(fcx: &@fn_ctxt, expr: &@ast::expr) -> bool {
1594
1609
}
1595
1610
1596
1611
// Check the arguments.
1612
+ let unifier =
1613
+ bind demand:: autoderef ( _, _, _, _, AUTODEREF_BLOCK_COERCE ) ;
1597
1614
let i = 0 u;
1598
1615
for a_opt: option:: t[ @ast:: expr] in args {
1599
1616
alt a_opt {
1600
1617
some( a) {
1601
- bot |= check_expr ( fcx, a) ;
1602
- demand:: autoderef ( fcx, a. span , arg_tys. ( i) . ty ,
1603
- expr_ty ( fcx. ccx . tcx , a) ,
1604
- AUTODEREF_BLOCK_COERCE ) ;
1618
+ bot |= check_expr_with_unifier ( fcx, a, unifier,
1619
+ arg_tys. ( i) . ty ) ;
1605
1620
}
1606
1621
none. { }
1607
1622
}
@@ -1613,9 +1628,8 @@ fn check_expr(fcx: &@fn_ctxt, expr: &@ast::expr) -> bool {
1613
1628
1614
1629
fn check_assignment ( fcx : & @fn_ctxt , sp : & span , lhs : & @ast:: expr ,
1615
1630
rhs : & @ast:: expr , id : & ast:: node_id ) -> bool {
1616
- let bot = check_expr ( fcx, lhs) | check_expr ( fcx, rhs) ;
1617
- demand:: simple ( fcx, sp, expr_ty ( fcx. ccx . tcx , lhs) ,
1618
- expr_ty ( fcx. ccx . tcx , rhs) ) ;
1631
+ let t = next_ty_var ( fcx) ;
1632
+ let bot = check_expr_with ( fcx, lhs, t) | check_expr_with ( fcx, rhs, t) ;
1619
1633
write:: ty_only_fixup ( fcx, id, ty:: mk_nil ( fcx. ccx . tcx ) ) ;
1620
1634
ret bot;
1621
1635
}
@@ -1671,18 +1685,14 @@ fn check_expr(fcx: &@fn_ctxt, expr: &@ast::expr) -> bool {
1671
1685
demand:: simple ( fcx, local. span ,
1672
1686
ty:: node_id_to_type ( fcx. ccx . tcx , local. node . id ) ,
1673
1687
element_ty) ;
1674
- let typ = ty:: mk_nil ( fcx. ccx . tcx ) ;
1675
- write:: ty_only_fixup ( fcx, node_id, typ) ;
1688
+ write:: nil_ty ( fcx. ccx . tcx , node_id) ;
1676
1689
ret bot;
1677
1690
}
1678
1691
1679
1692
// A generic function for checking the pred in a check
1680
1693
// or if-check
1681
1694
fn check_pred_expr ( fcx : & @fn_ctxt , e : & @ast:: expr ) -> bool {
1682
- let bot = check_expr ( fcx, e) ;
1683
- demand:: simple ( fcx, e. span , ty:: mk_bool ( fcx. ccx . tcx ) ,
1684
- expr_ty ( fcx. ccx . tcx , e) ) ;
1685
-
1695
+ let bot = check_expr_with ( fcx, e, ty:: mk_bool ( fcx. ccx . tcx ) ) ;
1686
1696
1687
1697
/* e must be a call expr where all arguments are either
1688
1698
literals or slots */
@@ -1732,10 +1742,9 @@ fn check_expr(fcx: &@fn_ctxt, expr: &@ast::expr) -> bool {
1732
1742
let if_t =
1733
1743
alt elsopt {
1734
1744
some( els) {
1735
- els_bot = check_expr ( fcx, els) ;
1736
1745
let thn_t = block_ty ( fcx. ccx . tcx , thn) ;
1746
+ els_bot = check_expr_with ( fcx, els, thn_t) ;
1737
1747
let elsopt_t = expr_ty ( fcx. ccx . tcx , els) ;
1738
- demand:: simple ( fcx, sp, thn_t, elsopt_t) ;
1739
1748
if !ty:: type_is_bot ( fcx. ccx . tcx , elsopt_t) {
1740
1749
elsopt_t
1741
1750
} else { thn_t }
@@ -1769,17 +1778,13 @@ fn check_expr(fcx: &@fn_ctxt, expr: &@ast::expr) -> bool {
1769
1778
write:: ty_only_fixup ( fcx, id, typ) ;
1770
1779
}
1771
1780
ast:: expr_binary ( binop, lhs, rhs) {
1772
- bot = check_expr ( fcx, lhs) ;
1773
- if ast:: lazy_binop ( binop) {
1774
- check_expr ( fcx, rhs) ;
1775
- } else {
1776
- bot |= check_expr ( fcx, rhs) ;
1777
- }
1781
+ let lhs_t = next_ty_var ( fcx) ;
1782
+ bot = check_expr_with ( fcx, lhs, lhs_t) ;
1778
1783
1779
- let lhs_t = expr_ty ( tcx, lhs) ;
1780
- let rhs_t = expr_ty ( tcx, rhs) ;
1784
+ let unifier = bind demand:: autoderef ( _, _, _, _, AUTODEREF_OK ) ;
1785
+ let rhs_bot = check_expr_with_unifier ( fcx, rhs, unifier, lhs_t) ;
1786
+ if !ast:: lazy_binop ( binop) { bot |= rhs_bot; }
1781
1787
1782
- demand:: autoderef ( fcx, rhs. span , lhs_t, rhs_t, AUTODEREF_OK ) ;
1783
1788
let deref_t = do_autoderef ( fcx, expr. span , lhs_t) ;
1784
1789
check_binop_type_compat ( fcx, expr. span , deref_t, binop) ;
1785
1790
@@ -1864,9 +1869,7 @@ fn check_expr(fcx: &@fn_ctxt, expr: &@ast::expr) -> bool {
1864
1869
alt expr_opt {
1865
1870
none. { /* do nothing */ }
1866
1871
some( e) {
1867
- check_expr ( fcx, e) ;
1868
- let ety = expr_ty ( tcx, e) ;
1869
- demand:: simple ( fcx, e. span , ty:: mk_str ( tcx) , ety) ;
1872
+ check_expr_with ( fcx, e, ty:: mk_str ( tcx) ) ;
1870
1873
}
1871
1874
}
1872
1875
write:: bot_ty ( tcx, id) ;
@@ -1882,15 +1885,12 @@ fn check_expr(fcx: &@fn_ctxt, expr: &@ast::expr) -> bool {
1882
1885
tcx. sess . span_fatal ( expr. span ,
1883
1886
"ret; in function returning non-nil" ) ;
1884
1887
}
1885
- write:: bot_ty ( tcx, id) ;
1886
1888
}
1887
1889
some ( e) {
1888
- check_expr ( fcx, e) ;
1889
- demand:: simple ( fcx, expr. span , fcx. ret_ty ,
1890
- expr_ty ( tcx, e) ) ;
1891
- write:: bot_ty ( tcx, id) ;
1890
+ check_expr_with ( fcx, e, fcx. ret_ty ) ;
1892
1891
}
1893
1892
}
1893
+ write:: bot_ty ( tcx, id) ;
1894
1894
}
1895
1895
ast:: expr_put ( expr_opt) {
1896
1896
require_impure ( tcx. sess , fcx. purity , expr. span ) ;
@@ -1906,19 +1906,16 @@ fn check_expr(fcx: &@fn_ctxt, expr: &@ast::expr) -> bool {
1906
1906
}
1907
1907
}
1908
1908
some ( e) {
1909
- bot = check_expr ( fcx, e) ;
1910
- demand:: simple ( fcx, expr. span , fcx. ret_ty ,
1911
- expr_ty ( tcx, e) ) ;
1909
+ bot = check_expr_with ( fcx, e, fcx. ret_ty ) ;
1912
1910
}
1913
1911
}
1914
1912
write:: nil_ty ( tcx, id) ;
1915
1913
}
1916
1914
ast:: expr_be ( e) {
1917
1915
// FIXME: prove instead of assert
1918
1916
assert ( ast:: is_call_expr ( e) ) ;
1919
- check_expr ( fcx, e) ;
1917
+ check_expr_with ( fcx, e, fcx . ret_ty ) ;
1920
1918
bot = true ;
1921
- demand:: simple ( fcx, e. span , fcx. ret_ty , expr_ty ( tcx, e) ) ;
1922
1919
write:: nil_ty ( tcx, id) ;
1923
1920
}
1924
1921
ast:: expr_log ( l, e) {
@@ -1937,9 +1934,7 @@ fn check_expr(fcx: &@fn_ctxt, expr: &@ast::expr) -> bool {
1937
1934
bot = check_expr ( fcx, ast:: ternary_to_if ( expr) ) ;
1938
1935
}
1939
1936
ast:: expr_assert ( e) {
1940
- bot = check_expr ( fcx, e) ;
1941
- let ety = expr_ty ( tcx, e) ;
1942
- demand:: simple ( fcx, expr. span , ty:: mk_bool ( tcx) , ety) ;
1937
+ bot = check_expr_with ( fcx, e, ty:: mk_bool ( tcx) ) ;
1943
1938
write:: nil_ty ( tcx, id) ;
1944
1939
}
1945
1940
ast:: expr_move ( lhs, rhs) {
@@ -1962,34 +1957,23 @@ fn check_expr(fcx: &@fn_ctxt, expr: &@ast::expr) -> bool {
1962
1957
}
1963
1958
ast:: expr_send ( lhs, rhs) {
1964
1959
require_impure ( tcx. sess , fcx. purity , expr. span ) ;
1965
- bot = check_expr ( fcx, lhs) | check_expr ( fcx, rhs) ;
1966
- let rhs_t = expr_ty ( tcx, rhs) ;
1960
+ let rhs_t = next_ty_var ( fcx) ;
1967
1961
let chan_t = ty:: mk_chan ( tcx, rhs_t) ;
1968
- let lhs_t = expr_ty ( tcx, lhs) ;
1969
- alt structure_of ( fcx, expr. span , lhs_t) {
1970
- ty:: ty_chan ( it) { }
1971
- _ {
1972
- let s = #fmt( "mismatched types: expected chan but found %s" ,
1973
- ty_to_str ( tcx, lhs_t) ) ;
1974
- tcx. sess . span_fatal ( expr. span , s) ;
1975
- }
1976
- }
1977
- demand:: simple ( fcx, expr. span , chan_t, lhs_t) ;
1962
+ bot = check_expr_with ( fcx, lhs, chan_t) |
1963
+ check_expr_with ( fcx, rhs, rhs_t) ;
1978
1964
write:: ty_only_fixup ( fcx, id, chan_t) ;
1979
1965
}
1980
1966
ast:: expr_recv ( lhs, rhs) {
1981
1967
require_impure ( tcx. sess , fcx. purity , expr. span ) ;
1982
- bot = check_expr ( fcx, lhs ) | check_expr ( fcx , rhs ) ;
1983
- let item_t = expr_ty ( tcx, rhs ) ;
1984
- let port_t = ty :: mk_port ( tcx , item_t ) ;
1985
- demand :: simple ( fcx , expr . span , port_t , expr_ty ( tcx , lhs ) ) ;
1986
- write:: ty_only_fixup ( fcx, id, item_t ) ;
1968
+ let rhs_t = next_ty_var ( fcx) ;
1969
+ let port_t = ty :: mk_port ( tcx, rhs_t ) ;
1970
+ bot = check_expr_with ( fcx , lhs , port_t ) |
1971
+ check_expr_with ( fcx , rhs , rhs_t ) ;
1972
+ write:: ty_only_fixup ( fcx, id, rhs_t ) ;
1987
1973
}
1988
1974
ast:: expr_if ( cond, thn, elsopt) {
1989
- bot = check_expr ( fcx, cond) |
1975
+ bot = check_expr_with ( fcx, cond, ty :: mk_bool ( tcx ) ) |
1990
1976
check_then_else ( fcx, thn, elsopt, id, expr. span ) ;
1991
- demand:: simple ( fcx, cond. span , ty:: mk_bool ( tcx) ,
1992
- expr_ty ( tcx, cond) ) ;
1993
1977
}
1994
1978
ast:: expr_for ( decl, seq, body) {
1995
1979
bot = check_expr ( fcx, seq) ;
@@ -2021,24 +2005,19 @@ fn check_expr(fcx: &@fn_ctxt, expr: &@ast::expr) -> bool {
2021
2005
body, id) ;
2022
2006
}
2023
2007
ast:: expr_while ( cond, body) {
2024
- bot = check_expr ( fcx, cond) ;
2008
+ bot = check_expr_with ( fcx, cond, ty :: mk_bool ( tcx ) ) ;
2025
2009
check_block ( fcx, body) ;
2026
- demand:: simple ( fcx, cond. span , ty:: mk_bool ( tcx) ,
2027
- expr_ty ( tcx, cond) ) ;
2028
- let typ = ty:: mk_nil ( tcx) ;
2029
- write:: ty_only_fixup ( fcx, id, typ) ;
2010
+ write:: ty_only_fixup ( fcx, id, ty:: mk_nil ( tcx) ) ;
2030
2011
}
2031
2012
ast:: expr_do_while ( body, cond) {
2032
- bot = check_expr ( fcx, cond) ;
2033
- check_block ( fcx, body) ;
2034
- let typ = block_ty ( tcx, body) ;
2035
- write:: ty_only_fixup ( fcx, id, typ) ;
2013
+ bot = check_expr ( fcx, cond) | check_block ( fcx, body) ;
2014
+ write:: ty_only_fixup ( fcx, id, block_ty ( tcx, body) ) ;
2036
2015
}
2037
2016
ast:: expr_alt ( expr, arms) {
2038
2017
bot = check_expr ( fcx, expr) ;
2018
+
2039
2019
// Typecheck the patterns first, so that we get types for all the
2040
2020
// bindings.
2041
-
2042
2021
let pattern_ty = ty:: expr_ty ( tcx, expr) ;
2043
2022
for arm: ast:: arm in arms {
2044
2023
let id_map = ast:: pat_id_map ( arm. pats . ( 0 ) ) ;
@@ -2052,12 +2031,7 @@ fn check_expr(fcx: &@fn_ctxt, expr: &@ast::expr) -> bool {
2052
2031
for arm: ast:: arm in arms {
2053
2032
if !check_block ( fcx, arm. block ) { arm_non_bot = true ; }
2054
2033
let bty = block_ty ( tcx, arm. block ) ;
2055
-
2056
- // Failing alt arms don't need to have a matching type
2057
- if !ty:: type_is_bot ( tcx, bty) {
2058
- result_ty =
2059
- demand:: simple ( fcx, arm. block . span , result_ty, bty) ;
2060
- }
2034
+ result_ty = demand:: simple ( fcx, arm. block . span , result_ty, bty) ;
2061
2035
}
2062
2036
bot |= !arm_non_bot;
2063
2037
if !arm_non_bot { result_ty = ty:: mk_bot ( tcx) ; }
@@ -2076,16 +2050,11 @@ fn check_expr(fcx: &@fn_ctxt, expr: &@ast::expr) -> bool {
2076
2050
}
2077
2051
ast:: expr_block ( b) {
2078
2052
bot = check_block ( fcx, b) ;
2079
- alt b. node . expr {
2080
- some ( expr) {
2081
- let typ = expr_ty ( tcx, expr) ;
2082
- write:: ty_only_fixup ( fcx, id, typ) ;
2083
- }
2084
- none. {
2085
- let typ = ty:: mk_nil ( tcx) ;
2086
- write:: ty_only_fixup ( fcx, id, typ) ;
2087
- }
2088
- }
2053
+ let typ = alt b. node . expr {
2054
+ some ( expr) { expr_ty ( tcx, expr) }
2055
+ none. { ty:: mk_nil ( tcx) }
2056
+ } ;
2057
+ write:: ty_only_fixup ( fcx, id, typ) ;
2089
2058
}
2090
2059
ast:: expr_bind ( f, args) {
2091
2060
// Call the generic checker.
@@ -2216,17 +2185,9 @@ fn check_expr(fcx: &@fn_ctxt, expr: &@ast::expr) -> bool {
2216
2185
write:: ty_only_fixup ( fcx, id, t_1) ;
2217
2186
}
2218
2187
ast:: expr_vec ( args, mut, kind) {
2219
- let t: ty:: t ;
2220
- if ivec:: len[ @ast:: expr] ( args) == 0 u {
2221
- t = next_ty_var ( fcx) ;
2222
- } else {
2223
- bot |= check_expr ( fcx, args. ( 0 ) ) ;
2224
- t = expr_ty ( tcx, args. ( 0 ) ) ;
2225
- }
2188
+ let t: ty:: t = next_ty_var ( fcx) ; ;
2226
2189
for e: @ast:: expr in args {
2227
- bot |= check_expr ( fcx, e) ;
2228
- let expr_t = expr_ty ( tcx, e) ;
2229
- demand:: simple ( fcx, expr. span , t, expr_t) ;
2190
+ bot |= check_expr_with ( fcx, e, t) ;
2230
2191
}
2231
2192
let typ;
2232
2193
alt kind {
@@ -2350,29 +2311,13 @@ fn check_expr(fcx: &@fn_ctxt, expr: &@ast::expr) -> bool {
2350
2311
}
2351
2312
}
2352
2313
ast:: expr_port ( typ) {
2353
- let t = next_ty_var ( fcx) ;
2354
- alt ast_ty_to_ty_crate_infer ( fcx. ccx , typ) {
2355
- some ( _t) {
2356
- demand:: simple ( fcx, expr. span , _t, t) ;
2357
- }
2358
- none. { }
2359
- }
2360
- let pt = ty:: mk_port ( tcx, t) ;
2314
+ let pt = ty:: mk_port ( tcx, ast_ty_to_ty_crate_tyvar ( fcx, typ) ) ;
2361
2315
write:: ty_only_fixup ( fcx, id, pt) ;
2362
2316
}
2363
2317
ast:: expr_chan ( x) {
2364
- check_expr ( fcx, x) ;
2365
- let port_t = expr_ty ( tcx, x) ;
2366
- alt structure_of ( fcx, expr. span , port_t) {
2367
- ty:: ty_port ( subtype) {
2368
- let ct = ty:: mk_chan ( tcx, subtype) ;
2369
- write:: ty_only_fixup ( fcx, id, ct) ;
2370
- }
2371
- _ {
2372
- tcx. sess . span_fatal ( expr. span ,
2373
- "bad port type: " + ty_to_str ( tcx, port_t) ) ;
2374
- }
2375
- }
2318
+ let t = next_ty_var ( fcx) ;
2319
+ check_expr_with ( fcx, x, ty:: mk_port ( tcx, t) ) ;
2320
+ write:: ty_only_fixup ( fcx, id, ty:: mk_chan ( tcx, t) ) ;
2376
2321
}
2377
2322
ast:: expr_anon_obj ( ao) {
2378
2323
let fields: [ ast:: anon_obj_field ] = ~[ ] ;
@@ -2512,6 +2457,8 @@ fn check_expr(fcx: &@fn_ctxt, expr: &@ast::expr) -> bool {
2512
2457
if bot {
2513
2458
write:: ty_only_fixup ( fcx, expr. id , ty:: mk_bot ( tcx) ) ;
2514
2459
}
2460
+
2461
+ unify ( fcx, expr. span , expected, expr_ty ( tcx, expr) ) ;
2515
2462
ret bot;
2516
2463
}
2517
2464
@@ -2531,19 +2478,8 @@ fn get_obj_info(ccx: &@crate_ctxt) -> option::t[obj_info] {
2531
2478
2532
2479
fn check_decl_initializer ( fcx : & @fn_ctxt , nid : ast:: node_id ,
2533
2480
init : & ast:: initializer ) -> bool {
2534
- let bot = check_expr ( fcx, init. expr ) ;
2535
2481
let lty = ty:: mk_var ( fcx. ccx . tcx , lookup_local ( fcx, init. expr . span , nid) ) ;
2536
- alt init. op {
2537
- ast:: init_assign. {
2538
- demand:: simple ( fcx, init. expr . span , lty,
2539
- expr_ty ( fcx. ccx . tcx , init. expr ) ) ;
2540
- }
2541
- ast:: init_move. {
2542
- demand:: simple ( fcx, init. expr . span , lty,
2543
- expr_ty ( fcx. ccx . tcx , init. expr ) ) ;
2544
- }
2545
- }
2546
- ret bot;
2482
+ ret check_expr_with ( fcx, init. expr , lty) ;
2547
2483
}
2548
2484
2549
2485
fn check_decl_local ( fcx : & @fn_ctxt , local : & @ast:: local ) -> bool {
0 commit comments