@@ -1146,24 +1146,9 @@ fn check_cast(fcx: &FnCtxt,
1146
1146
. span_err ( span,
1147
1147
"cannot cast as `bool`, compare with zero instead" ) ;
1148
1148
} else if ty:: type_is_region_ptr ( t_e) && ty:: type_is_unsafe_ptr ( t_1) {
1149
- fn is_vec ( t : ty:: t ) -> bool {
1150
- match ty:: get ( t) . sty {
1151
- ty:: ty_vec( ..) => true ,
1152
- ty:: ty_ptr( ty:: mt { ty : t, ..} ) |
1153
- ty:: ty_rptr( _, ty:: mt { ty : t, ..} ) |
1154
- ty:: ty_box( t) |
1155
- ty:: ty_uniq( t) => {
1156
- match ty:: get ( t) . sty {
1157
- ty:: ty_vec( _, None ) => true ,
1158
- _ => false ,
1159
- }
1160
- }
1161
- _ => false
1162
- }
1163
- }
1164
1149
fn types_compatible ( fcx : & FnCtxt , sp : Span ,
1165
1150
t1 : ty:: t , t2 : ty:: t ) -> bool {
1166
- if !is_vec ( t1) {
1151
+ if !ty :: type_is_vec ( t1) {
1167
1152
// If the type being casted from is not a vector, this special
1168
1153
// case does not apply.
1169
1154
return false
@@ -2779,10 +2764,30 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
2779
2764
fcx. write_ty ( id, enum_type) ;
2780
2765
}
2781
2766
2767
+ type ExprCheckerWithTy = fn ( & FnCtxt , & ast:: Expr , ty:: t ) ;
2768
+
2769
+ fn check_fn_for_vec_elements_expected ( fcx : & FnCtxt ,
2770
+ expected : Expectation )
2771
+ -> ( ExprCheckerWithTy , ty:: t ) {
2772
+ let tcx = fcx. ccx . tcx ;
2773
+ let ( coerce, t) = match expected {
2774
+ // If we're given an expected type, we can try to coerce to it
2775
+ ExpectHasType ( t) if ty:: type_is_vec ( t) => ( true , ty:: sequence_element_type ( tcx, t) ) ,
2776
+ // Otherwise we just leave the type to be resolved later
2777
+ _ => ( false , fcx. infcx ( ) . next_ty_var ( ) )
2778
+ } ;
2779
+ if coerce {
2780
+ ( check_expr_coercable_to_type, t)
2781
+ } else {
2782
+ ( check_expr_has_type, t)
2783
+ }
2784
+ }
2785
+
2782
2786
let tcx = fcx. ccx . tcx ;
2783
2787
let id = expr. id ;
2784
2788
match expr. node {
2785
2789
ast:: ExprVstore ( ev, vst) => {
2790
+ let ( check, t) = check_fn_for_vec_elements_expected ( fcx, expected) ;
2786
2791
let typ = match ev. node {
2787
2792
ast:: ExprVec ( ref args) => {
2788
2793
let mutability = match vst {
@@ -2791,9 +2796,8 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
2791
2796
} ;
2792
2797
let mut any_error = false ;
2793
2798
let mut any_bot = false ;
2794
- let t: ty:: t = fcx. infcx ( ) . next_ty_var ( ) ;
2795
2799
for e in args. iter ( ) {
2796
- check_expr_has_type ( fcx, & * * e, t) ;
2800
+ check ( fcx, & * * e, t) ;
2797
2801
let arg_t = fcx. expr_ty ( & * * e) ;
2798
2802
if ty:: type_is_error ( arg_t) {
2799
2803
any_error = true ;
@@ -2821,8 +2825,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
2821
2825
ast:: ExprVstoreMutSlice => ast:: MutMutable ,
2822
2826
_ => ast:: MutImmutable ,
2823
2827
} ;
2824
- let t = fcx. infcx ( ) . next_ty_var ( ) ;
2825
- check_expr_has_type ( fcx, & * * element, t) ;
2828
+ check ( fcx, & * * element, t) ;
2826
2829
let arg_t = fcx. expr_ty ( & * * element) ;
2827
2830
if ty:: type_is_error ( arg_t) {
2828
2831
ty:: mk_err ( )
@@ -3211,9 +3214,9 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
3211
3214
check_cast ( fcx, & * * e, & * * t, id, expr. span ) ;
3212
3215
}
3213
3216
ast:: ExprVec ( ref args) => {
3214
- let t : ty :: t = fcx . infcx ( ) . next_ty_var ( ) ;
3217
+ let ( check , t ) = check_fn_for_vec_elements_expected ( fcx , expected ) ;
3215
3218
for e in args. iter ( ) {
3216
- check_expr_has_type ( fcx, & * * e, t) ;
3219
+ check ( fcx, & * * e, t) ;
3217
3220
}
3218
3221
let typ = ty:: mk_vec ( tcx, ty:: mt { ty : t, mutbl : ast:: MutImmutable } ,
3219
3222
Some ( args. len ( ) ) ) ;
@@ -3222,8 +3225,8 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
3222
3225
ast:: ExprRepeat ( ref element, ref count_expr) => {
3223
3226
check_expr_has_type ( fcx, & * * count_expr, ty:: mk_uint ( ) ) ;
3224
3227
let count = ty:: eval_repeat_count ( fcx, & * * count_expr) ;
3225
- let t : ty :: t = fcx . infcx ( ) . next_ty_var ( ) ;
3226
- check_expr_has_type ( fcx, & * * element, t) ;
3228
+ let ( check , t ) = check_fn_for_vec_elements_expected ( fcx , expected ) ;
3229
+ check ( fcx, & * * element, t) ;
3227
3230
let element_ty = fcx. expr_ty ( & * * element) ;
3228
3231
if ty:: type_is_error ( element_ty) {
3229
3232
fcx. write_error ( id) ;
0 commit comments