summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs2
-rw-r--r--tests/ui/union/projection-as-union-type-error-2.rs20
-rw-r--r--tests/ui/union/projection-as-union-type-error-2.stderr17
-rw-r--r--tests/ui/union/projection-as-union-type-error.rs15
-rw-r--r--tests/ui/union/projection-as-union-type-error.stderr9
-rw-r--r--tests/ui/union/projection-as-union-type.rs19
6 files changed, 81 insertions, 1 deletions
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 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) {
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 <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,
+}
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: <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`.
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 <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,
+}
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: <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`.
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<T> Identity for T {
+ type Identity = Self;
+}
+
+pub type Foo = u8;
+
+pub union Bar {
+ pub a: <Foo as Identity>::Identity,
+ pub b: u8,
+}