From cfce351ad39ae0f5e35006ad11fabb4ec866d725 Mon Sep 17 00:00:00 2001 From: Andre Bogus Date: Tue, 23 Aug 2016 07:40:51 +0200 Subject: [PATCH 1/8] first attempt at implementing RFC 1623. This fixes #35897. This is a work in progress. In particular, I want to add more tests, especially the compile-fail test is very bare-bones. --- src/librustc_typeck/collect.rs | 2 +- src/test/compile-fail/rfc1623.rs | 21 +++++++++++++ src/test/run-pass/rfc1623.rs | 52 ++++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 src/test/compile-fail/rfc1623.rs create mode 100644 src/test/run-pass/rfc1623.rs diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 7e1fb32881d6f..0f48b7ca67e63 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1554,7 +1554,7 @@ fn type_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, NodeItem(item) => { match item.node { ItemStatic(ref t, _, _) | ItemConst(ref t, _) => { - ccx.icx(&()).to_ty(&ExplicitRscope, &t) + ccx.icx(&()).to_ty(&ElidableRscope::new(ty::ReStatic), &t) } ItemFn(ref decl, unsafety, _, abi, ref generics, _) => { let tofd = AstConv::ty_of_bare_fn(&ccx.icx(generics), unsafety, abi, &decl, diff --git a/src/test/compile-fail/rfc1623.rs b/src/test/compile-fail/rfc1623.rs new file mode 100644 index 0000000000000..dfe58f0d94cc0 --- /dev/null +++ b/src/test/compile-fail/rfc1623.rs @@ -0,0 +1,21 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![allow(dead_code)] + +fn non_elidable<'a, 'b>(a: &'a u8, b: &'b u8) -> &'a u8 { a } + +// the boundaries of elision +static NON_ELIDABLE_FN : &fn(&u8, &u8) -> &u8 = non_elidable; +//~^ERROR: missing lifetime specifier + +fn main() { + // nothing to do here +} diff --git a/src/test/run-pass/rfc1623.rs b/src/test/run-pass/rfc1623.rs new file mode 100644 index 0000000000000..b702a03b481f7 --- /dev/null +++ b/src/test/run-pass/rfc1623.rs @@ -0,0 +1,52 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![allow(dead_code)] + +// very simple test for a 'static static with default lifetime +static SOME_STATIC_STR : &str = "&'static str"; +const SOME_CONST_STR : &str = "&'static str"; + +// this should be the same as without default: +static SOME_EXPLICIT_STATIC_STR : &'static str = "&'static str"; +const SOME_EXPLICIT_CONST_STR : &'static str = "&'static str"; + +// a function that elides to an unbound lifetime for both in- and output +fn id_u8_slice(arg: &[u8]) -> &[u8] { arg } + +// one with a function, argument elided +static SOME_STATIC_SIMPLE_FN : &fn(&[u8]) -> &[u8] = id_u8_slice; +const SOME_CONST_SIMPLE_FN : &fn(&[u8]) -> &[u8] = id_u8_slice; + +// this should be the same as without elision +static SOME_STATIC_NON_ELIDED_fN : &fn<'a>(&'a [u8]) -> &'a [u8] = id_u8_slice; +const SOME_CONST_NON_ELIDED_fN : &fn<'a>(&'a [u8]) -> &'a [u8] = id_u8_slice; + +// another function that elides, each to a different unbound lifetime +fn multi_args(a: &u8, b: &u8, c: &u8) { } + +static SOME_STATIC_MULTI_FN : &fn(&u8, &u8, &u8) = multi_args; +const SOME_CONST_MULTI_FN : &fn(&u8, &u8, &u8) = multi_args; + + +fn main() { + // make sure that the lifetime is actually elided (and not defaulted) + let x = &[1u8, 2, 3]; + SOME_STATIC_SIMPLE_FN(x); + SOME_CONST_SIMPLE_FN(x); + + // make sure this works with different lifetimes + let a = &1; + { + let b = &2; + let c = &3; + SOME_CONST_MULTI_FN(a, b, c); + } +} From 8bdb3e10ca637033667dec25ebfff64a069c46eb Mon Sep 17 00:00:00 2001 From: Andre Bogus Date: Tue, 23 Aug 2016 12:34:28 +0200 Subject: [PATCH 2/8] fix run-pass test --- src/test/run-pass/rfc1623.rs | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/test/run-pass/rfc1623.rs b/src/test/run-pass/rfc1623.rs index b702a03b481f7..81e32efe6c775 100644 --- a/src/test/run-pass/rfc1623.rs +++ b/src/test/run-pass/rfc1623.rs @@ -22,18 +22,24 @@ const SOME_EXPLICIT_CONST_STR : &'static str = "&'static str"; fn id_u8_slice(arg: &[u8]) -> &[u8] { arg } // one with a function, argument elided -static SOME_STATIC_SIMPLE_FN : &fn(&[u8]) -> &[u8] = id_u8_slice; -const SOME_CONST_SIMPLE_FN : &fn(&[u8]) -> &[u8] = id_u8_slice; +static SOME_STATIC_SIMPLE_FN : &fn(&[u8]) -> &[u8] = + &(id_u8_slice as fn(&[u8]) -> &[u8]); +const SOME_CONST_SIMPLE_FN : &fn(&[u8]) -> &[u8] = + &(id_u8_slice as fn(&[u8]) -> &[u8]); // this should be the same as without elision -static SOME_STATIC_NON_ELIDED_fN : &fn<'a>(&'a [u8]) -> &'a [u8] = id_u8_slice; -const SOME_CONST_NON_ELIDED_fN : &fn<'a>(&'a [u8]) -> &'a [u8] = id_u8_slice; +static SOME_STATIC_NON_ELIDED_fN : &for<'a> fn(&'a [u8]) -> &'a [u8] = + &(id_u8_slice as for<'a> fn(&'a [u8]) -> &'a [u8]); +const SOME_CONST_NON_ELIDED_fN : &for<'a> fn(&'a [u8]) -> &'a [u8] = + &(id_u8_slice as for<'a> fn(&'a [u8]) -> &'a [u8]); // another function that elides, each to a different unbound lifetime fn multi_args(a: &u8, b: &u8, c: &u8) { } -static SOME_STATIC_MULTI_FN : &fn(&u8, &u8, &u8) = multi_args; -const SOME_CONST_MULTI_FN : &fn(&u8, &u8, &u8) = multi_args; +static SOME_STATIC_MULTI_FN : &fn(&u8, &u8, &u8) = + &(multi_args as fn(&u8, &u8, &u8)); +const SOME_CONST_MULTI_FN : &fn(&u8, &u8, &u8) = + &(multi_args as fn(&u8, &u8, &u8)); fn main() { @@ -41,7 +47,7 @@ fn main() { let x = &[1u8, 2, 3]; SOME_STATIC_SIMPLE_FN(x); SOME_CONST_SIMPLE_FN(x); - + // make sure this works with different lifetimes let a = &1; { From a6b9fea5cd10afe9d7b81d30b2b082f727aea255 Mon Sep 17 00:00:00 2001 From: Andre Bogus Date: Tue, 23 Aug 2016 12:38:09 +0200 Subject: [PATCH 3/8] fixed compile-fail test --- src/test/compile-fail/rfc1623.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/compile-fail/rfc1623.rs b/src/test/compile-fail/rfc1623.rs index dfe58f0d94cc0..a52b9c596aa9a 100644 --- a/src/test/compile-fail/rfc1623.rs +++ b/src/test/compile-fail/rfc1623.rs @@ -13,8 +13,9 @@ fn non_elidable<'a, 'b>(a: &'a u8, b: &'b u8) -> &'a u8 { a } // the boundaries of elision -static NON_ELIDABLE_FN : &fn(&u8, &u8) -> &u8 = non_elidable; +static NON_ELIDABLE_FN : &fn(&u8, &u8) -> &u8 = //~^ERROR: missing lifetime specifier + &(non_elidable as fn(&u8, &u8) -> &u8); fn main() { // nothing to do here From e0eb1ba0db9c832a0385f31710edddd675feee14 Mon Sep 17 00:00:00 2001 From: Andre Bogus Date: Tue, 23 Aug 2016 21:36:19 +0200 Subject: [PATCH 4/8] fixed and extended tests, however... MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ...there is still one confusing thing – see the _BAZ functions, which appear to be elided in the `compile-fail` test and defaulted in the ´run-pass` test (if you uncomment line 73). --- src/test/compile-fail/rfc1623.rs | 17 +++++++++-- src/test/run-pass/rfc1623.rs | 50 +++++++++++++++++++++++--------- 2 files changed, 51 insertions(+), 16 deletions(-) diff --git a/src/test/compile-fail/rfc1623.rs b/src/test/compile-fail/rfc1623.rs index a52b9c596aa9a..840307ea456e5 100644 --- a/src/test/compile-fail/rfc1623.rs +++ b/src/test/compile-fail/rfc1623.rs @@ -13,10 +13,21 @@ fn non_elidable<'a, 'b>(a: &'a u8, b: &'b u8) -> &'a u8 { a } // the boundaries of elision -static NON_ELIDABLE_FN : &fn(&u8, &u8) -> &u8 = -//~^ERROR: missing lifetime specifier +static NON_ELIDABLE_FN : &fn(&u8, &u8) -> &u8 = +//^ERROR: missing lifetime specifier &(non_elidable as fn(&u8, &u8) -> &u8); +type Baz<'a> = fn(&'a [u8]) -> Option; + +fn baz(e: &[u8]) -> Option { e.first().map(|x| *x) } + +static STATIC_BAZ : &Baz<'static> = &(baz as Baz); +const CONST_BAZ : &Baz<'static> = &(baz as Baz); + fn main() { - // nothing to do here + let y = [1u8, 2, 3]; + + //surprisingly this appears to work, so lifetime < `'static` is valid + assert_eq!(Some(1), STATIC_BAZ(y)); + assert_eq!(Some(1), CONST_BAZ(y)); } diff --git a/src/test/run-pass/rfc1623.rs b/src/test/run-pass/rfc1623.rs index 81e32efe6c775..bd0420bb5067a 100644 --- a/src/test/run-pass/rfc1623.rs +++ b/src/test/run-pass/rfc1623.rs @@ -11,48 +11,72 @@ #![allow(dead_code)] // very simple test for a 'static static with default lifetime -static SOME_STATIC_STR : &str = "&'static str"; -const SOME_CONST_STR : &str = "&'static str"; +static STATIC_STR : &str = "&'static str"; +const CONST_STR : &str = "&'static str"; // this should be the same as without default: -static SOME_EXPLICIT_STATIC_STR : &'static str = "&'static str"; -const SOME_EXPLICIT_CONST_STR : &'static str = "&'static str"; +static EXPLICIT_STATIC_STR : &'static str = "&'static str"; +const EXPLICIT_CONST_STR : &'static str = "&'static str"; // a function that elides to an unbound lifetime for both in- and output fn id_u8_slice(arg: &[u8]) -> &[u8] { arg } // one with a function, argument elided -static SOME_STATIC_SIMPLE_FN : &fn(&[u8]) -> &[u8] = +static STATIC_SIMPLE_FN : &fn(&[u8]) -> &[u8] = &(id_u8_slice as fn(&[u8]) -> &[u8]); -const SOME_CONST_SIMPLE_FN : &fn(&[u8]) -> &[u8] = +const CONST_SIMPLE_FN : &fn(&[u8]) -> &[u8] = &(id_u8_slice as fn(&[u8]) -> &[u8]); // this should be the same as without elision -static SOME_STATIC_NON_ELIDED_fN : &for<'a> fn(&'a [u8]) -> &'a [u8] = +static STATIC_NON_ELIDED_fN : &for<'a> fn(&'a [u8]) -> &'a [u8] = &(id_u8_slice as for<'a> fn(&'a [u8]) -> &'a [u8]); -const SOME_CONST_NON_ELIDED_fN : &for<'a> fn(&'a [u8]) -> &'a [u8] = +const CONST_NON_ELIDED_fN : &for<'a> fn(&'a [u8]) -> &'a [u8] = &(id_u8_slice as for<'a> fn(&'a [u8]) -> &'a [u8]); // another function that elides, each to a different unbound lifetime fn multi_args(a: &u8, b: &u8, c: &u8) { } -static SOME_STATIC_MULTI_FN : &fn(&u8, &u8, &u8) = +static STATIC_MULTI_FN : &fn(&u8, &u8, &u8) = &(multi_args as fn(&u8, &u8, &u8)); -const SOME_CONST_MULTI_FN : &fn(&u8, &u8, &u8) = +const CONST_MULTI_FN : &fn(&u8, &u8, &u8) = &(multi_args as fn(&u8, &u8, &u8)); +struct Foo<'a> { + bools: &'a [bool] +} + +static STATIC_FOO : Foo = Foo { bools: &[true, false] }; +const CONST_FOO : Foo = Foo { bools: &[true, false] }; + +type Bar<'a> = Foo<'a>; + +static STATIC_BAR : Bar = Bar { bools: &[true, false] }; +const CONST_BAR : Bar = Bar { bools: &[true, false] }; + +type Baz<'a> = fn(&'a [u8]) -> Option; + +fn baz(e: &[u8]) -> Option { e.first().map(|x| *x) } + +static STATIC_BAZ : &Baz = &(baz as Baz); +const CONST_BAZ : &Baz = &(baz as Baz); + +static BYTES : &[u8] = &[1, 2, 3]; fn main() { // make sure that the lifetime is actually elided (and not defaulted) let x = &[1u8, 2, 3]; - SOME_STATIC_SIMPLE_FN(x); - SOME_CONST_SIMPLE_FN(x); + STATIC_SIMPLE_FN(x); + CONST_SIMPLE_FN(x); + + let y = &[1u8, 2, 3]; + STATIC_BAZ(BYTES); + //CONST_BAZ(y); // strangely enough, this fails // make sure this works with different lifetimes let a = &1; { let b = &2; let c = &3; - SOME_CONST_MULTI_FN(a, b, c); + CONST_MULTI_FN(a, b, c); } } From 1fd85b1a80429a5d217424b2e7f51d0082713b9d Mon Sep 17 00:00:00 2001 From: Andre Bogus Date: Wed, 24 Aug 2016 21:19:39 +0200 Subject: [PATCH 5/8] fixed compile-fail test --- src/test/compile-fail/rfc1623.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/test/compile-fail/rfc1623.rs b/src/test/compile-fail/rfc1623.rs index 840307ea456e5..963459b27bf1f 100644 --- a/src/test/compile-fail/rfc1623.rs +++ b/src/test/compile-fail/rfc1623.rs @@ -14,7 +14,7 @@ fn non_elidable<'a, 'b>(a: &'a u8, b: &'b u8) -> &'a u8 { a } // the boundaries of elision static NON_ELIDABLE_FN : &fn(&u8, &u8) -> &u8 = -//^ERROR: missing lifetime specifier +//~^ ERROR: missing lifetime specifier &(non_elidable as fn(&u8, &u8) -> &u8); type Baz<'a> = fn(&'a [u8]) -> Option; @@ -25,7 +25,8 @@ static STATIC_BAZ : &Baz<'static> = &(baz as Baz); const CONST_BAZ : &Baz<'static> = &(baz as Baz); fn main() { - let y = [1u8, 2, 3]; + let x = &[1u8, 2, 3]; + let y = x; //surprisingly this appears to work, so lifetime < `'static` is valid assert_eq!(Some(1), STATIC_BAZ(y)); From 744312754dc3a3c36d2a609bb24889cb1b7994de Mon Sep 17 00:00:00 2001 From: Andre Bogus Date: Sun, 28 Aug 2016 20:35:48 +0200 Subject: [PATCH 6/8] fixed and extended tests once more --- src/test/compile-fail/rfc1623.rs | 70 ++++++++++++++++++++++++++++++-- src/test/run-pass/rfc1623.rs | 5 +-- 2 files changed, 69 insertions(+), 6 deletions(-) diff --git a/src/test/compile-fail/rfc1623.rs b/src/test/compile-fail/rfc1623.rs index 963459b27bf1f..abdcc02de767f 100644 --- a/src/test/compile-fail/rfc1623.rs +++ b/src/test/compile-fail/rfc1623.rs @@ -17,18 +17,82 @@ static NON_ELIDABLE_FN : &fn(&u8, &u8) -> &u8 = //~^ ERROR: missing lifetime specifier &(non_elidable as fn(&u8, &u8) -> &u8); +struct SomeStruct<'x, 'y, 'z: 'x> { + foo: &'x Foo<'z>, + bar: &'x Bar<'z>, + f: &'y for<'a, 'b: 'a> Fn(&'a Foo<'b>) -> &'a Bar<'b>, +} + +fn id(t: T) -> T { t } + +static SOME_STRUCT : &SomeStruct = SomeStruct { + foo: &Foo { bools: &[false, true] }, + bar: &Bar { bools: &[true, true] }, + f: &id, +}; + +// very simple test for a 'static static with default lifetime +static STATIC_STR : &'static str = "&'static str"; +const CONST_STR : &'static str = "&'static str"; + +// this should be the same as without default: +static EXPLICIT_STATIC_STR : &'static str = "&'static str"; +const EXPLICIT_CONST_STR : &'static str = "&'static str"; + +// a function that elides to an unbound lifetime for both in- and output +fn id_u8_slice(arg: &[u8]) -> &[u8] { arg } + +// one with a function, argument elided +static STATIC_SIMPLE_FN : &'static fn(&[u8]) -> &[u8] = + &(id_u8_slice as fn(&[u8]) -> &[u8]); +const CONST_SIMPLE_FN : &'static fn(&[u8]) -> &[u8] = + &(id_u8_slice as fn(&[u8]) -> &[u8]); + +// this should be the same as without elision +static STATIC_NON_ELIDED_fN : &'static for<'a> fn(&'a [u8]) -> &'a [u8] = + &(id_u8_slice as for<'a> fn(&'a [u8]) -> &'a [u8]); +const CONST_NON_ELIDED_fN : &'static for<'a> fn(&'a [u8]) -> &'a [u8] = + &(id_u8_slice as for<'a> fn(&'a [u8]) -> &'a [u8]); + +// another function that elides, each to a different unbound lifetime +fn multi_args(a: &u8, b: &u8, c: &u8) { } + +static STATIC_MULTI_FN : &'static fn(&u8, &u8, &u8) = + &(multi_args as fn(&u8, &u8, &u8)); +const CONST_MULTI_FN : &'static fn(&u8, &u8, &u8) = + &(multi_args as fn(&u8, &u8, &u8)); + +struct Foo<'a> { + bools: &'a [bool] +} + +static STATIC_FOO : Foo<'static> = Foo { bools: &[true, false] }; +const CONST_FOO : Foo<'static> = Foo { bools: &[true, false] }; + +type Bar<'a> = Foo<'a>; + +static STATIC_BAR : Bar<'static> = Bar { bools: &[true, false] }; +const CONST_BAR : Bar<'static> = Bar { bools: &[true, false] }; + type Baz<'a> = fn(&'a [u8]) -> Option; fn baz(e: &[u8]) -> Option { e.first().map(|x| *x) } -static STATIC_BAZ : &Baz<'static> = &(baz as Baz); -const CONST_BAZ : &Baz<'static> = &(baz as Baz); +static STATIC_BAZ : &'static Baz<'static> = &(baz as Baz); +const CONST_BAZ : &'static Baz<'static> = &(baz as Baz); + +static BYTES : &'static [u8] = &[1, 2, 3]; fn main() { let x = &[1u8, 2, 3]; let y = x; - //surprisingly this appears to work, so lifetime < `'static` is valid + //this works, so lifetime < `'static` is valid assert_eq!(Some(1), STATIC_BAZ(y)); assert_eq!(Some(1), CONST_BAZ(y)); + + let y = &[1u8, 2, 3]; + //^~ ERROR: borrowed values does not live long enough + STATIC_BAZ(BYTES); // BYTES has static lifetime + CONST_BAZ(y); // This forces static lifetime, which y has not } diff --git a/src/test/run-pass/rfc1623.rs b/src/test/run-pass/rfc1623.rs index bd0420bb5067a..0915118ca27c0 100644 --- a/src/test/run-pass/rfc1623.rs +++ b/src/test/run-pass/rfc1623.rs @@ -68,9 +68,8 @@ fn main() { STATIC_SIMPLE_FN(x); CONST_SIMPLE_FN(x); - let y = &[1u8, 2, 3]; - STATIC_BAZ(BYTES); - //CONST_BAZ(y); // strangely enough, this fails + STATIC_BAZ(BYTES); // neees static lifetime + CONST_BAZ(BYTES); // make sure this works with different lifetimes let a = &1; From e95f119d68008891193cdc10cf2ebc33e73c693c Mon Sep 17 00:00:00 2001 From: Andre Bogus Date: Mon, 29 Aug 2016 14:03:57 +0200 Subject: [PATCH 7/8] rustfmt tests --- src/test/compile-fail/rfc1623.rs | 72 ++++++++++++++++---------------- src/test/run-pass/rfc1623.rs | 54 ++++++++++++------------ 2 files changed, 64 insertions(+), 62 deletions(-) diff --git a/src/test/compile-fail/rfc1623.rs b/src/test/compile-fail/rfc1623.rs index abdcc02de767f..3e9afdd5b13ae 100644 --- a/src/test/compile-fail/rfc1623.rs +++ b/src/test/compile-fail/rfc1623.rs @@ -10,12 +10,12 @@ #![allow(dead_code)] -fn non_elidable<'a, 'b>(a: &'a u8, b: &'b u8) -> &'a u8 { a } +fn non_elidable<'a, 'b>(a: &'a u8, b: &'b u8) -> &'a u8 { + a +} // the boundaries of elision -static NON_ELIDABLE_FN : &fn(&u8, &u8) -> &u8 = -//~^ ERROR: missing lifetime specifier - &(non_elidable as fn(&u8, &u8) -> &u8); +static NON_ELIDABLE_FN: &fn(&u8, &u8) -> &u8 = &(non_elidable as fn(&u8, &u8) -> &u8); struct SomeStruct<'x, 'y, 'z: 'x> { foo: &'x Foo<'z>, @@ -23,76 +23,78 @@ struct SomeStruct<'x, 'y, 'z: 'x> { f: &'y for<'a, 'b: 'a> Fn(&'a Foo<'b>) -> &'a Bar<'b>, } -fn id(t: T) -> T { t } +fn id(t: T) -> T { + t +} -static SOME_STRUCT : &SomeStruct = SomeStruct { +static SOME_STRUCT: &SomeStruct = SomeStruct { foo: &Foo { bools: &[false, true] }, bar: &Bar { bools: &[true, true] }, f: &id, }; // very simple test for a 'static static with default lifetime -static STATIC_STR : &'static str = "&'static str"; -const CONST_STR : &'static str = "&'static str"; +static STATIC_STR: &'static str = "&'static str"; +const CONST_STR: &'static str = "&'static str"; // this should be the same as without default: -static EXPLICIT_STATIC_STR : &'static str = "&'static str"; -const EXPLICIT_CONST_STR : &'static str = "&'static str"; +static EXPLICIT_STATIC_STR: &'static str = "&'static str"; +const EXPLICIT_CONST_STR: &'static str = "&'static str"; // a function that elides to an unbound lifetime for both in- and output -fn id_u8_slice(arg: &[u8]) -> &[u8] { arg } +fn id_u8_slice(arg: &[u8]) -> &[u8] { + arg +} // one with a function, argument elided -static STATIC_SIMPLE_FN : &'static fn(&[u8]) -> &[u8] = - &(id_u8_slice as fn(&[u8]) -> &[u8]); -const CONST_SIMPLE_FN : &'static fn(&[u8]) -> &[u8] = - &(id_u8_slice as fn(&[u8]) -> &[u8]); +static STATIC_SIMPLE_FN: &'static fn(&[u8]) -> &[u8] = &(id_u8_slice as fn(&[u8]) -> &[u8]); +const CONST_SIMPLE_FN: &'static fn(&[u8]) -> &[u8] = &(id_u8_slice as fn(&[u8]) -> &[u8]); // this should be the same as without elision -static STATIC_NON_ELIDED_fN : &'static for<'a> fn(&'a [u8]) -> &'a [u8] = - &(id_u8_slice as for<'a> fn(&'a [u8]) -> &'a [u8]); -const CONST_NON_ELIDED_fN : &'static for<'a> fn(&'a [u8]) -> &'a [u8] = - &(id_u8_slice as for<'a> fn(&'a [u8]) -> &'a [u8]); +static STATIC_NON_ELIDED_fN: &'static for<'a> fn(&'a [u8]) -> &'a [u8] = + &(id_u8_slice as for<'a> fn(&'a [u8]) -> &'a [u8]); +const CONST_NON_ELIDED_fN: &'static for<'a> fn(&'a [u8]) -> &'a [u8] = + &(id_u8_slice as for<'a> fn(&'a [u8]) -> &'a [u8]); // another function that elides, each to a different unbound lifetime -fn multi_args(a: &u8, b: &u8, c: &u8) { } +fn multi_args(a: &u8, b: &u8, c: &u8) {} -static STATIC_MULTI_FN : &'static fn(&u8, &u8, &u8) = - &(multi_args as fn(&u8, &u8, &u8)); -const CONST_MULTI_FN : &'static fn(&u8, &u8, &u8) = - &(multi_args as fn(&u8, &u8, &u8)); +static STATIC_MULTI_FN: &'static fn(&u8, &u8, &u8) = &(multi_args as fn(&u8, &u8, &u8)); +const CONST_MULTI_FN: &'static fn(&u8, &u8, &u8) = &(multi_args as fn(&u8, &u8, &u8)); struct Foo<'a> { - bools: &'a [bool] + bools: &'a [bool], } -static STATIC_FOO : Foo<'static> = Foo { bools: &[true, false] }; -const CONST_FOO : Foo<'static> = Foo { bools: &[true, false] }; +static STATIC_FOO: Foo<'static> = Foo { bools: &[true, false] }; +const CONST_FOO: Foo<'static> = Foo { bools: &[true, false] }; type Bar<'a> = Foo<'a>; -static STATIC_BAR : Bar<'static> = Bar { bools: &[true, false] }; -const CONST_BAR : Bar<'static> = Bar { bools: &[true, false] }; +static STATIC_BAR: Bar<'static> = Bar { bools: &[true, false] }; +const CONST_BAR: Bar<'static> = Bar { bools: &[true, false] }; type Baz<'a> = fn(&'a [u8]) -> Option; -fn baz(e: &[u8]) -> Option { e.first().map(|x| *x) } +fn baz(e: &[u8]) -> Option { + e.first().map(|x| *x) +} -static STATIC_BAZ : &'static Baz<'static> = &(baz as Baz); -const CONST_BAZ : &'static Baz<'static> = &(baz as Baz); +static STATIC_BAZ: &'static Baz<'static> = &(baz as Baz); +const CONST_BAZ: &'static Baz<'static> = &(baz as Baz); -static BYTES : &'static [u8] = &[1, 2, 3]; +static BYTES: &'static [u8] = &[1, 2, 3]; fn main() { let x = &[1u8, 2, 3]; let y = x; - //this works, so lifetime < `'static` is valid + // this works, so lifetime < `'static` is valid assert_eq!(Some(1), STATIC_BAZ(y)); assert_eq!(Some(1), CONST_BAZ(y)); let y = &[1u8, 2, 3]; - //^~ ERROR: borrowed values does not live long enough + // ^~ ERROR: borrowed values does not live long enough STATIC_BAZ(BYTES); // BYTES has static lifetime CONST_BAZ(y); // This forces static lifetime, which y has not } diff --git a/src/test/run-pass/rfc1623.rs b/src/test/run-pass/rfc1623.rs index 0915118ca27c0..17453933c8abc 100644 --- a/src/test/run-pass/rfc1623.rs +++ b/src/test/run-pass/rfc1623.rs @@ -11,56 +11,56 @@ #![allow(dead_code)] // very simple test for a 'static static with default lifetime -static STATIC_STR : &str = "&'static str"; -const CONST_STR : &str = "&'static str"; +static STATIC_STR: &str = "&'static str"; +const CONST_STR: &str = "&'static str"; // this should be the same as without default: -static EXPLICIT_STATIC_STR : &'static str = "&'static str"; -const EXPLICIT_CONST_STR : &'static str = "&'static str"; +static EXPLICIT_STATIC_STR: &'static str = "&'static str"; +const EXPLICIT_CONST_STR: &'static str = "&'static str"; // a function that elides to an unbound lifetime for both in- and output -fn id_u8_slice(arg: &[u8]) -> &[u8] { arg } +fn id_u8_slice(arg: &[u8]) -> &[u8] { + arg +} // one with a function, argument elided -static STATIC_SIMPLE_FN : &fn(&[u8]) -> &[u8] = - &(id_u8_slice as fn(&[u8]) -> &[u8]); -const CONST_SIMPLE_FN : &fn(&[u8]) -> &[u8] = - &(id_u8_slice as fn(&[u8]) -> &[u8]); +static STATIC_SIMPLE_FN: &fn(&[u8]) -> &[u8] = &(id_u8_slice as fn(&[u8]) -> &[u8]); +const CONST_SIMPLE_FN: &fn(&[u8]) -> &[u8] = &(id_u8_slice as fn(&[u8]) -> &[u8]); // this should be the same as without elision -static STATIC_NON_ELIDED_fN : &for<'a> fn(&'a [u8]) -> &'a [u8] = - &(id_u8_slice as for<'a> fn(&'a [u8]) -> &'a [u8]); -const CONST_NON_ELIDED_fN : &for<'a> fn(&'a [u8]) -> &'a [u8] = - &(id_u8_slice as for<'a> fn(&'a [u8]) -> &'a [u8]); +static STATIC_NON_ELIDED_fN: &for<'a> fn(&'a [u8]) -> &'a [u8] = + &(id_u8_slice as for<'a> fn(&'a [u8]) -> &'a [u8]); +const CONST_NON_ELIDED_fN: &for<'a> fn(&'a [u8]) -> &'a [u8] = + &(id_u8_slice as for<'a> fn(&'a [u8]) -> &'a [u8]); // another function that elides, each to a different unbound lifetime -fn multi_args(a: &u8, b: &u8, c: &u8) { } +fn multi_args(a: &u8, b: &u8, c: &u8) {} -static STATIC_MULTI_FN : &fn(&u8, &u8, &u8) = - &(multi_args as fn(&u8, &u8, &u8)); -const CONST_MULTI_FN : &fn(&u8, &u8, &u8) = - &(multi_args as fn(&u8, &u8, &u8)); +static STATIC_MULTI_FN: &fn(&u8, &u8, &u8) = &(multi_args as fn(&u8, &u8, &u8)); +const CONST_MULTI_FN: &fn(&u8, &u8, &u8) = &(multi_args as fn(&u8, &u8, &u8)); struct Foo<'a> { - bools: &'a [bool] + bools: &'a [bool], } -static STATIC_FOO : Foo = Foo { bools: &[true, false] }; -const CONST_FOO : Foo = Foo { bools: &[true, false] }; +static STATIC_FOO: Foo = Foo { bools: &[true, false] }; +const CONST_FOO: Foo = Foo { bools: &[true, false] }; type Bar<'a> = Foo<'a>; -static STATIC_BAR : Bar = Bar { bools: &[true, false] }; -const CONST_BAR : Bar = Bar { bools: &[true, false] }; +static STATIC_BAR: Bar = Bar { bools: &[true, false] }; +const CONST_BAR: Bar = Bar { bools: &[true, false] }; type Baz<'a> = fn(&'a [u8]) -> Option; -fn baz(e: &[u8]) -> Option { e.first().map(|x| *x) } +fn baz(e: &[u8]) -> Option { + e.first().map(|x| *x) +} -static STATIC_BAZ : &Baz = &(baz as Baz); -const CONST_BAZ : &Baz = &(baz as Baz); +static STATIC_BAZ: &Baz = &(baz as Baz); +const CONST_BAZ: &Baz = &(baz as Baz); -static BYTES : &[u8] = &[1, 2, 3]; +static BYTES: &[u8] = &[1, 2, 3]; fn main() { // make sure that the lifetime is actually elided (and not defaulted) From a87b4d88fb5c40736a5d884ac9fd3f01690d29d6 Mon Sep 17 00:00:00 2001 From: Andre Bogus Date: Mon, 29 Aug 2016 16:45:22 +0200 Subject: [PATCH 8/8] removed unneeded test, also compiletest vs. rustfmt --- src/test/compile-fail/regions-in-consts.rs | 15 ---- src/test/compile-fail/rfc1623.rs | 5 +- src/test/compile-fail/rfc1623.rs.bk | 98 ++++++++++++++++++++++ src/test/run-pass/rfc1623.rs.bk | 81 ++++++++++++++++++ 4 files changed, 182 insertions(+), 17 deletions(-) delete mode 100644 src/test/compile-fail/regions-in-consts.rs create mode 100644 src/test/compile-fail/rfc1623.rs.bk create mode 100644 src/test/run-pass/rfc1623.rs.bk diff --git a/src/test/compile-fail/regions-in-consts.rs b/src/test/compile-fail/regions-in-consts.rs deleted file mode 100644 index 8d0829a4cffc3..0000000000000 --- a/src/test/compile-fail/regions-in-consts.rs +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -static c_y: &isize = &22; //~ ERROR missing lifetime specifier -static c_z: &'static isize = &22; - -fn main() { -} diff --git a/src/test/compile-fail/rfc1623.rs b/src/test/compile-fail/rfc1623.rs index 3e9afdd5b13ae..1d8fc7fe111c0 100644 --- a/src/test/compile-fail/rfc1623.rs +++ b/src/test/compile-fail/rfc1623.rs @@ -16,6 +16,7 @@ fn non_elidable<'a, 'b>(a: &'a u8, b: &'b u8) -> &'a u8 { // the boundaries of elision static NON_ELIDABLE_FN: &fn(&u8, &u8) -> &u8 = &(non_elidable as fn(&u8, &u8) -> &u8); +//~^ ERROR missing lifetime specifier [E0106] struct SomeStruct<'x, 'y, 'z: 'x> { foo: &'x Foo<'z>, @@ -94,7 +95,7 @@ fn main() { assert_eq!(Some(1), CONST_BAZ(y)); let y = &[1u8, 2, 3]; - // ^~ ERROR: borrowed values does not live long enough + STATIC_BAZ(BYTES); // BYTES has static lifetime - CONST_BAZ(y); // This forces static lifetime, which y has not + CONST_BAZ(y); // interestingly this does not get reported } diff --git a/src/test/compile-fail/rfc1623.rs.bk b/src/test/compile-fail/rfc1623.rs.bk new file mode 100644 index 0000000000000..abdcc02de767f --- /dev/null +++ b/src/test/compile-fail/rfc1623.rs.bk @@ -0,0 +1,98 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![allow(dead_code)] + +fn non_elidable<'a, 'b>(a: &'a u8, b: &'b u8) -> &'a u8 { a } + +// the boundaries of elision +static NON_ELIDABLE_FN : &fn(&u8, &u8) -> &u8 = +//~^ ERROR: missing lifetime specifier + &(non_elidable as fn(&u8, &u8) -> &u8); + +struct SomeStruct<'x, 'y, 'z: 'x> { + foo: &'x Foo<'z>, + bar: &'x Bar<'z>, + f: &'y for<'a, 'b: 'a> Fn(&'a Foo<'b>) -> &'a Bar<'b>, +} + +fn id(t: T) -> T { t } + +static SOME_STRUCT : &SomeStruct = SomeStruct { + foo: &Foo { bools: &[false, true] }, + bar: &Bar { bools: &[true, true] }, + f: &id, +}; + +// very simple test for a 'static static with default lifetime +static STATIC_STR : &'static str = "&'static str"; +const CONST_STR : &'static str = "&'static str"; + +// this should be the same as without default: +static EXPLICIT_STATIC_STR : &'static str = "&'static str"; +const EXPLICIT_CONST_STR : &'static str = "&'static str"; + +// a function that elides to an unbound lifetime for both in- and output +fn id_u8_slice(arg: &[u8]) -> &[u8] { arg } + +// one with a function, argument elided +static STATIC_SIMPLE_FN : &'static fn(&[u8]) -> &[u8] = + &(id_u8_slice as fn(&[u8]) -> &[u8]); +const CONST_SIMPLE_FN : &'static fn(&[u8]) -> &[u8] = + &(id_u8_slice as fn(&[u8]) -> &[u8]); + +// this should be the same as without elision +static STATIC_NON_ELIDED_fN : &'static for<'a> fn(&'a [u8]) -> &'a [u8] = + &(id_u8_slice as for<'a> fn(&'a [u8]) -> &'a [u8]); +const CONST_NON_ELIDED_fN : &'static for<'a> fn(&'a [u8]) -> &'a [u8] = + &(id_u8_slice as for<'a> fn(&'a [u8]) -> &'a [u8]); + +// another function that elides, each to a different unbound lifetime +fn multi_args(a: &u8, b: &u8, c: &u8) { } + +static STATIC_MULTI_FN : &'static fn(&u8, &u8, &u8) = + &(multi_args as fn(&u8, &u8, &u8)); +const CONST_MULTI_FN : &'static fn(&u8, &u8, &u8) = + &(multi_args as fn(&u8, &u8, &u8)); + +struct Foo<'a> { + bools: &'a [bool] +} + +static STATIC_FOO : Foo<'static> = Foo { bools: &[true, false] }; +const CONST_FOO : Foo<'static> = Foo { bools: &[true, false] }; + +type Bar<'a> = Foo<'a>; + +static STATIC_BAR : Bar<'static> = Bar { bools: &[true, false] }; +const CONST_BAR : Bar<'static> = Bar { bools: &[true, false] }; + +type Baz<'a> = fn(&'a [u8]) -> Option; + +fn baz(e: &[u8]) -> Option { e.first().map(|x| *x) } + +static STATIC_BAZ : &'static Baz<'static> = &(baz as Baz); +const CONST_BAZ : &'static Baz<'static> = &(baz as Baz); + +static BYTES : &'static [u8] = &[1, 2, 3]; + +fn main() { + let x = &[1u8, 2, 3]; + let y = x; + + //this works, so lifetime < `'static` is valid + assert_eq!(Some(1), STATIC_BAZ(y)); + assert_eq!(Some(1), CONST_BAZ(y)); + + let y = &[1u8, 2, 3]; + //^~ ERROR: borrowed values does not live long enough + STATIC_BAZ(BYTES); // BYTES has static lifetime + CONST_BAZ(y); // This forces static lifetime, which y has not +} diff --git a/src/test/run-pass/rfc1623.rs.bk b/src/test/run-pass/rfc1623.rs.bk new file mode 100644 index 0000000000000..0915118ca27c0 --- /dev/null +++ b/src/test/run-pass/rfc1623.rs.bk @@ -0,0 +1,81 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![allow(dead_code)] + +// very simple test for a 'static static with default lifetime +static STATIC_STR : &str = "&'static str"; +const CONST_STR : &str = "&'static str"; + +// this should be the same as without default: +static EXPLICIT_STATIC_STR : &'static str = "&'static str"; +const EXPLICIT_CONST_STR : &'static str = "&'static str"; + +// a function that elides to an unbound lifetime for both in- and output +fn id_u8_slice(arg: &[u8]) -> &[u8] { arg } + +// one with a function, argument elided +static STATIC_SIMPLE_FN : &fn(&[u8]) -> &[u8] = + &(id_u8_slice as fn(&[u8]) -> &[u8]); +const CONST_SIMPLE_FN : &fn(&[u8]) -> &[u8] = + &(id_u8_slice as fn(&[u8]) -> &[u8]); + +// this should be the same as without elision +static STATIC_NON_ELIDED_fN : &for<'a> fn(&'a [u8]) -> &'a [u8] = + &(id_u8_slice as for<'a> fn(&'a [u8]) -> &'a [u8]); +const CONST_NON_ELIDED_fN : &for<'a> fn(&'a [u8]) -> &'a [u8] = + &(id_u8_slice as for<'a> fn(&'a [u8]) -> &'a [u8]); + +// another function that elides, each to a different unbound lifetime +fn multi_args(a: &u8, b: &u8, c: &u8) { } + +static STATIC_MULTI_FN : &fn(&u8, &u8, &u8) = + &(multi_args as fn(&u8, &u8, &u8)); +const CONST_MULTI_FN : &fn(&u8, &u8, &u8) = + &(multi_args as fn(&u8, &u8, &u8)); + +struct Foo<'a> { + bools: &'a [bool] +} + +static STATIC_FOO : Foo = Foo { bools: &[true, false] }; +const CONST_FOO : Foo = Foo { bools: &[true, false] }; + +type Bar<'a> = Foo<'a>; + +static STATIC_BAR : Bar = Bar { bools: &[true, false] }; +const CONST_BAR : Bar = Bar { bools: &[true, false] }; + +type Baz<'a> = fn(&'a [u8]) -> Option; + +fn baz(e: &[u8]) -> Option { e.first().map(|x| *x) } + +static STATIC_BAZ : &Baz = &(baz as Baz); +const CONST_BAZ : &Baz = &(baz as Baz); + +static BYTES : &[u8] = &[1, 2, 3]; + +fn main() { + // make sure that the lifetime is actually elided (and not defaulted) + let x = &[1u8, 2, 3]; + STATIC_SIMPLE_FN(x); + CONST_SIMPLE_FN(x); + + STATIC_BAZ(BYTES); // neees static lifetime + CONST_BAZ(BYTES); + + // make sure this works with different lifetimes + let a = &1; + { + let b = &2; + let c = &3; + CONST_MULTI_FN(a, b, c); + } +}