@@ -83,6 +83,9 @@ struct PatInfo<'tcx, 'a> {
83
83
binding_mode : BindingMode ,
84
84
top_info : TopInfo < ' tcx > ,
85
85
decl_origin : Option < DeclOrigin < ' a > > ,
86
+
87
+ /// The depth of current pattern
88
+ current_depth : u32 ,
86
89
}
87
90
88
91
impl < ' tcx > FnCtxt < ' _ , ' tcx > {
@@ -152,7 +155,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
152
155
decl_origin : Option < DeclOrigin < ' tcx > > ,
153
156
) {
154
157
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 } ;
156
160
self . check_pat ( pat, expected, pat_info) ;
157
161
}
158
162
@@ -163,7 +167,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
163
167
/// Conversely, inside this module, `check_pat_top` should never be used.
164
168
#[ instrument( level = "debug" , skip( self , pat_info) ) ]
165
169
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
+
167
172
let path_res = match & pat. kind {
168
173
PatKind :: Path ( qpath) => Some (
169
174
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> {
172
177
} ;
173
178
let adjust_mode = self . calc_adjust_mode ( pat, path_res. map ( |( res, ..) | res) ) ;
174
179
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
+ } ;
177
186
178
187
let ty = match pat. kind {
179
188
PatKind :: Wild | PatKind :: Err ( _) => expected,
@@ -1046,14 +1055,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1046
1055
expected : Ty < ' tcx > ,
1047
1056
pat_info : PatInfo < ' tcx , ' _ > ,
1048
1057
) -> 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;
1050
1059
let tcx = self . tcx ;
1051
1060
let on_error = |e| {
1052
1061
for pat in subpats {
1053
1062
self . check_pat (
1054
1063
pat,
1055
1064
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 } ,
1057
1066
) ;
1058
1067
}
1059
1068
} ;
@@ -1120,7 +1129,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1120
1129
self . check_pat (
1121
1130
subpat,
1122
1131
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 } ,
1124
1133
) ;
1125
1134
1126
1135
self . tcx . check_stability (
@@ -2134,7 +2143,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2134
2143
// The expected type must be an array or slice, but was neither, so error.
2135
2144
_ => {
2136
2145
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)
2138
2147
} ) ;
2139
2148
let err = Ty :: new_error ( self . tcx , guar) ;
2140
2149
( err, Some ( err) , err)
@@ -2273,8 +2282,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2273
2282
& self ,
2274
2283
span : Span ,
2275
2284
expected_ty : Ty < ' tcx > ,
2276
- ti : TopInfo < ' tcx > ,
2285
+ pat_info : PatInfo < ' tcx , ' _ > ,
2277
2286
) -> ErrorGuaranteed {
2287
+ let PatInfo { top_info : ti, current_depth, .. } = pat_info;
2288
+
2278
2289
let mut err = struct_span_code_err ! (
2279
2290
self . dcx( ) ,
2280
2291
span,
@@ -2292,9 +2303,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2292
2303
&& let Some ( _) = ti. origin_expr
2293
2304
&& let Ok ( snippet) = self . tcx . sess . source_map ( ) . span_to_snippet ( span)
2294
2305
{
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 ( ) {
2298
2310
ty:: Adt ( adt_def, _)
2299
2311
if self . tcx . is_diagnostic_item ( sym:: Option , adt_def. did ( ) )
2300
2312
|| self . tcx . is_diagnostic_item ( sym:: Result , adt_def. did ( ) ) =>
@@ -2309,7 +2321,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2309
2321
}
2310
2322
_ => ( ) ,
2311
2323
}
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 {
2313
2327
err. span_suggestion (
2314
2328
span,
2315
2329
"consider slicing here" ,
0 commit comments