Skip to content

Commit 67ce547

Browse files
committed
Refactor and document the repeat length check
1 parent be54947 commit 67ce547

File tree

1 file changed

+22
-19
lines changed
  • compiler/rustc_typeck/src/check

1 file changed

+22
-19
lines changed

compiler/rustc_typeck/src/check/expr.rs

+22-19
Original file line numberDiff line numberDiff line change
@@ -1304,31 +1304,34 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13041304
element_ty: Ty<'tcx>,
13051305
) {
13061306
let tcx = self.tcx;
1307-
let is_const = match &element.kind {
1308-
hir::ExprKind::ConstBlock(..) => true,
1307+
// Actual constants as the repeat element get inserted repeatedly instead of getting copied via Copy.
1308+
match &element.kind {
1309+
hir::ExprKind::ConstBlock(..) => return,
13091310
hir::ExprKind::Path(qpath) => {
13101311
let res = self.typeck_results.borrow().qpath_res(qpath, element.hir_id);
1311-
matches!(
1312-
res,
1313-
Res::Def(DefKind::Const | DefKind::AssocConst | DefKind::AnonConst, _)
1314-
)
1312+
if let Res::Def(DefKind::Const | DefKind::AssocConst | DefKind::AnonConst, _) = res
1313+
{
1314+
return;
1315+
}
13151316
}
1317+
_ => {}
1318+
}
1319+
// If someone calls a const fn, they can extract that call out into a separate constant (or a const
1320+
// block in the future), so we check that to tell them that in the diagnostic. Does not affect typeck.
1321+
let is_const_fn = match element.kind {
1322+
hir::ExprKind::Call(func, _args) => match *self.node_ty(func.hir_id).kind() {
1323+
ty::FnDef(def_id, _) => tcx.is_const_fn(def_id),
1324+
_ => false,
1325+
},
13161326
_ => false,
13171327
};
1318-
if !is_const {
1319-
let is_const_fn = match element.kind {
1320-
hir::ExprKind::Call(func, _args) => match *self.node_ty(func.hir_id).kind() {
1321-
ty::FnDef(def_id, _) => tcx.is_const_fn(def_id),
1322-
_ => false,
1323-
},
1324-
_ => false,
1325-
};
13261328

1327-
if count.try_eval_usize(tcx, self.param_env).map_or(true, |len| len > 1) {
1328-
let lang_item = self.tcx.require_lang_item(LangItem::Copy, None);
1329-
let code = traits::ObligationCauseCode::RepeatElementCopy { is_const_fn };
1330-
self.require_type_meets(element_ty, element.span, code, lang_item);
1331-
}
1329+
// If the length is 0, we don't create any elements, so we don't copy any. If the length is 1, we
1330+
// don't copy that one element, we move it. Only check for Copy if the length is larger.
1331+
if count.try_eval_usize(tcx, self.param_env).map_or(true, |len| len > 1) {
1332+
let lang_item = self.tcx.require_lang_item(LangItem::Copy, None);
1333+
let code = traits::ObligationCauseCode::RepeatElementCopy { is_const_fn };
1334+
self.require_type_meets(element_ty, element.span, code, lang_item);
13321335
}
13331336
}
13341337

0 commit comments

Comments
 (0)