Skip to content

Commit e0fb6eb

Browse files
Nits
1 parent c957c4e commit e0fb6eb

File tree

1 file changed

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

1 file changed

+72
-71
lines changed

compiler/rustc_borrowck/src/type_check/mod.rs

Lines changed: 72 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1456,78 +1456,79 @@ 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 {
1463+
unreachable!();
1464+
};
14611465

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

0 commit comments

Comments
 (0)