Skip to content

Commit a4e551e

Browse files
committed
Use explicit promotion for repeat expression elements if the type is !Copy
1 parent 29aebf4 commit a4e551e

File tree

5 files changed

+18
-37
lines changed

5 files changed

+18
-37
lines changed

src/librustc_mir/transform/promote_consts.rs

+14-8
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,8 @@ impl Candidate {
122122
/// Returns `true` if we should use the "explicit" rules for promotability for this `Candidate`.
123123
fn forces_explicit_promotion(&self) -> bool {
124124
match self {
125-
Candidate::Ref(_) | Candidate::Repeat(_) => false,
126-
Candidate::Argument { .. } => true,
125+
Candidate::Ref(_) => false,
126+
Candidate::Argument { .. } | Candidate::Repeat(_) => true,
127127
}
128128
}
129129
}
@@ -203,14 +203,20 @@ impl<'tcx> Visitor<'tcx> for Collector<'_, 'tcx> {
203203
fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
204204
self.super_rvalue(rvalue, location);
205205

206-
match *rvalue {
206+
match rvalue {
207207
Rvalue::Ref(..) => {
208208
self.candidates.push(Candidate::Ref(location));
209209
}
210-
Rvalue::Repeat(..) if self.ccx.tcx.features().const_in_array_repeat_expressions => {
211-
// FIXME(#49147) only promote the element when it isn't `Copy`
212-
// (so that code that can copy it at runtime is unaffected).
213-
self.candidates.push(Candidate::Repeat(location));
210+
Rvalue::Repeat(elem, _)
211+
if self.ccx.tcx.features().const_in_array_repeat_expressions =>
212+
{
213+
if !elem.ty(&self.ccx.body.local_decls, self.ccx.tcx).is_copy_modulo_regions(
214+
self.ccx.tcx,
215+
self.ccx.param_env,
216+
self.span,
217+
) {
218+
self.candidates.push(Candidate::Repeat(location));
219+
}
214220
}
215221
_ => {}
216222
}
@@ -380,7 +386,7 @@ impl<'tcx> Validator<'_, 'tcx> {
380386
}
381387
}
382388
Candidate::Repeat(loc) => {
383-
assert!(!self.explicit);
389+
assert!(self.explicit);
384390

385391
let statement = &self.body[loc.block].statements[loc.statement_index];
386392
match &statement.kind {

src/test/ui/consts/rfc-2203-const-array-repeat-exprs/fn-call-in-non-const.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#![feature(const_in_array_repeat_expressions)]
22

3+
// check-pass
4+
35
// Some type that is not copyable.
46
struct Bar;
57

@@ -14,5 +16,4 @@ const fn copy() -> u32 {
1416
fn main() {
1517
let _: [u32; 2] = [copy(); 2];
1618
let _: [Option<Bar>; 2] = [no_copy(); 2];
17-
//~^ ERROR the trait bound `std::option::Option<Bar>: std::marker::Copy` is not satisfied
1819
}

src/test/ui/consts/rfc-2203-const-array-repeat-exprs/fn-call-in-non-const.stderr

-13
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
// ignore-tidy-linelength
21
#![feature(const_in_array_repeat_expressions)]
32

3+
// check-pass
4+
45
#[derive(Copy, Clone)]
56
struct Foo<T>(T);
67

78
fn main() {
89
[Foo(String::new()); 4];
9-
//~^ ERROR the trait bound `Foo<std::string::String>: std::marker::Copy` is not satisfied [E0277]
1010
}

src/test/ui/consts/rfc-2203-const-array-repeat-exprs/trait-error.stderr

-13
This file was deleted.

0 commit comments

Comments
 (0)