@@ -519,21 +519,28 @@ impl fmt::Debug for Pat {
519
519
}
520
520
521
521
impl Pat {
522
+ /// Attempt reparsing the pattern as a type.
523
+ /// This is intended for use by diagnostics.
522
524
pub ( super ) fn to_ty ( & self ) -> Option < P < Ty > > {
523
525
let node = match & self . node {
526
+ // In a type expression `_` is an inference variable.
524
527
PatKind :: Wild => TyKind :: Infer ,
528
+ // An IDENT pattern with no binding mode would be valid as path to a type. E.g. `u32`.
525
529
PatKind :: Ident ( BindingMode :: ByValue ( Mutability :: Immutable ) , ident, None ) => {
526
530
TyKind :: Path ( None , Path :: from_ident ( * ident) )
527
531
}
528
532
PatKind :: Path ( qself, path) => TyKind :: Path ( qself. clone ( ) , path. clone ( ) ) ,
529
533
PatKind :: Mac ( mac) => TyKind :: Mac ( mac. clone ( ) ) ,
534
+ // `&mut? P` can be reinterpreted as `&mut? T` where `T` is `P` reparsed as a type.
530
535
PatKind :: Ref ( pat, mutbl) => pat
531
536
. to_ty ( )
532
537
. map ( |ty| TyKind :: Rptr ( None , MutTy { ty, mutbl : * mutbl } ) ) ?,
533
- PatKind :: Slice ( pats, None , _) if pats. len ( ) == 1 => {
534
- pats[ 0 ] . to_ty ( ) . map ( TyKind :: Slice ) ?
535
- }
536
- PatKind :: Tuple ( pats, None ) => {
538
+ // A slice/array pattern `[P]` can be reparsed as `[T]`, an unsized array,
539
+ // when `P` can be reparsed as a type `T`.
540
+ PatKind :: Slice ( pats) if pats. len ( ) == 1 => pats[ 0 ] . to_ty ( ) . map ( TyKind :: Slice ) ?,
541
+ // A tuple pattern `(P0, .., Pn)` can be reparsed as `(T0, .., Tn)`
542
+ // assuming `T0` to `Tn` are all syntactically valid as types.
543
+ PatKind :: Tuple ( pats) => {
537
544
let mut tys = Vec :: with_capacity ( pats. len ( ) ) ;
538
545
// FIXME(#48994) - could just be collected into an Option<Vec>
539
546
for pat in pats {
0 commit comments