@@ -11,8 +11,8 @@ use rustc_errors::{
11
11
use rustc_hir:: def:: { CtorKind , DefKind , Res } ;
12
12
use rustc_hir:: pat_util:: EnumerateAndAdjustIterator ;
13
13
use rustc_hir:: {
14
- self as hir, BindingMode , ByRef , ExprKind , HirId , LangItem , Mutability , Pat , PatKind ,
15
- expr_needs_parens,
14
+ self as hir, BindingMode , ByRef , ExprKind , HirId , LangItem , Mutability , Pat , PatExprKind ,
15
+ PatKind , expr_needs_parens,
16
16
} ;
17
17
use rustc_infer:: infer;
18
18
use rustc_middle:: traits:: PatternOriginExpr ;
@@ -250,8 +250,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
250
250
fn check_pat ( & self , pat : & ' tcx Pat < ' tcx > , expected : Ty < ' tcx > , pat_info : PatInfo < ' _ , ' tcx > ) {
251
251
let PatInfo { binding_mode, max_ref_mutbl, top_info : ti, current_depth, .. } = pat_info;
252
252
253
- let path_res = match & pat. kind {
254
- PatKind :: Path ( qpath) => {
253
+ let path_res = match pat. kind {
254
+ PatKind :: Expr ( PatExprKind :: Path ( ref qpath) ) => {
255
255
Some ( self . resolve_ty_and_res_fully_qualified_call ( qpath, pat. hir_id , pat. span ) )
256
256
}
257
257
_ => None ,
@@ -271,6 +271,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
271
271
PatKind :: Wild | PatKind :: Err ( _) => expected,
272
272
// We allow any type here; we ensure that the type is uninhabited during match checking.
273
273
PatKind :: Never => expected,
274
+ PatKind :: Expr ( PatExprKind :: Path ( ref qpath) ) => {
275
+ self . check_pat_path ( pat. hir_id , pat. span , qpath, path_res. unwrap ( ) , expected, ti)
276
+ }
274
277
PatKind :: Expr ( ref lt) => {
275
278
self . check_pat_lit ( pat. hir_id , pat. span , lt, expected, ti, opt_expr_ty. unwrap ( ) )
276
279
}
@@ -281,9 +284,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
281
284
PatKind :: TupleStruct ( ref qpath, subpats, ddpos) => {
282
285
self . check_pat_tuple_struct ( pat, qpath, subpats, ddpos, expected, pat_info)
283
286
}
284
- PatKind :: Path ( ref qpath) => {
285
- self . check_pat_path ( pat. hir_id , pat. span , qpath, path_res. unwrap ( ) , expected, ti)
286
- }
287
287
PatKind :: Struct ( ref qpath, fields, has_rest_pat) => {
288
288
self . check_pat_struct ( pat, qpath, fields, has_rest_pat, expected, pat_info)
289
289
}
@@ -402,6 +402,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
402
402
| PatKind :: Slice ( ..) => AdjustMode :: Peel ,
403
403
// A never pattern behaves somewhat like a literal or unit variant.
404
404
PatKind :: Never => AdjustMode :: Peel ,
405
+ PatKind :: Expr ( PatExprKind :: Path ( _) ) => match opt_path_res. unwrap ( ) {
406
+ // These constants can be of a reference type, e.g. `const X: &u8 = &0;`.
407
+ // Peeling the reference types too early will cause type checking failures.
408
+ // Although it would be possible to *also* peel the types of the constants too.
409
+ Res :: Def ( DefKind :: Const | DefKind :: AssocConst , _) => AdjustMode :: Pass ,
410
+ // In the `ValueNS`, we have `SelfCtor(..) | Ctor(_, Const), _)` remaining which
411
+ // could successfully compile. The former being `Self` requires a unit struct.
412
+ // In either case, and unlike constants, the pattern itself cannot be
413
+ // a reference type wherefore peeling doesn't give up any expressiveness.
414
+ _ => AdjustMode :: Peel ,
415
+ } ,
416
+
405
417
// String and byte-string literals result in types `&str` and `&[u8]` respectively.
406
418
// All other literals result in non-reference types.
407
419
// As a result, we allow `if let 0 = &&0 {}` but not `if let "foo" = &&"foo" {}`.
@@ -415,17 +427,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
415
427
} ;
416
428
return ( adjust, Some ( ty) )
417
429
} ,
418
- PatKind :: Path ( _) => match opt_path_res. unwrap ( ) {
419
- // These constants can be of a reference type, e.g. `const X: &u8 = &0;`.
420
- // Peeling the reference types too early will cause type checking failures.
421
- // Although it would be possible to *also* peel the types of the constants too.
422
- Res :: Def ( DefKind :: Const | DefKind :: AssocConst , _) => AdjustMode :: Pass ,
423
- // In the `ValueNS`, we have `SelfCtor(..) | Ctor(_, Const), _)` remaining which
424
- // could successfully compile. The former being `Self` requires a unit struct.
425
- // In either case, and unlike constants, the pattern itself cannot be
426
- // a reference type wherefore peeling doesn't give up any expressiveness.
427
- _ => AdjustMode :: Peel ,
428
- } ,
429
430
// Ref patterns are complicated, we handle them in `check_pat_ref`.
430
431
PatKind :: Ref ( ..) => AdjustMode :: Pass ,
431
432
// A `_` pattern works with any expected type, so there's no need to do anything.
@@ -952,7 +953,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
952
953
PatKind :: Wild
953
954
| PatKind :: Never
954
955
| PatKind :: Binding ( ..)
955
- | PatKind :: Path ( ..)
956
956
| PatKind :: Box ( ..)
957
957
| PatKind :: Deref ( _)
958
958
| PatKind :: Ref ( ..)
0 commit comments