diff options
| author | bors <bors@rust-lang.org> | 2019-10-28 07:38:49 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2019-10-28 07:38:49 +0000 |
| commit | 03a50ae9b87021d4a166c70d2c932f1cb0aa8f28 (patch) | |
| tree | dff9cfee9afb9b5dc1d48c03411ad1286fe29be8 | |
| parent | 9285d401a6070094747465962bc49969b93e14c5 (diff) | |
| parent | 170718c93f3defba2edee69bae7abd64d1672355 (diff) | |
| download | rust-03a50ae9b87021d4a166c70d2c932f1cb0aa8f28.tar.gz rust-03a50ae9b87021d4a166c70d2c932f1cb0aa8f28.zip | |
Auto merge of #65188 - matthewjasper:stabilize-const-constructor, r=Centril
Stabilize `const_constructor`
# Stabilization proposal
I propose that we stabilize `#![feature(const_constructor)]`.
Tracking issue: https://github.com/rust-lang/rust/issues/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
8 files changed, 45 insertions, 109 deletions
diff --git a/src/librustc/ty/constness.rs b/src/librustc/ty/constness.rs index e4022bb24ad..676916f530a 100644 --- a/src/librustc/ty/constness.rs +++ b/src/librustc/ty/constness.rs @@ -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; @@ -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 @@ -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 diff --git a/src/libsyntax/feature_gate/accepted.rs b/src/libsyntax/feature_gate/accepted.rs index 36fcab8450b..d309a17298b 100644 --- a/src/libsyntax/feature_gate/accepted.rs +++ b/src/libsyntax/feature_gate/accepted.rs @@ -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 diff --git a/src/libsyntax/feature_gate/active.rs b/src/libsyntax/feature_gate/active.rs index f6e1d6c4224..3754a3d6fe9 100644 --- a/src/libsyntax/feature_gate/active.rs +++ b/src/libsyntax/feature_gate/active.rs @@ -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), diff --git a/src/test/ui/consts/const_constructor/const-construct-call.rs b/src/test/ui/consts/const_constructor/const-construct-call.rs index f2d2bda53c0..d883d3fa6e4 100644 --- a/src/test/ui/consts/const_constructor/const-construct-call.rs +++ b/src/test/ui/consts/const_constructor/const-construct-call.rs @@ -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. diff --git a/src/test/ui/consts/const_constructor/const_constructor_qpath.rs b/src/test/ui/consts/const_constructor/const_constructor_qpath.rs new file mode 100644 index 00000000000..18aa3d8e816 --- /dev/null +++ b/src/test/ui/consts/const_constructor/const_constructor_qpath.rs @@ -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()); +} diff --git a/src/test/ui/consts/const_constructor/feature-gate-const_constructor.const_fn.stderr b/src/test/ui/consts/const_constructor/feature-gate-const_constructor.const_fn.stderr deleted file mode 100644 index fa4f83ed01e..00000000000 --- a/src/test/ui/consts/const_constructor/feature-gate-const_constructor.const_fn.stderr +++ /dev/null @@ -1,34 +0,0 @@ -error: `std::prelude::v1::Some` is not yet stable as a const fn - --> $DIR/feature-gate-const_constructor.rs:9:37 - | -LL | const EXTERNAL_CONST: Option<i32> = {Some}(1); - | ^^^^^^^^^ - | - = help: add `#![feature(const_constructor)]` to the crate attributes to enable - -error: `E::V` is not yet stable as a const fn - --> $DIR/feature-gate-const_constructor.rs:12:24 - | -LL | const LOCAL_CONST: E = {E::V}(1); - | ^^^^^^^^^ - | - = help: add `#![feature(const_constructor)]` to the crate attributes to enable - -error: `std::prelude::v1::Some` is not yet stable as a const fn - --> $DIR/feature-gate-const_constructor.rs:17:13 - | -LL | let _ = {Some}(1); - | ^^^^^^^^^ - | - = help: add `#![feature(const_constructor)]` to the crate attributes to enable - -error: `E::V` is not yet stable as a const fn - --> $DIR/feature-gate-const_constructor.rs:23:13 - | -LL | let _ = {E::V}(1); - | ^^^^^^^^^ - | - = help: add `#![feature(const_constructor)]` to the crate attributes to enable - -error: aborting due to 4 previous errors - diff --git a/src/test/ui/consts/const_constructor/feature-gate-const_constructor.min_const_fn.stderr b/src/test/ui/consts/const_constructor/feature-gate-const_constructor.min_const_fn.stderr deleted file mode 100644 index fa4f83ed01e..00000000000 --- a/src/test/ui/consts/const_constructor/feature-gate-const_constructor.min_const_fn.stderr +++ /dev/null @@ -1,34 +0,0 @@ -error: `std::prelude::v1::Some` is not yet stable as a const fn - --> $DIR/feature-gate-const_constructor.rs:9:37 - | -LL | const EXTERNAL_CONST: Option<i32> = {Some}(1); - | ^^^^^^^^^ - | - = help: add `#![feature(const_constructor)]` to the crate attributes to enable - -error: `E::V` is not yet stable as a const fn - --> $DIR/feature-gate-const_constructor.rs:12:24 - | -LL | const LOCAL_CONST: E = {E::V}(1); - | ^^^^^^^^^ - | - = help: add `#![feature(const_constructor)]` to the crate attributes to enable - -error: `std::prelude::v1::Some` is not yet stable as a const fn - --> $DIR/feature-gate-const_constructor.rs:17:13 - | -LL | let _ = {Some}(1); - | ^^^^^^^^^ - | - = help: add `#![feature(const_constructor)]` to the crate attributes to enable - -error: `E::V` is not yet stable as a const fn - --> $DIR/feature-gate-const_constructor.rs:23:13 - | -LL | let _ = {E::V}(1); - | ^^^^^^^^^ - | - = help: add `#![feature(const_constructor)]` to the crate attributes to enable - -error: aborting due to 4 previous errors - diff --git a/src/test/ui/consts/const_constructor/feature-gate-const_constructor.rs b/src/test/ui/consts/const_constructor/feature-gate-const_constructor.rs deleted file mode 100644 index b37fd2fd243..00000000000 --- a/src/test/ui/consts/const_constructor/feature-gate-const_constructor.rs +++ /dev/null @@ -1,28 +0,0 @@ -// revisions: min_const_fn const_fn - -#![cfg_attr(const_fn, feature(const_fn))] - -enum E { - V(i32), -} - -const EXTERNAL_CONST: Option<i32> = {Some}(1); -//[min_const_fn]~^ ERROR is not yet stable as a const fn -//[const_fn]~^^ ERROR is not yet stable as a const fn -const LOCAL_CONST: E = {E::V}(1); -//[min_const_fn]~^ ERROR is not yet stable as a const fn -//[const_fn]~^^ ERROR is not yet stable as a const fn - -const fn external_fn() { - let _ = {Some}(1); - //[min_const_fn]~^ ERROR is not yet stable as a const fn - //[const_fn]~^^ ERROR is not yet stable as a const fn -} - -const fn local_fn() { - let _ = {E::V}(1); - //[min_const_fn]~^ ERROR is not yet stable as a const fn - //[const_fn]~^^ ERROR is not yet stable as a const fn -} - -fn main() {} |
