diff --git a/src/libcollectionstest/lib.rs b/src/libcollectionstest/lib.rs index 9b50478472fa9..0e3f9d5aaddf6 100644 --- a/src/libcollectionstest/lib.rs +++ b/src/libcollectionstest/lib.rs @@ -14,6 +14,7 @@ #![feature(collections)] #![feature(collections_drain)] #![feature(core)] +#![feature(const_fn)] #![feature(hash)] #![feature(rand)] #![feature(rustc_private)] diff --git a/src/libcoretest/lib.rs b/src/libcoretest/lib.rs index 3d14b3f3c8106..6ec3f5b7869b0 100644 --- a/src/libcoretest/lib.rs +++ b/src/libcoretest/lib.rs @@ -14,6 +14,7 @@ #![feature(box_syntax)] #![feature(unboxed_closures)] #![feature(core)] +#![feature(const_fn)] #![feature(test)] #![feature(rand)] #![feature(unicode)] diff --git a/src/liblog/lib.rs b/src/liblog/lib.rs index 4c92162b2d6dc..15767024ba80f 100644 --- a/src/liblog/lib.rs +++ b/src/liblog/lib.rs @@ -173,6 +173,7 @@ #![feature(staged_api)] #![feature(box_syntax)] #![feature(core)] +#![feature(const_fn)] #![feature(std_misc)] use std::boxed; diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index c92bb81c5fb25..4a715ca621cc2 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -29,6 +29,7 @@ #![feature(box_patterns)] #![feature(box_syntax)] #![feature(collections)] +#![feature(const_fn)] #![feature(core)] #![feature(duration)] #![feature(duration_span)] diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs index 3e084f3eeb305..ff7c570284f8e 100644 --- a/src/librustc/middle/check_const.rs +++ b/src/librustc/middle/check_const.rs @@ -199,8 +199,32 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> { } /// Returns true if the call is to a const fn or method. - fn handle_const_fn_call(&mut self, def_id: ast::DefId, ret_ty: Ty<'tcx>) -> bool { + fn handle_const_fn_call(&mut self, + expr: &ast::Expr, + def_id: ast::DefId, + ret_ty: Ty<'tcx>) + -> bool { if let Some(fn_like) = const_eval::lookup_const_fn_by_id(self.tcx, def_id) { + if + // we are in a static/const initializer + self.mode != Mode::Var && + + // feature-gate is not enabled + !self.tcx.sess.features.borrow().const_fn && + + // this doesn't come from a macro that has #[allow_internal_unstable] + !self.tcx.sess.codemap().span_allows_unstable(expr.span) + { + self.tcx.sess.span_err( + expr.span, + &format!("const fns are an unstable feature")); + fileline_help!( + self.tcx.sess, + expr.span, + "in Nightly builds, add `#![feature(const_fn)]` to the crate \ + attributes to enable"); + } + let qualif = self.fn_like(fn_like.kind(), fn_like.decl(), fn_like.body(), @@ -657,7 +681,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, } Some(def::DefMethod(did, def::FromImpl(_))) | Some(def::DefFn(did, _)) => { - v.handle_const_fn_call(did, node_ty) + v.handle_const_fn_call(e, did, node_ty) } _ => false }; @@ -677,7 +701,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, _ => None }; let is_const = match method_did { - Some(did) => v.handle_const_fn_call(did, node_ty), + Some(did) => v.handle_const_fn_call(e, did, node_ty), None => false }; if !is_const { diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index 8866e7ff19dcc..f25c6eb21a47b 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -30,6 +30,7 @@ #![feature(box_syntax)] #![feature(collections)] #![feature(core)] +#![feature(const_fn)] #![feature(libc)] #![feature(quote)] #![feature(rustc_diagnostic_macros)] diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 1177ebdc5315c..729e0b721f11a 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -332,7 +332,8 @@ pub struct Features { /// spans of #![feature] attrs for stable language features. for error reporting pub declared_stable_lang_features: Vec, /// #![feature] attrs for non-language (library) features - pub declared_lib_features: Vec<(InternedString, Span)> + pub declared_lib_features: Vec<(InternedString, Span)>, + pub const_fn: bool, } impl Features { @@ -352,7 +353,8 @@ impl Features { unmarked_api: false, negate_unsigned: false, declared_stable_lang_features: Vec::new(), - declared_lib_features: Vec::new() + declared_lib_features: Vec::new(), + const_fn: false, } } } @@ -802,7 +804,8 @@ fn check_crate_inner(cm: &CodeMap, span_handler: &SpanHandler, unmarked_api: cx.has_feature("unmarked_api"), negate_unsigned: cx.has_feature("negate_unsigned"), declared_stable_lang_features: accepted_features, - declared_lib_features: unknown_features + declared_lib_features: unknown_features, + const_fn: cx.has_feature("const_fn"), } } diff --git a/src/test/auxiliary/const_fn_lib.rs b/src/test/auxiliary/const_fn_lib.rs new file mode 100644 index 0000000000000..b0d5a6b12727b --- /dev/null +++ b/src/test/auxiliary/const_fn_lib.rs @@ -0,0 +1,16 @@ +// Copyright 2015 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. + +// Crate that exports a const fn. Used for testing cross-crate. + +#![crate_type="rlib"] +#![feature(const_fn)] + +pub const fn foo() -> usize { 22 } //~ ERROR const fn is unstable diff --git a/src/test/auxiliary/issue-17718.rs b/src/test/auxiliary/issue-17718.rs index b347e674f0a9f..373fc04217540 100644 --- a/src/test/auxiliary/issue-17718.rs +++ b/src/test/auxiliary/issue-17718.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(const_fn)] + use std::sync::atomic; pub const C1: usize = 1; diff --git a/src/test/compile-fail/const-fn-stability-calls-2.rs b/src/test/compile-fail/const-fn-stability-calls-2.rs new file mode 100644 index 0000000000000..dd9a415311e53 --- /dev/null +++ b/src/test/compile-fail/const-fn-stability-calls-2.rs @@ -0,0 +1,21 @@ +// Copyright 2015 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. + +// Test use of const fn from another crate without a feature gate. + +// aux-build:const_fn_lib.rs + +extern crate const_fn_lib; + +use const_fn_lib::foo; + +fn main() { + let x: [usize; foo()] = []; //~ ERROR unsupported constant expr +} diff --git a/src/test/compile-fail/const-fn-stability-calls-3.rs b/src/test/compile-fail/const-fn-stability-calls-3.rs new file mode 100644 index 0000000000000..0f413b0bbc112 --- /dev/null +++ b/src/test/compile-fail/const-fn-stability-calls-3.rs @@ -0,0 +1,25 @@ +// Copyright 2015 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. + +// Test use of const fn from another crate without a feature gate. + +#![feature(rustc_attrs)] +#![allow(unused_variables)] + +// aux-build:const_fn_lib.rs + +extern crate const_fn_lib; + +use const_fn_lib::foo; + +#[rustc_error] +fn main() { //~ ERROR compilation successful + let x = foo(); // use outside a constant is ok +} diff --git a/src/test/compile-fail/const-fn-stability-calls.rs b/src/test/compile-fail/const-fn-stability-calls.rs new file mode 100644 index 0000000000000..609077663ef54 --- /dev/null +++ b/src/test/compile-fail/const-fn-stability-calls.rs @@ -0,0 +1,34 @@ +// Copyright 2015 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. + +// Test use of const fn from another crate without a feature gate. + +// aux-build:const_fn_lib.rs + +extern crate const_fn_lib; + +use const_fn_lib::foo; + +static FOO: usize = foo(); //~ ERROR const fns are an unstable feature +const BAR: usize = foo(); //~ ERROR const fns are an unstable feature + +macro_rules! constant { + ($n:ident: $t:ty = $v:expr) => { + const $n: $t = $v; + } +} + +constant! { + BAZ: usize = foo() //~ ERROR const fns are an unstable feature +} + +fn main() { +// let x: [usize; foo()] = []; +} diff --git a/src/test/compile-fail/const-fn-stability.rs b/src/test/compile-fail/const-fn-stability.rs index 8aa5189bcd6bb..9913c2fa12c4a 100644 --- a/src/test/compile-fail/const-fn-stability.rs +++ b/src/test/compile-fail/const-fn-stability.rs @@ -25,4 +25,19 @@ impl Foo for u32 { const fn foo() -> u32 { 0 } //~ ERROR const fn is unstable } -fn main() { } +static FOO: usize = foo(); +const BAR: usize = foo(); + +macro_rules! constant { + ($n:ident: $t:ty = $v:expr) => { + const $n: $t = $v; + } +} + +constant! { + BAZ: usize = foo() +} + +fn main() { + let x: [usize; foo()] = []; +} diff --git a/src/test/compile-fail/dropck_arr_cycle_checked.rs b/src/test/compile-fail/dropck_arr_cycle_checked.rs index c9713ebcebe98..19f790ddc9071 100644 --- a/src/test/compile-fail/dropck_arr_cycle_checked.rs +++ b/src/test/compile-fail/dropck_arr_cycle_checked.rs @@ -13,6 +13,8 @@ // // (Compare against compile-fail/dropck_vec_cycle_checked.rs) +#![feature(const_fn)] + use std::cell::Cell; use id::Id; diff --git a/src/test/compile-fail/dropck_tarena_cycle_checked.rs b/src/test/compile-fail/dropck_tarena_cycle_checked.rs index 9309f5a243cd3..584e5eabf0cd8 100644 --- a/src/test/compile-fail/dropck_tarena_cycle_checked.rs +++ b/src/test/compile-fail/dropck_tarena_cycle_checked.rs @@ -17,6 +17,7 @@ // for the error message we see here.) #![allow(unstable)] +#![feature(const_fn)] extern crate arena; diff --git a/src/test/compile-fail/dropck_trait_cycle_checked.rs b/src/test/compile-fail/dropck_trait_cycle_checked.rs index 1d8c7e9ac3e82..6e0679da949e1 100644 --- a/src/test/compile-fail/dropck_trait_cycle_checked.rs +++ b/src/test/compile-fail/dropck_trait_cycle_checked.rs @@ -13,6 +13,8 @@ // // (Compare against compile-fail/dropck_vec_cycle_checked.rs) +#![feature(const_fn)] + use std::cell::Cell; use id::Id; diff --git a/src/test/compile-fail/dropck_vec_cycle_checked.rs b/src/test/compile-fail/dropck_vec_cycle_checked.rs index 8722246bb4eaa..bc33ff8399aa5 100644 --- a/src/test/compile-fail/dropck_vec_cycle_checked.rs +++ b/src/test/compile-fail/dropck_vec_cycle_checked.rs @@ -12,6 +12,8 @@ // // (Compare against compile-fail/dropck_arr_cycle_checked.rs) +#![feature(const_fn)] + use std::cell::Cell; use id::Id; diff --git a/src/test/compile-fail/functional-struct-update-respects-privacy.rs b/src/test/compile-fail/functional-struct-update-respects-privacy.rs index 3f41401eb69c1..d2df0d9ef2702 100644 --- a/src/test/compile-fail/functional-struct-update-respects-privacy.rs +++ b/src/test/compile-fail/functional-struct-update-respects-privacy.rs @@ -10,6 +10,8 @@ // RFC 736 (and Issue 21407): functional struct update should respect privacy. +#![feature(const_fn)] + // The `foo` module attempts to maintains an invariant that each `S` // has a unique `u64` id. use self::foo::S; diff --git a/src/test/compile-fail/issue-17718-const-borrow.rs b/src/test/compile-fail/issue-17718-const-borrow.rs index 12a9a27463157..ec6d1141c1a05 100644 --- a/src/test/compile-fail/issue-17718-const-borrow.rs +++ b/src/test/compile-fail/issue-17718-const-borrow.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(const_fn)] + use std::cell::UnsafeCell; const A: UnsafeCell = UnsafeCell::new(1); diff --git a/src/test/compile-fail/issue-7364.rs b/src/test/compile-fail/issue-7364.rs index 999e5f9db2dfc..7d0a900782992 100644 --- a/src/test/compile-fail/issue-7364.rs +++ b/src/test/compile-fail/issue-7364.rs @@ -9,6 +9,7 @@ // except according to those terms. #![feature(box_syntax)] +#![feature(const_fn)] use std::cell::RefCell; diff --git a/src/test/compile-fail/vec-must-not-hide-type-from-dropck.rs b/src/test/compile-fail/vec-must-not-hide-type-from-dropck.rs index 0b2112edf7280..375289596841d 100644 --- a/src/test/compile-fail/vec-must-not-hide-type-from-dropck.rs +++ b/src/test/compile-fail/vec-must-not-hide-type-from-dropck.rs @@ -23,6 +23,8 @@ // conditions above to be satisfied, meaning that if the dropck is // sound, it should reject this code. +#![feature(const_fn)] + use std::cell::Cell; use id::Id; diff --git a/src/test/debuginfo/constant-debug-locs.rs b/src/test/debuginfo/constant-debug-locs.rs index 72448ca2e001f..8032b53e9dd7c 100644 --- a/src/test/debuginfo/constant-debug-locs.rs +++ b/src/test/debuginfo/constant-debug-locs.rs @@ -15,6 +15,7 @@ #![allow(dead_code, unused_variables)] #![omit_gdb_pretty_printer_section] #![feature(std_misc, core)] +#![feature(const_fn)] // This test makes sure that the compiler doesn't crash when trying to assign // debug locations to const-expressions. diff --git a/src/test/run-pass-valgrind/cast-enum-with-dtor.rs b/src/test/run-pass-valgrind/cast-enum-with-dtor.rs index 2c3d7ef39e497..b13e34256d229 100644 --- a/src/test/run-pass-valgrind/cast-enum-with-dtor.rs +++ b/src/test/run-pass-valgrind/cast-enum-with-dtor.rs @@ -9,6 +9,7 @@ // except according to those terms. #![allow(dead_code)] +#![feature(const_fn)] // check dtor calling order when casting enums. diff --git a/src/test/run-pass/associated-types-project-from-type-param-via-bound-in-where-clause.rs b/src/test/run-pass/associated-types-project-from-type-param-via-bound-in-where-clause.rs index 5ceb1013ad811..8dc7d79ec2a77 100644 --- a/src/test/run-pass/associated-types-project-from-type-param-via-bound-in-where-clause.rs +++ b/src/test/run-pass/associated-types-project-from-type-param-via-bound-in-where-clause.rs @@ -12,6 +12,8 @@ // `Item` originates in a where-clause, not the declaration of // `T`. Issue #20300. +#![feature(const_fn)] + use std::marker::{PhantomData}; use std::sync::atomic::{AtomicUsize}; use std::sync::atomic::Ordering::SeqCst; diff --git a/src/test/run-pass/box-of-array-of-drop-1.rs b/src/test/run-pass/box-of-array-of-drop-1.rs index 1c7359a0fad9d..e889d74c7ccc4 100644 --- a/src/test/run-pass/box-of-array-of-drop-1.rs +++ b/src/test/run-pass/box-of-array-of-drop-1.rs @@ -11,6 +11,8 @@ // Test that we cleanup a fixed size Box<[D; k]> properly when D has a // destructor. +#![feature(const_fn)] + use std::thread; use std::sync::atomic::{AtomicUsize, Ordering}; diff --git a/src/test/run-pass/box-of-array-of-drop-2.rs b/src/test/run-pass/box-of-array-of-drop-2.rs index ad781f00356d7..f108ef4f5d22d 100644 --- a/src/test/run-pass/box-of-array-of-drop-2.rs +++ b/src/test/run-pass/box-of-array-of-drop-2.rs @@ -11,6 +11,8 @@ // Test that we cleanup dynamic sized Box<[D]> properly when D has a // destructor. +#![feature(const_fn)] + use std::thread; use std::sync::atomic::{AtomicUsize, Ordering}; diff --git a/src/test/run-pass/const-fn-cross-crate.rs b/src/test/run-pass/const-fn-cross-crate.rs new file mode 100644 index 0000000000000..5d0c17af71719 --- /dev/null +++ b/src/test/run-pass/const-fn-cross-crate.rs @@ -0,0 +1,25 @@ +// Copyright 2015 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. + +// aux-build:const_fn_lib.rs + +// A very basic test of const fn functionality. + +#![feature(const_fn)] + +extern crate const_fn_lib; + +use const_fn_lib::foo; + +const FOO: usize = foo(); + +fn main() { + assert_eq!(FOO, 22); +} diff --git a/src/test/run-pass/const-fn-method.rs b/src/test/run-pass/const-fn-method.rs new file mode 100644 index 0000000000000..42c7a47c59db1 --- /dev/null +++ b/src/test/run-pass/const-fn-method.rs @@ -0,0 +1,25 @@ +// 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. + +#![feature(const_fn)] + +struct Foo { value: u32 } + +impl Foo { + const fn new() -> Foo { + Foo { value: 22 } + } +} + +const FOO: Foo = Foo::new(); + +pub fn main() { + assert_eq!(FOO.value, 22); +} diff --git a/src/test/run-pass/issue-17718-static-unsafe-interior.rs b/src/test/run-pass/issue-17718-static-unsafe-interior.rs index c18d51e84d84f..993e5e1c1e6e9 100644 --- a/src/test/run-pass/issue-17718-static-unsafe-interior.rs +++ b/src/test/run-pass/issue-17718-static-unsafe-interior.rs @@ -11,6 +11,8 @@ // pretty-expanded FIXME #23616 #![feature(core)] +#![feature(const_fn)] + use std::marker; use std::cell::UnsafeCell; diff --git a/src/test/run-pass/issue-17718.rs b/src/test/run-pass/issue-17718.rs index 457bbb23e1820..2bb69d105ff5d 100644 --- a/src/test/run-pass/issue-17718.rs +++ b/src/test/run-pass/issue-17718.rs @@ -12,6 +12,7 @@ #![feature(core)] +#![feature(const_fn)] extern crate issue_17718 as other; diff --git a/src/test/run-pass/issue-21486.rs b/src/test/run-pass/issue-21486.rs index c20237f1f86b4..699189a4e6aed 100644 --- a/src/test/run-pass/issue-21486.rs +++ b/src/test/run-pass/issue-21486.rs @@ -12,6 +12,7 @@ // created via FRU and control-flow breaks in the middle of // construction. +#![feature(const_fn)] use std::sync::atomic::{Ordering, AtomicUsize}; diff --git a/src/test/run-pass/nested-vec-3.rs b/src/test/run-pass/nested-vec-3.rs index e59900caf07ec..89ac626158392 100644 --- a/src/test/run-pass/nested-vec-3.rs +++ b/src/test/run-pass/nested-vec-3.rs @@ -12,6 +12,7 @@ // the contents implement Drop and we hit a panic in the middle of // construction. +#![feature(const_fn)] use std::thread; use std::sync::atomic::{AtomicUsize, Ordering}; diff --git a/src/test/run-pass/struct-order-of-eval-3.rs b/src/test/run-pass/struct-order-of-eval-3.rs index c0ed4ea3ce82f..b67eb205396b2 100644 --- a/src/test/run-pass/struct-order-of-eval-3.rs +++ b/src/test/run-pass/struct-order-of-eval-3.rs @@ -11,6 +11,7 @@ // Checks that functional-record-update order-of-eval is as expected // even when no Drop-implementations are involved. +#![feature(const_fn)] use std::sync::atomic::{Ordering, AtomicUsize}; diff --git a/src/test/run-pass/struct-order-of-eval-4.rs b/src/test/run-pass/struct-order-of-eval-4.rs index 83ea0e3ab74ea..20d27d8b309bb 100644 --- a/src/test/run-pass/struct-order-of-eval-4.rs +++ b/src/test/run-pass/struct-order-of-eval-4.rs @@ -11,6 +11,7 @@ // Checks that struct-literal expression order-of-eval is as expected // even when no Drop-implementations are involved. +#![feature(const_fn)] use std::sync::atomic::{Ordering, AtomicUsize}; diff --git a/src/test/run-pass/vector-sort-panic-safe.rs b/src/test/run-pass/vector-sort-panic-safe.rs index f3c4ecb035e51..209fe22207f49 100644 --- a/src/test/run-pass/vector-sort-panic-safe.rs +++ b/src/test/run-pass/vector-sort-panic-safe.rs @@ -10,6 +10,7 @@ #![feature(rand, core)] +#![feature(const_fn)] use std::sync::atomic::{AtomicUsize, Ordering}; use std::__rand::{thread_rng, Rng};