@@ -1146,24 +1146,9 @@ fn check_cast(fcx: &FnCtxt,
11461146 . span_err ( span,
11471147 "cannot cast as `bool`, compare with zero instead" ) ;
11481148 } 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- }
11641149 fn types_compatible ( fcx : & FnCtxt , sp : Span ,
11651150 t1 : ty:: t , t2 : ty:: t ) -> bool {
1166- if !is_vec ( t1) {
1151+ if !ty :: type_is_vec ( t1) {
11671152 // If the type being casted from is not a vector, this special
11681153 // case does not apply.
11691154 return false
@@ -2779,10 +2764,30 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
27792764 fcx. write_ty ( id, enum_type) ;
27802765 }
27812766
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+
27822786 let tcx = fcx. ccx . tcx ;
27832787 let id = expr. id ;
27842788 match expr. node {
27852789 ast:: ExprVstore ( ev, vst) => {
2790+ let ( check, t) = check_fn_for_vec_elements_expected ( fcx, expected) ;
27862791 let typ = match ev. node {
27872792 ast:: ExprVec ( ref args) => {
27882793 let mutability = match vst {
@@ -2791,9 +2796,8 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
27912796 } ;
27922797 let mut any_error = false ;
27932798 let mut any_bot = false ;
2794- let t: ty:: t = fcx. infcx ( ) . next_ty_var ( ) ;
27952799 for e in args. iter ( ) {
2796- check_expr_has_type ( fcx, & * * e, t) ;
2800+ check ( fcx, & * * e, t) ;
27972801 let arg_t = fcx. expr_ty ( & * * e) ;
27982802 if ty:: type_is_error ( arg_t) {
27992803 any_error = true ;
@@ -2821,8 +2825,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
28212825 ast:: ExprVstoreMutSlice => ast:: MutMutable ,
28222826 _ => ast:: MutImmutable ,
28232827 } ;
2824- let t = fcx. infcx ( ) . next_ty_var ( ) ;
2825- check_expr_has_type ( fcx, & * * element, t) ;
2828+ check ( fcx, & * * element, t) ;
28262829 let arg_t = fcx. expr_ty ( & * * element) ;
28272830 if ty:: type_is_error ( arg_t) {
28282831 ty:: mk_err ( )
@@ -3211,9 +3214,9 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
32113214 check_cast ( fcx, & * * e, & * * t, id, expr. span ) ;
32123215 }
32133216 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 ) ;
32153218 for e in args. iter ( ) {
3216- check_expr_has_type ( fcx, & * * e, t) ;
3219+ check ( fcx, & * * e, t) ;
32173220 }
32183221 let typ = ty:: mk_vec ( tcx, ty:: mt { ty : t, mutbl : ast:: MutImmutable } ,
32193222 Some ( args. len ( ) ) ) ;
@@ -3222,8 +3225,8 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
32223225 ast:: ExprRepeat ( ref element, ref count_expr) => {
32233226 check_expr_has_type ( fcx, & * * count_expr, ty:: mk_uint ( ) ) ;
32243227 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) ;
32273230 let element_ty = fcx. expr_ty ( & * * element) ;
32283231 if ty:: type_is_error ( element_ty) {
32293232 fcx. write_error ( id) ;
0 commit comments