Auto merge of #25880 - nikomatsakis:const-fn-feature-gate-calls, r=alexcrichton

The previous feature gate assumed we would not define any (stable) const fns. But then @eddyb went and cleaned up the code. So this now extends the feature-gate to prohibit calls; but calls inside of macros are considered ok.

r? @alexcrichton
This commit is contained in:
bors 2015-05-29 17:38:40 +00:00
commit 84254948c2
35 changed files with 232 additions and 7 deletions

View File

@ -14,6 +14,7 @@
#![feature(collections)]
#![feature(collections_drain)]
#![feature(core)]
#![feature(const_fn)]
#![feature(hash)]
#![feature(rand)]
#![feature(rustc_private)]

View File

@ -14,6 +14,7 @@
#![feature(box_syntax)]
#![feature(unboxed_closures)]
#![feature(core)]
#![feature(const_fn)]
#![feature(test)]
#![feature(rand)]
#![feature(unicode)]

View File

@ -173,6 +173,7 @@
#![feature(staged_api)]
#![feature(box_syntax)]
#![feature(core)]
#![feature(const_fn)]
#![feature(std_misc)]
use std::boxed;

View File

@ -29,6 +29,7 @@
#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(collections)]
#![feature(const_fn)]
#![feature(core)]
#![feature(duration)]
#![feature(duration_span)]

View File

@ -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 {

View File

@ -30,6 +30,7 @@
#![feature(box_syntax)]
#![feature(collections)]
#![feature(core)]
#![feature(const_fn)]
#![feature(libc)]
#![feature(quote)]
#![feature(rustc_diagnostic_macros)]

View File

@ -332,7 +332,8 @@ pub struct Features {
/// spans of #![feature] attrs for stable language features. for error reporting
pub declared_stable_lang_features: Vec<Span>,
/// #![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<F>(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"),
}
}

View File

@ -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 <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.
// 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

View File

@ -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;

View File

@ -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 <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.
// 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
}

View File

@ -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 <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.
// 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
}

View File

@ -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 <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.
// 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()] = [];
}

View File

@ -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()] = [];
}

View File

@ -13,6 +13,8 @@
//
// (Compare against compile-fail/dropck_vec_cycle_checked.rs)
#![feature(const_fn)]
use std::cell::Cell;
use id::Id;

View File

@ -17,6 +17,7 @@
// for the error message we see here.)
#![allow(unstable)]
#![feature(const_fn)]
extern crate arena;

View File

@ -13,6 +13,8 @@
//
// (Compare against compile-fail/dropck_vec_cycle_checked.rs)
#![feature(const_fn)]
use std::cell::Cell;
use id::Id;

View File

@ -12,6 +12,8 @@
//
// (Compare against compile-fail/dropck_arr_cycle_checked.rs)
#![feature(const_fn)]
use std::cell::Cell;
use id::Id;

View File

@ -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;

View File

@ -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<usize> = UnsafeCell::new(1);

View File

@ -9,6 +9,7 @@
// except according to those terms.
#![feature(box_syntax)]
#![feature(const_fn)]
use std::cell::RefCell;

View File

@ -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;

View File

@ -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.

View File

@ -9,6 +9,7 @@
// except according to those terms.
#![allow(dead_code)]
#![feature(const_fn)]
// check dtor calling order when casting enums.

View File

@ -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;

View File

@ -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};

View File

@ -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};

View File

@ -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 <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.
// 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);
}

View File

@ -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 <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.
#![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);
}

View File

@ -11,6 +11,8 @@
// pretty-expanded FIXME #23616
#![feature(core)]
#![feature(const_fn)]
use std::marker;
use std::cell::UnsafeCell;

View File

@ -12,6 +12,7 @@
#![feature(core)]
#![feature(const_fn)]
extern crate issue_17718 as other;

View File

@ -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};

View File

@ -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};

View File

@ -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};

View File

@ -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};

View File

@ -10,6 +10,7 @@
#![feature(rand, core)]
#![feature(const_fn)]
use std::sync::atomic::{AtomicUsize, Ordering};
use std::__rand::{thread_rng, Rng};