Skip to content

Commit d8415b1

Browse files
author
Lukas Markeffsky
committed
[NFC] clean up pointer cast typeck code
1 parent 81eec23 commit d8415b1

File tree

1 file changed

+51
-50
lines changed
  • compiler/rustc_hir_typeck/src

1 file changed

+51
-50
lines changed

compiler/rustc_hir_typeck/src/cast.rs

+51-50
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
//! * `e` has type `T` and `T` coerces to `U`; *coercion-cast*
55
//! * `e` has type `*T`, `U` is `*U_0`, and either `U_0: Sized` or
66
//! pointer_kind(`T`) = pointer_kind(`U_0`); *ptr-ptr-cast*
7-
//! * `e` has type `*T` and `U` is a numeric type, while `T: Sized`; *ptr-addr-cast*
7+
//! * `e` has type `*T` and `U` is an integer type, while `T: Sized`; *ptr-addr-cast*
88
//! * `e` is an integer and `U` is `*U_0`, while `U_0: Sized`; *addr-ptr-cast*
99
//! * `e` has type `T` and `T` and `U` are any numeric types; *numeric-cast*
1010
//! * `e` is a C-like enum and `U` is an integer type; *enum-cast*
@@ -689,7 +689,12 @@ impl<'a, 'tcx> CastCheck<'tcx> {
689689
if !fcx.type_is_sized_modulo_regions(fcx.param_env, mt.ty) {
690690
return Err(CastError::IllegalCast);
691691
}
692-
self.check_ref_cast(fcx, TypeAndMut { mutbl, ty: inner_ty }, mt)
692+
self.check_array_ptr_cast(
693+
fcx,
694+
TypeAndMut { mutbl, ty: inner_ty },
695+
mt,
696+
)?;
697+
Ok(CastKind::ArrayPtrCast)
693698
}
694699
_ => Err(CastError::NonScalar),
695700
};
@@ -724,25 +729,33 @@ impl<'a, 'tcx> CastCheck<'tcx> {
724729
Err(CastError::IllegalCast)
725730
}
726731

727-
// ptr -> *
728-
(Ptr(m_e), Ptr(m_c)) => self.check_ptr_ptr_cast(fcx, m_e, m_c), // ptr-ptr-cast
729-
732+
// ptr-ptr-cast
733+
(Ptr(m_e), Ptr(m_c)) => {
734+
self.check_ptr_ptr_cast(fcx, m_e.ty, m_c.ty)?;
735+
Ok(CastKind::PtrPtrCast)
736+
}
730737
// ptr-addr-cast
731738
(Ptr(m_expr), Int(t_c)) => {
732739
self.lossy_provenance_ptr2int_lint(fcx, t_c);
733-
self.check_ptr_addr_cast(fcx, m_expr)
740+
self.check_ptr_addr_cast(fcx, m_expr.ty)?;
741+
Ok(CastKind::PtrAddrCast)
734742
}
743+
// fptr-addr-cast
735744
(FnPtr, Int(_)) => {
736745
// FIXME(#95489): there should eventually be a lint for these casts
737746
Ok(CastKind::FnPtrAddrCast)
738747
}
739748
// addr-ptr-cast
740749
(Int(_), Ptr(mt)) => {
741750
self.fuzzy_provenance_int2ptr_lint(fcx);
742-
self.check_addr_ptr_cast(fcx, mt)
751+
self.check_addr_ptr_cast(fcx, mt.ty)?;
752+
Ok(CastKind::AddrPtrCast)
753+
}
754+
// fptr-ptr-cast
755+
(FnPtr, Ptr(mt)) => {
756+
self.check_fptr_ptr_cast(fcx, mt.ty)?;
757+
Ok(CastKind::FnPtrPtrCast)
743758
}
744-
// fn-ptr-cast
745-
(FnPtr, Ptr(mt)) => self.check_fptr_ptr_cast(fcx, mt),
746759

747760
// prim -> prim
748761
(Int(CEnum), Int(_)) => {
@@ -765,17 +778,17 @@ impl<'a, 'tcx> CastCheck<'tcx> {
765778
}
766779
}
767780

