Skip to content

Commit

Permalink
Auto merge of #65188 - matthewjasper:stabilize-const-constructor, r=C…
Browse files Browse the repository at this point in the history
…entril

Stabilize `const_constructor`

# Stabilization proposal

I propose that we stabilize `#![feature(const_constructor)]`.

Tracking issue: #61456
Version target: 1.40 (2019-11-05 => beta, 2019-12-19 => stable).

## What is stabilized

### User guide

Tuple struct and tuple variant constructors are now considered to be constant functions. As such a call expression where the callee has a tuple struct or variant constructor "function item" type can be called:

```rust
const fn make_options() {
    // These already work because they are special cased:
    Some(0);
    (Option::Some)(1);
    // These also work now:
    let f = Option::Some;
    f(2);
    {Option::Some}(3);
    <Option<_>>::Some(5);
}
```

### Motivation

Consistency with other `const fn`. Consistency between syntactic path forms.

This should also ensure that constructors implement `const Fn` traits and can be coerced to `const fn` function pointers, if they are introduced.

## Tests

* [ui/consts/const_constructor/const-construct-call.rs](https://github.com/rust-lang/rust/blob/0d75ab2293a106eb674ac01860910cfc1580837e/src/test/ui/consts/const_constructor/const-construct-call.rs) - Tests various syntactic forms, use in both `const fn` and `const` items, and constructors in both the current and extern crates.
* [ui/consts/const_constructor/const_constructor_qpath.rs](https://github.com/rust-lang/rust/blob/1850dfcdabf8258a1f023f26c2c59e96b869dd95/src/test/ui/consts/const_constructor/const_constructor_qpath.rs) - Tests that type qualified paths to enum variants are also considered to be `const fn`.(#64247)

r? @oli-obk

Closes #61456
Closes  #64247
  • Loading branch information
bors committed Oct 28, 2019
2 parents 9285d40 + 170718c commit 03a50ae
Show file tree
Hide file tree
Showing 8 changed files with 45 additions and 109 deletions.
11 changes: 3 additions & 8 deletions src/librustc/ty/constness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::ty::query::Providers;
use crate::hir::def_id::DefId;
use crate::hir;
use crate::ty::TyCtxt;
use syntax_pos::symbol::{sym, Symbol};
use syntax_pos::symbol::Symbol;
use crate::hir::map::blocks::FnLikeNode;
use syntax::attr;

Expand All @@ -13,14 +13,11 @@ impl<'tcx> TyCtxt<'tcx> {
self.is_const_fn_raw(def_id) && match self.is_unstable_const_fn(def_id) {
Some(feature_name) => {
// has a `rustc_const_unstable` attribute, check whether the user enabled the
// corresponding feature gate, const_constructor is not a lib feature, so has
// to be checked separately.
// corresponding feature gate.
self.features()
.declared_lib_features
.iter()
.any(|&(sym, _)| sym == feature_name)
|| (feature_name == sym::const_constructor
&& self.features().const_constructor)
},
// functions without const stability are either stable user written
// const fn or the user is using feature gates and we thus don't
Expand All @@ -31,9 +28,7 @@ impl<'tcx> TyCtxt<'tcx> {

/// Whether the `def_id` is an unstable const fn and what feature gate is necessary to enable it
pub fn is_unstable_const_fn(self, def_id: DefId) -> Option<Symbol> {
if self.is_constructor(def_id) {
Some(sym::const_constructor)
} else if self.is_const_fn_raw(def_id) {
if self.is_const_fn_raw(def_id) {
self.lookup_stability(def_id)?.const_stability
} else {
None
Expand Down
2 changes: 2 additions & 0 deletions src/libsyntax/feature_gate/accepted.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,8 @@ declare_features! (
(accepted, macros_in_extern, "1.40.0", Some(49476), None),
/// Allows future-proofing enums/structs with the `#[non_exhaustive]` attribute (RFC 2008).
(accepted, non_exhaustive, "1.40.0", Some(44109), None),
/// Allows calling constructor functions in `const fn`.
(accepted, const_constructor, "1.40.0", Some(61456), None),

// -------------------------------------------------------------------------
// feature-group-end: accepted features
Expand Down
3 changes: 0 additions & 3 deletions src/libsyntax/feature_gate/active.rs
Original file line number Diff line number Diff line change
Expand Up @@ -488,9 +488,6 @@ declare_features! (
/// Allows the user of associated type bounds.
(active, associated_type_bounds, "1.34.0", Some(52662), None),

/// Allows calling constructor functions in `const fn`.
(active, const_constructor, "1.37.0", Some(61456), None),

/// Allows `if/while p && let q = r && ...` chains.
(active, let_chains, "1.37.0", Some(53667), None),

Expand Down
2 changes: 0 additions & 2 deletions src/test/ui/consts/const_constructor/const-construct-call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@

#![cfg_attr(const_fn, feature(const_fn))]

#![feature(const_constructor)]

// Ctor(..) is transformed to Ctor { 0: ... } in HAIR lowering, so directly
// calling constructors doesn't require them to be const.

Expand Down
40 changes: 40 additions & 0 deletions src/test/ui/consts/const_constructor/const_constructor_qpath.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// revisions: min_const_fn const_fn
// run-pass

#![cfg_attr(const_fn, feature(const_fn))]

trait ConstDefault {
const DEFAULT: Self;
}

#[derive(PartialEq)]
enum E {
V(i32),
W(usize),
}

impl ConstDefault for E {
const DEFAULT: Self = Self::V(23);
}

impl ConstDefault for Option<i32> {
const DEFAULT: Self = Self::Some(23);
}

impl E {
const NON_DEFAULT: Self = Self::W(12);
const fn local_fn() -> Self {
Self::V(23)
}
}

const fn explicit_qpath() -> E {
let _x = <Option<usize>>::Some(23);
<E>::W(12)
}

fn main() {
assert!(E::DEFAULT == E::local_fn());
assert!(Option::DEFAULT == Some(23));
assert!(E::NON_DEFAULT == explicit_qpath());
}

This file was deleted.

This file was deleted.

This file was deleted.

0 comments on commit 03a50ae

Please sign in to comment.