@@ -321,6 +321,8 @@ impl<'a> Parser<'a> {
321321 self . parse_borrowed_pointee ( ) ?
322322 } else if self . eat_keyword_noexpect ( kw:: Typeof ) {
323323 self . parse_typeof_ty ( ) ?
324+ } else if self . is_builtin ( ) {
325+ self . parse_builtin_ty ( ) ?
324326 } else if self . eat_keyword ( exp ! ( Underscore ) ) {
325327 // A type to be inferred `_`
326328 TyKind :: Infer
@@ -763,6 +765,42 @@ impl<'a> Parser<'a> {
763765 Ok ( TyKind :: Typeof ( expr) )
764766 }
765767
768+ fn parse_builtin_ty ( & mut self ) -> PResult < ' a , TyKind > {
769+ self . parse_builtin ( |this, lo, ident| {
770+ Ok ( match ident. name {
771+ sym:: field_of => Some ( this. parse_ty_field_of ( lo) ?) ,
772+ _ => None ,
773+ } )
774+ } )
775+ }
776+
777+ /// Built-in macro for `field_of!` expressions.
778+ pub ( crate ) fn parse_ty_field_of ( & mut self , _lo : Span ) -> PResult < ' a , TyKind > {
779+ let container = self . parse_ty ( ) ?;
780+ self . expect ( exp ! ( Comma ) ) ?;
781+
782+ let fields = self . parse_floating_field_access ( ) ?;
783+ let trailing_comma = self . eat_noexpect ( & TokenKind :: Comma ) ;
784+
785+ if let Err ( mut e) = self . expect_one_of ( & [ ] , & [ exp ! ( CloseParen ) ] ) {
786+ if trailing_comma {
787+ e. note ( "unexpected third argument to field_of" ) ;
788+ } else {
789+ e. note ( "field_of expects dot-separated field and variant names" ) ;
790+ }
791+ e. emit ( ) ;
792+ }
793+
794+ // Eat tokens until the macro call ends.
795+ if self . may_recover ( ) {
796+ while !self . token . kind . is_close_delim_or_eof ( ) {
797+ self . bump ( ) ;
798+ }
799+ }
800+
801+ Ok ( TyKind :: FieldOf ( container, fields) )
802+ }
803+
766804 /// Parses a function pointer type (`TyKind::FnPtr`).
767805 /// ```ignore (illustrative)
768806 /// [unsafe] [extern "ABI"] fn (S) -> T
0 commit comments