781+
/// ptr-ptr-cast. metadata must match.
768782
fn check_ptr_ptr_cast(
769783
&self,
770784
fcx: &FnCtxt<'a, 'tcx>,
771-
m_expr: ty::TypeAndMut<'tcx>,
772-
m_cast: ty::TypeAndMut<'tcx>,
773-
) -> Result<CastKind, CastError> {
774-
debug!("check_ptr_ptr_cast m_expr={:?} m_cast={:?}", m_expr, m_cast);
775-
// ptr-ptr cast. vtables must match.
785+
expr: Ty<'tcx>,
786+
cast: Ty<'tcx>,
787+
) -> Result<(), CastError> {
788+
debug!(?expr, ?cast, "check_ptr_ptr_cast");
776789

777-
let expr_kind = fcx.pointer_kind(m_expr.ty, self.span)?;
778-
let cast_kind = fcx.pointer_kind(m_cast.ty, self.span)?;
790+
let expr_kind = fcx.pointer_kind(expr, self.span)?;
791+
let cast_kind = fcx.pointer_kind(cast, self.span)?;
779792

780793
let Some(cast_kind) = cast_kind else {
781794
// We can't cast if target pointer kind is unknown
@@ -784,7 +797,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
784797

785798
// Cast to thin pointer is OK
786799
if cast_kind == PointerKind::Thin {
787-
return Ok(CastKind::PtrPtrCast);
800+
return Ok(());
788801
}
789802

790803
let Some(expr_kind) = expr_kind else {
@@ -799,56 +812,48 @@ impl<'a, 'tcx> CastCheck<'tcx> {
799812

800813
// vtable kinds must match
801814
if fcx.tcx.erase_regions(cast_kind) == fcx.tcx.erase_regions(expr_kind) {
802-
Ok(CastKind::PtrPtrCast)
815+
Ok(())
803816
} else {
804817
Err(CastError::DifferingKinds)
805818
}
806819
}
807820

808-
fn check_fptr_ptr_cast(
809-
&self,
810-
fcx: &FnCtxt<'a, 'tcx>,
811-
m_cast: ty::TypeAndMut<'tcx>,
812-
) -> Result<CastKind, CastError> {
813-
// fptr-ptr cast. must be to thin ptr
814-
815-
match fcx.pointer_kind(m_cast.ty, self.span)? {
821+
/// fptr-ptr-cast. target must be thin.
822+
fn check_fptr_ptr_cast(&self, fcx: &FnCtxt<'a, 'tcx>, cast: Ty<'tcx>) -> Result<(), CastError> {
823+
match fcx.pointer_kind(cast, self.span)? {
816824
None => Err(CastError::UnknownCastPtrKind),
817-
Some(PointerKind::Thin) => Ok(CastKind::FnPtrPtrCast),
825+
Some(PointerKind::Thin) => Ok(()),
818826
_ => Err(CastError::IllegalCast),
819827
}
820828
}
821829

830+
/// ptr-addr-cast. source must be thin.
822831
fn check_ptr_addr_cast(
823832
&self,
824833
fcx: &FnCtxt<'a, 'tcx>,
825-
m_expr: ty::TypeAndMut<'tcx>,
834+
expr: Ty<'tcx>,
826835
) -> Result<CastKind, CastError> {
827-
// ptr-addr cast. must be from thin ptr
828-
829-
match fcx.pointer_kind(m_expr.ty, self.span)? {
836+
match fcx.pointer_kind(expr, self.span)? {
830837
None => Err(CastError::UnknownExprPtrKind),
831838
Some(PointerKind::Thin) => Ok(CastKind::PtrAddrCast),
832839
_ => Err(CastError::NeedViaThinPtr),
833840
}
834841
}
835842

836-
fn check_ref_cast(
843+
/// array-ptr-cast.
844+
///
845+
/// This is a special case to cast from `&[T; N]` directly to `*const T`.
846+
/// It was added to work around LLVM limitations way before Rust 1.0 and only exists
847+
/// for backwards compatibility now.
848+
fn check_array_ptr_cast(
837849
&self,
838850
fcx: &FnCtxt<'a, 'tcx>,
839851
m_expr: ty::TypeAndMut<'tcx>,
840852
m_cast: ty::TypeAndMut<'tcx>,
841-
) -> Result<CastKind, CastError> {
842-
// array-ptr-cast: allow mut-to-mut, mut-to-const, const-to-const
853+
) -> Result<(), CastError> {
854+
// allow mut-to-mut, mut-to-const, const-to-const
843855
if m_expr.mutbl >= m_cast.mutbl {
844856
if let ty::Array(ety, _) = m_expr.ty.kind() {
845-
// Due to the limitations of LLVM global constants,
846-
// region pointers end up pointing at copies of
847-
// vector elements instead of the original values.
848-
// To allow raw pointers to work correctly, we
849-
// need to special-case obtaining a raw pointer
850-
// from a region pointer to a vector.
851-
852857
// Coerce to a raw pointer so that we generate AddressOf in MIR.
853858
let array_ptr_type = Ty::new_ptr(fcx.tcx, m_expr);
854859
fcx.coerce(self.expr, self.expr_ty, array_ptr_type, AllowTwoPhase::No, None)
@@ -862,22 +867,18 @@ impl<'a, 'tcx> CastCheck<'tcx> {
862867

863868
// this will report a type mismatch if needed
864869
fcx.demand_eqtype(self.span, *ety, m_cast.ty);
865-
return Ok(CastKind::ArrayPtrCast);
870+
return Ok(());
866871
}
867872
}
868873

869874
Err(CastError::IllegalCast)
870875
}
871876

872-
fn check_addr_ptr_cast(
873-
&self,
874-
fcx: &FnCtxt<'a, 'tcx>,
875-
m_cast: TypeAndMut<'tcx>,
876-
) -> Result<CastKind, CastError> {
877-
// ptr-addr cast. pointer must be thin.
878-
match fcx.pointer_kind(m_cast.ty, self.span)? {
877+
/// addr-ptr-cast. target must be thin.
878+
fn check_addr_ptr_cast(&self, fcx: &FnCtxt<'a, 'tcx>, cast: Ty<'tcx>) -> Result<(), CastError> {
879+
match fcx.pointer_kind(cast, self.span)? {
879880
None => Err(CastError::UnknownCastPtrKind),
880-
Some(PointerKind::Thin) => Ok(CastKind::AddrPtrCast),
881+
Some(PointerKind::Thin) => Ok(()),
881882
Some(PointerKind::VTable(_)) => Err(CastError::IntToFatCast(Some("a vtable"))),
882883
Some(PointerKind::Length) => Err(CastError::IntToFatCast(Some("a length"))),
883884
Some(PointerKind::OfAlias(_) | PointerKind::OfParam(_)) => {

0 commit comments

Comments
 (0)