@@ -1298,14 +1298,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
12981298                let  span = expr. span . shrink_to_hi ( ) ; 
12991299                let  subdiag = if  self . type_is_copy_modulo_regions ( self . param_env ,  ty)  { 
13001300                    errors:: OptionResultRefMismatch :: Copied  {  span,  def_path } 
1301-                 }  else  if  let  Some ( clone_did)  = self . tcx . lang_items ( ) . clone_trait ( ) 
1302-                     && rustc_trait_selection:: traits:: type_known_to_meet_bound_modulo_regions ( 
1303-                         self , 
1304-                         self . param_env , 
1305-                         ty, 
1306-                         clone_did, 
1307-                     ) 
1308-                 { 
1301+                 }  else  if  self . type_is_clone_modulo_regions ( self . param_env ,  ty)  { 
13091302                    errors:: OptionResultRefMismatch :: Cloned  {  span,  def_path } 
13101303                }  else  { 
13111304                    return  false ; 
@@ -2158,6 +2151,79 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
21582151        } 
21592152    } 
21602153
2154+     /// Suggest replacing comma with semicolon in incorrect repeat expressions 
2155+ /// like `["_", 10]` or `vec![String::new(), 10]`. 
2156+ pub ( crate )  fn  suggest_semicolon_in_repeat_expr ( 
2157+         & self , 
2158+         err :  & mut  Diag < ' _ > , 
2159+         expr :  & hir:: Expr < ' _ > , 
2160+         expr_ty :  Ty < ' tcx > , 
2161+     )  -> bool  { 
2162+         // Check if `expr` is contained in array of two elements 
2163+         if  let  hir:: Node :: Expr ( array_expr)  = self . tcx . parent_hir_node ( expr. hir_id ) 
2164+             && let  hir:: ExprKind :: Array ( elements)  = array_expr. kind 
2165+             && let  [ first,  second]  = & elements[ ..] 
2166+             && second. hir_id  == expr. hir_id 
2167+         { 
2168+             // Span between the two elements of the array 
2169+             let  comma_span = first. span . between ( second. span ) ; 
2170+ 
2171+             // Check if `expr` is a constant value of type `usize`. 
2172+             // This can only detect const variable declarations and 
2173+             // calls to const functions. 
2174+ 
2175+             // Checking this here instead of rustc_hir::hir because 
2176+             // this check needs access to `self.tcx` but rustc_hir 
2177+             // has no access to `TyCtxt`. 
2178+             let  expr_is_const_usize = expr_ty. is_usize ( ) 
2179+                 && match  expr. kind  { 
2180+                     ExprKind :: Path ( QPath :: Resolved ( 
2181+                         None , 
2182+                         Path  {  res :  Res :: Def ( DefKind :: Const ,  _) ,  .. } , 
2183+                     ) )  => true , 
2184+                     ExprKind :: Call ( 
2185+                         Expr  { 
2186+                             kind : 
2187+                                 ExprKind :: Path ( QPath :: Resolved ( 
2188+                                     None , 
2189+                                     Path  {  res :  Res :: Def ( DefKind :: Fn ,  fn_def_id) ,  .. } , 
2190+                                 ) ) , 
2191+                             ..
2192+                         } , 
2193+                         _, 
2194+                     )  => self . tcx . is_const_fn ( * fn_def_id) , 
2195+                     _ => false , 
2196+                 } ; 
2197+ 
2198+             // `array_expr` is from a macro `vec!["a", 10]` if 
2199+             // 1. array expression's span is imported from a macro 
2200+             // 2. first element of array implements `Clone` trait 
2201+             // 3. second element is an integer literal or is an expression of `usize` like type 
2202+             if  self . tcx . sess . source_map ( ) . is_imported ( array_expr. span ) 
2203+                 && self . type_is_clone_modulo_regions ( self . param_env ,  self . check_expr ( first) ) 
2204+                 && ( second. is_size_lit ( )  || expr_ty. is_usize_like ( ) ) 
2205+             { 
2206+                 err. subdiagnostic ( errors:: ReplaceCommaWithSemicolon  { 
2207+                     comma_span, 
2208+                     descr :  "a vector" , 
2209+                 } ) ; 
2210+                 return  true ; 
2211+             }  else  if  self . type_is_copy_modulo_regions ( self . param_env ,  self . check_expr ( first) ) 
2212+                 && ( second. is_size_lit ( )  || expr_is_const_usize) 
2213+             { 
2214+                 // `array_expr` is from an array `["a", 10]` if 
2215+                 // 1. first element of array implements `Copy` trait 
2216+                 // 2. second element is an integer literal or is a const value of type `usize` 
2217+                 err. subdiagnostic ( errors:: ReplaceCommaWithSemicolon  { 
2218+                     comma_span, 
2219+                     descr :  "an array" , 
2220+                 } ) ; 
2221+                 return  true ; 
2222+             } 
2223+         } 
2224+         false 
2225+     } 
2226+ 
21612227    /// If the expected type is an enum (Issue #55250) with any variants whose 
21622228/// sole field is of the found type, suggest such variants. (Issue #42764) 
21632229pub ( crate )  fn  suggest_compatible_variants ( 
0 commit comments