about summary refs log tree commit diff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/ui/impl-trait/rpit/early_bound.rs13
-rw-r--r--tests/ui/impl-trait/rpit/early_bound.stderr26
-rw-r--r--tests/ui/type-alias-impl-trait/hidden_behind_struct_field2.rs8
-rw-r--r--tests/ui/type-alias-impl-trait/hidden_behind_struct_field2.stderr15
-rw-r--r--tests/ui/type-alias-impl-trait/impl_trait_in_trait_defined_outside_trait.rs38
-rw-r--r--tests/ui/type-alias-impl-trait/impl_trait_in_trait_defined_outside_trait.stderr41
-rw-r--r--tests/ui/type-alias-impl-trait/impl_trait_in_trait_defined_outside_trait2.rs22
-rw-r--r--tests/ui/type-alias-impl-trait/impl_trait_in_trait_defined_outside_trait2.stderr17
-rw-r--r--tests/ui/type-alias-impl-trait/impl_trait_in_trait_defined_outside_trait3.rs38
-rw-r--r--tests/ui/type-alias-impl-trait/in-assoc-ty-early-bound.rs17
-rw-r--r--tests/ui/type-alias-impl-trait/in-assoc-ty-early-bound.stderr13
-rw-r--r--tests/ui/type-alias-impl-trait/in-assoc-ty-early-bound2.rs21
-rw-r--r--tests/ui/type-alias-impl-trait/in-assoc-ty-early-bound2.stderr22
-rw-r--r--tests/ui/type-alias-impl-trait/itiat-allow-nested-closures.bad.stderr23
-rw-r--r--tests/ui/type-alias-impl-trait/itiat-allow-nested-closures.rs26
-rw-r--r--tests/ui/type-alias-impl-trait/itiat-forbid-nested-items.rs20
-rw-r--r--tests/ui/type-alias-impl-trait/itiat-forbid-nested-items.stderr22
17 files changed, 378 insertions, 4 deletions
diff --git a/tests/ui/impl-trait/rpit/early_bound.rs b/tests/ui/impl-trait/rpit/early_bound.rs
new file mode 100644
index 00000000000..03bd64d4d76
--- /dev/null
+++ b/tests/ui/impl-trait/rpit/early_bound.rs
@@ -0,0 +1,13 @@
+use std::convert::identity;
+
+fn test<'a: 'a>(n: bool) -> impl Sized + 'a {
+    //~^ ERROR concrete type differs from previous defining opaque type use
+    let true = n else { loop {} };
+    let _ = || {
+        let _ = identity::<&'a ()>(test(false));
+        //~^ ERROR hidden type for `impl Sized + 'a` captures lifetime that does not appear in bounds
+    };
+    loop {}
+}
+
+fn main() {}
diff --git a/tests/ui/impl-trait/rpit/early_bound.stderr b/tests/ui/impl-trait/rpit/early_bound.stderr
new file mode 100644
index 00000000000..815368f250e
--- /dev/null
+++ b/tests/ui/impl-trait/rpit/early_bound.stderr
@@ -0,0 +1,26 @@
+error[E0700]: hidden type for `impl Sized + 'a` captures lifetime that does not appear in bounds
+  --> $DIR/early_bound.rs:7:17
+   |
+LL | fn test<'a: 'a>(n: bool) -> impl Sized + 'a {
+   |         --                  --------------- opaque type defined here
+   |         |
+   |         hidden type `&'a ()` captures the lifetime `'a` as defined here
+...
+LL |         let _ = identity::<&'a ()>(test(false));
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: concrete type differs from previous defining opaque type use
+  --> $DIR/early_bound.rs:3:29
+   |
+LL | fn test<'a: 'a>(n: bool) -> impl Sized + 'a {
+   |                             ^^^^^^^^^^^^^^^ expected `&()`, got `()`
+   |
+note: previous use here
+  --> $DIR/early_bound.rs:7:36
+   |
+LL |         let _ = identity::<&'a ()>(test(false));
+   |                                    ^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0700`.
diff --git a/tests/ui/type-alias-impl-trait/hidden_behind_struct_field2.rs b/tests/ui/type-alias-impl-trait/hidden_behind_struct_field2.rs
index e440dce5e51..4c881dd1330 100644
--- a/tests/ui/type-alias-impl-trait/hidden_behind_struct_field2.rs
+++ b/tests/ui/type-alias-impl-trait/hidden_behind_struct_field2.rs
@@ -1,9 +1,8 @@
-//! This test shows that we can even follow projections
-//! into associated types of the same impl if they are
-//! indirectly mentioned in a struct field.
+//! This test shows that we do not treat opaque types
+//! as defined by a method if the opaque type is
+//! only indirectly mentioned in a struct field.
 
 #![feature(impl_trait_in_assoc_type)]
-// check-pass
 
 struct Bar;
 
@@ -16,6 +15,7 @@ impl Trait for Bar {
     type Assoc = impl std::fmt::Debug;
     fn foo() -> Foo {
         Foo { field: () }
+        //~^ ERROR: item constrains opaque type that is not in its signature
     }
 }
 
diff --git a/tests/ui/type-alias-impl-trait/hidden_behind_struct_field2.stderr b/tests/ui/type-alias-impl-trait/hidden_behind_struct_field2.stderr
new file mode 100644
index 00000000000..5c53dfa3a75
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/hidden_behind_struct_field2.stderr
@@ -0,0 +1,15 @@
+error: item constrains opaque type that is not in its signature
+  --> $DIR/hidden_behind_struct_field2.rs:17:22
+   |
+LL |         Foo { field: () }
+   |                      ^^
+   |
+   = note: this item must mention the opaque type in its signature in order to be able to register hidden types
+note: this item must mention the opaque type in its signature in order to be able to register hidden types
+  --> $DIR/hidden_behind_struct_field2.rs:16:8
+   |
+LL |     fn foo() -> Foo {
+   |        ^^^
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/type-alias-impl-trait/impl_trait_in_trait_defined_outside_trait.rs b/tests/ui/type-alias-impl-trait/impl_trait_in_trait_defined_outside_trait.rs
new file mode 100644
index 00000000000..a788563ab77
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/impl_trait_in_trait_defined_outside_trait.rs
@@ -0,0 +1,38 @@
+//! Check that we cannot instantiate a hidden type in the body
+//! of an assoc fn or const unless mentioned in the signature.
+
+#![feature(impl_trait_in_assoc_type)]
+
+trait Trait: Sized {
+    type Assoc;
+    fn foo();
+    fn bar() -> Self::Assoc;
+}
+
+impl Trait for () {
+    type Assoc = impl std::fmt::Debug;
+    fn foo() {
+        let x: Self::Assoc = 42; //~ ERROR: mismatched types
+    }
+    fn bar() -> Self::Assoc {
+        ""
+    }
+}
+
+trait Trait2: Sized {
+    type Assoc;
+    const FOO: ();
+    fn bar() -> Self::Assoc;
+}
+
+impl Trait2 for () {
+    type Assoc = impl std::fmt::Debug;
+    const FOO: () = {
+        let x: Self::Assoc = 42; //~ ERROR: mismatched types
+    };
+    fn bar() -> Self::Assoc {
+        ""
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/impl_trait_in_trait_defined_outside_trait.stderr b/tests/ui/type-alias-impl-trait/impl_trait_in_trait_defined_outside_trait.stderr
new file mode 100644
index 00000000000..1d7a97c5367
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/impl_trait_in_trait_defined_outside_trait.stderr
@@ -0,0 +1,41 @@
+error[E0308]: mismatched types
+  --> $DIR/impl_trait_in_trait_defined_outside_trait.rs:15:30
+   |
+LL |     type Assoc = impl std::fmt::Debug;
+   |                  -------------------- the expected opaque type
+LL |     fn foo() {
+LL |         let x: Self::Assoc = 42;
+   |                -----------   ^^ expected opaque type, found integer
+   |                |
+   |                expected due to this
+   |
+   = note: expected opaque type `<() as Trait>::Assoc`
+                     found type `{integer}`
+note: this item must have the opaque type in its signature in order to be able to register hidden types
+  --> $DIR/impl_trait_in_trait_defined_outside_trait.rs:14:8
+   |
+LL |     fn foo() {
+   |        ^^^
+
+error[E0308]: mismatched types
+  --> $DIR/impl_trait_in_trait_defined_outside_trait.rs:31:30
+   |
+LL |     type Assoc = impl std::fmt::Debug;
+   |                  -------------------- the expected opaque type
+LL |     const FOO: () = {
+LL |         let x: Self::Assoc = 42;
+   |                -----------   ^^ expected opaque type, found integer
+   |                |
+   |                expected due to this
+   |
+   = note: expected opaque type `<() as Trait2>::Assoc`
+                     found type `{integer}`
+note: this item must have the opaque type in its signature in order to be able to register hidden types
+  --> $DIR/impl_trait_in_trait_defined_outside_trait.rs:30:11
+   |
+LL |     const FOO: () = {
+   |           ^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/type-alias-impl-trait/impl_trait_in_trait_defined_outside_trait2.rs b/tests/ui/type-alias-impl-trait/impl_trait_in_trait_defined_outside_trait2.rs
new file mode 100644
index 00000000000..77cdca198da
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/impl_trait_in_trait_defined_outside_trait2.rs
@@ -0,0 +1,22 @@
+//! Check that we cannot instantiate a hidden type from another assoc type.
+
+#![feature(impl_trait_in_assoc_type)]
+
+trait Trait: Sized {
+    type Assoc;
+    type Foo;
+    fn foo() -> Self::Assoc;
+}
+
+impl Trait for () {
+    type Assoc = impl std::fmt::Debug;
+    type Foo = [(); {
+        let x: Self::Assoc = 42; //~ ERROR: mismatched types
+        3
+    }];
+    fn foo() -> Self::Assoc {
+        ""
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/impl_trait_in_trait_defined_outside_trait2.stderr b/tests/ui/type-alias-impl-trait/impl_trait_in_trait_defined_outside_trait2.stderr
new file mode 100644
index 00000000000..708c3f28d2d
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/impl_trait_in_trait_defined_outside_trait2.stderr
@@ -0,0 +1,17 @@
+error[E0308]: mismatched types
+  --> $DIR/impl_trait_in_trait_defined_outside_trait2.rs:14:30
+   |
+LL |     type Assoc = impl std::fmt::Debug;
+   |                  -------------------- the expected opaque type
+LL |     type Foo = [(); {
+LL |         let x: Self::Assoc = 42;
+   |                -----------   ^^ expected opaque type, found integer
+   |                |
+   |                expected due to this
+   |
+   = note: expected opaque type `<() as Trait>::Assoc`
+                     found type `{integer}`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/type-alias-impl-trait/impl_trait_in_trait_defined_outside_trait3.rs b/tests/ui/type-alias-impl-trait/impl_trait_in_trait_defined_outside_trait3.rs
new file mode 100644
index 00000000000..dfcf7336533
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/impl_trait_in_trait_defined_outside_trait3.rs
@@ -0,0 +1,38 @@
+//! Check that non-defining assoc items can use the opaque type
+//! opaquely.
+
+// check-pass
+
+#![feature(impl_trait_in_assoc_type)]
+
+trait Trait: Sized {
+    type Assoc;
+    fn foo();
+    fn bar() -> Self::Assoc;
+}
+
+impl Trait for () {
+    type Assoc = impl std::fmt::Debug;
+    fn foo() {
+        let x: Self::Assoc = Self::bar();
+    }
+    fn bar() -> Self::Assoc {
+        ""
+    }
+}
+
+trait Trait2: Sized {
+    type Assoc;
+    const FOO: ();
+    const BAR: Self::Assoc;
+}
+
+impl Trait2 for () {
+    type Assoc = impl Copy;
+    const FOO: () = {
+        let x: Self::Assoc = Self::BAR;
+    };
+    const BAR: Self::Assoc = "";
+}
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/in-assoc-ty-early-bound.rs b/tests/ui/type-alias-impl-trait/in-assoc-ty-early-bound.rs
new file mode 100644
index 00000000000..baeba1d3de6
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/in-assoc-ty-early-bound.rs
@@ -0,0 +1,17 @@
+#![feature(impl_trait_in_assoc_type)]
+
+trait Foo {
+    type Assoc<'a, 'b>;
+    fn bar<'a: 'a, 'b: 'b>(_: &'a ()) -> Self::Assoc<'a, 'b>;
+}
+
+impl Foo for () {
+    type Assoc<'a, 'b> = impl Sized;
+    fn bar<'a: 'a, 'b: 'b>(x: &'a ()) -> Self::Assoc<'a, 'b> {
+        let closure = |x: &'a ()| -> Self::Assoc<'b, 'a> { x };
+        //~^ ERROR `<() as Foo>::Assoc<'b, 'a>` captures lifetime that does not appear in bounds
+        x
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/in-assoc-ty-early-bound.stderr b/tests/ui/type-alias-impl-trait/in-assoc-ty-early-bound.stderr
new file mode 100644
index 00000000000..a7d3e7f0be4
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/in-assoc-ty-early-bound.stderr
@@ -0,0 +1,13 @@
+error[E0700]: hidden type for `<() as Foo>::Assoc<'b, 'a>` captures lifetime that does not appear in bounds
+  --> $DIR/in-assoc-ty-early-bound.rs:11:60
+   |
+LL |     type Assoc<'a, 'b> = impl Sized;
+   |                          ---------- opaque type defined here
+LL |     fn bar<'a: 'a, 'b: 'b>(x: &'a ()) -> Self::Assoc<'a, 'b> {
+   |            -- hidden type `&'a ()` captures the lifetime `'a` as defined here
+LL |         let closure = |x: &'a ()| -> Self::Assoc<'b, 'a> { x };
+   |                                                            ^
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0700`.
diff --git a/tests/ui/type-alias-impl-trait/in-assoc-ty-early-bound2.rs b/tests/ui/type-alias-impl-trait/in-assoc-ty-early-bound2.rs
new file mode 100644
index 00000000000..7452000b65d
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/in-assoc-ty-early-bound2.rs
@@ -0,0 +1,21 @@
+#![feature(impl_trait_in_assoc_type)]
+
+trait Foo {
+    type Assoc<'a>;
+    fn bar<'a: 'a>();
+}
+
+impl Foo for () {
+    type Assoc<'a> = impl Sized; //~ ERROR unconstrained opaque type
+    fn bar<'a: 'a>()
+    where
+        Self::Assoc<'a>:,
+    {
+        let _ = |x: &'a ()| {
+            let _: Self::Assoc<'a> = x;
+            //~^ ERROR `<() as Foo>::Assoc<'a>` captures lifetime that does not appear in bound
+        };
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/in-assoc-ty-early-bound2.stderr b/tests/ui/type-alias-impl-trait/in-assoc-ty-early-bound2.stderr
new file mode 100644
index 00000000000..1274a8b60de
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/in-assoc-ty-early-bound2.stderr
@@ -0,0 +1,22 @@
+error[E0700]: hidden type for `<() as Foo>::Assoc<'a>` captures lifetime that does not appear in bounds
+  --> $DIR/in-assoc-ty-early-bound2.rs:15:20
+   |
+LL |     type Assoc<'a> = impl Sized;
+   |                      ---------- opaque type defined here
+LL |     fn bar<'a: 'a>()
+   |            -- hidden type `&'a ()` captures the lifetime `'a` as defined here
+...
+LL |             let _: Self::Assoc<'a> = x;
+   |                    ^^^^^^^^^^^^^^^
+
+error: unconstrained opaque type
+  --> $DIR/in-assoc-ty-early-bound2.rs:9:22
+   |
+LL |     type Assoc<'a> = impl Sized;
+   |                      ^^^^^^^^^^
+   |
+   = note: `Assoc` must be used in combination with a concrete type within the same impl
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0700`.
diff --git a/tests/ui/type-alias-impl-trait/itiat-allow-nested-closures.bad.stderr b/tests/ui/type-alias-impl-trait/itiat-allow-nested-closures.bad.stderr
new file mode 100644
index 00000000000..4acc47eaef2
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/itiat-allow-nested-closures.bad.stderr
@@ -0,0 +1,23 @@
+error[E0308]: mismatched types
+  --> $DIR/itiat-allow-nested-closures.rs:21:22
+   |
+LL |     type Assoc = impl Sized;
+   |                  ---------- the found opaque type
+...
+LL |         let _: i32 = closure();
+   |                ---   ^^^^^^^^^ expected `i32`, found opaque type
+   |                |
+   |                expected due to this
+
+error[E0308]: mismatched types
+  --> $DIR/itiat-allow-nested-closures.rs:22:9
+   |
+LL |     fn bar() -> Self::Assoc {
+   |                 ----------- expected `()` because of return type
+...
+LL |         1i32
+   |         ^^^^ expected `()`, found `i32`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/type-alias-impl-trait/itiat-allow-nested-closures.rs b/tests/ui/type-alias-impl-trait/itiat-allow-nested-closures.rs
new file mode 100644
index 00000000000..55994d6a325
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/itiat-allow-nested-closures.rs
@@ -0,0 +1,26 @@
+#![feature(impl_trait_in_assoc_type)]
+
+// revisions: ok bad
+// [ok] check-pass
+
+trait Foo {
+    type Assoc;
+    fn bar() -> Self::Assoc;
+}
+
+impl Foo for () {
+    type Assoc = impl Sized;
+    fn bar() -> Self::Assoc {
+        let closure = || -> Self::Assoc {
+            #[cfg(ok)]
+            let x: Self::Assoc = 42_i32;
+            #[cfg(bad)]
+            let x: Self::Assoc = ();
+            x
+        };
+        let _: i32 = closure(); //[bad]~ ERROR mismatched types
+        1i32 //[bad]~ ERROR mismatched types
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/itiat-forbid-nested-items.rs b/tests/ui/type-alias-impl-trait/itiat-forbid-nested-items.rs
new file mode 100644
index 00000000000..8c9d780c111
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/itiat-forbid-nested-items.rs
@@ -0,0 +1,20 @@
+#![feature(impl_trait_in_assoc_type)]
+
+trait Foo {
+    type Assoc;
+    fn bar() -> Self::Assoc;
+}
+
+impl Foo for () {
+    type Assoc = impl Sized;
+    fn bar() -> Self::Assoc {
+        fn foo() -> <() as Foo>::Assoc {
+            let x: <() as Foo>::Assoc = 42_i32; //~ ERROR mismatched types
+            x
+        };
+        let _: i32 = foo();
+        1i32
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/itiat-forbid-nested-items.stderr b/tests/ui/type-alias-impl-trait/itiat-forbid-nested-items.stderr
new file mode 100644
index 00000000000..c177201431a
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/itiat-forbid-nested-items.stderr
@@ -0,0 +1,22 @@
+error[E0308]: mismatched types
+  --> $DIR/itiat-forbid-nested-items.rs:12:41
+   |
+LL |     type Assoc = impl Sized;
+   |                  ---------- the expected opaque type
+...
+LL |             let x: <() as Foo>::Assoc = 42_i32;
+   |                    ------------------   ^^^^^^ expected opaque type, found `i32`
+   |                    |
+   |                    expected due to this
+   |
+   = note: expected opaque type `<() as Foo>::Assoc`
+                     found type `i32`
+note: this item must have the opaque type in its signature in order to be able to register hidden types
+  --> $DIR/itiat-forbid-nested-items.rs:11:12
+   |
+LL |         fn foo() -> <() as Foo>::Assoc {
+   |            ^^^
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0308`.