about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAndre Bogus <bogusandre@gmail.com>2016-09-07 23:18:46 +0200
committerAndre Bogus <bogusandre@gmail.com>2016-09-07 23:18:46 +0200
commit41d1cd7196d6799fa960ac220d20b958c1b797ed (patch)
treef3dfd90ea9297b1e96c1a994e5046a9c5698be71
parentcf0cdc452b3335eec4d0d5ec27e922763d9835bc (diff)
downloadrust-41d1cd7196d6799fa960ac220d20b958c1b797ed.tar.gz
rust-41d1cd7196d6799fa960ac220d20b958c1b797ed.zip
add static_in_const feature gate
also updates tests and deletes the spurious .bk files I inadvertently
added last time.
-rw-r--r--src/librustc_typeck/collect.rs2
-rw-r--r--src/librustc_typeck/rscope.rs39
-rw-r--r--src/libsyntax/feature_gate.rs3
-rw-r--r--src/test/compile-fail/const-unsized.rs2
-rw-r--r--src/test/compile-fail/issue-24446.rs2
-rw-r--r--src/test/compile-fail/rfc1623.rs2
-rw-r--r--src/test/compile-fail/rfc1623.rs.bk98
-rw-r--r--src/test/run-pass/rfc1623.rs1
-rw-r--r--src/test/run-pass/rfc1623.rs.bk81
9 files changed, 48 insertions, 182 deletions
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index fcc0b09e31a..0eb6a747263 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -1567,7 +1567,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(&ElidableRscope::new(ty::ReStatic), &t)
+                        ccx.icx(&()).to_ty(&StaticRscope::new(&ccx.tcx), &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/librustc_typeck/rscope.rs b/src/librustc_typeck/rscope.rs
index f5b13c4207d..5b00a625bac 100644
--- a/src/librustc_typeck/rscope.rs
+++ b/src/librustc_typeck/rscope.rs
@@ -213,6 +213,45 @@ impl RegionScope for ElidableRscope {
     }
 }
 
