@@ -2044,63 +2044,64 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
20442044 self . tcx. sess,
20452045 span,
20462046 E0529 ,
2047- "expected an array or slice, found `{}`" ,
2048- expected_ty
2047+ "expected an array or slice, found `{expected_ty}`"
20492048 ) ;
2050- if let ty:: Ref ( _, ty, _) = expected_ty. kind ( ) {
2051- if let ty:: Array ( ..) | ty:: Slice ( ..) = ty. kind ( ) {
2052- err . help ( "the semantics of slice patterns changed recently; see issue #62254" ) ;
2053- }
2049+ if let ty:: Ref ( _, ty, _) = expected_ty. kind ( )
2050+ && let ty:: Array ( ..) | ty:: Slice ( ..) = ty. kind ( )
2051+ {
2052+ err . help ( "the semantics of slice patterns changed recently; see issue #62254" ) ;
20542053 } else if Autoderef :: new ( & self . infcx , self . param_env , self . body_id , span, expected_ty, span)
20552054 . any ( |( ty, _) | matches ! ( ty. kind( ) , ty:: Slice ( ..) | ty:: Array ( ..) ) )
2055+ && let ( Some ( span) , true ) = ( ti. span , ti. origin_expr )
2056+ && let Ok ( snippet) = self . tcx . sess . source_map ( ) . span_to_snippet ( span)
20562057 {
2057- if let ( Some ( span) , true ) = ( ti. span , ti. origin_expr ) {
2058- if let Ok ( snippet) = self . tcx . sess . source_map ( ) . span_to_snippet ( span) {
2059- let applicability = Autoderef :: new (
2060- & self . infcx ,
2061- self . param_env ,
2062- self . body_id ,
2063- span,
2064- self . resolve_vars_if_possible ( ti. expected ) ,
2065- span,
2066- )
2067- . find_map ( |( ty, _) | {
2068- match ty. kind ( ) {
2069- ty:: Adt ( adt_def, _)
2070- if self . tcx . is_diagnostic_item ( sym:: Option , adt_def. did ( ) )
2071- || self . tcx . is_diagnostic_item ( sym:: Result , adt_def. did ( ) ) =>
2072- {
2073- // Slicing won't work here, but `.as_deref()` might (issue #91328).
2074- err. span_suggestion (
2075- span,
2076- "consider using `as_deref` here" ,
2077- format ! ( "{}.as_deref()" , snippet) ,
2078- Applicability :: MaybeIncorrect ,
2079- ) ;
2080- Some ( None )
2081- }
2082-
2083- ty:: Slice ( ..) | ty:: Array ( ..) => {
2084- Some ( Some ( Applicability :: MachineApplicable ) )
2085- }
2086-
2087- _ => None ,
2088- }
2089- } )
2090- . unwrap_or ( Some ( Applicability :: MaybeIncorrect ) ) ;
2091-
2092- if let Some ( applicability) = applicability {
2058+ let any_target_ty = Autoderef :: new (
2059+ & self . infcx ,
2060+ self . param_env ,
2061+ self . body_id ,
2062+ span,
2063+ self . resolve_vars_if_possible ( ti. expected ) ,
2064+ span,
2065+ )
2066+ . any ( |( ty, _) | {
2067+ debug ! ( "kind={:?}" , ty. kind( ) ) ;
2068+ match ty. kind ( ) {
2069+ ty:: Adt ( adt_def, _)
2070+ if self . tcx . is_diagnostic_item ( sym:: Option , adt_def. did ( ) )
2071+ || self . tcx . is_diagnostic_item ( sym:: Result , adt_def. did ( ) ) =>
2072+ {
2073+ // Slicing won't work here, but `.as_deref()` might (issue #91328).
20932074 err. span_suggestion (
20942075 span,
2095- "consider slicing here" ,
2096- format ! ( "{}[..]" , snippet ) ,
2097- applicability ,
2076+ "consider using `as_deref` here" ,
2077+ format ! ( "{snippet}.as_deref()" ) ,
2078+ Applicability :: MaybeIncorrect ,
20982079 ) ;
2080+ false
20992081 }
2082+ _ => self . is_slice_or_array_or_vector ( ty) ,
21002083 }
2084+ } ) ;
2085+
2086+ if any_target_ty {
2087+ err. span_suggestion (
2088+ span,
2089+ "consider slicing here" ,
2090+ format ! ( "{snippet}[..]" ) ,
2091+ Applicability :: MachineApplicable ,
2092+ ) ;
21012093 }
21022094 }
2103- err. span_label ( span, format ! ( "pattern cannot match with input type `{}`" , expected_ty ) ) ;
2095+ err. span_label ( span, format ! ( "pattern cannot match with input type `{expected_ty }`" ) ) ;
21042096 err. emit ( ) ;
21052097 }
2098+
2099+ fn is_slice_or_array_or_vector ( & self , ty : Ty < ' tcx > ) -> bool {
2100+ match ty. kind ( ) {
2101+ ty:: Adt ( adt_def, _) if self . tcx . is_diagnostic_item ( sym:: Vec , adt_def. did ( ) ) => true ,
2102+ ty:: Ref ( _, ty, _) => self . is_slice_or_array_or_vector ( * ty) ,
2103+ ty:: Slice ( ..) | ty:: Array ( ..) => true ,
2104+ _ => false ,
2105+ }
2106+ }
21062107}
0 commit comments