diff options
Diffstat (limited to 'src/test/ui/associated-types/cache')
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 + |