summaryrefslogtreecommitdiffstats
path: root/src/test/ui/associated-types/cache
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/ui/associated-types/cache')
-rw-r--r--src/test/ui/associated-types/cache/chrono-scan.rs30
-rw-r--r--src/test/ui/associated-types/cache/elision.rs23
-rw-r--r--src/test/ui/associated-types/cache/project-fn-ret-contravariant.krisskross.stderr30
-rw-r--r--src/test/ui/associated-types/cache/project-fn-ret-contravariant.rs50
-rw-r--r--src/test/ui/associated-types/cache/project-fn-ret-contravariant.transmute.stderr10
-rw-r--r--src/test/ui/associated-types/cache/project-fn-ret-invariant.krisskross.stderr36
-rw-r--r--src/test/ui/associated-types/cache/project-fn-ret-invariant.oneuse.stderr36
-rw-r--r--src/test/ui/associated-types/cache/project-fn-ret-invariant.rs64
-rw-r--r--src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr15
9 files changed, 294 insertions, 0 deletions
diff --git a/src/test/ui/associated-types/cache/chrono-scan.rs b/src/test/ui/associated-types/cache/chrono-scan.rs
new file mode 100644
index 000000000..964ddc9b6
--- /dev/null
+++ b/src/test/ui/associated-types/cache/chrono-scan.rs
@@ -0,0 +1,30 @@
+// check-pass
+
+#![allow(deprecated)]
+
+pub type ParseResult<T> = Result<T, ()>;
+
+pub enum Item<'a> {
+ Literal(&'a str)
+}
+
+pub fn colon_or_space(s: &str) -> ParseResult<&str> {
+ unimplemented!()
+}
+
+pub fn timezone_offset_zulu<F>(s: &str, colon: F) -> ParseResult<(&str, i32)>
+ where F: FnMut(&str) -> ParseResult<&str> {
+ unimplemented!()
+}
+
+pub fn parse<'a, I>(mut s: &str, items: I) -> ParseResult<()>
+ where I: Iterator<Item=Item<'a>> {
+ macro_rules! try_consume {
+ ($e:expr) => ({ let (s_, v) = try!($e); s = s_; v })
+ }
+ let offset = try_consume!(timezone_offset_zulu(s.trim_start(), colon_or_space));
+ let offset = try_consume!(timezone_offset_zulu(s.trim_start(), colon_or_space));
+ Ok(())
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-types/cache/elision.rs b/src/test/ui/associated-types/cache/elision.rs
new file mode 100644
index 000000000..b3e1ec8ad
--- /dev/null
+++ b/src/test/ui/associated-types/cache/elision.rs
@@ -0,0 +1,23 @@
+// Check that you are allowed to implement using elision but write
+// trait without elision (a bug in this cropped up during
+// bootstrapping, so this is a regression test).
+
+// check-pass
+
+pub struct SplitWhitespace<'a> {
+ x: &'a u8
+}
+
+pub trait UnicodeStr {
+ fn split_whitespace<'a>(&'a self) -> SplitWhitespace<'a>;
+}
+
+impl UnicodeStr for str {
+ #[inline]
+ fn split_whitespace(&self) -> SplitWhitespace {
+ unimplemented!()
+ }
+}
+
+
+fn main() { }
diff --git a/src/test/ui/associated-types/cache/project-fn-ret-contravariant.krisskross.stderr b/src/test/ui/associated-types/cache/project-fn-ret-contravariant.krisskross.stderr
new file mode 100644
index 000000000..2ecee1341
--- /dev/null
+++ b/src/test/ui/associated-types/cache/project-fn-ret-contravariant.krisskross.stderr
@@ -0,0 +1,30 @@
+error: lifetime may not live long enough
+ --> $DIR/project-fn-ret-contravariant.rs:46:4
+ |
+LL | fn transmute<'a,'b>(x: &'a u32, y: &'b u32) -> (&'a u32, &'b u32) {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+...
+LL | (a, b)
+ | ^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
+ |
+ = help: consider adding the following bound: `'a: 'b`
+
+error: lifetime may not live long enough
+ --> $DIR/project-fn-ret-contravariant.rs:46:4
+ |
+LL | fn transmute<'a,'b>(x: &'a u32, y: &'b u32) -> (&'a u32, &'b u32) {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+...
+LL | (a, b)
+ | ^^^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b`
+ |
+ = help: consider adding the following bound: `'b: 'a`
+
+help: `'a` and `'b` must be the same: replace one with the other
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/associated-types/cache/project-fn-ret-contravariant.rs b/src/test/ui/associated-types/cache/project-fn-ret-contravariant.rs
new file mode 100644
index 000000000..f1ea6627a
--- /dev/null
+++ b/src/test/ui/associated-types/cache/project-fn-ret-contravariant.rs
@@ -0,0 +1,50 @@
+#![feature(unboxed_closures)]
+
+// Test for projection cache. We should be able to project distinct
+// lifetimes from `foo` as we reinstantiate it multiple times, but not
+// if we do it just once. In this variant, the region `'a` is used in
+// an contravariant position, which affects the results.
+
+// revisions: ok oneuse transmute krisskross
+//[ok] check-pass
+//[oneuse] check-pass
+
+#![allow(dead_code, unused_variables)]
+
+fn foo<'a>() -> &'a u32 { loop { } }
+
+fn bar<T>(t: T, x: T::Output) -> T::Output
+ where T: FnOnce<()>
+{
+ t()
+}
+
+#[cfg(ok)] // two instantiations: OK
+fn baz<'a,'b>(x: &'a u32, y: &'b u32) -> (&'a u32, &'b u32) {
+ let a = bar(foo, x);
+ let b = bar(foo, y);
+ (a, b)
+}
+
+#[cfg(oneuse)] // one instantiation: OK (surprisingly)
+fn baz<'a,'b>(x: &'a u32, y: &'b u32) -> (&'a u32, &'b u32) {
+ let f /* : fn() -> &'static u32 */ = foo; // <-- inferred type annotated
+ let a = bar(f, x); // this is considered ok because fn args are contravariant...
+ let b = bar(f, y); // ...and hence we infer T to distinct values in each call.
+ (a, b)
+}
+
+#[cfg(transmute)] // one instantiations: BAD
+fn baz<'a,'b>(x: &'a u32) -> &'static u32 {
+ bar(foo, x) //[transmute]~ ERROR lifetime may not live long enough
+}
+
+#[cfg(krisskross)] // two instantiations, mixing and matching: BAD
+fn transmute<'a,'b>(x: &'a u32, y: &'b u32) -> (&'a u32, &'b u32) {
+ let a = bar(foo, y);
+ let b = bar(foo, x);
+ (a, b) //[krisskross]~ ERROR lifetime may not live long enough
+ //[krisskross]~^ ERROR lifetime may not live long enough
+}
+
+fn main() { }
diff --git a/src/test/ui/associated-types/cache/project-fn-ret-contravariant.transmute.stderr b/src/test/ui/associated-types/cache/project-fn-ret-contravariant.transmute.stderr
new file mode 100644
index 000000000..6d8ab2c3f
--- /dev/null
+++ b/src/test/ui/associated-types/cache/project-fn-ret-contravariant.transmute.stderr
@@ -0,0 +1,10 @@
+error: lifetime may not live long enough
+ --> $DIR/project-fn-ret-contravariant.rs:39:4
+ |
+LL | fn baz<'a,'b>(x: &'a u32) -> &'static u32 {
+ | -- lifetime `'a` defined here
+LL | bar(foo, x)
+ | ^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/associated-types/cache/project-fn-ret-invariant.krisskross.stderr b/src/test/ui/associated-types/cache/project-fn-ret-invariant.krisskross.stderr
new file mode 100644
index 000000000..ada12c7ee
--- /dev/null
+++ b/src/test/ui/associated-types/cache/project-fn-ret-invariant.krisskross.stderr
@@ -0,0 +1,36 @@
+error: lifetime may not live long enough
+ --> $DIR/project-fn-ret-invariant.rs:59:5
+ |
+LL | fn transmute<'a, 'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+...
+LL | (a, b)
+ | ^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
+ |
+ = help: consider adding the following bound: `'a: 'b`
+ = note: requirement occurs because of the type `Type<'_>`, which makes the generic argument `'_` invariant
+ = note: the struct `Type<'a>` is invariant over the parameter `'a`
+ = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
+
+error: lifetime may not live long enough
+ --> $DIR/project-fn-ret-invariant.rs:59:5
+ |
+LL | fn transmute<'a, 'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+...
+LL | (a, b)
+ | ^^^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b`
+ |
+ = help: consider adding the following bound: `'b: 'a`
+ = note: requirement occurs because of the type `Type<'_>`, which makes the generic argument `'_` invariant
+ = note: the struct `Type<'a>` is invariant over the parameter `'a`
+ = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
+
+help: `'a` and `'b` must be the same: replace one with the other
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/associated-types/cache/project-fn-ret-invariant.oneuse.stderr b/src/test/ui/associated-types/cache/project-fn-ret-invariant.oneuse.stderr
new file mode 100644
index 000000000..cc1560162
--- /dev/null
+++ b/src/test/ui/associated-types/cache/project-fn-ret-invariant.oneuse.stderr
@@ -0,0 +1,36 @@
+error: lifetime may not live long enough
+ --> $DIR/project-fn-ret-invariant.rs:40:13
+ |
+LL | fn baz<'a, 'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+LL | let f = foo; // <-- No consistent type can be inferred for `f` here.
+LL | let a = bar(f, x);
+ | ^^^^^^^^^ argument requires that `'a` must outlive `'b`
+ |
+ = help: consider adding the following bound: `'a: 'b`
+ = note: requirement occurs because of the type `Type<'_>`, which makes the generic argument `'_` invariant
+ = note: the struct `Type<'a>` is invariant over the parameter `'a`
+ = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
+
+error: lifetime may not live long enough
+ --> $DIR/project-fn-ret-invariant.rs:40:13
+ |
+LL | fn baz<'a, 'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+LL | let f = foo; // <-- No consistent type can be inferred for `f` here.
+LL | let a = bar(f, x);
+ | ^^^^^^^^^ argument requires that `'b` must outlive `'a`
+ |
+ = help: consider adding the following bound: `'b: 'a`
+ = note: requirement occurs because of a function pointer to `foo`
+ = note: the function `foo` is invariant over the parameter `'a`
+ = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
+
+help: `'a` and `'b` must be the same: replace one with the other
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/associated-types/cache/project-fn-ret-invariant.rs b/src/test/ui/associated-types/cache/project-fn-ret-invariant.rs
new file mode 100644
index 000000000..1075fd6e0
--- /dev/null
+++ b/src/test/ui/associated-types/cache/project-fn-ret-invariant.rs
@@ -0,0 +1,64 @@
+#![feature(unboxed_closures)]
+// Test for projection cache. We should be able to project distinct
+// lifetimes from `foo` as we reinstantiate it multiple times, but not
+// if we do it just once. In this variant, the region `'a` is used in
+// an invariant position, which affects the results.
+
+// revisions: ok oneuse transmute krisskross
+//[ok] check-pass
+
+#![allow(dead_code, unused_variables)]
+
+use std::marker::PhantomData;
+
+struct Type<'a> {
+ // Invariant
+ data: PhantomData<fn(&'a u32) -> &'a u32>,
+}
+
+fn foo<'a>() -> Type<'a> {
+ loop {}
+}
+
+fn bar<T>(t: T, x: T::Output) -> T::Output
+where
+ T: FnOnce<()>,
+{
+ t()
+}
+
+#[cfg(ok)] // two instantiations: OK
+fn baz<'a, 'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) {
+ let a = bar(foo, x);
+ let b = bar(foo, y);
+ (a, b)
+}
+
+#[cfg(oneuse)] // one instantiation: BAD
+fn baz<'a, 'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) {
+ let f = foo; // <-- No consistent type can be inferred for `f` here.
+ let a = bar(f, x);
+ //[oneuse]~^ ERROR lifetime may not live long enough
+ //[oneuse]~| ERROR lifetime may not live long enough
+ let b = bar(f, y);
+ (a, b)
+}
+
+#[cfg(transmute)] // one instantiations: BAD
+fn baz<'a, 'b>(x: Type<'a>) -> Type<'static> {
+ // Cannot instantiate `foo` with any lifetime other than `'a`,
+ // since it is provided as input.
+
+ bar(foo, x) //[transmute]~ ERROR lifetime may not live long enough
+}
+
+#[cfg(krisskross)] // two instantiations, mixing and matching: BAD
+fn transmute<'a, 'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) {
+ let a = bar(foo, y);
+ let b = bar(foo, x);
+ (a, b)
+ //[krisskross]~^ ERROR lifetime may not live long enough
+ //[krisskross]~| ERROR lifetime may not live long enough
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr b/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr
new file mode 100644
index 000000000..b64cb2c3d
--- /dev/null
+++ b/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr
@@ -0,0 +1,15 @@
+error: lifetime may not live long enough
+ --> $DIR/project-fn-ret-invariant.rs:52:5
+ |
+LL | fn baz<'a, 'b>(x: Type<'a>) -> Type<'static> {
+ | -- lifetime `'a` defined here
+...
+LL | bar(foo, x)
+ | ^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
+ |
+ = note: requirement occurs because of the type `Type<'_>`, which makes the generic argument `'_` invariant
+ = note: the struct `Type<'a>` is invariant over the parameter `'a`
+ = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
+
+error: aborting due to previous error
+