Skip to content

Commit

Permalink
Normalize field before checking PhantomData in coerce/dispatch impl v…
Browse files Browse the repository at this point in the history
…alidation
  • Loading branch information
compiler-errors committed Jan 8, 2025
1 parent 11bc805 commit f47c58f
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 3 deletions.
23 changes: 20 additions & 3 deletions compiler/rustc_hir_analysis/src/coherence/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -260,13 +260,22 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<()
.iter()
.filter(|field| {
// Ignore PhantomData fields
if tcx.type_of(field.did).instantiate_identity().is_phantom_data() {
let unnormalized_ty = tcx.type_of(field.did).instantiate_identity();
if tcx
.try_normalize_erasing_regions(
ty::TypingEnv::non_body_analysis(tcx, def_a.did()),
unnormalized_ty,
)
.unwrap_or(unnormalized_ty)
.is_phantom_data()
{
return false;
}

let ty_a = field.ty(tcx, args_a);
let ty_b = field.ty(tcx, args_b);

// FIXME: We could do normalization here, but is it really worth it?
if ty_a == ty_b {
// Allow 1-ZSTs that don't mention type params.
//
Expand Down Expand Up @@ -469,8 +478,16 @@ pub(crate) fn coerce_unsized_info<'tcx>(
.filter_map(|(i, f)| {
let (a, b) = (f.ty(tcx, args_a), f.ty(tcx, args_b));

if tcx.type_of(f.did).instantiate_identity().is_phantom_data() {
// Ignore PhantomData fields
// Ignore PhantomData fielzds
let unnormalized_ty = tcx.type_of(f.did).instantiate_identity();
if tcx
.try_normalize_erasing_regions(
ty::TypingEnv::non_body_analysis(tcx, def_a.did()),
unnormalized_ty,
)
.unwrap_or(unnormalized_ty)
.is_phantom_data()
{
return None;
}

Expand Down
25 changes: 25 additions & 0 deletions tests/ui/self/phantomdata-in-coerce-and-dispatch-impls.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//@ check-pass

#![feature(coerce_unsized, dispatch_from_dyn, unsize)]

use std::marker::Unsize;
use std::ops::{CoerceUnsized, DispatchFromDyn};
use std::marker::PhantomData;

trait Mirror {
type Assoc;
}
impl<T> Mirror for T {
type Assoc = T;
}

struct W<T: 'static> {
t: &'static T,
f: <PhantomData<T> as Mirror>::Assoc,
}

impl<T, U> CoerceUnsized<W<U>> for W<T> where T: Unsize<U> {}

impl<T, U> DispatchFromDyn<W<U>> for W<T> where T: Unsize<U> {}

fn main() {}

0 comments on commit f47c58f

Please sign in to comment.