Allow dropping dyn principal

This commit is contained in:
Michael Goulet 2023-08-09 00:31:26 +00:00 committed by Maybe Lapkin
parent 3a85d3fa78
commit e3800a1a04
10 changed files with 83 additions and 35 deletions

View file

@ -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}"

View file

@ -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

View file

@ -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),

View file

@ -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.

View file

@ -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(