Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 7 additions & 8 deletions compiler/rustc_hir_typeck/src/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1051,20 +1051,19 @@ impl<'a, 'tcx> CastCheck<'tcx> {
fn check_ref_cast(
&self,
fcx: &FnCtxt<'a, 'tcx>,
m_expr: ty::TypeAndMut<'tcx>,
m_cast: ty::TypeAndMut<'tcx>,
mut m_expr: ty::TypeAndMut<'tcx>,
mut m_cast: ty::TypeAndMut<'tcx>,
) -> Result<CastKind, CastError<'tcx>> {
// array-ptr-cast: allow mut-to-mut, mut-to-const, const-to-const
m_expr.ty = fcx.try_structurally_resolve_type(self.expr_span, m_expr.ty);
m_cast.ty = fcx.try_structurally_resolve_type(self.cast_span, m_cast.ty);

if m_expr.mutbl >= m_cast.mutbl
&& let ty::Array(ety, _) = m_expr.ty.kind()
&& fcx.can_eq(fcx.param_env, *ety, m_cast.ty)
{
// Due to the limitations of LLVM global constants,
// region pointers end up pointing at copies of
// vector elements instead of the original values.
// To allow raw pointers to work correctly, we
// need to special-case obtaining a raw pointer
// from a region pointer to a vector.
// Due to historical reasons we allow directly casting references of
// arrays into raw pointers of their element type.

// Coerce to a raw pointer so that we generate RawPtr in MIR.
let array_ptr_type = Ty::new_ptr(fcx.tcx, m_expr.ty, m_expr.mutbl);
Expand Down
22 changes: 22 additions & 0 deletions tests/ui/cast/cast-alias-of-array-to-element.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//@ check-pass
//@ revisions: current next
//@ ignore-compare-mode-next-solver (explicit revisions)
//@[next] compile-flags: -Znext-solver

// Regression test for <https://github.com/rust-lang/trait-system-refactor-initiative/issues/203>.
// Test that we structually normalize in the hacky `&[T; N] -> *const T` in cast.

trait Mirror {
type Assoc: ?Sized;
}
impl<T: ?Sized> Mirror for T {
type Assoc = T;
}

struct W<'a>(&'a <[f32; 0] as Mirror>::Assoc);

fn foo(x: W<'_>) -> *const f32 {
x.0 as *const f32
}

fn main() {}
Loading