Normalize field before checking PhantomData in coerce/dispatch impl validation
This commit is contained in:
parent
11bc805369
commit
3cd75812c8
2 changed files with 45 additions and 3 deletions
|
@ -260,13 +260,22 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<()
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|field| {
|
.filter(|field| {
|
||||||
// Ignore PhantomData fields
|
// 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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let ty_a = field.ty(tcx, args_a);
|
let ty_a = field.ty(tcx, args_a);
|
||||||
let ty_b = field.ty(tcx, args_b);
|
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 {
|
if ty_a == ty_b {
|
||||||
// Allow 1-ZSTs that don't mention type params.
|
// Allow 1-ZSTs that don't mention type params.
|
||||||
//
|
//
|
||||||
|
@ -469,8 +478,16 @@ pub(crate) fn coerce_unsized_info<'tcx>(
|
||||||
.filter_map(|(i, f)| {
|
.filter_map(|(i, f)| {
|
||||||
let (a, b) = (f.ty(tcx, args_a), f.ty(tcx, args_b));
|
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 fields
|
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;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
25
tests/ui/self/phantomdata-in-coerce-and-dispatch-impls.rs
Normal file
25
tests/ui/self/phantomdata-in-coerce-and-dispatch-impls.rs
Normal file
|
@ -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() {}
|
Loading…
Add table
Add a link
Reference in a new issue