@@ -83,6 +83,9 @@ struct PatInfo<'tcx, 'a> {
8383 binding_mode : BindingMode ,
8484 top_info : TopInfo < ' tcx > ,
8585 decl_origin : Option < DeclOrigin < ' a > > ,
86+
87+ /// The depth of current pattern
88+ current_depth : u32 ,
8689}
8790
8891impl < ' tcx > FnCtxt < ' _ , ' tcx > {
@@ -152,7 +155,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
152155 decl_origin : Option < DeclOrigin < ' tcx > > ,
153156 ) {
154157 let info = TopInfo { expected, origin_expr, span } ;
155- let pat_info = PatInfo { binding_mode : INITIAL_BM , top_info : info, decl_origin } ;
158+ let pat_info =
159+ PatInfo { binding_mode : INITIAL_BM , top_info : info, decl_origin, current_depth : 0 } ;
156160 self . check_pat ( pat, expected, pat_info) ;
157161 }
158162
@@ -163,7 +167,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
163167 /// Conversely, inside this module, `check_pat_top` should never be used.
164168 #[ instrument( level = "debug" , skip( self , pat_info) ) ]
165169 fn check_pat ( & self , pat : & ' tcx Pat < ' tcx > , expected : Ty < ' tcx > , pat_info : PatInfo < ' tcx , ' _ > ) {
166- let PatInfo { binding_mode : def_bm, top_info : ti, .. } = pat_info;
170+ let PatInfo { binding_mode : def_bm, top_info : ti, current_depth, .. } = pat_info;
171+
167172 let path_res = match & pat. kind {
168173 PatKind :: Path ( qpath) => Some (
169174 self . resolve_ty_and_res_fully_qualified_call ( qpath, pat. hir_id , pat. span , None ) ,
@@ -172,8 +177,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
172177 } ;
173178 let adjust_mode = self . calc_adjust_mode ( pat, path_res. map ( |( res, ..) | res) ) ;
174179 let ( expected, def_bm) = self . calc_default_binding_mode ( pat, expected, def_bm, adjust_mode) ;
175- let pat_info =
176- PatInfo { binding_mode : def_bm, top_info : ti, decl_origin : pat_info. decl_origin } ;
180+ let pat_info = PatInfo {
181+ binding_mode : def_bm,
182+ top_info : ti,
183+ decl_origin : pat_info. decl_origin ,
184+ current_depth : current_depth + 1 ,
185+ } ;
177186
178187 let ty = match pat. kind {
179188 PatKind :: Wild | PatKind :: Err ( _) => expected,
@@ -1046,14 +1055,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10461055 expected : Ty < ' tcx > ,
10471056 pat_info : PatInfo < ' tcx , ' _ > ,
10481057 ) -> Ty < ' tcx > {
1049- let PatInfo { binding_mode : def_bm, top_info : ti, decl_origin } = pat_info;
1058+ let PatInfo { binding_mode : def_bm, top_info : ti, decl_origin, current_depth } = pat_info;
10501059 let tcx = self . tcx ;
10511060 let on_error = |e| {
10521061 for pat in subpats {
10531062 self . check_pat (
10541063 pat,
10551064 Ty :: new_error ( tcx, e) ,
1056- PatInfo { binding_mode : def_bm, top_info : ti, decl_origin } ,
1065+ PatInfo { binding_mode : def_bm, top_info : ti, decl_origin, current_depth } ,
10571066 ) ;
10581067 }
10591068 } ;
@@ -1120,7 +1129,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
11201129 self . check_pat (
11211130 subpat,
11221131 field_ty,
1123- PatInfo { binding_mode : def_bm, top_info : ti, decl_origin } ,
1132+ PatInfo { binding_mode : def_bm, top_info : ti, decl_origin, current_depth } ,
11241133 ) ;
11251134
11261135 self . tcx . check_stability (
@@ -2134,7 +2143,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
21342143 // The expected type must be an array or slice, but was neither, so error.
21352144 _ => {
21362145 let guar = expected. error_reported ( ) . err ( ) . unwrap_or_else ( || {
2137- self . error_expected_array_or_slice ( span, expected, pat_info. top_info )
2146+ self . error_expected_array_or_slice ( span, expected, pat_info)
21382147 } ) ;
21392148 let err = Ty :: new_error ( self . tcx , guar) ;
21402149 ( err, Some ( err) , err)
@@ -2273,8 +2282,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
22732282 & self ,
22742283 span : Span ,
22752284 expected_ty : Ty < ' tcx > ,
2276- ti : TopInfo < ' tcx > ,
2285+ pat_info : PatInfo < ' tcx , ' _ > ,
22772286 ) -> ErrorGuaranteed {
2287+ let PatInfo { top_info : ti, current_depth, .. } = pat_info;
2288+
22782289 let mut err = struct_span_code_err ! (
22792290 self . dcx( ) ,
22802291 span,
@@ -2292,9 +2303,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
22922303 && let Some ( _) = ti. origin_expr
22932304 && let Ok ( snippet) = self . tcx . sess . source_map ( ) . span_to_snippet ( span)
22942305 {
2295- let ty = self . resolve_vars_if_possible ( ti. expected ) ;
2296- let is_slice_or_array_or_vector = self . is_slice_or_array_or_vector ( ty) ;
2297- match is_slice_or_array_or_vector. 1 . kind ( ) {
2306+ let resolved_ty = self . resolve_vars_if_possible ( ti. expected ) ;
2307+ let ( is_slice_or_array_or_vector, resolved_ty) =
2308+ self . is_slice_or_array_or_vector ( resolved_ty) ;
2309+ match resolved_ty. kind ( ) {
22982310 ty:: Adt ( adt_def, _)
22992311 if self . tcx . is_diagnostic_item ( sym:: Option , adt_def. did ( ) )
23002312 || self . tcx . is_diagnostic_item ( sym:: Result , adt_def. did ( ) ) =>
@@ -2309,7 +2321,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
23092321 }
23102322 _ => ( ) ,
23112323 }
2312- if is_slice_or_array_or_vector. 0 {
2324+
2325+ let is_top_level = current_depth <= 1 ;
2326+ if is_slice_or_array_or_vector && is_top_level {
23132327 err. span_suggestion (
23142328 span,
23152329 "consider slicing here" ,
0 commit comments