1
Fork 0

Disable dyn* upcasting

This commit is contained in:
Michael Goulet 2022-11-19 04:48:01 +00:00
parent 70f8737b2f
commit c620a972f3
7 changed files with 75 additions and 35 deletions

View file

@ -755,20 +755,9 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
if let ty::Dynamic(a_data, _, _) = a.kind()
&& let ty::Dynamic(b_data, _, _) = b.kind()
&& a_data.principal_def_id() == b_data.principal_def_id()
{
if a_data.principal_def_id() == b_data.principal_def_id() {
return self.unify_and(a, b, |_| vec![]);
} else if !self.tcx().features().trait_upcasting {
let mut err = feature_err(
&self.tcx.sess.parse_sess,
sym::trait_upcasting,
self.cause.span,
&format!(
"cannot cast `{a}` to `{b}`, trait upcasting coercion is experimental"
),
);
err.emit();
}
return self.unify_and(a, b, |_| vec![]);
}
// Check the obligations of the cast -- for example, when casting
@ -796,19 +785,16 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
])
.collect();
// Enforce that the type is `usize`/pointer-sized. For now, only those
// can be coerced to `dyn*`, except for `dyn* -> dyn*` upcasts.
if !a.is_dyn_star() {
obligations.push(Obligation::new(
self.tcx,
self.cause.clone(),
self.param_env,
ty::Binder::dummy(
self.tcx.at(self.cause.span).mk_trait_ref(hir::LangItem::PointerSized, [a]),
)
.to_poly_trait_predicate(),
));
}
// Enforce that the type is `usize`/pointer-sized.
obligations.push(Obligation::new(
self.tcx,
self.cause.clone(),
self.param_env,
ty::Binder::dummy(
self.tcx.at(self.cause.span).mk_trait_ref(hir::LangItem::PointerSized, [a]),
)
.to_poly_trait_predicate(),
));
Ok(InferOk {
value: (vec![Adjustment { kind: Adjust::DynStar, target: b }], b),

View file

@ -776,9 +776,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
match (source.kind(), target.kind()) {
// Trait+Kx+'a -> Trait+Ky+'b (upcasts).
(&ty::Dynamic(ref data_a, _, dyn_a), &ty::Dynamic(ref data_b, _, dyn_b))
if dyn_a == dyn_b =>
{
(&ty::Dynamic(ref data_a, _, ty::Dyn), &ty::Dynamic(ref data_b, _, ty::Dyn)) => {
// Upcast coercions permit several things:
//
// 1. Dropping auto traits, e.g., `Foo + Send` to `Foo`

View file

@ -803,9 +803,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let upcast_trait_ref;
match (source.kind(), target.kind()) {
// TraitA+Kx+'a -> TraitB+Ky+'b (trait upcasting coercion).
(&ty::Dynamic(ref data_a, r_a, repr_a), &ty::Dynamic(ref data_b, r_b, repr_b))
if repr_a == repr_b =>
{
(
&ty::Dynamic(ref data_a, r_a, repr_a @ ty::Dyn),
&ty::Dynamic(ref data_b, r_b, ty::Dyn),
) => {
// See `assemble_candidates_for_unsizing` for more info.
// We already checked the compatibility of auto traits within `assemble_candidates_for_unsizing`.
let principal_a = data_a.principal().unwrap();
@ -831,7 +832,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
.map(ty::Binder::dummy),
);
let existential_predicates = tcx.mk_poly_existential_predicates(iter);
let source_trait = tcx.mk_dynamic(existential_predicates, r_b, repr_b);
let source_trait = tcx.mk_dynamic(existential_predicates, r_b, repr_a);
// Require that the traits involved in this upcast are **equal**;
// only the **lifetime bound** is changed.