Auto merge of #25609 - nikomatsakis:const-fn, r=pnkfelix
This is a port of @eddyb's `const-fn` branch. I rebased it, tweaked a few things, and added tests as well as a feature gate. The set of tests is still pretty rudimentary, I'd appreciate suggestions on new tests to write. Also, a double-check that the feature-gate covers all necessary cases. One question: currently, the feature-gate allows the *use* of const functions from stable code, just not the definition. This seems to fit our usual strategy, and implies that we might (perhaps) allow some constant functions in libstd someday, even before stabilizing const-fn, if we were willing to commit to the existence of const fns but found some details of their impl unsatisfactory. r? @pnkfelix
This commit is contained in:
commit
ba0e1cd814
55 changed files with 848 additions and 212 deletions
|
|
@ -117,7 +117,7 @@ static mut STATIC14: SafeStruct = SafeStruct {
|
|||
//~^ ERROR mutable statics are not allowed to have destructors
|
||||
field1: SafeEnum::Variant1,
|
||||
field2: SafeEnum::Variant4("str".to_string())
|
||||
//~^ ERROR static contains unimplemented expression type
|
||||
//~^ ERROR method calls in statics are limited to constant inherent methods
|
||||
};
|
||||
|
||||
static STATIC15: &'static [Box<MyOwned>] = &[
|
||||
|
|
|
|||
26
src/test/compile-fail/const-fn-mismatch.rs
Normal file
26
src/test/compile-fail/const-fn-mismatch.rs
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
// 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 that we can't declare a const fn in an impl -- right now it's
|
||||
// just not allowed at all, though eventually it'd make sense to allow
|
||||
// it if the trait fn is const (but right now no trait fns can be
|
||||
// const).
|
||||
|
||||
#![feature(const_fn)]
|
||||
|
||||
trait Foo {
|
||||
fn f() -> u32;
|
||||
}
|
||||
|
||||
impl Foo for u32 {
|
||||
const fn f() -> u32 { 22 } //~ ERROR E0379
|
||||
}
|
||||
|
||||
fn main() { }
|
||||
21
src/test/compile-fail/const-fn-not-in-trait.rs
Normal file
21
src/test/compile-fail/const-fn-not-in-trait.rs
Normal 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 that const fn is illegal in a trait declaration, whether or
|
||||
// not a default is provided.
|
||||
|
||||
#![feature(const_fn)]
|
||||
|
||||
trait Foo {
|
||||
const fn f() -> u32; //~ ERROR trait fns cannot be declared const
|
||||
const fn g() -> u32 { 0 } //~ ERROR trait fns cannot be declared const
|
||||
}
|
||||
|
||||
fn main() { }
|
||||
47
src/test/compile-fail/const-fn-not-safe-for-const.rs
Normal file
47
src/test/compile-fail/const-fn-not-safe-for-const.rs
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
// 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 that we can't call random fns in a const fn or do other bad things.
|
||||
|
||||
#![feature(const_fn)]
|
||||
|
||||
use std::mem::transmute;
|
||||
|
||||
fn random() -> u32 { 0 }
|
||||
|
||||
const fn sub(x: &u32) -> usize {
|
||||
unsafe { transmute(x) } //~ ERROR E0015
|
||||
}
|
||||
|
||||
const fn sub1() -> u32 {
|
||||
random() //~ ERROR E0015
|
||||
}
|
||||
|
||||
static Y: u32 = 0;
|
||||
|
||||
const fn get_Y() -> u32 {
|
||||
Y
|
||||
//~^ ERROR E0013
|
||||
//~| ERROR cannot refer to other statics by value
|
||||
}
|
||||
|
||||
const fn get_Y_addr() -> &'static u32 {
|
||||
&Y
|
||||
//~^ ERROR E0013
|
||||
}
|
||||
|
||||
const fn get() -> u32 {
|
||||
let x = 22; //~ ERROR E0016
|
||||
let y = 44; //~ ERROR E0016
|
||||
x + y
|
||||
}
|
||||
|
||||
fn main() {
|
||||
}
|
||||
28
src/test/compile-fail/const-fn-stability.rs
Normal file
28
src/test/compile-fail/const-fn-stability.rs
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
// 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 without feature gate.
|
||||
|
||||
const fn foo() -> usize { 0 } //~ ERROR const fn is unstable
|
||||
|
||||
trait Foo {
|
||||
const fn foo() -> u32; //~ ERROR const fn is unstable
|
||||
const fn bar() -> u32 { 0 } //~ ERROR const fn is unstable
|
||||
}
|
||||
|
||||
impl Foo {
|
||||
const fn baz() -> u32 { 0 } //~ ERROR const fn is unstable
|
||||
}
|
||||
|
||||
impl Foo for u32 {
|
||||
const fn foo() -> u32 { 0 } //~ ERROR const fn is unstable
|
||||
}
|
||||
|
||||
fn main() { }
|
||||
|
|
@ -20,6 +20,6 @@ mod Y {
|
|||
|
||||
static foo: *const Y::X = Y::foo(Y::x as *const Y::X);
|
||||
//~^ ERROR the trait `core::marker::Sync` is not implemented for the type
|
||||
//~| ERROR function calls in statics are limited to struct and enum constructors
|
||||
//~| ERROR E0015
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,6 @@ static boxed: Box<RefCell<isize>> = box RefCell::new(0);
|
|||
//~^ ERROR allocations are not allowed in statics
|
||||
//~| ERROR the trait `core::marker::Sync` is not implemented for the type
|
||||
//~| ERROR the trait `core::marker::Sync` is not implemented for the type
|
||||
//~| ERROR function calls in statics are limited to struct and enum constructors
|
||||
//~| ERROR E0015
|
||||
|
||||
fn main() { }
|
||||
|
|
|
|||
|
|
@ -11,6 +11,6 @@
|
|||
fn foo() -> isize { 23 }
|
||||
|
||||
static a: [isize; 2] = [foo(); 2];
|
||||
//~^ ERROR: function calls in statics are limited to struct and enum constructors
|
||||
//~^ ERROR: E0015
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
23
src/test/run-pass/const-fn-nested.rs
Normal file
23
src/test/run-pass/const-fn-nested.rs
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
// 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 a call whose argument is the result of another call.
|
||||
|
||||
#![feature(const_fn)]
|
||||
|
||||
const fn sub(x: u32, y: u32) -> u32 {
|
||||
x - y
|
||||
}
|
||||
|
||||
const X: u32 = sub(sub(88, 44), 22);
|
||||
|
||||
fn main() {
|
||||
assert_eq!(X, 22);
|
||||
}
|
||||
32
src/test/run-pass/const-fn.rs
Normal file
32
src/test/run-pass/const-fn.rs
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
// 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.
|
||||
|
||||
// A very basic test of const fn functionality.
|
||||
|
||||
#![feature(const_fn)]
|
||||
|
||||
const fn add(x: u32, y: u32) -> u32 {
|
||||
x + y
|
||||
}
|
||||
|
||||
const fn sub(x: u32, y: u32) -> u32 {
|
||||
x - y
|
||||
}
|
||||
|
||||
const SUM: u32 = add(44, 22);
|
||||
const DIFF: u32 = sub(44, 22);
|
||||
|
||||
fn main() {
|
||||
assert_eq!(SUM, 66);
|
||||
assert!(SUM != 88);
|
||||
|
||||
assert_eq!(DIFF, 22);
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue