Skip to content

Commit a34c42f

Browse files
committed
Expect an array when expected and acutal types are both arrays during cast
Signed-off-by: xizheyin <[email protected]>
1 parent 8962536 commit a34c42f

File tree

5 files changed

+28
-30
lines changed

5 files changed

+28
-30
lines changed

Diff for: compiler/rustc_hir_typeck/src/cast.rs

+20-19
Original file line numberDiff line numberDiff line change
@@ -1042,30 +1042,31 @@ impl<'a, 'tcx> CastCheck<'tcx> {
10421042
m_cast: ty::TypeAndMut<'tcx>,
10431043
) -> Result<CastKind, CastError<'tcx>> {
10441044
// array-ptr-cast: allow mut-to-mut, mut-to-const, const-to-const
1045-
if m_expr.mutbl >= m_cast.mutbl {
1046-
if let ty::Array(ety, _) = m_expr.ty.kind() {
1047-
// Due to the limitations of LLVM global constants,
1048-
// region pointers end up pointing at copies of
1049-
// vector elements instead of the original values.
1050-
// To allow raw pointers to work correctly, we
1051-
// need to special-case obtaining a raw pointer
1052-
// from a region pointer to a vector.
1053-
1054-
// Coerce to a raw pointer so that we generate RawPtr in MIR.
1055-
let array_ptr_type = Ty::new_ptr(fcx.tcx, m_expr.ty, m_expr.mutbl);
1056-
fcx.coerce(self.expr, self.expr_ty, array_ptr_type, AllowTwoPhase::No, None)
1057-
.unwrap_or_else(|_| {
1058-
bug!(
1045+
if m_expr.mutbl >= m_cast.mutbl
1046+
&& let ty::Array(ety, _) = m_expr.ty.kind()
1047+
&& fcx.can_eq(fcx.param_env, *ety, m_cast.ty)
1048+
{
1049+
// Due to the limitations of LLVM global constants,
1050+
// region pointers end up pointing at copies of
1051+
// vector elements instead of the original values.
1052+
// To allow raw pointers to work correctly, we
1053+
// need to special-case obtaining a raw pointer
1054+
// from a region pointer to a vector.
1055+
1056+
// Coerce to a raw pointer so that we generate RawPtr in MIR.
1057+
let array_ptr_type = Ty::new_ptr(fcx.tcx, m_expr.ty, m_expr.mutbl);
1058+
fcx.coerce(self.expr, self.expr_ty, array_ptr_type, AllowTwoPhase::No, None)
1059+
.unwrap_or_else(|_| {
1060+
bug!(
10591061
"could not cast from reference to array to pointer to array ({:?} to {:?})",
10601062
self.expr_ty,
10611063
array_ptr_type,
10621064
)
1063-
});
1065+
});
10641066

1065-
// this will report a type mismatch if needed
1066-
fcx.demand_eqtype(self.span, *ety, m_cast.ty);
1067-
return Ok(CastKind::ArrayPtrCast);
1068-
}
1067+
// this will report a type mismatch if needed
1068+
fcx.demand_eqtype(self.span, *ety, m_cast.ty);
1069+
return Ok(CastKind::ArrayPtrCast);
10691070
}
10701071

10711072
Err(CastError::IllegalCast)

Diff for: tests/ui/cast/cast-array-issue-138836.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
fn main() {
22
let a: [u8; 3] = [1,2,3];
33
let b = &a;
4-
let c = b as *const [u32; 3]; //~ ERROR mismatched types [E0308]
4+
let c = b as *const [u32; 3]; //~ ERROR casting `&[u8; 3]` as `*const [u32; 3]` is invalid
55
}

Diff for: tests/ui/cast/cast-array-issue-138836.stderr

+3-6
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
1-
error[E0308]: mismatched types
1+
error[E0606]: casting `&[u8; 3]` as `*const [u32; 3]` is invalid
22
--> $DIR/cast-array-issue-138836.rs:4:13
33
|
44
LL | let c = b as *const [u32; 3];
5-
| ^^^^^^^^^^^^^^^^^^^^ expected `[u8; 3]`, found `[u32; 3]`
6-
|
7-
= note: expected array `[u8; 3]`
8-
found array `[u32; 3]`
5+
| ^^^^^^^^^^^^^^^^^^^^
96

107
error: aborting due to 1 previous error
118

12-
For more information about this error, try `rustc --explain E0308`.
9+
For more information about this error, try `rustc --explain E0606`.

Diff for: tests/ui/consts/const-cast-wrong-type.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
const a: [u8; 3] = ['h' as u8, 'i' as u8, 0 as u8];
2-
const b: *const i8 = &a as *const i8; //~ ERROR mismatched types
2+
const b: *const i8 = &a as *const i8; //~ ERROR casting `&[u8; 3]` as `*const i8` is invalid
33

44
fn main() {
55
}

Diff for: tests/ui/consts/const-cast-wrong-type.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
error[E0308]: mismatched types
1+
error[E0606]: casting `&[u8; 3]` as `*const i8` is invalid
22
--> $DIR/const-cast-wrong-type.rs:2:22
33
|
44
LL | const b: *const i8 = &a as *const i8;
5-
| ^^^^^^^^^^^^^^^ expected `u8`, found `i8`
5+
| ^^^^^^^^^^^^^^^
66

77
error: aborting due to 1 previous error
88

9-
For more information about this error, try `rustc --explain E0308`.
9+
For more information about this error, try `rustc --explain E0606`.

0 commit comments

Comments
 (0)