Skip to content

Commit

Permalink
Auto merge of #106938 - GuillaumeGomez:normalize-projection-field-ty,…
Browse files Browse the repository at this point in the history
… r=oli-obk

Add missing normalization for union fields types

Overshadows #106808.
From the experiment #103985.

In short, it allows to use projections as a type for union's fields.

cc `@compiler-errors`
r? `@oli-obk`
  • Loading branch information
bors committed Feb 9, 2023
2 parents e7acd07 + 6c63b94 commit c40919b
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 1 deletion.
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/check/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> b

let param_env = tcx.param_env(item_def_id);
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) {
let (field_span, ty_span) = match tcx.hir().get_if_local(field.did) {
Expand Down
20 changes: 20 additions & 0 deletions tests/ui/union/projection-as-union-type-error-2.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 17 additions & 0 deletions tests/ui/union/projection-as-union-type-error-2.stderr
Original file line number Diff line number Diff line change
@@ -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 changes: 15 additions & 0 deletions tests/ui/union/projection-as-union-type-error.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 9 additions & 0 deletions tests/ui/union/projection-as-union-type-error.stderr
Original file line number Diff line number Diff line change
@@ -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 changes: 19 additions & 0 deletions tests/ui/union/projection-as-union-type.rs
Original file line number Diff line number Diff line change
@@ -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,
}

0 comments on commit c40919b

Please sign in to comment.