auto merge of #16953 : nick29581/rust/dst-bug-7, r=pcwalton
Closes #16947 r?
This commit is contained in:
commit
3b5d92c923
@ -1859,6 +1859,19 @@ pub fn cast_type_kind(tcx: &ty::ctxt, t: ty::t) -> cast_kind {
|
||||
}
|
||||
}
|
||||
|
||||
fn cast_is_noop(t_in: ty::t, t_out: ty::t) -> bool {
|
||||
if ty::type_is_boxed(t_in) || ty::type_is_boxed(t_out) {
|
||||
return false;
|
||||
}
|
||||
|
||||
match (ty::deref(t_in, true), ty::deref(t_out, true)) {
|
||||
(Some(ty::mt{ ty: t_in, .. }), Some(ty::mt{ ty: t_out, .. })) => {
|
||||
t_in == t_out
|
||||
}
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
||||
fn trans_imm_cast<'a>(bcx: &'a Block<'a>,
|
||||
expr: &ast::Expr,
|
||||
id: ast::NodeId)
|
||||
@ -1877,7 +1890,13 @@ fn trans_imm_cast<'a>(bcx: &'a Block<'a>,
|
||||
|
||||
// Convert the value to be cast into a ValueRef, either by-ref or
|
||||
// by-value as appropriate given its type:
|
||||
let datum = unpack_datum!(bcx, trans(bcx, expr));
|
||||
let mut datum = unpack_datum!(bcx, trans(bcx, expr));
|
||||
|
||||
if cast_is_noop(datum.ty, t_out) {
|
||||
datum.ty = t_out;
|
||||
return DatumBlock::new(bcx, datum);
|
||||
}
|
||||
|
||||
let newval = match (k_in, k_out) {
|
||||
(cast_integral, cast_integral) => {
|
||||
let llexpr = datum.to_llscalarish(bcx);
|
||||
|
@ -1502,10 +1502,9 @@ fn check_cast(fcx: &FnCtxt,
|
||||
} else if ty::type_is_region_ptr(t_e) && ty::type_is_unsafe_ptr(t_1) {
|
||||
fn types_compatible(fcx: &FnCtxt, sp: Span,
|
||||
t1: ty::t, t2: ty::t) -> bool {
|
||||
if !ty::type_is_vec(t1) {
|
||||
// If the type being casted from is not a vector, this special
|
||||
// case does not apply.
|
||||
return false
|
||||
match ty::get(t1).sty {
|
||||
ty::ty_vec(_, Some(_)) => {}
|
||||
_ => return false
|
||||
}
|
||||
if ty::type_needs_infer(t2) {
|
||||
// This prevents this special case from going off when casting
|
||||
@ -1529,7 +1528,7 @@ fn check_cast(fcx: &FnCtxt,
|
||||
// need to special-case obtaining an unsafe pointer
|
||||
// from a region pointer to a vector.
|
||||
|
||||
/* this cast is only allowed from &[T] to *T or
|
||||
/* this cast is only allowed from &[T, ..n] to *T or
|
||||
&T to *T. */
|
||||
match (&ty::get(t_e).sty, &ty::get(t_1).sty) {
|
||||
(&ty::ty_rptr(_, ty::mt { ty: mt1, mutbl: ast::MutImmutable }),
|
||||
|
@ -53,6 +53,15 @@ pub fn main() {
|
||||
assert!(len == 3);
|
||||
}
|
||||
|
||||
// raw slice with explicit cast
|
||||
let a = &[1i, 2, 3] as *const [_];
|
||||
unsafe {
|
||||
let b = (*a)[2];
|
||||
assert!(b == 3);
|
||||
let len = (*a).len();
|
||||
assert!(len == 3);
|
||||
}
|
||||
|
||||
// raw DST struct with slice
|
||||
let c: *const Foo<[_]> = &Foo {f: [1i, 2, 3]};
|
||||
unsafe {
|
||||
@ -85,6 +94,14 @@ pub fn main() {
|
||||
assert!(len == 3);
|
||||
}
|
||||
|
||||
let a = &mut [1i, 2, 3] as *mut [_];
|
||||
unsafe {
|
||||
let b = (*a)[2];
|
||||
assert!(b == 3);
|
||||
let len = (*a).len();
|
||||
assert!(len == 3);
|
||||
}
|
||||
|
||||
let c: *mut Foo<[_]> = &mut Foo {f: [1i, 2, 3]};
|
||||
unsafe {
|
||||
let b = (&*c).f[0];
|
||||
|
Loading…
Reference in New Issue
Block a user