Remove const_in_array_rep_expr

This commit is contained in:
kadmin 2021-01-26 22:49:30 +00:00
parent fe39653116
commit 6946534d84
28 changed files with 31 additions and 199 deletions

View File

@ -485,9 +485,6 @@ pub fn set(&self, features: &mut Features, span: Span) {
/// Allows `async || body` closures.
(active, async_closure, "1.37.0", Some(62290), None),
/// Allows `[x; N]` where `x` is a constant (RFC 2203).
(active, const_in_array_repeat_expressions, "1.37.0", Some(49147), None),
/// Allows `impl Trait` to be used inside type aliases (RFC 2515).
(active, type_alias_impl_trait, "1.38.0", Some(63063), None),

View File

@ -97,6 +97,9 @@ macro_rules! declare_features {
(removed, extern_in_paths, "1.33.0", Some(55600), None,
Some("subsumed by `::foo::bar` paths")),
(removed, quote, "1.33.0", Some(29601), None, None),
/// Allows `[x; N]` where `x` is a constant (RFC 2203).
(removed, const_in_array_repeat_expressions, "1.37.0", Some(49147), None,
Some("removed due to causing promotable bugs")),
/// Allows using `#[unsafe_destructor_blind_to_params]` (RFC 1238).
(removed, dropck_parametricity, "1.38.0", Some(28498), None, None),
(removed, await_macro, "1.38.0", Some(50547), None,

View File

@ -228,8 +228,7 @@ pub enum ObligationCauseCode<'tcx> {
/// Inline asm operand type must be `Sized`.
InlineAsmSized,
/// `[T, ..n]` implies that `T` must be `Copy`.
/// If `true`, suggest `const_in_array_repeat_expressions` feature flag.
RepeatVec(bool),
RepeatVec,
/// Types of fields (other than the last, except for packed structs) in a struct must be sized.
FieldSized {

View File

@ -43,10 +43,6 @@
use crate::dataflow::impls::MaybeInitializedPlaces;
use crate::dataflow::move_paths::MoveData;
use crate::dataflow::ResultsCursor;
use crate::transform::{
check_consts::ConstCx,
promote_consts::should_suggest_const_in_array_repeat_expressions_attribute,
};
use crate::borrow_check::{
borrow_set::BorrowSet,
@ -1997,22 +1993,13 @@ fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: L
let span = body.source_info(location).span;
let ty = operand.ty(body, tcx);
if !self.infcx.type_is_copy_modulo_regions(self.param_env, ty, span) {
let ccx = ConstCx::new_with_param_env(tcx, body, self.param_env);
// To determine if `const_in_array_repeat_expressions` feature gate should
// be mentioned, need to check if the rvalue is promotable.
let should_suggest =
should_suggest_const_in_array_repeat_expressions_attribute(
&ccx, operand,
);
debug!("check_rvalue: should_suggest={:?}", should_suggest);
let def_id = body.source.def_id().expect_local();
self.infcx.report_selection_error(
&traits::Obligation::new(
ObligationCause::new(
span,
self.tcx().hir().local_def_id_to_hir_id(def_id),
traits::ObligationCauseCode::RepeatVec(should_suggest),
traits::ObligationCauseCode::RepeatVec,
),
self.param_env,
ty::Binder::bind(ty::TraitRef::new(

View File

@ -246,7 +246,8 @@ pub fn in_operand<Q, F>(cx: &ConstCx<'_, 'tcx>, in_local: &mut F, operand: &Oper
};
// Check the qualifs of the value of `const` items.
if let ty::ConstKind::Unevaluated(def, _, None) = constant.literal.val {
if let ty::ConstKind::Unevaluated(def, _, promoted) = constant.literal.val {
assert!(promoted.is_none());
// Don't peek inside trait associated constants.
if cx.tcx.trait_of_item(def.did).is_none() {
let qualifs = if let Some((did, param_did)) = def.as_const_arg() {

View File

@ -102,9 +102,6 @@ pub enum Candidate {
/// Borrow of a constant temporary, candidate for lifetime extension.
Ref(Location),
/// Promotion of the `x` in `[x; 32]`.
Repeat(Location),
/// Currently applied to function calls where the callee has the unstable
/// `#[rustc_args_required_const]` attribute as well as the SIMD shuffle
/// intrinsic. The intrinsic requires the arguments are indeed constant and
@ -120,14 +117,14 @@ impl Candidate {
/// Returns `true` if we should use the "explicit" rules for promotability for this `Candidate`.
fn forces_explicit_promotion(&self) -> bool {
match self {
Candidate::Ref(_) | Candidate::Repeat(_) => false,
Candidate::Ref(_) => false,
Candidate::Argument { .. } | Candidate::InlineAsm { .. } => true,
}
}
fn source_info(&self, body: &Body<'_>) -> SourceInfo {
match self {
Candidate::Ref(location) | Candidate::Repeat(location) => *body.source_info(*location),
Candidate::Ref(location) => *body.source_info(*location),
Candidate::Argument { bb, .. } | Candidate::InlineAsm { bb, .. } => {
*body.source_info(body.terminator_loc(*bb))
}
@ -213,11 +210,6 @@ fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
Rvalue::Ref(..) => {
self.candidates.push(Candidate::Ref(location));
}
Rvalue::Repeat(..) if self.ccx.tcx.features().const_in_array_repeat_expressions => {
// FIXME(#49147) only promote the element when it isn't `Copy`
// (so that code that can copy it at runtime is unaffected).
self.candidates.push(Candidate::Repeat(location));
}
_ => {}
}
}
@ -334,21 +326,6 @@ fn validate_candidate(&self, candidate: Candidate) -> Result<(), Unpromotable> {
_ => bug!(),
}
}
Candidate::Repeat(loc) => {
assert!(!self.explicit);
let statement = &self.body[loc.block].statements[loc.statement_index];
match &statement.kind {
StatementKind::Assign(box (_, Rvalue::Repeat(ref operand, _))) => {
if !self.tcx.features().const_in_array_repeat_expressions {
return Err(Unpromotable);
}
self.validate_operand(operand)
}
_ => bug!(),
}
}
Candidate::Argument { bb, index } => {
assert!(self.explicit);
@ -1090,18 +1067,6 @@ fn promote_candidate(
_ => bug!(),
}
}
Candidate::Repeat(loc) => {
let statement = &mut blocks[loc.block].statements[loc.statement_index];
match statement.kind {
StatementKind::Assign(box (_, Rvalue::Repeat(ref mut operand, _))) => {
let ty = operand.ty(local_decls, self.tcx);
let span = statement.source_info.span;
Rvalue::Use(mem::replace(operand, promoted_operand(ty, span)))
}
_ => bug!(),
}
}
Candidate::Argument { bb, index } => {
let terminator = blocks[bb].terminator_mut();
match terminator.kind {
@ -1182,8 +1147,7 @@ pub fn promote_candidates<'tcx>(
let mut extra_statements = vec![];
for candidate in candidates.into_iter().rev() {
match candidate {
Candidate::Repeat(Location { block, statement_index })
| Candidate::Ref(Location { block, statement_index }) => {
Candidate::Ref(Location { block, statement_index }) => {
if let StatementKind::Assign(box (place, _)) =
&body[block].statements[statement_index].kind
{
@ -1267,27 +1231,3 @@ pub fn promote_candidates<'tcx>(
promotions
}
/// This function returns `true` if the `const_in_array_repeat_expressions` feature attribute should
/// be suggested. This function is probably quite expensive, it shouldn't be run in the happy path.
/// Feature attribute should be suggested if `operand` can be promoted and the feature is not
/// enabled.
crate fn should_suggest_const_in_array_repeat_expressions_attribute<'tcx>(
ccx: &ConstCx<'_, 'tcx>,
operand: &Operand<'tcx>,
) -> bool {
let mut rpo = traversal::reverse_postorder(&ccx.body);
let (temps, _) = collect_temps_and_candidates(&ccx, &mut rpo);
let validator = Validator { ccx, temps: &temps, explicit: false };
let should_promote = validator.validate_operand(operand).is_ok();
let feature_flag = validator.ccx.tcx.features().const_in_array_repeat_expressions;
debug!(
"should_suggest_const_in_array_repeat_expressions_flag: def_id={:?} \
should_promote={:?} feature_flag={:?}",
validator.ccx.def_id(),
should_promote,
feature_flag
);
should_promote && !feature_flag
}

View File

@ -1881,23 +1881,10 @@ fn note_obligation_cause_code<T>(
ObligationCauseCode::Coercion { source: _, target } => {
err.note(&format!("required by cast to type `{}`", self.ty_to_string(target)));
}
ObligationCauseCode::RepeatVec(suggest_const_in_array_repeat_expressions) => {
ObligationCauseCode::RepeatVec => {
err.note(
"the `Copy` trait is required because the repeated element will be copied",
);
if suggest_const_in_array_repeat_expressions {
err.note(
"this array initializer can be evaluated at compile-time, see issue \
#49147 <https://github.com/rust-lang/rust/issues/49147> \
for more information",
);
if tcx.sess.opts.unstable_features.is_nightly_build() {
err.help(
"add `#![feature(const_in_array_repeat_expressions)]` to the \
crate attributes to enable",
);
}
}
}
ObligationCauseCode::VariableType(hir_id) => {
let parent_node = self.tcx.hir().get_parent_node(hir_id);

View File

@ -89,7 +89,6 @@
#![feature(coerce_unsized)]
#![feature(const_btree_new)]
#![feature(const_fn)]
#![feature(const_in_array_repeat_expressions)]
#![feature(cow_is_borrowed)]
#![feature(const_cow_is_borrowed)]
#![feature(dispatch_from_dyn)]

View File

@ -1,11 +0,0 @@
# `const_in_array_repeat_expressions`
The tracking issue for this feature is: [#49147]
[#49147]: https://github.com/rust-lang/rust/issues/49147
------------------------
Relaxes the rules for repeat expressions, `[x; N]` such that `x` may also be `const` (strictly
speaking rvalue promotable), in addition to `typeof(x): Copy`. The result of `[x; N]` where `x` is
`const` is itself also `const`.

View File

@ -1,22 +1,18 @@
error[E0277]: the trait bound `Header<'_>: Copy` is not satisfied
--> $DIR/issue-80371.rs:8:19
--> $DIR/repeat_empty_ok.rs:8:19
|
LL | let headers = [Header{value: &[]}; 128];
| ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `Header<'_>`
|
= note: the `Copy` trait is required because the repeated element will be copied
= note: this array initializer can be evaluated at compile-time, see issue #49147 <https://github.com/rust-lang/rust/issues/49147> for more information
= help: add `#![feature(const_in_array_repeat_expressions)]` to the crate attributes to enable
error[E0277]: the trait bound `Header<'_>: Copy` is not satisfied
--> $DIR/issue-80371.rs:13:19
--> $DIR/repeat_empty_ok.rs:13:19
|
LL | let headers = [Header{value: &[0]}; 128];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `Header<'_>`
|
= note: the `Copy` trait is required because the repeated element will be copied
= note: this array initializer can be evaluated at compile-time, see issue #49147 <https://github.com/rust-lang/rust/issues/49147> for more information
= help: add `#![feature(const_in_array_repeat_expressions)]` to the crate attributes to enable
error: aborting due to 2 previous errors

View File

@ -1,7 +1,7 @@
// run-pass
#![allow(unused)]
#![feature(const_in_array_repeat_expressions)]
#![feature(inline_const)]
#![allow(unused, incomplete_features)]
// Some type that is not copyable.
struct Bar;
@ -18,6 +18,6 @@ const fn type_copy() -> u32 {
// This is allowed because all promotion contexts use the explicit rules for promotability when
// inside an explicit const context.
const _: [Option<Bar>; 2] = [type_no_copy(); 2];
const _: [Option<Bar>; 2] = [const { type_no_copy() }; 2];
fn main() {}

View File

@ -1,5 +1,3 @@
#![feature(const_in_array_repeat_expressions)]
// Some type that is not copyable.
struct Bar;

View File

@ -1,5 +1,5 @@
error[E0277]: the trait bound `Option<Bar>: Copy` is not satisfied
--> $DIR/fn-call-in-non-const.rs:16:31
--> $DIR/fn-call-in-non-const.rs:14:31
|
LL | let _: [Option<Bar>; 2] = [no_copy(); 2];
| ^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `Option<Bar>`

View File

@ -1,6 +1,5 @@
// ignore-compare-mode-nll
// compile-flags: -Z borrowck=migrate
#![feature(const_in_array_repeat_expressions)]
#![allow(warnings)]
// Some type that is not copyable.

View File

@ -1,5 +1,5 @@
error[E0277]: the trait bound `Option<Bar>: Copy` is not satisfied
--> $DIR/migrate-fail.rs:14:37
--> $DIR/migrate-fail.rs:13:37
|
LL | let arr: [Option<Bar>; 2] = [x; 2];
| ^^^^^^ the trait `Copy` is not implemented for `Option<Bar>`
@ -9,7 +9,7 @@ LL | let arr: [Option<Bar>; 2] = [x; 2];
= note: the `Copy` trait is required because the repeated element will be copied
error[E0277]: the trait bound `Option<Bar>: Copy` is not satisfied
--> $DIR/migrate-fail.rs:20:37
--> $DIR/migrate-fail.rs:19:37
|
LL | let arr: [Option<Bar>; 2] = [x; 2];
| ^^^^^^ the trait `Copy` is not implemented for `Option<Bar>`

View File

@ -1,7 +1,6 @@
// check-pass
// compile-flags: -Z borrowck=migrate
// ignore-compare-mode-nll
#![feature(const_in_array_repeat_expressions)]
#![allow(warnings)]
// Some type that is not copyable.

View File

@ -1,5 +1,4 @@
// ignore-compare-mode-nll
#![feature(const_in_array_repeat_expressions, nll)]
#![allow(warnings)]
// Some type that is not copyable.

View File

@ -1,5 +1,5 @@
error[E0277]: the trait bound `Option<Bar>: Copy` is not satisfied
--> $DIR/nll-fail.rs:13:37
--> $DIR/nll-fail.rs:12:37
|
LL | let arr: [Option<Bar>; 2] = [x; 2];
| ^^^^^^ the trait `Copy` is not implemented for `Option<Bar>`
@ -9,7 +9,7 @@ LL | let arr: [Option<Bar>; 2] = [x; 2];
= note: the `Copy` trait is required because the repeated element will be copied
error[E0277]: the trait bound `Option<Bar>: Copy` is not satisfied
--> $DIR/nll-fail.rs:19:37
--> $DIR/nll-fail.rs:18:37
|
LL | let arr: [Option<Bar>; 2] = [x; 2];
| ^^^^^^ the trait `Copy` is not implemented for `Option<Bar>`

View File

@ -1,7 +1,6 @@
// check-pass
// ignore-compare-mode-nll
#![allow(warnings)]
#![feature(const_in_array_repeat_expressions, nll)]
// Some type that is not copyable.
struct Bar;

View File

@ -1,5 +1,4 @@
// run-pass
#![feature(const_in_array_repeat_expressions)]
#[derive(Debug, Eq, PartialEq)]
struct Bar;

View File

@ -1,5 +1,3 @@
#![feature(const_in_array_repeat_expressions)]
#[derive(Copy, Clone)]
struct Foo<T>(T);

View File

@ -1,5 +1,5 @@
error[E0277]: the trait bound `Foo<String>: Copy` is not satisfied
--> $DIR/trait-error.rs:7:5
--> $DIR/trait-error.rs:5:5
|
LL | [Foo(String::new()); 4];
| ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `Foo<String>`

View File

@ -1,17 +0,0 @@
#![allow(warnings)]
struct Bar;
// This function would compile with the feature gate, and tests that it is suggested.
fn foo() {
let arr: [Option<String>; 2] = [None::<String>; 2];
//~^ ERROR the trait bound `Option<String>: Copy` is not satisfied [E0277]
}
// This function would not compile with the feature gate, and tests that it is not suggested.
fn bar() {
let arr: [Option<String>; 2] = [Some("foo".to_string()); 2];
//~^ ERROR the trait bound `Option<String>: Copy` is not satisfied [E0277]
}
fn main() {}

View File

@ -1,25 +0,0 @@
error[E0277]: the trait bound `Option<String>: Copy` is not satisfied
--> $DIR/feature-gate-const_in_array_repeat_expressions.rs:7:36
|
LL | let arr: [Option<String>; 2] = [None::<String>; 2];
| ^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `Option<String>`
|
= help: the following implementations were found:
<Option<T> as Copy>
= note: the `Copy` trait is required because the repeated element will be copied
= note: this array initializer can be evaluated at compile-time, see issue #49147 <https://github.com/rust-lang/rust/issues/49147> for more information
= help: add `#![feature(const_in_array_repeat_expressions)]` to the crate attributes to enable
error[E0277]: the trait bound `Option<String>: Copy` is not satisfied
--> $DIR/feature-gate-const_in_array_repeat_expressions.rs:13:36
|
LL | let arr: [Option<String>; 2] = [Some("foo".to_string()); 2];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `Option<String>`
|
= help: the following implementations were found:
<Option<T> as Copy>
= note: the `Copy` trait is required because the repeated element will be copied
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0277`.

View File

@ -2,7 +2,6 @@
// edition:2018
#![feature(async_closure)]
#![feature(const_in_array_repeat_expressions)]
#![feature(generators)]
#![deny(unused_must_use)]
@ -18,10 +17,6 @@ fn unused() {
[Box::new([|| {}; 10]); 1]; //~ ERROR unused array of boxed arrays of closures that must be used
[|| { //~ ERROR unused array of generators that must be used
yield 42u32;
}; 42];
vec![|| "a"].pop().unwrap(); //~ ERROR unused closure that must be used
let b = false;

View File

@ -1,5 +1,5 @@
error: unused closure that must be used
--> $DIR/unused-closure.rs:10:5
--> $DIR/unused-closure.rs:9:5
|
LL | / || {
LL | | println!("Hello!");
@ -7,14 +7,14 @@ LL | | };
| |______^
|
note: the lint level is defined here
--> $DIR/unused-closure.rs:7:9
--> $DIR/unused-closure.rs:6:9
|
LL | #![deny(unused_must_use)]
| ^^^^^^^^^^^^^^^
= note: closures are lazy and do nothing unless called
error: unused implementer of `Future` that must be used
--> $DIR/unused-closure.rs:14:5
--> $DIR/unused-closure.rs:13:5
|
LL | async {};
| ^^^^^^^^^
@ -22,7 +22,7 @@ LL | async {};
= note: futures do nothing unless you `.await` or poll them
error: unused closure that must be used
--> $DIR/unused-closure.rs:15:5
--> $DIR/unused-closure.rs:14:5
|
LL | || async {};
| ^^^^^^^^^^^^
@ -30,7 +30,7 @@ LL | || async {};
= note: closures are lazy and do nothing unless called
error: unused closure that must be used
--> $DIR/unused-closure.rs:16:5
--> $DIR/unused-closure.rs:15:5
|
LL | async || {};
| ^^^^^^^^^^^^
@ -38,25 +38,15 @@ LL | async || {};
= note: closures are lazy and do nothing unless called
error: unused array of boxed arrays of closures that must be used
--> $DIR/unused-closure.rs:19:5
--> $DIR/unused-closure.rs:18:5
|
LL | [Box::new([|| {}; 10]); 1];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: closures are lazy and do nothing unless called
error: unused array of generators that must be used
--> $DIR/unused-closure.rs:21:5
|
LL | / [|| {
LL | | yield 42u32;
LL | | }; 42];
| |___________^
|
= note: generators are lazy and do nothing unless resumed
error: unused closure that must be used
--> $DIR/unused-closure.rs:25:5
--> $DIR/unused-closure.rs:20:5
|
LL | vec![|| "a"].pop().unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -64,12 +54,12 @@ LL | vec![|| "a"].pop().unwrap();
= note: closures are lazy and do nothing unless called
error: unused closure that must be used
--> $DIR/unused-closure.rs:28:9
--> $DIR/unused-closure.rs:23:9
|
LL | || true;
| ^^^^^^^^
|
= note: closures are lazy and do nothing unless called
error: aborting due to 8 previous errors
error: aborting due to 7 previous errors