@@ -207,14 +207,26 @@ impl<'tcx> Visitor<'tcx> for Collector<'_, 'tcx> {
207
207
Rvalue :: Ref ( ..) => {
208
208
self . candidates . push ( Candidate :: Ref ( location) ) ;
209
209
}
210
- Rvalue :: Repeat ( elem, _ )
210
+ Rvalue :: Repeat ( elem, n )
211
211
if self . ccx . tcx . features ( ) . const_in_array_repeat_expressions =>
212
212
{
213
- if ! elem. ty ( & self . ccx . body . local_decls , self . ccx . tcx ) . is_copy_modulo_regions (
213
+ let is_copy = elem. ty ( & self . ccx . body . local_decls , self . ccx . tcx ) . is_copy_modulo_regions (
214
214
self . ccx . tcx ,
215
215
self . ccx . param_env ,
216
216
self . span ,
217
- ) {
217
+ ) ;
218
+ let n = n. try_eval_usize ( self . ccx . tcx , self . ccx . param_env ) ;
219
+ let length_requires_copy_or_promotion = match n {
220
+ // Unevaluable (e.g. too generic) -> assume > 1.
221
+ None => true ,
222
+ // A single element does not need copying, we can just use the given element.
223
+ // Zero elements don't even need that one element.
224
+ Some ( 0 ..=1 ) => false ,
225
+ // All other lengths require copying (or promotion-"copying" by creating a
226
+ // a constant and using that many times).
227
+ Some ( _) => true ,
228
+ } ;
229
+ if !is_copy && length_requires_copy_or_promotion {
218
230
self . candidates . push ( Candidate :: Repeat ( location) ) ;
219
231
}
220
232
}
@@ -741,6 +753,14 @@ pub fn validate_candidates(
741
753
// and `#[rustc_args_required_const]` arguments here.
742
754
743
755
let is_promotable = validator. validate_candidate ( candidate) . is_ok ( ) ;
756
+
757
+ if validator. explicit && !is_promotable {
758
+ ccx. tcx . sess . delay_span_bug (
759
+ ccx. body . span ,
760
+ "Explicit promotion requested, but failed to promote" ,
761
+ ) ;
762
+ }
763
+
744
764
match candidate {
745
765
Candidate :: Argument { bb, index } if !is_promotable => {
746
766
let span = ccx. body [ bb] . terminator ( ) . source_info . span ;
0 commit comments