@@ -1780,6 +1780,22 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
1780
1780
_ { none }
1781
1781
}
1782
1782
}
1783
+ fn lookup_op_method ( fcx : @fn_ctxt , op_ex : @ast:: expr , self_t : ty:: t ,
1784
+ opname : str ,
1785
+ args : [ option:: t < @ast:: expr > ] ) -> option:: t < ty:: t > {
1786
+ let isc = fcx. ccx . impl_map . get ( op_ex. id ) ;
1787
+ alt lookup_method ( fcx, isc, opname, self_t, op_ex. span ) {
1788
+ some ( { method_ty, n_tps: 0 u, substs, origin} ) {
1789
+ let callee_id = ast_util:: op_expr_callee_id ( op_ex) ;
1790
+ write:: ty_fixup ( fcx, callee_id, { substs : some( substs) ,
1791
+ ty: method_ty} ) ;
1792
+ check_call_or_bind ( fcx, op_ex. span , method_ty, args) ;
1793
+ fcx. ccx . method_map . insert ( op_ex. id , origin) ;
1794
+ some ( ty:: ty_fn_ret ( fcx. ccx . tcx , method_ty) )
1795
+ }
1796
+ _ { none }
1797
+ }
1798
+ }
1783
1799
fn check_binop ( fcx : @fn_ctxt , ex : @ast:: expr , ty : ty:: t ,
1784
1800
op : ast:: binop , rhs : @ast:: expr ) -> ty:: t {
1785
1801
let resolved_t = structurally_resolved_type ( fcx, ex. span , ty) ;
@@ -1792,22 +1808,14 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
1792
1808
} ;
1793
1809
}
1794
1810
1795
- let isc = fcx. ccx . impl_map . get ( ex. id ) ;
1796
1811
alt binop_method ( op) {
1797
1812
some ( name) {
1798
- alt lookup_method ( fcx, isc, name, resolved_t, ex. span ) {
1799
- some ( { method_ty, n_tps: 0 u, substs, origin} ) {
1800
- let callee_id = ast_util:: op_expr_callee_id ( ex) ;
1801
- write:: ty_fixup ( fcx, callee_id, { substs : some( substs) ,
1802
- ty: method_ty} ) ;
1803
- check_call_or_bind ( fcx, ex. span , method_ty, [ some ( rhs) ] ) ;
1804
- fcx. ccx . method_map . insert ( ex. id , origin) ;
1805
- ret ty:: ty_fn_ret ( tcx, method_ty) ;
1806
- }
1813
+ alt lookup_op_method ( fcx, ex, resolved_t, name, [ some ( rhs) ] ) {
1814
+ some ( ret_ty) { ret ret_ty; }
1807
1815
_ { }
1808
1816
}
1809
1817
}
1810
- none { }
1818
+ _ { }
1811
1819
}
1812
1820
tcx. sess . span_err (
1813
1821
ex. span , "binary operation " + ast_util:: binop_to_str ( op) +
@@ -1817,23 +1825,15 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
1817
1825
}
1818
1826
fn check_user_unop ( fcx : @fn_ctxt , op_str : str , mname : str ,
1819
1827
ex : @ast:: expr , rhs_t : ty:: t ) -> ty:: t {
1820
- let isc = fcx. ccx . impl_map . get ( ex. id ) ;
1821
- let tcx = fcx. ccx . tcx ;
1822
- alt lookup_method ( fcx, isc, mname, rhs_t, ex. span ) {
1823
- some ( { method_ty, n_tps: 0 u, substs, origin} ) {
1824
- let callee_id = ast_util:: op_expr_callee_id ( ex) ;
1825
- write:: ty_fixup ( fcx, callee_id, { substs : some( substs) ,
1826
- ty: method_ty} ) ;
1827
- check_call_or_bind ( fcx, ex. span , method_ty, [ ] ) ;
1828
- fcx. ccx . method_map . insert ( ex. id , origin) ;
1829
- ret ty:: ty_fn_ret ( tcx, method_ty) ;
1828
+ alt lookup_op_method ( fcx, ex, rhs_t, mname, [ ] ) {
1829
+ some ( ret_ty) { ret_ty }
1830
+ _ {
1831
+ fcx. ccx . tcx . sess . span_err (
1832
+ ex. span , #fmt[ "cannot apply unary operator `%s` to type `%s`" ,
1833
+ op_str, ty_to_str ( fcx. ccx . tcx , rhs_t) ] ) ;
1834
+ rhs_t
1830
1835
}
1831
- _ { }
1832
1836
}
1833
- tcx. sess . span_err (
1834
- ex. span , #fmt[ "can not apply unary operator `%s` to type `%s`" ,
1835
- op_str, ty_to_str ( tcx, rhs_t) ] ) ;
1836
- rhs_t
1837
1837
}
1838
1838
1839
1839
let tcx = fcx. ccx . tcx ;
@@ -1888,7 +1888,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
1888
1888
}
1889
1889
ty:: ty_ptr ( inner) {
1890
1890
oper_t = inner. ty ;
1891
- require_unsafe ( fcx . ccx . tcx . sess , fcx. purity , expr. span ) ;
1891
+ require_unsafe ( tcx. sess , fcx. purity , expr. span ) ;
1892
1892
}
1893
1893
_ {
1894
1894
tcx. sess . span_fatal ( expr. span ,
@@ -1989,7 +1989,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
1989
1989
ast:: expr_copy ( a) {
1990
1990
bot = check_expr_with_unifier ( fcx, a, unify, expected) ;
1991
1991
let tpot =
1992
- ty:: node_id_to_ty_param_substs_opt_and_ty ( fcx . ccx . tcx , a. id ) ;
1992
+ ty:: node_id_to_ty_param_substs_opt_and_ty ( tcx, a. id ) ;
1993
1993
write:: ty_fixup ( fcx, id, tpot) ;
1994
1994
1995
1995
}
@@ -2073,9 +2073,8 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
2073
2073
let proto = alt ty:: struct ( tcx, expected) {
2074
2074
ty:: ty_fn ( { proto, _} ) { proto }
2075
2075
_ {
2076
- fcx. ccx . tcx . sess . span_warn (
2077
- expr. span ,
2078
- "unable to infer kind of closure, defaulting to block" ) ;
2076
+ tcx. sess . span_warn ( expr. span , "unable to infer kind of closure, \
2077
+ defaulting to block") ;
2079
2078
ast:: proto_block
2080
2079
}
2081
2080
} ;
@@ -2190,10 +2189,10 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
2190
2189
vec:: reserve ( elt_ts, vec:: len ( elts) ) ;
2191
2190
for e in elts {
2192
2191
check_expr ( fcx, e) ;
2193
- let ety = expr_ty ( fcx . ccx . tcx , e) ;
2192
+ let ety = expr_ty ( tcx, e) ;
2194
2193
elt_ts += [ ety] ;
2195
2194
}
2196
- let typ = ty:: mk_tup ( fcx . ccx . tcx , elt_ts) ;
2195
+ let typ = ty:: mk_tup ( tcx, elt_ts) ;
2197
2196
write:: ty_only_fixup ( fcx, id, typ) ;
2198
2197
}
2199
2198
ast:: expr_rec ( fields, base) {
@@ -2312,26 +2311,39 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
2312
2311
}
2313
2312
ast:: expr_index ( base, idx) {
2314
2313
bot |= check_expr ( fcx, base) ;
2315
- let base_t = expr_ty ( tcx, base) ;
2316
- base_t = do_autoderef ( fcx, expr. span , base_t ) ;
2314
+ let raw_base_t = expr_ty ( tcx, base) ;
2315
+ let base_t = do_autoderef ( fcx, expr. span , raw_base_t ) ;
2317
2316
bot |= check_expr ( fcx, idx) ;
2318
2317
let idx_t = expr_ty ( tcx, idx) ;
2319
- if !type_is_integral ( fcx, idx. span , idx_t) {
2320
- tcx. sess . span_err ( idx. span ,
2321
- "mismatched types: expected \
2322
- `integer` but found `"
2323
- + ty_to_str ( tcx, idx_t) + "`" ) ;
2318
+ fn require_integral ( fcx : @fn_ctxt , sp : span , t : ty:: t ) {
2319
+ if !type_is_integral ( fcx, sp, t) {
2320
+ fcx. ccx . tcx . sess . span_err ( sp, "mismatched types: expected \
2321
+ `integer` but found `"
2322
+ + ty_to_str ( fcx. ccx . tcx , t) + "`" ) ;
2323
+ }
2324
2324
}
2325
2325
alt structure_of ( fcx, expr. span , base_t) {
2326
- ty:: ty_vec ( mt) { write:: ty_only_fixup ( fcx, id, mt. ty ) ; }
2326
+ ty:: ty_vec ( mt) {
2327
+ require_integral ( fcx, idx. span , idx_t) ;
2328
+ write:: ty_only_fixup ( fcx, id, mt. ty ) ;
2329
+ }
2327
2330
ty:: ty_str {
2331
+ require_integral( fcx, idx. span , idx_t) ;
2328
2332
let typ = ty:: mk_mach_uint ( tcx, ast:: ty_u8) ;
2329
2333
write:: ty_only_fixup ( fcx, id, typ) ;
2330
2334
}
2331
2335
_ {
2332
- tcx. sess . span_fatal ( expr. span ,
2333
- "vector-indexing bad type: " +
2334
- ty_to_str ( tcx, base_t) ) ;
2336
+ let resolved = structurally_resolved_type ( fcx, expr. span ,
2337
+ raw_base_t) ;
2338
+ alt lookup_op_method ( fcx, expr, resolved, "op_index" ,
2339
+ [ some ( idx) ] ) {
2340
+ some ( ret_ty) { write:: ty_only_fixup ( fcx, id, ret_ty) ; }
2341
+ _ {
2342
+ tcx. sess . span_fatal (
2343
+ expr. span , "cannot index a value of type `" +
2344
+ ty_to_str ( tcx, base_t) + "`" ) ;
2345
+ }
2346
+ }
2335
2347
}
2336
2348
}
2337
2349
}
@@ -2922,7 +2934,8 @@ mod dict {
2922
2934
}
2923
2935
// Must resolve bounds on methods with bounded params
2924
2936
ast:: expr_field ( _, _, _) | ast:: expr_binary ( _, _, _) |
2925
- ast:: expr_unary ( _, _) | ast:: expr_assign_op ( _, _, _) {
2937
+ ast:: expr_unary ( _, _) | ast:: expr_assign_op ( _, _, _) |
2938
+ ast:: expr_index ( _, _) {
2926
2939
alt cx. method_map . find ( ex. id ) {
2927
2940
some ( method_static ( did) ) {
2928
2941
let bounds = ty:: lookup_item_type ( cx. tcx , did) . bounds ;
0 commit comments