Nits
This commit is contained in:
parent
c957c4e704
commit
e0fb6ebf7b
1 changed files with 69 additions and 68 deletions
|
|
@ -1456,78 +1456,79 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
|||
}
|
||||
CastKind::PtrToPtr => {
|
||||
let ty_from = op.ty(self.body, tcx);
|
||||
let cast_ty_from = CastTy::from_ty(ty_from);
|
||||
let cast_ty_to = CastTy::from_ty(*ty);
|
||||
let Some(CastTy::Ptr(src)) = CastTy::from_ty(ty_from) else {
|
||||
unreachable!();
|
||||
};
|
||||
let Some(CastTy::Ptr(dst)) = CastTy::from_ty(*ty) else {
|
||||
unreachable!();
|
||||
};
|
||||
|
||||
match (cast_ty_from, cast_ty_to) {
|
||||
(Some(CastTy::Ptr(src)), Some(CastTy::Ptr(dst))) => {
|
||||
if self
|
||||
.infcx
|
||||
.type_is_sized_modulo_regions(self.infcx.param_env, dst.ty)
|
||||
{
|
||||
// Wide to thin ptr cast. This may even occur in an env with
|
||||
// impossible predicates, such as `where dyn Trait: Sized`.
|
||||
// In this case, we don't want to fall into the case below,
|
||||
// since the types may not actually be equatable, but it's
|
||||
// fine to perform this operation in an impossible env.
|
||||
} else if let ty::Dynamic(src_tty, _src_lt, ty::Dyn) =
|
||||
*self.struct_tail(src.ty, location).kind()
|
||||
&& let ty::Dynamic(dst_tty, dst_lt, ty::Dyn) =
|
||||
*self.struct_tail(dst.ty, location).kind()
|
||||
&& src_tty.principal().is_some()
|
||||
&& dst_tty.principal().is_some()
|
||||
{
|
||||
// This checks (lifetime part of) vtable validity for pointer casts,
|
||||
// which is irrelevant when there are aren't principal traits on
|
||||
// both sides (aka only auto traits).
|
||||
//
|
||||
// Note that other checks (such as denying `dyn Send` -> `dyn
|
||||
// Debug`) are in `rustc_hir_typeck`.
|
||||
if self.infcx.type_is_sized_modulo_regions(self.infcx.param_env, dst.ty) {
|
||||
// Wide to thin ptr cast. This may even occur in an env with
|
||||
// impossible predicates, such as `where dyn Trait: Sized`.
|
||||
// In this case, we don't want to fall into the case below,
|
||||
// since the types may not actually be equatable, but it's
|
||||
// fine to perform this operation in an impossible env.
|
||||
let trait_ref = ty::TraitRef::new(
|
||||
tcx,
|
||||
tcx.require_lang_item(LangItem::Sized, self.last_span),
|
||||
[dst.ty],
|
||||
);
|
||||
self.prove_trait_ref(
|
||||
trait_ref,
|
||||
location.to_locations(),
|
||||
ConstraintCategory::Cast {
|
||||
is_implicit_coercion: true,
|
||||
unsize_to: None,
|
||||
},
|
||||
);
|
||||
} else if let ty::Dynamic(src_tty, _src_lt, ty::Dyn) =
|
||||
*self.struct_tail(src.ty, location).kind()
|
||||
&& let ty::Dynamic(dst_tty, dst_lt, ty::Dyn) =
|
||||
*self.struct_tail(dst.ty, location).kind()
|
||||
&& src_tty.principal().is_some()
|
||||
&& dst_tty.principal().is_some()
|
||||
{
|
||||
// This checks (lifetime part of) vtable validity for pointer casts,
|
||||
// which is irrelevant when there are aren't principal traits on
|
||||
// both sides (aka only auto traits).
|
||||
//
|
||||
// Note that other checks (such as denying `dyn Send` -> `dyn
|
||||
// Debug`) are in `rustc_hir_typeck`.
|
||||
|
||||
// Remove auto traits.
|
||||
// Auto trait checks are handled in `rustc_hir_typeck` as FCW.
|
||||
let src_obj = Ty::new_dynamic(
|
||||
tcx,
|
||||
tcx.mk_poly_existential_predicates(
|
||||
&src_tty.without_auto_traits().collect::<Vec<_>>(),
|
||||
),
|
||||
// FIXME: Once we disallow casting `*const dyn Trait + 'short`
|
||||
// to `*const dyn Trait + 'long`, then this can just be `src_lt`.
|
||||
dst_lt,
|
||||
ty::Dyn,
|
||||
);
|
||||
let dst_obj = Ty::new_dynamic(
|
||||
tcx,
|
||||
tcx.mk_poly_existential_predicates(
|
||||
&dst_tty.without_auto_traits().collect::<Vec<_>>(),
|
||||
),
|
||||
dst_lt,
|
||||
ty::Dyn,
|
||||
);
|
||||
// Remove auto traits.
|
||||
// Auto trait checks are handled in `rustc_hir_typeck` as FCW.
|
||||
let src_obj = Ty::new_dynamic(
|
||||
tcx,
|
||||
tcx.mk_poly_existential_predicates(
|
||||
&src_tty.without_auto_traits().collect::<Vec<_>>(),
|
||||
),
|
||||
// FIXME: Once we disallow casting `*const dyn Trait + 'short`
|
||||
// to `*const dyn Trait + 'long`, then this can just be `src_lt`.
|
||||
dst_lt,
|
||||
ty::Dyn,
|
||||
);
|
||||
let dst_obj = Ty::new_dynamic(
|
||||
tcx,
|
||||
tcx.mk_poly_existential_predicates(
|
||||
&dst_tty.without_auto_traits().collect::<Vec<_>>(),
|
||||
),
|
||||
dst_lt,
|
||||
ty::Dyn,
|
||||
);
|
||||
|
||||
debug!(?src_tty, ?dst_tty, ?src_obj, ?dst_obj);
|
||||
debug!(?src_tty, ?dst_tty, ?src_obj, ?dst_obj);
|
||||
|
||||
self.sub_types(
|
||||
src_obj,
|
||||
dst_obj,
|
||||
location.to_locations(),
|
||||
ConstraintCategory::Cast {
|
||||
is_implicit_coercion: false,
|
||||
unsize_to: None,
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
span_mirbug!(
|
||||
self,
|
||||
rvalue,
|
||||
"Invalid PtrToPtr cast {:?} -> {:?}",
|
||||
ty_from,
|
||||
ty
|
||||
)
|
||||
}
|
||||
self.sub_types(
|
||||
src_obj,
|
||||
dst_obj,
|
||||
location.to_locations(),
|
||||
ConstraintCategory::Cast {
|
||||
is_implicit_coercion: false,
|
||||
unsize_to: None,
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
CastKind::Transmute => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue