@@ -4,10 +4,10 @@ use itertools::Itertools;
4
4
use rustc_data_structures:: fx:: FxIndexSet ;
5
5
use rustc_errors:: codes:: * ;
6
6
use rustc_errors:: { Applicability , Diag , ErrorGuaranteed , MultiSpan , a_or_an, listify, pluralize} ;
7
- use rustc_hir:: def:: { CtorOf , DefKind , Res } ;
7
+ use rustc_hir:: def:: { CtorKind , CtorOf , DefKind , Res } ;
8
8
use rustc_hir:: def_id:: DefId ;
9
9
use rustc_hir:: intravisit:: Visitor ;
10
- use rustc_hir:: { ExprKind , HirId , Node , QPath } ;
10
+ use rustc_hir:: { ExprKind , HirId , LangItem , Node , QPath } ;
11
11
use rustc_hir_analysis:: check:: potentially_plural_count;
12
12
use rustc_hir_analysis:: hir_ty_lowering:: HirTyLowerer ;
13
13
use rustc_index:: IndexVec ;
@@ -155,6 +155,50 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
155
155
}
156
156
}
157
157
158
+ /// Requires that `element_ty` is `Copy` (unless it's a const expression itself).
159
+ pub ( super ) fn enforce_repeat_element_needs_copy_bound (
160
+ & self ,
161
+ element : & hir:: Expr < ' _ > ,
162
+ element_ty : Ty < ' tcx > ,
163
+ ) {
164
+ // Actual constants as the repeat element get inserted repeatedly instead of getting copied via Copy.
165
+ match & element. kind {
166
+ hir:: ExprKind :: ConstBlock ( ..) => return ,
167
+ hir:: ExprKind :: Path ( qpath) => {
168
+ let res = self . typeck_results . borrow ( ) . qpath_res ( qpath, element. hir_id ) ;
169
+ if let Res :: Def ( DefKind :: Const | DefKind :: AssocConst | DefKind :: AnonConst , _) = res
170
+ {
171
+ return ;
172
+ }
173
+ }
174
+ _ => { }
175
+ }
176
+
177
+ // If someone calls a const fn or constructs a const value, they can extract that
178
+ // out into a separate constant (or a const block in the future), so we check that
179
+ // to tell them that in the diagnostic. Does not affect typeck.
180
+ let is_constable = match element. kind {
181
+ hir:: ExprKind :: Call ( func, _args) => match * self . node_ty ( func. hir_id ) . kind ( ) {
182
+ ty:: FnDef ( def_id, _) if self . tcx . is_stable_const_fn ( def_id) => {
183
+ traits:: IsConstable :: Fn
184
+ }
185
+ _ => traits:: IsConstable :: No ,
186
+ } ,
187
+ hir:: ExprKind :: Path ( qpath) => {
188
+ match self . typeck_results . borrow ( ) . qpath_res ( & qpath, element. hir_id ) {
189
+ Res :: Def ( DefKind :: Ctor ( _, CtorKind :: Const ) , _) => traits:: IsConstable :: Ctor ,
190
+ _ => traits:: IsConstable :: No ,
191
+ }
192
+ }
193
+ _ => traits:: IsConstable :: No ,
194
+ } ;
195
+
196
+ let lang_item = self . tcx . require_lang_item ( LangItem :: Copy , None ) ;
197
+ let code =
198
+ traits:: ObligationCauseCode :: RepeatElementCopy { is_constable, elt_span : element. span } ;
199
+ self . require_type_meets ( element_ty, element. span , code, lang_item) ;
200
+ }
201
+
158
202
/// Generic function that factors out common logic from function calls,
159
203
/// method calls and overloaded operators.
160
204
pub ( in super :: super ) fn check_argument_types (
0 commit comments