@@ -3063,12 +3063,22 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
3063
3063
let t_1_is_char = type_is_char( fcx, expr. span, t_1) ;
3064
3064
let t_1_is_bare_fn = type_is_bare_fn( fcx, expr. span, t_1) ;
3065
3065
3066
+ let t_1_is_ptr_dst_vec = type_is_ptr_dst_vec( fcx, expr. span, t_1) ;
3067
+ let t_e_is_ptr_sized_vec = type_is_ptr_sized_vec( fcx, expr. span, t_e) ;
3068
+ let t_matching_ptrs = types_are_matching_ptrs( fcx, expr. span, t_1, t_e) ;
3069
+
3066
3070
// casts to scalars other than `char` and `bare fn` are trivial
3067
3071
let t_1_is_trivial = t_1_is_scalar &&
3068
3072
!t_1_is_char && !t_1_is_bare_fn;
3069
3073
3070
3074
if type_is_c_like_enum( fcx, expr. span, t_e) && t_1_is_trivial {
3071
3075
// casts from C-like enums are allowed
3076
+ } else if t_1_is_ptr_dst_vec && t_e_is_ptr_sized_vec && t_matching_ptrs {
3077
+ // casts from `&[T, ..n]` to `&[T]` or `~[T, ..n]` to `~[T]` are allowed
3078
+
3079
+ // Note(nrc): we should handle this check in a more general way, allowing
3080
+ // coercion from `[T, ..n]` to `[T]` and covariant coercions.
3081
+ // We should also handle `*[T]`
3072
3082
} else if t_1_is_char {
3073
3083
let te = fcx. infcx( ) . resolve_type_vars_if_possible( te) ;
3074
3084
if ty:: get( te) . sty != ty:: ty_uint( ast:: TyU8 ) {
@@ -4013,6 +4023,46 @@ pub fn type_is_c_like_enum(fcx: &FnCtxt, sp: Span, typ: ty::t) -> bool {
4013
4023
return ty:: type_is_c_like_enum ( fcx. ccx . tcx , typ_s) ;
4014
4024
}
4015
4025
4026
+ pub fn type_is_ptr_sized_vec ( fcx : & FnCtxt , sp : Span , typ : ty:: t ) -> bool {
4027
+ let typ_s = structure_of ( fcx, sp, typ) ;
4028
+ match typ_s {
4029
+ & ty:: ty_uniq( t) => match ty:: get ( t) . sty {
4030
+ ty:: ty_vec( _, Some ( _) ) => true ,
4031
+ _ => false ,
4032
+ } ,
4033
+ & ty:: ty_rptr( _, mt) => match ty:: get ( mt. ty ) . sty {
4034
+ ty:: ty_vec( _, Some ( _) ) => true ,
4035
+ _ => false ,
4036
+ } ,
4037
+ _ => false ,
4038
+ }
4039
+ }
4040
+
4041
+ pub fn type_is_ptr_dst_vec ( fcx : & FnCtxt , sp : Span , typ : ty:: t ) -> bool {
4042
+ let typ_s = structure_of ( fcx, sp, typ) ;
4043
+ match typ_s {
4044
+ & ty:: ty_uniq( t) => match ty:: get ( t) . sty {
4045
+ ty:: ty_vec( _, None ) => true ,
4046
+ _ => false ,
4047
+ } ,
4048
+ & ty:: ty_rptr( _, mt) => match ty:: get ( mt. ty ) . sty {
4049
+ ty:: ty_vec( _, None ) => true ,
4050
+ _ => false ,
4051
+ } ,
4052
+ _ => false ,
4053
+ }
4054
+ }
4055
+
4056
+ pub fn types_are_matching_ptrs ( fcx : & FnCtxt , sp : Span , typ1 : ty:: t , typ2 : ty:: t ) -> bool {
4057
+ let typ1_s = structure_of ( fcx, sp, typ1) ;
4058
+ let typ2_s = structure_of ( fcx, sp, typ2) ;
4059
+ match ( typ1_s, typ2_s) {
4060
+ ( & ty:: ty_rptr( ..) , & ty:: ty_rptr( ..) ) => true ,
4061
+ ( & ty:: ty_uniq( ..) , & ty:: ty_uniq( ..) ) => true ,
4062
+ _ => false
4063
+ }
4064
+ }
4065
+
4016
4066
pub fn ast_expr_vstore_to_vstore ( fcx : & FnCtxt ,
4017
4067
e : & ast:: Expr ,
4018
4068
v : ast:: ExprVstore )
0 commit comments