-
Notifications
You must be signed in to change notification settings - Fork 13.9k
Description
This is a tracking issue for the RFC "Const functions and inherent methods" (rust-lang/rfcs#911).
This issue only tracks a minimal subset of the proposal in 911 that we are (hopefully) comfortable with stabilizing. To opt into the minimal subset, use #![feature(min_const_fn)]. To use the more expansive feature set, you can continue using #![feature(const_fn)] and other associated feature gates.
The minimal set will not include items from the following (incomplete) list:
-
const fns with type parameters with bounds (includingwhereclauses) in scope (including from the parent e.g.impl) other than: lifetimes,Sized, or (the "un"-bound)?SizedThis restriction exists because we are not sure about our story around what bounds mean in a
const fncontext. See RFC: const bounds and methods rfcs#2237,const fnand generics const-eval#1, and https://github.com/Centril/rfc-effects/ for a discussion on this. -
const fns with argument types or return types that containfnpointers,dyn Trait, orimpl Trait.This is checked recursively.
The restriction ensures that you may not reach a value of these types by any means.This restriction exists for the same reasons as in 1.
-
const fns with any operations on floating-point numbers. This is achieved by making any floating-point operation not beconstinsideconst fn.This restriction exists because we are not sure about the story wrt. determinism, achieving the same results on compile-time / run-time (including other machines) and floating points.
-
using a
const fncall in a pattern, e.g.;const fn twice<T: Copy>(x: T) -> (T, T) { (x, x) } match x { twice(21) => { ... } _ => { ... } }
-
anything else that is not currently in
const_fnor constants- raw ptr to
usizecast (e.g.*const/mut T -> usize). - raw ptr deref.
if/if let/match.loop/while.letand destructuring.
- raw ptr to
-
union field access.
-
code requiring
unsafeblocks.
Exhaustive list of features supported in const fn with #![feature(min_const_fn)]:
-
type parameters where the parameters have any of the following as part of their bounds (either on
whereor directly on the parameters):- lifetimes
Sized
This means that
<T: 'a + ?Sized>and<T: 'b + Sized>+<T>are all permitted.
Note that?Sizedis the absence of a constraint when bounds have been fully elaborated
which includes adding implicitSizedbounds.
This entails that permittingSized+ lifetimes allows the above examples.This rule also applies to type parameters of items that contain
const fns. -
arithmetic operators on integers
-
boolean operators (except for
&&and||which are banned since they are short-circuiting). -
any kind of aggregate constructor (array,
struct,enum, tuple, ...) -
calls to other
const fns (methods and functions) -
index operations on arrays and slices
-
field accesses on structs and tuples
-
reading from constants (but not statics, not even taking a reference to a static)
-
&and*(only dereferencing of references, not raw pointers) -
casts except for raw pointer to
usizecasts -
const unsafe fnis allowed, but the body must consist of safe operations only
The bar for stabilizing const fns in libcore/liballoc/libstd will be that they are writable in stable user code (unless they are wrappers for intrinsics, i.e. size_of and align_of). This means that they must work with min_const_fn.
Things to be done before stabilizing:
- Implement the
min_const_fnfeature gate. (Implement themin_const_fnfeature gate #53604) - Ensure that the above restrictions apply.
- Adjust documentation (see instructions on forge)
- Stabilization PR (see instructions on forge)
Unresolved questions:
None.
Vocabulary: