@@ -20,6 +20,7 @@ use syntax_pos::{Span, DUMMY_SP};
2020use codemap:: { respan, Spanned } ;
2121use abi:: Abi ;
2222use ext:: hygiene:: { Mark , SyntaxContext } ;
23+ use parse:: parser:: { RecoverQPath , PathStyle } ;
2324use print:: pprust;
2425use ptr:: P ;
2526use rustc_data_structures:: indexed_vec;
@@ -519,6 +520,38 @@ impl Pat {
519520 }
520521}
521522
523+ impl RecoverQPath for Pat {
524+ fn to_ty ( & self ) -> Option < P < Ty > > {
525+ let node = match & self . node {
526+ PatKind :: Wild => TyKind :: Infer ,
527+ PatKind :: Ident ( BindingMode :: ByValue ( Mutability :: Immutable ) , ident, None ) =>
528+ TyKind :: Path ( None , Path :: from_ident ( ident. span , ident. node ) ) ,
529+ PatKind :: Path ( qself, path) => TyKind :: Path ( qself. clone ( ) , path. clone ( ) ) ,
530+ PatKind :: Mac ( mac) => TyKind :: Mac ( mac. clone ( ) ) ,
531+ PatKind :: Ref ( pat, mutbl) =>
532+ pat. to_ty ( ) . 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+ PatKind :: Tuple ( pats, None ) => {
536+ let mut tys = Vec :: new ( ) ;
537+ for pat in pats {
538+ tys. push ( pat. to_ty ( ) ?) ;
539+ }
540+ TyKind :: Tup ( tys)
541+ }
542+ _ => return None ,
543+ } ;
544+
545+ Some ( P ( Ty { node, id : self . id , span : self . span } ) )
546+ }
547+ fn to_recovered ( & self , qself : Option < QSelf > , path : Path ) -> Self {
548+ Self { span : path. span , node : PatKind :: Path ( qself, path) , id : self . id }
549+ }
550+ fn to_string ( & self ) -> String {
551+ pprust:: pat_to_string ( self )
552+ }
553+ }
554+
522555/// A single field in a struct pattern
523556///
524557/// Patterns like the fields of Foo `{ x, ref y, ref mut z }`
@@ -877,6 +910,54 @@ impl Expr {
877910 true
878911 }
879912 }
913+
914+ fn to_bound ( & self ) -> Option < TyParamBound > {
915+ match & self . node {
916+ ExprKind :: Path ( None , path) =>
917+ Some ( TraitTyParamBound ( PolyTraitRef :: new ( Vec :: new ( ) , path. clone ( ) , self . span ) ,
918+ TraitBoundModifier :: None ) ) ,
919+ _ => None ,
920+ }
921+ }
922+ }
923+
924+ impl RecoverQPath for Expr {
925+ fn to_ty ( & self ) -> Option < P < Ty > > {
926+ let node = match & self . node {
927+ ExprKind :: Path ( qself, path) => TyKind :: Path ( qself. clone ( ) , path. clone ( ) ) ,
928+ ExprKind :: Mac ( mac) => TyKind :: Mac ( mac. clone ( ) ) ,
929+ ExprKind :: Paren ( expr) => expr. to_ty ( ) . map ( TyKind :: Paren ) ?,
930+ ExprKind :: AddrOf ( mutbl, expr) =>
931+ expr. to_ty ( ) . map ( |ty| TyKind :: Rptr ( None , MutTy { ty, mutbl : * mutbl } ) ) ?,
932+ ExprKind :: Repeat ( expr, expr_len) =>
933+ expr. to_ty ( ) . map ( |ty| TyKind :: Array ( ty, expr_len. clone ( ) ) ) ?,
934+ ExprKind :: Array ( exprs) if exprs. len ( ) == 1 =>
935+ exprs[ 0 ] . to_ty ( ) . map ( TyKind :: Slice ) ?,
936+ ExprKind :: Tup ( exprs) => {
937+ let mut tys = Vec :: new ( ) ;
938+ for expr in exprs {
939+ tys. push ( expr. to_ty ( ) ?) ;
940+ }
941+ TyKind :: Tup ( tys)
942+ }
943+ ExprKind :: Binary ( binop, lhs, rhs) if binop. node == BinOpKind :: Add =>
944+ if let ( Some ( lhs) , Some ( rhs) ) = ( lhs. to_bound ( ) , rhs. to_bound ( ) ) {
945+ TyKind :: TraitObject ( vec ! [ lhs, rhs] , TraitObjectSyntax :: None )
946+ } else {
947+ return None ;
948+ }
949+ _ => return None ,
950+ } ;
951+
952+ Some ( P ( Ty { node, id : self . id , span : self . span } ) )
953+ }
954+ fn to_recovered ( & self , qself : Option < QSelf > , path : Path ) -> Self {
955+ Self { span : path. span , node : ExprKind :: Path ( qself, path) ,
956+ id : self . id , attrs : self . attrs . clone ( ) }
957+ }
958+ fn to_string ( & self ) -> String {
959+ pprust:: expr_to_string ( self )
960+ }
880961}
881962
882963impl fmt:: Debug for Expr {
@@ -1388,6 +1469,19 @@ pub struct Ty {
13881469 pub span : Span ,
13891470}
13901471
1472+ impl RecoverQPath for Ty {
1473+ fn to_ty ( & self ) -> Option < P < Ty > > {
1474+ Some ( P ( self . clone ( ) ) )
1475+ }
1476+ fn to_recovered ( & self , qself : Option < QSelf > , path : Path ) -> Self {
1477+ Self { span : path. span , node : TyKind :: Path ( qself, path) , id : self . id }
1478+ }
1479+ fn to_string ( & self ) -> String {
1480+ pprust:: ty_to_string ( self )
1481+ }
1482+ const PATH_STYLE : PathStyle = PathStyle :: Type ;
1483+ }
1484+
13911485impl fmt:: Debug for Ty {
13921486 fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
13931487 write ! ( f, "type({})" , pprust:: ty_to_string( self ) )
0 commit comments