@@ -2042,63 +2042,60 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
20422042 self . tcx. sess,
20432043 span,
20442044 E0529 ,
2045- "expected an array or slice, found `{}`" ,
2046- expected_ty
2045+ "expected an array or slice, found `{expected_ty}`"
20472046 ) ;
2048- if let ty:: Ref ( _, ty, _) = expected_ty. kind ( ) {
2049- if let ty:: Array ( ..) | ty:: Slice ( ..) = ty. kind ( ) {
2050- err . help ( "the semantics of slice patterns changed recently; see issue #62254" ) ;
2051- }
2047+ if let ty:: Ref ( _, ty, _) = expected_ty. kind ( )
2048+ && let ty:: Array ( ..) | ty:: Slice ( ..) = ty. kind ( )
2049+ {
2050+ err . help ( "the semantics of slice patterns changed recently; see issue #62254" ) ;
20522051 } else if Autoderef :: new ( & self . infcx , self . param_env , self . body_id , span, expected_ty, span)
20532052 . any ( |( ty, _) | matches ! ( ty. kind( ) , ty:: Slice ( ..) | ty:: Array ( ..) ) )
2053+ && let ( Some ( span) , true ) = ( ti. span , ti. origin_expr )
2054+ && let Ok ( snippet) = self . tcx . sess . source_map ( ) . span_to_snippet ( span)
20542055 {
2055- if let ( Some ( span) , true ) = ( ti. span , ti. origin_expr ) {
2056- if let Ok ( snippet) = self . tcx . sess . source_map ( ) . span_to_snippet ( span) {
2057- let applicability = Autoderef :: new (
2058- & self . infcx ,
2059- self . param_env ,
2060- self . body_id ,
2061- span,
2062- self . resolve_vars_if_possible ( ti. expected ) ,
2056+ let ty = self . resolve_vars_if_possible ( ti. expected ) ;
2057+ let is_slice_or_array_or_vector = self . is_slice_or_array_or_vector ( & mut err, snippet. clone ( ) , ty) ;
2058+ match is_slice_or_array_or_vector. 1 . kind ( ) {
2059+ ty:: Adt ( adt_def, _)
2060+ if self . tcx . is_diagnostic_item ( sym:: Option , adt_def. did ( ) )
2061+ || self . tcx . is_diagnostic_item ( sym:: Result , adt_def. did ( ) ) =>
2062+ {
2063+ // Slicing won't work here, but `.as_deref()` might (issue #91328).
2064+ err. span_suggestion (
20632065 span,
2064- )
2065- . find_map ( |( ty, _) | {
2066- match ty. kind ( ) {
2067- ty:: Adt ( adt_def, _)
2068- if self . tcx . is_diagnostic_item ( sym:: Option , adt_def. did ( ) )
2069- || self . tcx . is_diagnostic_item ( sym:: Result , adt_def. did ( ) ) =>
2070- {
2071- // Slicing won't work here, but `.as_deref()` might (issue #91328).
2072- err. span_suggestion (
2073- span,
2074- "consider using `as_deref` here" ,
2075- format ! ( "{}.as_deref()" , snippet) ,
2076- Applicability :: MaybeIncorrect ,
2077- ) ;
2078- Some ( None )
2079- }
2080-
2081- ty:: Slice ( ..) | ty:: Array ( ..) => {
2082- Some ( Some ( Applicability :: MachineApplicable ) )
2083- }
2084-
2085- _ => None ,
2086- }
2087- } )
2088- . unwrap_or ( Some ( Applicability :: MaybeIncorrect ) ) ;
2089-
2090- if let Some ( applicability) = applicability {
2091- err. span_suggestion (
2092- span,
2093- "consider slicing here" ,
2094- format ! ( "{}[..]" , snippet) ,
2095- applicability,
2096- ) ;
2097- }
2066+ "consider using `as_deref` here" ,
2067+ format ! ( "{snippet}.as_deref()" ) ,
2068+ Applicability :: MaybeIncorrect ,
2069+ ) ;
20982070 }
2071+ _ => ( )
2072+ }
2073+ if is_slice_or_array_or_vector. 0 {
2074+ err. span_suggestion (
2075+ span,
2076+ "consider slicing here" ,
2077+ format ! ( "{snippet}[..]" ) ,
2078+ Applicability :: MachineApplicable ,
2079+ ) ;
20992080 }
21002081 }
2101- err. span_label ( span, format ! ( "pattern cannot match with input type `{}`" , expected_ty ) ) ;
2082+ err. span_label ( span, format ! ( "pattern cannot match with input type `{expected_ty }`" ) ) ;
21022083 err. emit ( ) ;
21032084 }
2085+
2086+ fn is_slice_or_array_or_vector (
2087+ & self ,
2088+ err : & mut Diagnostic ,
2089+ snippet : String ,
2090+ ty : Ty < ' tcx > ,
2091+ ) -> ( bool , Ty < ' tcx > ) {
2092+ match ty. kind ( ) {
2093+ ty:: Adt ( adt_def, _) if self . tcx . is_diagnostic_item ( sym:: Vec , adt_def. did ( ) ) => {
2094+ ( true , ty)
2095+ }
2096+ ty:: Ref ( _, ty, _) => self . is_slice_or_array_or_vector ( err, snippet, * ty) ,
2097+ ty:: Slice ( ..) | ty:: Array ( ..) => ( true , ty) ,
2098+ _ => ( false , ty) ,
2099+ }
2100+ }
21042101}
0 commit comments