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:
commit
84254948c2
|
@ -14,6 +14,7 @@
|
|||
#![feature(collections)]
|
||||
#![feature(collections_drain)]
|
||||
#![feature(core)]
|
||||
#![feature(const_fn)]
|
||||
#![feature(hash)]
|
||||
#![feature(rand)]
|
||||
#![feature(rustc_private)]
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#![feature(box_syntax)]
|
||||
#![feature(unboxed_closures)]
|
||||
#![feature(core)]
|
||||
#![feature(const_fn)]
|
||||
#![feature(test)]
|
||||
#![feature(rand)]
|
||||
#![feature(unicode)]
|
||||
|
|
|
@ -173,6 +173,7 @@
|
|||
#![feature(staged_api)]
|
||||
#![feature(box_syntax)]
|
||||
#![feature(core)]
|
||||
#![feature(const_fn)]
|
||||
#![feature(std_misc)]
|
||||
|
||||
use std::boxed;
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#![feature(box_patterns)]
|
||||
#![feature(box_syntax)]
|
||||
#![feature(collections)]
|
||||
#![feature(const_fn)]
|
||||
#![feature(core)]
|
||||
#![feature(duration)]
|
||||
#![feature(duration_span)]
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#![feature(box_syntax)]
|
||||
#![feature(collections)]
|
||||
#![feature(core)]
|
||||
#![feature(const_fn)]
|
||||
#![feature(libc)]
|
||||
#![feature(quote)]
|
||||
#![feature(rustc_diagnostic_macros)]
|
||||
|
|
|
@ -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"),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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()] = [];
|
||||
}
|
|
@ -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()] = [];
|
||||
}
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
//
|
||||
// (Compare against compile-fail/dropck_vec_cycle_checked.rs)
|
||||
|
||||
#![feature(const_fn)]
|
||||
|
||||
use std::cell::Cell;
|
||||
use id::Id;
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
// for the error message we see here.)
|
||||
|
||||
#![allow(unstable)]
|
||||
#![feature(const_fn)]
|
||||
|
||||
extern crate arena;
|
||||
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
//
|
||||
// (Compare against compile-fail/dropck_vec_cycle_checked.rs)
|
||||
|
||||
#![feature(const_fn)]
|
||||
|
||||
use std::cell::Cell;
|
||||
use id::Id;
|
||||
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
//
|
||||
// (Compare against compile-fail/dropck_arr_cycle_checked.rs)
|
||||
|
||||
#![feature(const_fn)]
|
||||
|
||||
use std::cell::Cell;
|
||||
use id::Id;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
// except according to those terms.
|
||||
|
||||
#![feature(box_syntax)]
|
||||
#![feature(const_fn)]
|
||||
|
||||
use std::cell::RefCell;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
// except according to those terms.
|
||||
|
||||
#![allow(dead_code)]
|
||||
#![feature(const_fn)]
|
||||
|
||||
// check dtor calling order when casting enums.
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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};
|
||||
|
||||
|
|
|
@ -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};
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -11,6 +11,8 @@
|
|||
// pretty-expanded FIXME #23616
|
||||
|
||||
#![feature(core)]
|
||||
#![feature(const_fn)]
|
||||
|
||||
|
||||
use std::marker;
|
||||
use std::cell::UnsafeCell;
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
|
||||
#![feature(core)]
|
||||
#![feature(const_fn)]
|
||||
|
||||
extern crate issue_17718 as other;
|
||||
|
||||
|
|
|
@ -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};
|
||||
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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};
|
||||
|
||||
|
|
|
@ -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};
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
|
||||
#![feature(rand, core)]
|
||||
#![feature(const_fn)]
|
||||
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
use std::__rand::{thread_rng, Rng};
|
||||
|
|
Loading…
Reference in New Issue