Skip to content

Commit 24eefd0

Browse files
Make sure to detect trait upcasting coercion even after normalization
1 parent 7e66c0b commit 24eefd0

File tree

4 files changed

+20
-29
lines changed

4 files changed

+20
-29
lines changed

compiler/rustc_hir_typeck/src/coercion.rs

Lines changed: 9 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -622,7 +622,6 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
622622
ty::TraitRef::new(self.tcx, coerce_unsized_did, [coerce_source, coerce_target])
623623
)];
624624

625-
let mut has_unsized_tuple_coercion = false;
626625
let mut has_trait_upcasting_coercion = None;
627626

628627
// Keep resolving `CoerceUnsized` and `Unsize` predicates to avoid
@@ -636,29 +635,14 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
636635
Some(ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred)))
637636
if traits.contains(&trait_pred.def_id()) =>
638637
{
639-
let trait_pred = self.resolve_vars_if_possible(trait_pred);
640-
if unsize_did == trait_pred.def_id() {
641-
let self_ty = trait_pred.self_ty();
642-
let unsize_ty = trait_pred.trait_ref.args[1].expect_ty();
643-
if let (ty::Dynamic(ref data_a, ..), ty::Dynamic(ref data_b, ..)) =
644-
(self_ty.kind(), unsize_ty.kind())
645-
&& data_a.principal_def_id() != data_b.principal_def_id()
646-
{
647-
debug!("coerce_unsized: found trait upcasting coercion");
648-
has_trait_upcasting_coercion = Some((self_ty, unsize_ty));
649-
}
650-
if let ty::Tuple(..) = unsize_ty.kind() {
651-
debug!("coerce_unsized: found unsized tuple coercion");
652-
has_unsized_tuple_coercion = true;
653-
}
654-
}
655638
trait_pred
656639
}
657640
_ => {
658641
coercion.obligations.push(obligation);
659642
continue;
660643
}
661644
};
645+
let trait_pred = self.resolve_vars_if_possible(trait_pred);
662646
match selcx.select(&obligation.with(selcx.tcx(), trait_pred)) {
663647
// Uncertain or unimplemented.
664648
Ok(None) => {
@@ -701,18 +685,15 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
701685
// be silent, as it causes a type mismatch later.
702686
}
703687

704-
Ok(Some(impl_source)) => queue.extend(impl_source.nested_obligations()),
705-
}
706-
}
688+
Ok(Some(impl_source)) => {
689+
if matches!(impl_source, traits::ImplSource::TraitUpcasting(..)) {
690+
has_trait_upcasting_coercion =
691+
Some((trait_pred.self_ty(), trait_pred.trait_ref.args.type_at(1)));
692+
}
707693

708-
if has_unsized_tuple_coercion && !self.tcx.features().unsized_tuple_coercion {
709-
feature_err(
710-
&self.tcx.sess.parse_sess,
711-
sym::unsized_tuple_coercion,
712-
self.cause.span,
713-
"unsized tuple coercion is not stable enough for use and is subject to change",
714-
)
715-
.emit();
694+
queue.extend(impl_source.nested_obligations())
695+
}
696+
}
716697
}
717698

718699
if let Some((sub, sup)) = has_trait_upcasting_coercion

compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,13 @@ fn rematch_object<'tcx>(
315315
// If we're upcasting, get the offset of the vtable pointer, otherwise get
316316
// the base of the vtable.
317317
Ok(Some(if is_upcasting {
318-
ImplSource::TraitUpcasting(ImplSourceTraitUpcastingData { vtable_vptr_slot, nested })
318+
// If source and target trait def ids are identical,
319+
// then we are simply removing auto traits.
320+
if source_trait_ref.def_id() == target_trait_ref.def_id() {
321+
ImplSource::Builtin(nested)
322+
} else {
323+
ImplSource::TraitUpcasting(ImplSourceTraitUpcastingData { vtable_vptr_slot, nested })
324+
}
319325
} else {
320326
ImplSource::Object(ImplSourceObjectData { vtable_base, nested })
321327
}))

tests/ui/traits/new-solver/normalize-unsize-rhs.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// compile-flags: -Ztrait-solver=next
22
// check-pass
33

4+
#![feature(trait_upcasting)]
5+
46
trait A {}
57
trait B: A {}
68

tests/ui/traits/new-solver/trait-upcast-lhs-needs-normalization.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// check-pass
22
// compile-flags: -Ztrait-solver=next
33

4+
#![feature(trait_upcasting)]
5+
46
pub trait A {}
57
pub trait B: A {}
68

0 commit comments

Comments
 (0)