diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 47eace961be..5e3601efbbe 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -121,7 +121,7 @@ fn allowed_union_field<'tcx>( 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) { diff --git a/tests/ui/union/projection-as-union-type-error-2.rs b/tests/ui/union/projection-as-union-type-error-2.rs new file mode 100644 index 00000000000..b88167b3b54 --- /dev/null +++ b/tests/ui/union/projection-as-union-type-error-2.rs @@ -0,0 +1,20 @@ +// Test to ensure that there is no ICE when normalizing a projection +// which is invalid (from ). + +#![crate_type = "lib"] + +trait Identity { + type Identity; +} +trait NotImplemented {} + +impl Identity for T { + type Identity = Self; +} + +type Foo = u8; + +union Bar { + a: ::Identity, //~ ERROR + b: u8, +} diff --git a/tests/ui/union/projection-as-union-type-error-2.stderr b/tests/ui/union/projection-as-union-type-error-2.stderr new file mode 100644 index 00000000000..bab226f271d --- /dev/null +++ b/tests/ui/union/projection-as-union-type-error-2.stderr @@ -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: ::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 Identity for T { + | -------------- ^^^^^^^^ ^ + | | + | unsatisfied trait bound introduced here + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/union/projection-as-union-type-error.rs b/tests/ui/union/projection-as-union-type-error.rs new file mode 100644 index 00000000000..17091c35fb2 --- /dev/null +++ b/tests/ui/union/projection-as-union-type-error.rs @@ -0,0 +1,15 @@ +// Test to ensure that there is no ICE when normalizing a projection +// which is invalid (from ). + +#![crate_type = "lib"] + +pub trait Identity { + type Identity; +} + +pub type Foo = u8; + +pub union Bar { + a: ::Identity, //~ ERROR + b: u8, +} diff --git a/tests/ui/union/projection-as-union-type-error.stderr b/tests/ui/union/projection-as-union-type-error.stderr new file mode 100644 index 00000000000..e4fbe9603ad --- /dev/null +++ b/tests/ui/union/projection-as-union-type-error.stderr @@ -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: ::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`. diff --git a/tests/ui/union/projection-as-union-type.rs b/tests/ui/union/projection-as-union-type.rs new file mode 100644 index 00000000000..143434c96f8 --- /dev/null +++ b/tests/ui/union/projection-as-union-type.rs @@ -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 Identity for T { + type Identity = Self; +} + +pub type Foo = u8; + +pub union Bar { + pub a: ::Identity, + pub b: u8, +}