Auto merge of #106938 - GuillaumeGomez:normalize-projection-field-ty, r=oli-obk
Add missing normalization for union fields types Overshadows https://github.com/rust-lang/rust/pull/106808. From the experiment https://github.com/rust-lang/rust/pull/103985. In short, it allows to use projections as a type for union's fields. cc `@compiler-errors` r? `@oli-obk`
This commit is contained in:
commit
c40919b7a7
@ -121,7 +121,7 @@ fn allowed_union_field<'tcx>(
|
|||||||
|
|
||||||
let param_env = tcx.param_env(item_def_id);
|
let param_env = tcx.param_env(item_def_id);
|
||||||
for field in &def.non_enum_variant().fields {
|
for field in &def.non_enum_variant().fields {
|
||||||
let field_ty = field.ty(tcx, substs);
|
let field_ty = tcx.normalize_erasing_regions(param_env, field.ty(tcx, substs));
|
||||||
|
|
||||||
if !allowed_union_field(field_ty, tcx, param_env) {
|
if !allowed_union_field(field_ty, tcx, param_env) {
|
||||||
let (field_span, ty_span) = match tcx.hir().get_if_local(field.did) {
|
let (field_span, ty_span) = match tcx.hir().get_if_local(field.did) {
|
||||||
|
20
tests/ui/union/projection-as-union-type-error-2.rs
Normal file
20
tests/ui/union/projection-as-union-type-error-2.rs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
// Test to ensure that there is no ICE when normalizing a projection
|
||||||
|
// which is invalid (from <https://github.com/rust-lang/rust/pull/106938>).
|
||||||
|
|
||||||
|
#![crate_type = "lib"]
|
||||||
|
|
||||||
|
trait Identity {
|
||||||
|
type Identity;
|
||||||
|
}
|
||||||
|
trait NotImplemented {}
|
||||||
|
|
||||||
|
impl<T: NotImplemented> Identity for T {
|
||||||
|
type Identity = Self;
|
||||||
|
}
|
||||||
|
|
||||||
|
type Foo = u8;
|
||||||
|
|
||||||
|
union Bar {
|
||||||
|
a: <Foo as Identity>::Identity, //~ ERROR
|
||||||
|
b: u8,
|
||||||
|
}
|
17
tests/ui/union/projection-as-union-type-error-2.stderr
Normal file
17
tests/ui/union/projection-as-union-type-error-2.stderr
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
error[E0277]: the trait bound `u8: NotImplemented` is not satisfied
|
||||||
|
--> $DIR/projection-as-union-type-error-2.rs:18:8
|
||||||
|
|
|
||||||
|
LL | a: <Foo as Identity>::Identity,
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NotImplemented` is not implemented for `u8`
|
||||||
|
|
|
||||||
|
note: required for `u8` to implement `Identity`
|
||||||
|
--> $DIR/projection-as-union-type-error-2.rs:11:25
|
||||||
|
|
|
||||||
|
LL | impl<T: NotImplemented> Identity for T {
|
||||||
|
| -------------- ^^^^^^^^ ^
|
||||||
|
| |
|
||||||
|
| unsatisfied trait bound introduced here
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
15
tests/ui/union/projection-as-union-type-error.rs
Normal file
15
tests/ui/union/projection-as-union-type-error.rs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
// Test to ensure that there is no ICE when normalizing a projection
|
||||||
|
// which is invalid (from <https://github.com/rust-lang/rust/pull/106938>).
|
||||||
|
|
||||||
|
#![crate_type = "lib"]
|
||||||
|
|
||||||
|
pub trait Identity {
|
||||||
|
type Identity;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type Foo = u8;
|
||||||
|
|
||||||
|
pub union Bar {
|
||||||
|
a: <Foo as Identity>::Identity, //~ ERROR
|
||||||
|
b: u8,
|
||||||
|
}
|
9
tests/ui/union/projection-as-union-type-error.stderr
Normal file
9
tests/ui/union/projection-as-union-type-error.stderr
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
error[E0277]: the trait bound `u8: Identity` is not satisfied
|
||||||
|
--> $DIR/projection-as-union-type-error.rs:13:9
|
||||||
|
|
|
||||||
|
LL | a: <Foo as Identity>::Identity,
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Identity` is not implemented for `u8`
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
19
tests/ui/union/projection-as-union-type.rs
Normal file
19
tests/ui/union/projection-as-union-type.rs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
// Ensures that we can use projections as union field's type.
|
||||||
|
// check-pass
|
||||||
|
|
||||||
|
#![crate_type = "lib"]
|
||||||
|
|
||||||
|
pub trait Identity {
|
||||||
|
type Identity;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Identity for T {
|
||||||
|
type Identity = Self;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type Foo = u8;
|
||||||
|
|
||||||
|
pub union Bar {
|
||||||
|
pub a: <Foo as Identity>::Identity,
|
||||||
|
pub b: u8,
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user