Skip to content

Commit 82cac15

Browse files
committed
typeck/expr.rs: extract out check_expr_repeat.
1 parent 877d834 commit 82cac15

File tree

1 file changed

+73
-62
lines changed

1 file changed

+73
-62
lines changed

src/librustc_typeck/check/expr.rs

Lines changed: 73 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -128,68 +128,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
128128
self.check_expr_array(args, expected, expr)
129129
}
130130
ExprKind::Repeat(ref element, ref count) => {
131-
let count_def_id = tcx.hir().local_def_id_from_hir_id(count.hir_id);
132-
let count = if self.const_param_def_id(count).is_some() {
133-
Ok(self.to_const(count, self.tcx.type_of(count_def_id)))
134-
} else {
135-
let param_env = ty::ParamEnv::empty();
136-
let substs = InternalSubsts::identity_for_item(tcx.global_tcx(), count_def_id);
137-
let instance = ty::Instance::resolve(
138-
tcx.global_tcx(),
139-
param_env,
140-
count_def_id,
141-
substs,
142-
).unwrap();
143-
let global_id = GlobalId {
144-
instance,
145-
promoted: None
146-
};
147-
148-
tcx.const_eval(param_env.and(global_id))
149-
};
150-
151-
let uty = match expected {
152-
ExpectHasType(uty) => {
153-
match uty.sty {
154-
ty::Array(ty, _) | ty::Slice(ty) => Some(ty),
155-
_ => None
156-
}
157-
}
158-
_ => None
159-
};
160-
161-
let (element_ty, t) = match uty {
162-
Some(uty) => {
163-
self.check_expr_coercable_to_type(&element, uty);
164-
(uty, uty)
165-
}
166-
None => {
167-
let ty = self.next_ty_var(TypeVariableOrigin {
168-
kind: TypeVariableOriginKind::MiscVariable,
169-
span: element.span,
170-
});
171-
let element_ty = self.check_expr_has_type_or_error(&element, ty);
172-
(element_ty, ty)
173-
}
174-
};
175-
176-
if let Ok(count) = count {
177-
let zero_or_one = count.assert_usize(tcx).map_or(false, |count| count <= 1);
178-
if !zero_or_one {
179-
// For [foo, ..n] where n > 1, `foo` must have
180-
// Copy type:
181-
let lang_item = self.tcx.require_lang_item(lang_items::CopyTraitLangItem);
182-
self.require_type_meets(t, expr.span, traits::RepeatVec, lang_item);
183-
}
184-
}
185-
186-
if element_ty.references_error() {
187-
tcx.types.err
188-
} else if let Ok(count) = count {
189-
tcx.mk_ty(ty::Array(t, count))
190-
} else {
191-
tcx.types.err
192-
}
131+
self.check_expr_repeat(element, count, expected, expr)
193132
}
194133
ExprKind::Tup(ref elts) => {
195134
let flds = expected.only_has_type(self).and_then(|ty| {
@@ -824,4 +763,76 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
824763
};
825764
self.tcx.mk_array(element_ty, args.len() as u64)
826765
}
766+
767+
fn check_expr_repeat(
768+
&self,
769+
element: &'tcx hir::Expr,
770+
count: &'tcx hir::AnonConst,
771+
expected: Expectation<'tcx>,
772+
expr: &'tcx hir::Expr,
773+
) -> Ty<'tcx> {
774+
let tcx = self.tcx;
775+
let count_def_id = tcx.hir().local_def_id_from_hir_id(count.hir_id);
776+
let count = if self.const_param_def_id(count).is_some() {
777+
Ok(self.to_const(count, tcx.type_of(count_def_id)))
778+
} else {
779+
let param_env = ty::ParamEnv::empty();
780+
let substs = InternalSubsts::identity_for_item(tcx.global_tcx(), count_def_id);
781+
let instance = ty::Instance::resolve(
782+
tcx.global_tcx(),
783+
param_env,
784+
count_def_id,
785+
substs,
786+
).unwrap();
787+
let global_id = GlobalId {
788+
instance,
789+
promoted: None
790+
};
791+
792+
tcx.const_eval(param_env.and(global_id))
793+
};
794+
795+
let uty = match expected {
796+
ExpectHasType(uty) => {
797+
match uty.sty {
798+
ty::Array(ty, _) | ty::Slice(ty) => Some(ty),
799+
_ => None
800+
}
801+
}
802+
_ => None
803+
};
804+
805+
let (element_ty, t) = match uty {
806+
Some(uty) => {
807+
self.check_expr_coercable_to_type(&element, uty);
808+
(uty, uty)
809+
}
810+
None => {
811+
let ty = self.next_ty_var(TypeVariableOrigin {
812+
kind: TypeVariableOriginKind::MiscVariable,
813+
span: element.span,
814+
});
815+
let element_ty = self.check_expr_has_type_or_error(&element, ty);
816+
(element_ty, ty)
817+
}
818+
};
819+
820+
if let Ok(count) = count {
821+
let zero_or_one = count.assert_usize(tcx).map_or(false, |count| count <= 1);
822+
if !zero_or_one {
823+
// For [foo, ..n] where n > 1, `foo` must have
824+
// Copy type:
825+
let lang_item = tcx.require_lang_item(lang_items::CopyTraitLangItem);
826+
self.require_type_meets(t, expr.span, traits::RepeatVec, lang_item);
827+
}
828+
}
829+
830+
if element_ty.references_error() {
831+
tcx.types.err
832+
} else if let Ok(count) = count {
833+
tcx.mk_ty(ty::Array(t, count))
834+
} else {
835+
tcx.types.err
836+
}
837+
}
827838
}

0 commit comments

Comments
 (0)