Skip to content

Commit 0ee588a

Browse files
Nits
1 parent c957c4e commit 0ee588a

File tree

1 file changed

+70
-71
lines changed
  • compiler/rustc_borrowck/src/type_check

1 file changed

+70
-71
lines changed

compiler/rustc_borrowck/src/type_check/mod.rs

Lines changed: 70 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1456,78 +1456,77 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
14561456
}
14571457
CastKind::PtrToPtr => {
14581458
let ty_from = op.ty(self.body, tcx);
1459-
let cast_ty_from = CastTy::from_ty(ty_from);
1460-
let cast_ty_to = CastTy::from_ty(*ty);
1459+
let Some(CastTy::Ptr(src)) = CastTy::from_ty(ty_from) else {
1460+
unreachable!()
1461+
};
1462+
let Some(CastTy::Ptr(dst)) = CastTy::from_ty(*ty) else { unreachable!() };
1463+
1464+
if self.infcx.type_is_sized_modulo_regions(self.infcx.param_env, dst.ty) {
1465+
// Wide to thin ptr cast. This may even occur in an env with
1466+
// impossible predicates, such as `where dyn Trait: Sized`.
1467+
// In this case, we don't want to fall into the case below,
1468+
// since the types may not actually be equatable, but it's
1469+
// fine to perform this operation in an impossible env.
1470+
let trait_ref = ty::TraitRef::new(
1471+
tcx,
1472+
tcx.require_lang_item(LangItem::Sized, self.last_span),
1473+
[dst.ty],
1474+
);
1475+
self.prove_trait_ref(
1476+
trait_ref,
1477+
location.to_locations(),
1478+
ConstraintCategory::Cast {
1479+
is_implicit_coercion: true,
1480+
unsize_to: None,
1481+
},
1482+
);
1483+
} else if let ty::Dynamic(src_tty, _src_lt, ty::Dyn) =
1484+
*self.struct_tail(src.ty, location).kind()
1485+
&& let ty::Dynamic(dst_tty, dst_lt, ty::Dyn) =
1486+
*self.struct_tail(dst.ty, location).kind()
1487+
&& src_tty.principal().is_some()
1488+
&& dst_tty.principal().is_some()
1489+
{
1490+
// This checks (lifetime part of) vtable validity for pointer casts,
1491+
// which is irrelevant when there are aren't principal traits on
1492+
// both sides (aka only auto traits).
1493+
//
1494+
// Note that other checks (such as denying `dyn Send` -> `dyn
1495+
// Debug`) are in `rustc_hir_typeck`.
1496+
1497+
// Remove auto traits.
1498+
// Auto trait checks are handled in `rustc_hir_typeck` as FCW.
1499+
let src_obj = Ty::new_dynamic(
1500+
tcx,
1501+
tcx.mk_poly_existential_predicates(
1502+
&src_tty.without_auto_traits().collect::<Vec<_>>(),
1503+
),
1504+
// FIXME: Once we disallow casting `*const dyn Trait + 'short`
1505+
// to `*const dyn Trait + 'long`, then this can just be `src_lt`.
1506+
dst_lt,
1507+
ty::Dyn,
1508+
);
1509+
let dst_obj = Ty::new_dynamic(
1510+
tcx,
1511+
tcx.mk_poly_existential_predicates(
1512+
&dst_tty.without_auto_traits().collect::<Vec<_>>(),
1513+
),
1514+
dst_lt,
1515+
ty::Dyn,
1516+
);
14611517

1462-
match (cast_ty_from, cast_ty_to) {
1463-
(Some(CastTy::Ptr(src)), Some(CastTy::Ptr(dst))) => {
1464-
if self
1465-
.infcx
1466-
.type_is_sized_modulo_regions(self.infcx.param_env, dst.ty)
1467-
{
1468-
// Wide to thin ptr cast. This may even occur in an env with
1469-
// impossible predicates, such as `where dyn Trait: Sized`.
1470-
// In this case, we don't want to fall into the case below,
1471-
// since the types may not actually be equatable, but it's
1472-
// fine to perform this operation in an impossible env.
1473-
} else if let ty::Dynamic(src_tty, _src_lt, ty::Dyn) =
1474-
*self.struct_tail(src.ty, location).kind()
1475-
&& let ty::Dynamic(dst_tty, dst_lt, ty::Dyn) =
1476-
*self.struct_tail(dst.ty, location).kind()
1477-
&& src_tty.principal().is_some()
1478-
&& dst_tty.principal().is_some()
1479-
{
1480-
// This checks (lifetime part of) vtable validity for pointer casts,
1481-
// which is irrelevant when there are aren't principal traits on
1482-
// both sides (aka only auto traits).
1483-
//
1484-
// Note that other checks (such as denying `dyn Send` -> `dyn
1485-
// Debug`) are in `rustc_hir_typeck`.
1486-
1487-
// Remove auto traits.
1488-
// Auto trait checks are handled in `rustc_hir_typeck` as FCW.
1489-
let src_obj = Ty::new_dynamic(
1490-
tcx,
1491-
tcx.mk_poly_existential_predicates(
1492-
&src_tty.without_auto_traits().collect::<Vec<_>>(),
1493-
),
1494-
// FIXME: Once we disallow casting `*const dyn Trait + 'short`
1495-
// to `*const dyn Trait + 'long`, then this can just be `src_lt`.
1496-
dst_lt,
1497-
ty::Dyn,
1498-
);
1499-
let dst_obj = Ty::new_dynamic(
1500-
tcx,
1501-
tcx.mk_poly_existential_predicates(
1502-
&dst_tty.without_auto_traits().collect::<Vec<_>>(),
1503-
),
1504-
dst_lt,
1505-
ty::Dyn,
1506-
);
1507-
1508-
debug!(?src_tty, ?dst_tty, ?src_obj, ?dst_obj);
1509-
1510-
self.sub_types(
1511-
src_obj,
1512-
dst_obj,
1513-
location.to_locations(),
1514-
ConstraintCategory::Cast {
1515-
is_implicit_coercion: false,
1516-
unsize_to: None,
1517-
},
1518-
)
1519-
.unwrap();
1520-
}
1521-
}
1522-
_ => {
1523-
span_mirbug!(
1524-
self,
1525-
rvalue,
1526-
"Invalid PtrToPtr cast {:?} -> {:?}",
1527-
ty_from,
1528-
ty
1529-
)
1530-
}
1518+
debug!(?src_tty, ?dst_tty, ?src_obj, ?dst_obj);
1519+
1520+
self.sub_types(
1521+
src_obj,
1522+
dst_obj,
1523+
location.to_locations(),
1524+
ConstraintCategory::Cast {
1525+
is_implicit_coercion: false,
1526+
unsize_to: None,
1527+
},
1528+
)
1529+
.unwrap();
15311530
}
15321531
}
15331532
CastKind::Transmute => {

0 commit comments

Comments
 (0)