@@ -457,7 +457,7 @@ fn ty_of_item(tcx: ty::ctxt, mode: mode, it: @ast::item)
457
457
tcx. tcache . insert ( local_def ( it. id ) , tpt) ;
458
458
ret tpt;
459
459
}
460
- ast:: item_mod ( _ ) { fail ; }
460
+ ast:: item_impl ( _ , _ , _ ) | ast :: item_mod ( _ ) |
461
461
ast:: item_native_mod ( _) { fail; }
462
462
}
463
463
}
@@ -689,17 +689,20 @@ mod collect {
689
689
}
690
690
fn convert ( cx : @ctxt , it : @ast:: item ) {
691
691
alt it. node {
692
- ast:: item_mod ( _) | ast:: item_impl ( _, _, _) {
693
- // ignore item_mod, it has no type.
694
- }
695
- ast:: item_native_mod ( native_mod) {
696
- // do nothing, as native modules have no types.
697
- }
692
+ // These don't define types.
693
+ ast:: item_mod ( _) | ast:: item_native_mod ( _) { }
698
694
ast:: item_tag ( variants, ty_params) {
699
695
let tpt = ty_of_item ( cx. tcx , m_collect, it) ;
700
696
write:: ty_only ( cx. tcx , it. id , tpt. ty ) ;
701
697
get_tag_variant_types ( cx, local_def ( it. id ) , variants, ty_params) ;
702
698
}
699
+ ast:: item_impl ( _, _, ms) {
700
+ for m in ms {
701
+ write:: ty_only ( cx. tcx , m. node . id ,
702
+ ty:: method_ty_to_fn_ty ( cx. tcx , ty_of_method (
703
+ cx. tcx , m_collect, m) ) ) ;
704
+ }
705
+ }
703
706
ast:: item_obj ( object, ty_params, ctor_id) {
704
707
// Now we need to call ty_of_obj_ctor(); this is the type that
705
708
// we write into the table for this item.
@@ -714,8 +717,8 @@ mod collect {
714
717
// ty_of_obj().)
715
718
let method_types = ty_of_obj_methods ( cx. tcx , m_collect, object) ;
716
719
let i = 0 u;
717
- while i < vec :: len :: < @ast :: method > ( object. methods ) {
718
- write:: ty_only ( cx. tcx , object . methods [ i ] . node . id ,
720
+ for m in object. methods {
721
+ write:: ty_only ( cx. tcx , m . node . id ,
719
722
ty:: method_ty_to_fn_ty ( cx. tcx ,
720
723
method_types[ i] ) ) ;
721
724
i += 1 u;
@@ -919,8 +922,6 @@ fn variant_arg_types(ccx: @crate_ctxt, _sp: span, vid: ast::def_id,
919
922
let tpt = ty:: lookup_item_type ( ccx. tcx , vid) ;
920
923
alt ty:: struct ( ccx. tcx , tpt. ty ) {
921
924
ty:: ty_fn ( _, ins, _, _, _) {
922
-
923
-
924
925
// N-ary variant.
925
926
for arg: ty:: arg in ins {
926
927
let arg_ty =
@@ -930,7 +931,6 @@ fn variant_arg_types(ccx: @crate_ctxt, _sp: span, vid: ast::def_id,
930
931
}
931
932
_ {
932
933
// Nullary variant. Do nothing, as there are no arguments.
933
-
934
934
}
935
935
}
936
936
/* result is a vector of the *expected* types of all the fields */
@@ -2144,35 +2144,70 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
2144
2144
}
2145
2145
}
2146
2146
ast:: expr_field ( base, field) {
2147
+ // FIXME proper type compare, notice conflicts
2148
+ fn lookup_method ( fcx : @fn_ctxt , isc : resolve:: iscopes ,
2149
+ name : ast:: ident , ty : ty:: t )
2150
+ -> option:: t < @ast:: method > {
2151
+ let result = none;
2152
+ std:: list:: iter ( isc) { |impls|
2153
+ for im in * impls {
2154
+ alt im. node {
2155
+ ast:: item_impl ( _, slf, mthds) {
2156
+ let self_ty = ast_ty_to_ty_crate ( fcx. ccx , slf) ;
2157
+ alt unify:: unify ( fcx, ty, self_ty) {
2158
+ ures_ok ( _) { }
2159
+ _ { cont; }
2160
+ }
2161
+ for m in mthds {
2162
+ if m. node . ident == name {
2163
+ result = some ( m) ;
2164
+ ret;
2165
+ }
2166
+ }
2167
+ }
2168
+ }
2169
+ }
2170
+ }
2171
+ result
2172
+ }
2147
2173
bot |= check_expr ( fcx, base) ;
2148
2174
let base_t = expr_ty ( tcx, base) ;
2149
- base_t = do_autoderef ( fcx, expr. span , base_t) ;
2150
- alt structure_of ( fcx, expr. span , base_t) {
2151
- ty:: ty_rec ( fields) {
2152
- let ix: uint = ty:: field_idx ( tcx. sess , expr. span , field, fields) ;
2153
- if ix >= vec:: len :: < ty:: field > ( fields) {
2154
- tcx. sess . span_fatal ( expr. span , "bad index on record" ) ;
2155
- }
2156
- write:: ty_only_fixup ( fcx, id, fields[ ix] . mt . ty ) ;
2157
- }
2158
- ty:: ty_obj ( methods) {
2159
- let ix: uint =
2160
- ty:: method_idx ( tcx. sess , expr. span , field, methods) ;
2161
- if ix >= vec:: len :: < ty:: method > ( methods) {
2162
- tcx. sess . span_fatal ( expr. span , "bad index on obj" ) ;
2163
- }
2164
- let meth = methods[ ix] ;
2165
- let t =
2166
- ty:: mk_fn ( tcx, meth. proto , meth. inputs , meth. output , meth. cf ,
2167
- meth. constrs ) ;
2168
- write:: ty_only_fixup ( fcx, id, t) ;
2175
+ let iscope = fcx. ccx . impl_map . get ( expr. id ) ;
2176
+ alt lookup_method ( fcx, iscope, field, base_t) {
2177
+ some ( method) {
2178
+ let mt = ty_of_method ( fcx. ccx . tcx , m_check, method) ;
2179
+ let f_ty = ty:: mk_fn ( fcx. ccx . tcx , mt. proto , mt. inputs ,
2180
+ mt. output , mt. cf , mt. constrs ) ;
2181
+ write:: ty_only_fixup ( fcx, id, f_ty) ;
2169
2182
}
2170
2183
_ {
2171
- let t_err = resolve_type_vars_if_possible ( fcx, base_t) ;
2172
- let msg =
2173
- #fmt[ "attempted field access on type %s" ,
2174
- ty_to_str ( tcx, t_err) ] ;
2175
- tcx. sess . span_fatal ( expr. span , msg) ;
2184
+ base_t = do_autoderef ( fcx, expr. span , base_t) ;
2185
+ alt structure_of ( fcx, expr. span , base_t) {
2186
+ ty:: ty_rec ( fields) {
2187
+ let ix = ty:: field_idx ( tcx. sess , expr. span , field, fields) ;
2188
+ if ix >= vec:: len :: < ty:: field > ( fields) {
2189
+ tcx. sess . span_fatal ( expr. span , "bad index on record" ) ;
2190
+ }
2191
+ write:: ty_only_fixup ( fcx, id, fields[ ix] . mt . ty ) ;
2192
+ }
2193
+ ty:: ty_obj ( methods) {
2194
+ let ix = ty:: method_idx ( tcx. sess , expr. span , field, methods) ;
2195
+ if ix >= vec:: len :: < ty:: method > ( methods) {
2196
+ tcx. sess . span_fatal ( expr. span , "bad index on obj" ) ;
2197
+ }
2198
+ let meth = methods[ ix] ;
2199
+ let t = ty:: mk_fn ( tcx, meth. proto , meth. inputs , meth. output ,
2200
+ meth. cf , meth. constrs ) ;
2201
+ write:: ty_only_fixup ( fcx, id, t) ;
2202
+ }
2203
+ _ {
2204
+ let t_err = resolve_type_vars_if_possible ( fcx, base_t) ;
2205
+ let msg = #fmt[ "attempted field access on type %s, but no \
2206
+ method implementation was found",
2207
+ ty_to_str ( tcx, t_err) ] ;
2208
+ tcx. sess . span_fatal ( expr. span , msg) ;
2209
+ }
2210
+ }
2176
2211
}
2177
2212
}
2178
2213
}
@@ -2602,13 +2637,12 @@ fn check_item(ccx: @crate_ctxt, it: @ast::item) {
2602
2637
ast:: item_obj ( ob, _, _) {
2603
2638
// We're entering an object, so gather up the info we need.
2604
2639
ccx. obj_infos += [ regular_obj ( ob. fields , it. id ) ] ;
2605
-
2606
2640
// Typecheck the methods.
2607
2641
for method: @ast:: method in ob. methods { check_method ( ccx, method) ; }
2608
-
2609
2642
// Now remove the info from the stack.
2610
2643
vec:: pop :: < obj_info > ( ccx. obj_infos ) ;
2611
2644
}
2645
+ ast:: item_impl ( _, _, ms) { for m in ms { check_method ( ccx, m) ; } }
2612
2646
_ { /* nothing to do */ }
2613
2647
}
2614
2648
}
0 commit comments