]> git.lizzy.rs Git - rust.git/commitdiff
add static_in_const feature gate
authorAndre Bogus <bogusandre@gmail.com>
Wed, 7 Sep 2016 21:18:46 +0000 (23:18 +0200)
committerAndre Bogus <bogusandre@gmail.com>
Wed, 7 Sep 2016 21:18:46 +0000 (23:18 +0200)
also updates tests and deletes the spurious .bk files I inadvertently
added last time.

src/librustc_typeck/collect.rs
src/librustc_typeck/rscope.rs
src/libsyntax/feature_gate.rs
src/test/compile-fail/const-unsized.rs
src/test/compile-fail/issue-24446.rs
src/test/compile-fail/rfc1623.rs
src/test/compile-fail/rfc1623.rs.bk [deleted file]
src/test/run-pass/rfc1623.rs
src/test/run-pass/rfc1623.rs.bk [deleted file]

index fcc0b09e31acf158db22235f004e7910f3c464d8..0eb6a747263ea661ddd839e1c4e9182496713563 100644 (file)
@@ -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,
index f5b13c4207d905aaec9066559b8dc0b100140ae8..5b00a625bacf5b18a2a6e1385130e42b159158c9 100644 (file)
@@ -213,6 +213,45 @@ fn anon_regions(&self,
     }
 }
 
+/// 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 {
index dd2956f706c95f83ae6ec1177cc3bbddfc7cd2be..8b8a41fc204881d66fc61fe364314c2d1d1f23c2 100644 (file)
@@ -295,6 +295,9 @@ pub fn new() -> 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! (
index a73164b957c831a8896859fb196858d2b3fb493d..07d6edb1f3b15619b016b5a75fba5516d514be9e 100644 (file)
@@ -15,6 +15,7 @@
 //~| 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 @@
 //~| 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
index b9382520cf9d3166c3ba6461973d4aeff5a4884d..d721c8bb6d2bfd654c0fca4fa6586a8a45e1713a 100644 (file)
@@ -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
     };
 }
index 1d8fc7fe111c035b3fb36f2b928c0db6d926148a..083cc218eecf33bd7bf3c0583ce3ecc0d6212d2d 100644 (file)
@@ -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 (file)
index abdcc02..0000000
+++ /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
-}
index 17453933c8abcdc35b87ca4a20a409d8ec817b8d..fc9143dc450b76469a2a692c143b958ea7f09b50 100644 (file)
@@ -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 (file)
index 0915118..0000000
+++ /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);
-    }
-}