@@ -2875,11 +2875,21 @@ type dict_map = hashmap<ast::node_id, dict_res>;
2875
2875
// Detect points where an interface-bounded type parameter is instantiated,
2876
2876
// resolve the impls for the parameters.
2877
2877
fn resolve_dicts ( tcx : ty:: ctxt , impl_map : resolve:: impl_map ,
2878
- crate : @ast:: crate ) -> dict_map {
2878
+ method_map : method_map , crate : @ast:: crate ) -> dict_map {
2879
2879
type ccx = { tcx : ty:: ctxt ,
2880
2880
impl_map : resolve:: impl_map ,
2881
+ method_map : method_map ,
2881
2882
dict_map : dict_map } ;
2882
- let cx = { tcx: tcx, impl_map: impl_map, dict_map: new_int_hash ( ) } ;
2883
+ let cx = { tcx: tcx, impl_map: impl_map,
2884
+ method_map: method_map, dict_map: new_int_hash ( ) } ;
2885
+
2886
+ fn has_iface_bounds ( tps : [ ty:: param_bounds ] ) -> bool {
2887
+ vec:: any ( tps, { |bs|
2888
+ vec:: any ( * bs, { |b|
2889
+ alt b { ty : : bound_iface ( _) { true } _ { false } }
2890
+ } )
2891
+ } )
2892
+ }
2883
2893
fn resolve_expr ( ex : @ast:: expr , cx : ccx , v : visit:: vt < ccx > ) {
2884
2894
alt ex. node {
2885
2895
ast:: expr_path ( _) {
@@ -2889,14 +2899,25 @@ fn resolve_dicts(tcx: ty::ctxt, impl_map: resolve::impl_map,
2889
2899
some ( ts) {
2890
2900
let did = ast_util:: def_id_of_def ( cx. tcx . def_map . get ( ex. id ) ) ;
2891
2901
let item_ty = ty:: lookup_item_type ( cx. tcx , did) ;
2892
- if vec:: any ( * item_ty. bounds , { |bs|
2893
- vec:: any ( * bs, { |b|
2894
- alt b { ty : : bound_iface ( _) { true } _ { false } }
2895
- } )
2896
- } ) {
2902
+ if has_iface_bounds ( * item_ty. bounds ) {
2897
2903
let impls = cx. impl_map . get ( ex. id ) ;
2898
2904
cx. dict_map . insert ( ex. id , lookup_dicts (
2899
- cx. tcx , impls, ex. span , * item_ty. bounds , ts) ) ;
2905
+ cx. tcx , impls, ex. span , item_ty. bounds , ts) ) ;
2906
+ }
2907
+ }
2908
+ _ { }
2909
+ }
2910
+ }
2911
+ // Must resolve bounds on methods with bounded params
2912
+ ast:: expr_field ( _, _, _) {
2913
+ alt cx. method_map . find ( ex. id ) {
2914
+ some ( method_static ( did) ) {
2915
+ let bounds = ty:: lookup_item_type ( cx. tcx , did) . bounds ;
2916
+ if has_iface_bounds ( * bounds) {
2917
+ let tys = ty:: node_id_to_type_params ( cx. tcx , ex. id ) ;
2918
+ let iscs = cx. impl_map . get ( ex. id ) ;
2919
+ cx. dict_map . insert ( ex. id , lookup_dicts (
2920
+ cx. tcx , iscs, ex. span , bounds, tys) ) ;
2900
2921
}
2901
2922
}
2902
2923
_ { }
@@ -2906,8 +2927,9 @@ fn resolve_dicts(tcx: ty::ctxt, impl_map: resolve::impl_map,
2906
2927
}
2907
2928
visit:: visit_expr ( ex, cx, v) ;
2908
2929
}
2930
+
2909
2931
fn lookup_dicts ( tcx : ty:: ctxt , isc : resolve:: iscopes , sp : span ,
2910
- bounds : [ ty:: param_bounds ] , tys : [ ty:: t ] )
2932
+ bounds : @ [ ty:: param_bounds ] , tys : [ ty:: t ] )
2911
2933
-> dict_res {
2912
2934
let result = [ ] , i = 0 u;
2913
2935
for ty in tys {
@@ -2923,6 +2945,7 @@ fn resolve_dicts(tcx: ty::ctxt, impl_map: resolve::impl_map,
2923
2945
}
2924
2946
@result
2925
2947
}
2948
+
2926
2949
fn lookup_dict ( tcx : ty:: ctxt , isc : resolve:: iscopes , sp : span ,
2927
2950
ty : ty:: t , iface_ty : ty:: t ) -> dict_origin {
2928
2951
let iface_id = alt ty:: struct ( tcx, iface_ty) {
@@ -2951,6 +2974,7 @@ fn resolve_dicts(tcx: ty::ctxt, impl_map: resolve::impl_map,
2951
2974
for im in * impls {
2952
2975
if im. iface_did == some ( iface_id) {
2953
2976
let self_ty = impl_self_ty ( tcx, im. did ) . ty ;
2977
+ let im_bs = ty:: lookup_item_type ( tcx, im. did ) . bounds ;
2954
2978
let params = @mutable [ mutable] ;
2955
2979
alt ty:: unify:: unify ( ty, self_ty,
2956
2980
ty:: unify:: bind_params ( params) ,
@@ -2963,9 +2987,10 @@ fn resolve_dicts(tcx: ty::ctxt, impl_map: resolve::impl_map,
2963
2987
} else {
2964
2988
let params = vec:: map_mut (
2965
2989
* params, { |p| option:: get ( p) } ) ;
2966
- // FIXME[impl] check for sub-bounds
2967
- found = some ( dict_static (
2968
- im. did , params, @[ ] ) ) ;
2990
+ let subres = lookup_dicts ( tcx, isc, sp,
2991
+ im_bs, params) ;
2992
+ found = some ( dict_static ( im. did , params,
2993
+ subres) ) ;
2969
2994
}
2970
2995
}
2971
2996
_ { }
@@ -2985,6 +3010,7 @@ fn resolve_dicts(tcx: ty::ctxt, impl_map: resolve::impl_map,
2985
3010
ty_to_str ( tcx, iface_ty) + " for " +
2986
3011
ty_to_str ( tcx, ty) ) ;
2987
3012
}
3013
+
2988
3014
visit:: visit_crate ( * crate , cx, visit:: mk_vt ( @{
2989
3015
visit_expr: resolve_expr
2990
3016
with * visit:: default_visitor ( )
@@ -3006,7 +3032,7 @@ fn check_crate(tcx: ty::ctxt, impl_map: resolve::impl_map,
3006
3032
bind check_native_item ( ccx, _)
3007
3033
with * visit:: default_simple_visitor ( ) } ) ;
3008
3034
visit:: visit_crate ( * crate , ( ) , visit) ;
3009
- let dict_map = resolve_dicts ( tcx, impl_map, crate ) ;
3035
+ let dict_map = resolve_dicts ( tcx, impl_map, ccx . method_map , crate ) ;
3010
3036
check_for_main_fn ( tcx, crate ) ;
3011
3037
tcx. sess . abort_if_errors ( ) ;
3012
3038
( ccx. method_map , dict_map)
0 commit comments