Skip to content

Commit 2ee961c

Browse files
committed
Allow coercions from &[T, ..n] to &[T] also ~
This only allows them at the type checking stage. We still require implementation in trans. Also needs tests. Part of rust-lang#13716.
1 parent a08198b commit 2ee961c

File tree

1 file changed

+50
-0
lines changed
  • src/librustc/middle/typeck/check

1 file changed

+50
-0
lines changed

src/librustc/middle/typeck/check/mod.rs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3063,12 +3063,22 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
30633063
let t_1_is_char = type_is_char(fcx, expr.span, t_1);
30643064
let t_1_is_bare_fn = type_is_bare_fn(fcx, expr.span, t_1);
30653065

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+
30663070
// casts to scalars other than `char` and `bare fn` are trivial
30673071
let t_1_is_trivial = t_1_is_scalar &&
30683072
!t_1_is_char && !t_1_is_bare_fn;
30693073

30703074
if type_is_c_like_enum(fcx, expr.span, t_e) && t_1_is_trivial {
30713075
// 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]`
30723082
} else if t_1_is_char {
30733083
let te = fcx.infcx().resolve_type_vars_if_possible(te);
30743084
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 {
40134023
return ty::type_is_c_like_enum(fcx.ccx.tcx, typ_s);
40144024
}
40154025

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+
40164066
pub fn ast_expr_vstore_to_vstore(fcx: &FnCtxt,
40174067
e: &ast::Expr,
40184068
v: ast::ExprVstore)

0 commit comments

Comments
 (0)