+/// A scope that behaves as an ElidabeRscope with a `'static` default region
+/// that should also warn if the `static_in_const` feature is unset.
+#[derive(Copy, Clone)]
+pub struct StaticRscope<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
+    tcx: &'a ty::TyCtxt<'a, 'gcx, 'tcx>,
+}
+
+impl<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> StaticRscope<'a, 'gcx, 'tcx> {
+    /// create a new StaticRscope from a reference to the `TyCtxt`
+    pub fn new(tcx: &'a ty::TyCtxt<'a, 'gcx, 'tcx>) -> Self {
+        StaticRscope { tcx: tcx }
+    }
+}
+
+impl<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> RegionScope for StaticRscope<'a, 'gcx, 'tcx> {
+    fn anon_regions(&self,
+                    _span: Span,
+                    count: usize)
+                    -> Result<Vec<ty::Region>, Option<Vec<ElisionFailureInfo>>> {
+        Ok(vec![ty::ReStatic; count])
+    }
+
+    fn object_lifetime_default(&self, span: Span) -> Option<ty::Region> {
+        Some(self.base_object_lifetime_default(span))
+    }
+
+    fn base_object_lifetime_default(&self, span: Span) -> ty::Region {
+        if !self.tcx.sess.features.borrow().static_in_const {
+            self.tcx
+                .sess
+                .struct_span_warn(span,
+                                  "This needs a `'static` lifetime or the \
+                                  `static_in_const` feature, see #35897")
+                .emit();
+        }
+        ty::ReStatic
+    }
+}
+
 /// A scope in which we generate anonymous, late-bound regions for
 /// omitted regions. This occurs in function signatures.
 pub struct BindingRscope {
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index dd2956f706c..8b8a41fc204 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -295,6 +295,9 @@ declare_features! (
 
     // Allows untagged unions `union U { ... }`
     (active, untagged_unions, "1.13.0", Some(32836)),
+
+    // elide `'static` lifetimes in `static`s and `const`s
+    (active, static_in_const, "1.13.0", Some(35897)),
 );
 
 declare_features! (
diff --git a/src/test/compile-fail/const-unsized.rs b/src/test/compile-fail/const-unsized.rs
index a73164b957c..07d6edb1f3b 100644
--- a/src/test/compile-fail/const-unsized.rs
+++ b/src/test/compile-fail/const-unsized.rs
@@ -15,6 +15,7 @@ const CONST_0: Debug+Sync = *(&0 as &(Debug+Sync));
 //~| NOTE `std::fmt::Debug + Sync + 'static: std::marker::Sized` not satisfied
 //~| NOTE does not have a constant size known at compile-time
 //~| NOTE constant expressions must have a statically known size
+//~| WARNING This needs a `'static` lifetime or the `static_in_const` feature
 
 const CONST_FOO: str = *"foo";
 //~^ ERROR `str: std::marker::Sized` is not satisfied
@@ -27,6 +28,7 @@ static STATIC_1: Debug+Sync = *(&1 as &(Debug+Sync));
 //~| NOTE `std::fmt::Debug + Sync + 'static: std::marker::Sized` not satisfied
 //~| NOTE does not have a constant size known at compile-time
 //~| NOTE constant expressions must have a statically known size
+//~| WARNING This needs a `'static` lifetime or the `static_in_const` feature
 
 static STATIC_BAR: str = *"bar";
 //~^ ERROR `str: std::marker::Sized` is not satisfied
diff --git a/src/test/compile-fail/issue-24446.rs b/src/test/compile-fail/issue-24446.rs
index b9382520cf9..d721c8bb6d2 100644
--- a/src/test/compile-fail/issue-24446.rs
+++ b/src/test/compile-fail/issue-24446.rs
@@ -12,7 +12,7 @@ fn main() {
     static foo: Fn() -> u32 = || -> u32 {
         //~^ ERROR: mismatched types
         //~| ERROR: `std::ops::Fn() -> u32 + 'static: std::marker::Sized` is not satisfied
-
+        //~| WARNING: This needs a `'static` lifetime or the `static_in_const` feature
         0
     };
 }
diff --git a/src/test/compile-fail/rfc1623.rs b/src/test/compile-fail/rfc1623.rs
index 1d8fc7fe111..083cc218eec 100644
--- a/src/test/compile-fail/rfc1623.rs
+++ b/src/test/compile-fail/rfc1623.rs
@@ -7,7 +7,7 @@
 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
-
+#![feature(static_in_const)]
 #![allow(dead_code)]
 
 fn non_elidable<'a, 'b>(a: &'a u8, b: &'b u8) -> &'a u8 {
diff --git a/src/test/compile-fail/rfc1623.rs.bk b/src/test/compile-fail/rfc1623.rs.bk
deleted file mode 100644
index abdcc02de76..00000000000
--- a/src/test/compile-fail/rfc1623.rs.bk
+++ /dev/null
@@ -1,98 +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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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 { 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<u8>;
-
-fn baz(e: &[u8]) -> Option<u8> { 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 b/src/test/run-pass/rfc1623.rs
index 17453933c8a..fc9143dc450 100644
--- a/src/test/run-pass/rfc1623.rs
+++ b/src/test/run-pass/rfc1623.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(static_in_const)]
 #![allow(dead_code)]
 
 // very simple test for a 'static static with default lifetime
diff --git a/src/test/run-pass/rfc1623.rs.bk b/src/test/run-pass/rfc1623.rs.bk
deleted file mode 100644
index 0915118ca27..00000000000
--- a/src/test/run-pass/rfc1623.rs.bk
+++ /dev/null
@@ -1,81 +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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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<u8>;
-
-fn baz(e: &[u8]) -> Option<u8> { 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);
-    }
-}