Created
December 4, 2017 18:55
-
-
Save Centril/df583b162859794458b26af2e00ab6a8 to your computer and use it in GitHub Desktop.
Const Trait System
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//****************************************************************************** | |
// "const_trait_system" | |
//****************************************************************************** | |
/* | |
Dependency DAG of proposal: | |
[A, B] -> [] | |
[C] -> [B] and/or [A] -- NOTE: C is moot without B or A. | |
[D, E] -> [B] | |
An arrow denotes that a proposal requires a node on the RHS to pass. | |
*/ | |
//============================================================================== | |
// A. const fn in trait | |
//============================================================================== | |
// Removes: error[E0379]: trait fns cannot be declared const | |
trait Ada { | |
const fn compute(n: usize) -> usize; | |
} | |
// You now HAVE to write: | |
impl Ada for Foo { | |
const /* <-- mandatory */ fn compute(n: usize) -> usize { | |
n * 2 | |
} | |
} | |
// This of course means that `fn compute(..)` may be used in any const context. | |
//============================================================================== | |
// B. overconstrain fn in trait impl as const | |
//============================================================================== | |
// Removes: error[E0379]: trait fns cannot be declared const | |
// Assume: | |
trait Bar { | |
fn baz(); | |
fn quux() -> usize; | |
} | |
// You may now write: | |
impl Bar for Foo { | |
const fn baz() {} | |
const fn quux() -> usize { 1 } | |
} | |
// Foo::baz() and Foo::quux() are now usable in a const context. | |
//============================================================================== | |
// C. const impl as syntactic sugar for const fn | |
//============================================================================== | |
const impl Bar for Foo { | |
fn baz() {} | |
fn quux() -> usize { 1 } | |
} | |
// ==> | |
impl Bar for Foo { | |
const fn baz() {} | |
const fn quux() -> usize { 1 } | |
} | |
// constant impl means "all fns are const" semantically. | |
//============================================================================== | |
// D. allow use of trait-fn in const fn iff impl as const impl | |
//============================================================================== | |
// Consider: | |
trait Default { fn default() -> Self; } | |
// And: | |
impl Default for Foo { | |
const fn default() -> Self { | |
Foo(5) | |
} | |
} | |
impl Default for Wibble { | |
fn default() -> Self { | |
Wibble(Box::new(5)) | |
} | |
} | |
// You may then write: | |
const fn example<D: Default>() -> D { | |
D::default() | |
} | |
// This is only callable iff the specific type for D has | |
// an impl of Default where default() is marked as const fn. | |
fn main() { | |
// This is allowed: | |
const MY_FOO: Foo = example::<Foo>(); | |
// This is NOT: | |
const MY_WIBBLE: Wibble = example::<Wibble>(); | |
} | |
//============================================================================== | |
// E. const trait bound iff impl is const impl | |
//============================================================================== | |
// Consider: | |
fn example<D: const Default>() -> D { | |
D::default() | |
} | |
// This entails that: | |
fn main() { | |
// This is allowed: | |
let foo = example::<Foo>(); | |
// This is NOT: | |
let wibble = example::<Wibble>(); | |
} | |
// The const modifier on a bound in a non-const fn means that a type can only | |
// be substituted for a type variable iff the impl of the required trait is | |
// semantically a const impl (= all fn:s are marked as const). |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment