@@ -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