Normalize struct types in confirm_builtin_unsize_candidate
This commit is contained in:
parent
6153d3cbe6
commit
7893ca74e5
@ -1039,9 +1039,25 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
return Err(Unimplemented);
|
return Err(Unimplemented);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract `TailField<T>` and `TailField<U>` from `Struct<T>` and `Struct<U>`.
|
// Extract `TailField<T>` and `TailField<U>` from `Struct<T>` and `Struct<U>`,
|
||||||
let source_tail = tail_field_ty.subst(tcx, substs_a);
|
// normalizing in the process, since `type_of` returns something directly from
|
||||||
let target_tail = tail_field_ty.subst(tcx, substs_b);
|
// astconv (which means it's un-normalized).
|
||||||
|
let source_tail = normalize_with_depth_to(
|
||||||
|
self,
|
||||||
|
obligation.param_env,
|
||||||
|
obligation.cause.clone(),
|
||||||
|
obligation.recursion_depth + 1,
|
||||||
|
tail_field_ty.subst(tcx, substs_a),
|
||||||
|
&mut nested,
|
||||||
|
);
|
||||||
|
let target_tail = normalize_with_depth_to(
|
||||||
|
self,
|
||||||
|
obligation.param_env,
|
||||||
|
obligation.cause.clone(),
|
||||||
|
obligation.recursion_depth + 1,
|
||||||
|
tail_field_ty.subst(tcx, substs_b),
|
||||||
|
&mut nested,
|
||||||
|
);
|
||||||
|
|
||||||
// Check that the source struct with the target's
|
// Check that the source struct with the target's
|
||||||
// unsizing parameters is equal to the target.
|
// unsizing parameters is equal to the target.
|
||||||
|
21
src/test/ui/unsized/issue-75899-but-gats.rs
Normal file
21
src/test/ui/unsized/issue-75899-but-gats.rs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
// check-pass
|
||||||
|
|
||||||
|
use std::fmt::Debug;
|
||||||
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
|
trait Foo {
|
||||||
|
type Gat<'a>: ?Sized where Self: 'a;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Bar<'a, T: Foo + 'a>(T::Gat<'a>);
|
||||||
|
|
||||||
|
struct Baz<T: ?Sized>(PhantomData<T>);
|
||||||
|
|
||||||
|
impl<T: ?Sized> Foo for Baz<T> {
|
||||||
|
type Gat<'a> = T where Self: 'a;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let x = Bar::<'_, Baz<()>>(());
|
||||||
|
let y: &Bar<'_, Baz<dyn Debug>> = &x;
|
||||||
|
}
|
18
src/test/ui/unsized/issue-75899.rs
Normal file
18
src/test/ui/unsized/issue-75899.rs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
// check-pass
|
||||||
|
|
||||||
|
trait Trait {}
|
||||||
|
impl<T> Trait for T {}
|
||||||
|
|
||||||
|
trait Noop {
|
||||||
|
type Assoc: ?Sized;
|
||||||
|
}
|
||||||
|
impl<T: ?Sized> Noop for T {
|
||||||
|
type Assoc = T;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct NoopNewtype<T: ?Sized + Noop>(T::Assoc);
|
||||||
|
fn coerce_newtype<T: Trait>(x: &NoopNewtype<T>) -> &NoopNewtype<dyn Trait + '_> {
|
||||||
|
x
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
Loading…
x
Reference in New Issue
Block a user