Fix trait upcasting to dyn type with no principal when there are projections
This commit is contained in:
parent
0c478fdfe1
commit
45afefa7c0
2 changed files with 37 additions and 14 deletions
|
@ -1090,12 +1090,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
{
|
{
|
||||||
// See `assemble_candidates_for_unsizing` for more info.
|
// See `assemble_candidates_for_unsizing` for more info.
|
||||||
// We already checked the compatibility of auto traits within `assemble_candidates_for_unsizing`.
|
// We already checked the compatibility of auto traits within `assemble_candidates_for_unsizing`.
|
||||||
let iter = data_a
|
let existential_predicates = if data_b.principal().is_some() {
|
||||||
|
tcx.mk_poly_existential_predicates_from_iter(
|
||||||
|
data_a
|
||||||
.principal()
|
.principal()
|
||||||
.filter(|_| {
|
|
||||||
// optionally drop the principal, if we're unsizing to no principal
|
|
||||||
data_b.principal().is_some()
|
|
||||||
})
|
|
||||||
.map(|b| b.map_bound(ty::ExistentialPredicate::Trait))
|
.map(|b| b.map_bound(ty::ExistentialPredicate::Trait))
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.chain(
|
.chain(
|
||||||
|
@ -1108,8 +1106,20 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
.auto_traits()
|
.auto_traits()
|
||||||
.map(ty::ExistentialPredicate::AutoTrait)
|
.map(ty::ExistentialPredicate::AutoTrait)
|
||||||
.map(ty::Binder::dummy),
|
.map(ty::Binder::dummy),
|
||||||
);
|
),
|
||||||
let existential_predicates = tcx.mk_poly_existential_predicates_from_iter(iter);
|
)
|
||||||
|
} else {
|
||||||
|
// If we're unsizing to a dyn type that has no principal, then drop
|
||||||
|
// the principal and projections from the type. We use the auto traits
|
||||||
|
// from the RHS type since as we noted that we've checked for auto
|
||||||
|
// trait compatibility during unsizing.
|
||||||
|
tcx.mk_poly_existential_predicates_from_iter(
|
||||||
|
data_b
|
||||||
|
.auto_traits()
|
||||||
|
.map(ty::ExistentialPredicate::AutoTrait)
|
||||||
|
.map(ty::Binder::dummy),
|
||||||
|
)
|
||||||
|
};
|
||||||
let source_trait = Ty::new_dynamic(tcx, existential_predicates, r_b, dyn_a);
|
let source_trait = Ty::new_dynamic(tcx, existential_predicates, r_b, dyn_a);
|
||||||
|
|
||||||
// Require that the traits involved in this upcast are **equal**;
|
// Require that the traits involved in this upcast are **equal**;
|
||||||
|
|
13
tests/ui/traits/dyn-drop-principal-with-projections.rs
Normal file
13
tests/ui/traits/dyn-drop-principal-with-projections.rs
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
//@ check-pass
|
||||||
|
|
||||||
|
trait Tr {
|
||||||
|
type Assoc;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Tr for () {
|
||||||
|
type Assoc = ();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let x = &() as &(dyn Tr<Assoc = ()> + Send) as &dyn Send;
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue