summaryrefslogtreecommitdiffstats
path: root/src/test/ui/nll/relate_tys
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/ui/nll/relate_tys')
-rw-r--r--src/test/ui/nll/relate_tys/fn-subtype.rs8
-rw-r--r--src/test/ui/nll/relate_tys/fn-subtype.stderr12
-rw-r--r--src/test/ui/nll/relate_tys/hr-fn-aaa-as-aba.rs24
-rw-r--r--src/test/ui/nll/relate_tys/hr-fn-aaa-as-aba.stderr21
-rw-r--r--src/test/ui/nll/relate_tys/hr-fn-aau-eq-abu.rs23
-rw-r--r--src/test/ui/nll/relate_tys/hr-fn-aba-as-aaa.rs15
-rw-r--r--src/test/ui/nll/relate_tys/impl-fn-ignore-binder-via-bottom.rs33
-rw-r--r--src/test/ui/nll/relate_tys/impl-fn-ignore-binder-via-bottom.stderr20
-rw-r--r--src/test/ui/nll/relate_tys/issue-48071.rs24
-rw-r--r--src/test/ui/nll/relate_tys/opaque-hrtb.rs14
-rw-r--r--src/test/ui/nll/relate_tys/opaque-hrtb.stderr11
-rw-r--r--src/test/ui/nll/relate_tys/trait-hrtb.rs14
-rw-r--r--src/test/ui/nll/relate_tys/trait-hrtb.stderr12
-rw-r--r--src/test/ui/nll/relate_tys/universe-violation.rs15
-rw-r--r--src/test/ui/nll/relate_tys/universe-violation.stderr12
-rw-r--r--src/test/ui/nll/relate_tys/var-appears-twice.rs25
-rw-r--r--src/test/ui/nll/relate_tys/var-appears-twice.stderr14
17 files changed, 297 insertions, 0 deletions
diff --git a/src/test/ui/nll/relate_tys/fn-subtype.rs b/src/test/ui/nll/relate_tys/fn-subtype.rs
new file mode 100644
index 000000000..ba89fa19c
--- /dev/null
+++ b/src/test/ui/nll/relate_tys/fn-subtype.rs
@@ -0,0 +1,8 @@
+// Test that NLL produces correct spans for higher-ranked subtyping errors.
+//
+// compile-flags:-Zno-leak-check
+
+fn main() {
+ let x: fn(&'static ()) = |_| {};
+ let y: for<'a> fn(&'a ()) = x; //~ ERROR mismatched types [E0308]
+}
diff --git a/src/test/ui/nll/relate_tys/fn-subtype.stderr b/src/test/ui/nll/relate_tys/fn-subtype.stderr
new file mode 100644
index 000000000..21073647e
--- /dev/null
+++ b/src/test/ui/nll/relate_tys/fn-subtype.stderr
@@ -0,0 +1,12 @@
+error[E0308]: mismatched types
+ --> $DIR/fn-subtype.rs:7:33
+ |
+LL | let y: for<'a> fn(&'a ()) = x;
+ | ^ one type is more general than the other
+ |
+ = note: expected fn pointer `for<'a> fn(&'a ())`
+ found fn pointer `fn(&())`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/nll/relate_tys/hr-fn-aaa-as-aba.rs b/src/test/ui/nll/relate_tys/hr-fn-aaa-as-aba.rs
new file mode 100644
index 000000000..7891bab09
--- /dev/null
+++ b/src/test/ui/nll/relate_tys/hr-fn-aaa-as-aba.rs
@@ -0,0 +1,24 @@
+// Test that the NLL `relate_tys` code correctly deduces that a
+// function returning either argument CANNOT be upcast to one
+// that returns always its first argument.
+//
+// compile-flags:-Zno-leak-check
+
+fn make_it() -> for<'a> fn(&'a u32, &'a u32) -> &'a u32 {
+ panic!()
+}
+
+fn foo() {
+ let a: for<'a, 'b> fn(&'a u32, &'b u32) -> &'a u32 = make_it();
+ //~^ ERROR mismatched types [E0308]
+ drop(a);
+}
+
+fn bar() {
+ // The code path for patterns is mildly different, so go ahead and
+ // test that too:
+ let _: for<'a, 'b> fn(&'a u32, &'b u32) -> &'a u32 = make_it();
+ //~^ ERROR mismatched types [E0308]
+}
+
+fn main() {}
diff --git a/src/test/ui/nll/relate_tys/hr-fn-aaa-as-aba.stderr b/src/test/ui/nll/relate_tys/hr-fn-aaa-as-aba.stderr
new file mode 100644
index 000000000..7d76c916d
--- /dev/null
+++ b/src/test/ui/nll/relate_tys/hr-fn-aaa-as-aba.stderr
@@ -0,0 +1,21 @@
+error[E0308]: mismatched types
+ --> $DIR/hr-fn-aaa-as-aba.rs:12:58
+ |
+LL | let a: for<'a, 'b> fn(&'a u32, &'b u32) -> &'a u32 = make_it();
+ | ^^^^^^^^^ one type is more general than the other
+ |
+ = note: expected fn pointer `for<'a, 'b> fn(&'a u32, &'b u32) -> &'a u32`
+ found fn pointer `for<'a> fn(&'a u32, &'a u32) -> &'a u32`
+
+error[E0308]: mismatched types
+ --> $DIR/hr-fn-aaa-as-aba.rs:20:12
+ |
+LL | let _: for<'a, 'b> fn(&'a u32, &'b u32) -> &'a u32 = make_it();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
+ |
+ = note: expected fn pointer `for<'a, 'b> fn(&'a u32, &'b u32) -> &'a u32`
+ found fn pointer `for<'a> fn(&'a u32, &'a u32) -> &'a u32`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/nll/relate_tys/hr-fn-aau-eq-abu.rs b/src/test/ui/nll/relate_tys/hr-fn-aau-eq-abu.rs
new file mode 100644
index 000000000..92730341c
--- /dev/null
+++ b/src/test/ui/nll/relate_tys/hr-fn-aau-eq-abu.rs
@@ -0,0 +1,23 @@
+// Test an interesting corner case that ought to be legal (though the
+// current code actually gets it wrong, see below): a fn that takes
+// two arguments that are references with the same lifetime is in fact
+// equivalent to a fn that takes two references with distinct
+// lifetimes. This is true because the two functions can call one
+// another -- effectively, the single lifetime `'a` is just inferred
+// to be the intersection of the two distinct lifetimes.
+//
+// check-pass
+// compile-flags:-Zno-leak-check
+
+use std::cell::Cell;
+
+fn make_cell_aa() -> Cell<for<'a> fn(&'a u32, &'a u32)> {
+ panic!()
+}
+
+fn aa_eq_ab() {
+ let a: Cell<for<'a, 'b> fn(&'a u32, &'b u32)> = make_cell_aa();
+ drop(a);
+}
+
+fn main() { }
diff --git a/src/test/ui/nll/relate_tys/hr-fn-aba-as-aaa.rs b/src/test/ui/nll/relate_tys/hr-fn-aba-as-aaa.rs
new file mode 100644
index 000000000..7cc0acf45
--- /dev/null
+++ b/src/test/ui/nll/relate_tys/hr-fn-aba-as-aaa.rs
@@ -0,0 +1,15 @@
+// Test that the NLL `relate_tys` code correctly deduces that a
+// function returning always its first argument can be upcast to one
+// that returns either first or second argument.
+//
+// check-pass
+// compile-flags:-Zno-leak-check
+
+fn make_it() -> for<'a, 'b> fn(&'a u32, &'b u32) -> &'a u32 {
+ panic!()
+}
+
+fn main() {
+ let a: for<'a> fn(&'a u32, &'a u32) -> &'a u32 = make_it();
+ drop(a);
+}
diff --git a/src/test/ui/nll/relate_tys/impl-fn-ignore-binder-via-bottom.rs b/src/test/ui/nll/relate_tys/impl-fn-ignore-binder-via-bottom.rs
new file mode 100644
index 000000000..c4db6fc97
--- /dev/null
+++ b/src/test/ui/nll/relate_tys/impl-fn-ignore-binder-via-bottom.rs
@@ -0,0 +1,33 @@
+// Test that the NLL solver cannot find a solution
+// for `exists<R1> { forall<R1> { R2: R1 } }`.
+//
+// In this test, the impl should match `fn(T)` for some `T`,
+// but we ask it to match `for<'a> fn(&'a ())`. Due to argument
+// contravariance, this effectively requires a `T = &'b ()` where
+// `forall<'a> { 'a: 'b }`. Therefore, we get an error.
+//
+// Note the use of `-Zno-leak-check` here. This is presently required in order
+// to skip the leak-check errors.
+//
+// c.f. Issue #57642.
+//
+// compile-flags:-Zno-leak-check
+
+trait Y {
+ type F;
+ fn make_f() -> Self::F;
+}
+
+impl<T> Y for fn(T) {
+ type F = fn(T);
+
+ fn make_f() -> Self::F {
+ |_| {}
+ }
+}
+
+fn main() {
+ let _x = <fn(&())>::make_f();
+ //~^ ERROR implementation of `Y` is not general enough
+ //~| ERROR implementation of `Y` is not general enough
+}
diff --git a/src/test/ui/nll/relate_tys/impl-fn-ignore-binder-via-bottom.stderr b/src/test/ui/nll/relate_tys/impl-fn-ignore-binder-via-bottom.stderr
new file mode 100644
index 000000000..51adfca3e
--- /dev/null
+++ b/src/test/ui/nll/relate_tys/impl-fn-ignore-binder-via-bottom.stderr
@@ -0,0 +1,20 @@
+error: implementation of `Y` is not general enough
+ --> $DIR/impl-fn-ignore-binder-via-bottom.rs:30:14
+ |
+LL | let _x = <fn(&())>::make_f();
+ | ^^^^^^^^^^^^^^^^^^^ implementation of `Y` is not general enough
+ |
+ = note: `Y` would have to be implemented for the type `for<'r> fn(&'r ())`
+ = note: ...but `Y` is actually implemented for the type `fn(&'0 ())`, for some specific lifetime `'0`
+
+error: implementation of `Y` is not general enough
+ --> $DIR/impl-fn-ignore-binder-via-bottom.rs:30:14
+ |
+LL | let _x = <fn(&())>::make_f();
+ | ^^^^^^^^^^^^^^^^^^^ implementation of `Y` is not general enough
+ |
+ = note: `Y` would have to be implemented for the type `for<'r> fn(&'r ())`
+ = note: ...but `Y` is actually implemented for the type `fn(&'0 ())`, for some specific lifetime `'0`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/nll/relate_tys/issue-48071.rs b/src/test/ui/nll/relate_tys/issue-48071.rs
new file mode 100644
index 000000000..73361a0d3
--- /dev/null
+++ b/src/test/ui/nll/relate_tys/issue-48071.rs
@@ -0,0 +1,24 @@
+// Regression test for #48071. This test used to ICE because -- in
+// the leak-check -- it would pass since we knew that the return type
+// was `'static`, and hence `'static: 'a` was legal even for a
+// placeholder region, but in NLL land it would fail because we had
+// rewritten `'static` to a region variable.
+//
+// check-pass
+
+trait Foo {
+ fn foo(&self) { }
+}
+
+impl Foo for () {
+}
+
+type MakeFooFn = for<'a> fn(&'a u8) -> Box<dyn Foo + 'a>;
+
+fn make_foo(x: &u8) -> Box<dyn Foo + 'static> {
+ Box::new(())
+}
+
+fn main() {
+ let x: MakeFooFn = make_foo as MakeFooFn;
+}
diff --git a/src/test/ui/nll/relate_tys/opaque-hrtb.rs b/src/test/ui/nll/relate_tys/opaque-hrtb.rs
new file mode 100644
index 000000000..261372523
--- /dev/null
+++ b/src/test/ui/nll/relate_tys/opaque-hrtb.rs
@@ -0,0 +1,14 @@
+trait MyTrait<T> {}
+
+struct Foo;
+impl<T> MyTrait<T> for Foo {}
+
+fn bar<Input>() -> impl MyTrait<Input> {
+ Foo
+}
+
+fn foo() -> impl for<'a> MyTrait<&'a str> {
+ bar() //~ ERROR implementation of `MyTrait` is not general enough
+}
+
+fn main() {}
diff --git a/src/test/ui/nll/relate_tys/opaque-hrtb.stderr b/src/test/ui/nll/relate_tys/opaque-hrtb.stderr
new file mode 100644
index 000000000..d75ec2b57
--- /dev/null
+++ b/src/test/ui/nll/relate_tys/opaque-hrtb.stderr
@@ -0,0 +1,11 @@
+error: implementation of `MyTrait` is not general enough
+ --> $DIR/opaque-hrtb.rs:11:5
+ |
+LL | bar()
+ | ^^^^^ implementation of `MyTrait` is not general enough
+ |
+ = note: `impl MyTrait<&'2 str>` must implement `MyTrait<&'1 str>`, for any lifetime `'1`...
+ = note: ...but it actually implements `MyTrait<&'2 str>`, for some specific lifetime `'2`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/nll/relate_tys/trait-hrtb.rs b/src/test/ui/nll/relate_tys/trait-hrtb.rs
new file mode 100644
index 000000000..7f40e93cd
--- /dev/null
+++ b/src/test/ui/nll/relate_tys/trait-hrtb.rs
@@ -0,0 +1,14 @@
+// Test that NLL generates proper error spans for trait HRTB errors
+//
+// compile-flags:-Zno-leak-check
+
+trait Foo<'a> {}
+
+fn make_foo<'a>() -> Box<dyn Foo<'a>> {
+ panic!()
+}
+
+fn main() {
+ let x: Box<dyn Foo<'static>> = make_foo();
+ let y: Box<dyn for<'a> Foo<'a>> = x; //~ ERROR mismatched types [E0308]
+}
diff --git a/src/test/ui/nll/relate_tys/trait-hrtb.stderr b/src/test/ui/nll/relate_tys/trait-hrtb.stderr
new file mode 100644
index 000000000..aa1927711
--- /dev/null
+++ b/src/test/ui/nll/relate_tys/trait-hrtb.stderr
@@ -0,0 +1,12 @@
+error[E0308]: mismatched types
+ --> $DIR/trait-hrtb.rs:13:39
+ |
+LL | let y: Box<dyn for<'a> Foo<'a>> = x;
+ | ^ one type is more general than the other
+ |
+ = note: expected trait object `dyn for<'a> Foo<'a>`
+ found trait object `dyn Foo<'_>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/nll/relate_tys/universe-violation.rs b/src/test/ui/nll/relate_tys/universe-violation.rs
new file mode 100644
index 000000000..c5f9d4406
--- /dev/null
+++ b/src/test/ui/nll/relate_tys/universe-violation.rs
@@ -0,0 +1,15 @@
+// Test that the NLL `relate_tys` code correctly deduces that a
+// function returning either argument CANNOT be upcast to one
+// that returns always its first argument.
+//
+// compile-flags:-Zno-leak-check
+
+fn make_it() -> fn(&'static u32) -> &'static u32 {
+ panic!()
+}
+
+fn main() {
+ let a: fn(_) -> _ = make_it();
+ let b: fn(&u32) -> &u32 = a; //~ ERROR mismatched types [E0308]
+ drop(a);
+}
diff --git a/src/test/ui/nll/relate_tys/universe-violation.stderr b/src/test/ui/nll/relate_tys/universe-violation.stderr
new file mode 100644
index 000000000..6f38154e3
--- /dev/null
+++ b/src/test/ui/nll/relate_tys/universe-violation.stderr
@@ -0,0 +1,12 @@
+error[E0308]: mismatched types
+ --> $DIR/universe-violation.rs:13:31
+ |
+LL | let b: fn(&u32) -> &u32 = a;
+ | ^ one type is more general than the other
+ |
+ = note: expected fn pointer `for<'r> fn(&'r u32) -> &'r u32`
+ found fn pointer `fn(&u32) -> &u32`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/nll/relate_tys/var-appears-twice.rs b/src/test/ui/nll/relate_tys/var-appears-twice.rs
new file mode 100644
index 000000000..77129f446
--- /dev/null
+++ b/src/test/ui/nll/relate_tys/var-appears-twice.rs
@@ -0,0 +1,25 @@
+// Test that the NLL `relate_tys` code correctly deduces that a
+// function returning always its first argument can be upcast to one
+// that returns either first or second argument.
+
+use std::cell::Cell;
+
+type DoubleCell<A> = Cell<(A, A)>;
+type DoublePair<A> = (A, A);
+
+fn make_cell<'b>(x: &'b u32) -> Cell<(&'static u32, &'b u32)> {
+ panic!()
+}
+
+fn main() {
+ let a: &'static u32 = &22;
+ let b = 44;
+
+ // Here we get an error because `DoubleCell<_>` requires the same type
+ // on both parts of the `Cell`, and we can't have that.
+ let x: DoubleCell<_> = make_cell(&b); //~ ERROR
+
+ // Here we do not get an error because `DoublePair<_>` permits
+ // variance on the lifetimes involved.
+ let y: DoublePair<_> = make_cell(&b).get();
+}
diff --git a/src/test/ui/nll/relate_tys/var-appears-twice.stderr b/src/test/ui/nll/relate_tys/var-appears-twice.stderr
new file mode 100644
index 000000000..d032ce6f2
--- /dev/null
+++ b/src/test/ui/nll/relate_tys/var-appears-twice.stderr
@@ -0,0 +1,14 @@
+error[E0597]: `b` does not live long enough
+ --> $DIR/var-appears-twice.rs:20:38
+ |
+LL | let x: DoubleCell<_> = make_cell(&b);
+ | ------------- ^^ borrowed value does not live long enough
+ | |
+ | type annotation requires that `b` is borrowed for `'static`
+...
+LL | }
+ | - `b` dropped here while still borrowed
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0597`.