Allow dropping dyn principal
This commit is contained in:
parent
3a85d3fa78
commit
e3800a1a04
10 changed files with 83 additions and 35 deletions
|
|
@ -34,7 +34,9 @@ pub(crate) fn unsized_info<'tcx>(
|
|||
{
|
||||
let old_info =
|
||||
old_info.expect("unsized_info: missing old info for trait upcasting coercion");
|
||||
if data_a.principal_def_id() == data_b.principal_def_id() {
|
||||
let b_principal_def_id = data_b.principal_def_id();
|
||||
if data_a.principal_def_id() == b_principal_def_id || b_principal_def_id.is_none() {
|
||||
// A NOP cast that doesn't actually change anything, should be allowed even with invalid vtables.
|
||||
debug_assert!(
|
||||
validate_trivial_unsize(fx.tcx, data_a, data_b),
|
||||
"NOP unsize vtable changed principal trait ref: {data_a} -> {data_b}"
|
||||
|
|
|
|||
|
|
@ -147,7 +147,7 @@ pub fn validate_trivial_unsize<'tcx>(
|
|||
infcx.leak_check(universe, None).is_ok()
|
||||
})
|
||||
}
|
||||
(None, None) => true,
|
||||
(_, None) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
|
@ -175,7 +175,8 @@ fn unsized_info<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
|
|||
{
|
||||
let old_info =
|
||||
old_info.expect("unsized_info: missing old info for trait upcasting coercion");
|
||||
if data_a.principal_def_id() == data_b.principal_def_id() {
|
||||
let b_principal_def_id = data_b.principal_def_id();
|
||||
if data_a.principal_def_id() == b_principal_def_id || b_principal_def_id.is_none() {
|
||||
// Codegen takes advantage of the additional assumption, where if the
|
||||
// principal trait def id of what's being casted doesn't change,
|
||||
// then we don't need to adjust the vtable at all. This
|
||||
|
|
|
|||
|
|
@ -785,7 +785,8 @@ where
|
|||
let mut responses = vec![];
|
||||
// If the principal def ids match (or are both none), then we're not doing
|
||||
// trait upcasting. We're just removing auto traits (or shortening the lifetime).
|
||||
if a_data.principal_def_id() == b_data.principal_def_id() {
|
||||
let b_principal_def_id = b_data.principal_def_id();
|
||||
if a_data.principal_def_id() == b_principal_def_id || b_principal_def_id.is_none() {
|
||||
responses.extend(self.consider_builtin_upcast_to_principal(
|
||||
goal,
|
||||
CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
|
||||
|
|
|
|||
|
|
@ -1018,7 +1018,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
// #2 (region bounds).
|
||||
let principal_def_id_a = a_data.principal_def_id();
|
||||
let principal_def_id_b = b_data.principal_def_id();
|
||||
if principal_def_id_a == principal_def_id_b {
|
||||
if principal_def_id_a == principal_def_id_b || principal_def_id_b.is_none() {
|
||||
// We may upcast to auto traits that are either explicitly listed in
|
||||
// the object type's bounds, or implied by the principal trait ref's
|
||||
// supertraits.
|
||||
|
|
|
|||
|
|
@ -1153,6 +1153,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
// We already checked the compatibility of auto traits within `assemble_candidates_for_unsizing`.
|
||||
let iter = data_a
|
||||
.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))
|
||||
.into_iter()
|
||||
.chain(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue