@@ -111,24 +111,53 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
111
111
pub ( in super :: super ) fn check_repeat_exprs ( & self ) {
112
112
let mut deferred_repeat_expr_checks = self . deferred_repeat_expr_checks . borrow_mut ( ) ;
113
113
debug ! ( "FnCtxt::check_repeat_exprs: {} deferred checks" , deferred_repeat_expr_checks. len( ) ) ;
114
- for ( element, element_ty, count) in deferred_repeat_expr_checks. drain ( ..) {
115
- // We want to emit an error if the const is not structurally resolveable as otherwise
116
- // we can find up conservatively proving `Copy` which may infer the repeat expr count
117
- // to something that never required `Copy` in the first place.
118
- let count =
119
- self . structurally_resolve_const ( element. span , self . normalize ( element. span , count) ) ;
120
-
121
- // Avoid run on "`NotCopy: Copy` is not implemented" errors when the repeat expr count
122
- // is erroneous/unknown. The user might wind up specifying a repeat count of 0/1.
123
- if count. references_error ( ) {
124
- continue ;
125
- }
126
114
127
- // If the length is 0, we don't create any elements, so we don't copy any.
128
- // If the length is 1, we don't copy that one element, we move it. Only check
129
- // for `Copy` if the length is larger.
130
- if count. try_to_target_usize ( self . tcx ) . is_none_or ( |x| x > 1 ) {
131
- self . enforce_repeat_element_needs_copy_bound ( element, element_ty) ;
115
+ let deferred_repeat_expr_checks = deferred_repeat_expr_checks
116
+ . drain ( ..)
117
+ . flat_map ( |( element, element_ty, count) | {
118
+ // We want to emit an error if the const is not structurally resolveable as otherwise
119
+ // we can find up conservatively proving `Copy` which may infer the repeat expr count
120
+ // to something that never required `Copy` in the first place.
121
+ let count = self
122
+ . structurally_resolve_const ( element. span , self . normalize ( element. span , count) ) ;
123
+
124
+ // Avoid run on "`NotCopy: Copy` is not implemented" errors when the repeat expr count
125
+ // is erroneous/unknown. The user might wind up specifying a repeat count of 0/1.
126
+ if count. references_error ( ) {
127
+ return None ;
128
+ }
129
+
130
+ Some ( ( element, element_ty, count) )
131
+ } )
132
+ // We collect to force the side effects of structurally resolving the repeat count to happen in one
133
+ // go, to avoid side effects from proving `Copy` affecting whether repeat counts are known or not.
134
+ // If we did not do this we would get results that depend on the order that we evaluate each repeat
135
+ // expr's `Copy` check.
136
+ . collect :: < Vec < _ > > ( ) ;
137
+
138
+ for ( element, element_ty, count) in deferred_repeat_expr_checks {
139
+ match count. kind ( ) {
140
+ ty:: ConstKind :: Value ( val)
141
+ if val. try_to_target_usize ( self . tcx ) . is_none_or ( |count| count > 1 ) =>
142
+ {
143
+ self . enforce_repeat_element_needs_copy_bound ( element, element_ty)
144
+ }
145
+ // If the length is 0 or 1 we don't actually copy the element, we either don't create it
146
+ // or we just use the one value.
147
+ ty:: ConstKind :: Value ( _) => ( ) ,
148
+
149
+ // If the length is a generic parameter or some rigid alias then conservatively
150
+ // require `element_ty: Copy` as it may wind up being `>1` after monomorphization.
151
+ ty:: ConstKind :: Param ( _)
152
+ | ty:: ConstKind :: Expr ( _)
153
+ | ty:: ConstKind :: Placeholder ( _)
154
+ | ty:: ConstKind :: Unevaluated ( _) => {
155
+ self . enforce_repeat_element_needs_copy_bound ( element, element_ty)
156
+ }
157
+
158
+ ty:: ConstKind :: Bound ( _, _) | ty:: ConstKind :: Infer ( _) | ty:: ConstKind :: Error ( _) => {
159
+ unreachable ! ( )
160
+ }
132
161
}
133
162
}
134
163
}
0 commit comments