2525 Concept ,
2626 DecltypeSpecifier ,
2727 DecoratedType ,
28+ DeductionGuide ,
2829 EnumDecl ,
2930 Enumerator ,
3031 Field ,
@@ -1868,10 +1869,9 @@ def _parse_parameters(
18681869 _auto_return_typename = PQName ([AutoSpecifier ()])
18691870
18701871 def _parse_trailing_return_type (
1871- self , fn : typing .Union [ Function , FunctionType ]
1872- ) -> None :
1872+ self , return_type : typing .Optional [ DecoratedType ]
1873+ ) -> DecoratedType :
18731874 # entry is "->"
1874- return_type = fn .return_type
18751875 if not (
18761876 isinstance (return_type , Type )
18771877 and not return_type .const
@@ -1890,8 +1890,7 @@ def _parse_trailing_return_type(
18901890
18911891 dtype = self ._parse_cv_ptr (parsed_type )
18921892
1893- fn .has_trailing_return = True
1894- fn .return_type = dtype
1893+ return dtype
18951894
18961895 def _parse_fn_end (self , fn : Function ) -> None :
18971896 """
@@ -1918,7 +1917,9 @@ def _parse_fn_end(self, fn: Function) -> None:
19181917 fn .raw_requires = self ._parse_requires (rtok )
19191918
19201919 if self .lex .token_if ("ARROW" ):
1921- self ._parse_trailing_return_type (fn )
1920+ return_type = self ._parse_trailing_return_type (fn .return_type )
1921+ fn .has_trailing_return = True
1922+ fn .return_type = return_type
19221923
19231924 if self .lex .token_if ("{" ):
19241925 self ._discard_contents ("{" , "}" )
@@ -1966,7 +1967,9 @@ def _parse_method_end(self, method: Method) -> None:
19661967 elif tok_value in ("&" , "&&" ):
19671968 method .ref_qualifier = tok_value
19681969 elif tok_value == "->" :
1969- self ._parse_trailing_return_type (method )
1970+ return_type = self ._parse_trailing_return_type (method .return_type )
1971+ method .has_trailing_return = True
1972+ method .return_type = return_type
19701973 if self .lex .token_if ("{" ):
19711974 self ._discard_contents ("{" , "}" )
19721975 method .has_body = True
@@ -2000,6 +2003,7 @@ def _parse_function(
20002003 is_friend : bool ,
20012004 is_typedef : bool ,
20022005 msvc_convention : typing .Optional [LexToken ],
2006+ is_guide : bool = False ,
20032007 ) -> bool :
20042008 """
20052009 Assumes the caller has already consumed the return type and name, this consumes the
@@ -2076,7 +2080,21 @@ def _parse_function(
20762080 self .visitor .on_method_impl (state , method )
20772081
20782082 return method .has_body or method .has_trailing_return
2079-
2083+ elif is_guide :
2084+ assert isinstance (state , (ExternBlockState , NamespaceBlockState ))
2085+ if not self .lex .token_if ("ARROW" ):
2086+ raise self ._parse_error (None , expected = "Trailing return type" )
2087+ return_type = self ._parse_trailing_return_type (
2088+ Type (PQName ([AutoSpecifier ()]))
2089+ )
2090+ guide = DeductionGuide (
2091+ return_type ,
2092+ name = pqname ,
2093+ parameters = params ,
2094+ doxygen = doxygen ,
2095+ )
2096+ self .visitor .on_deduction_guide (state , guide )
2097+ return False
20802098 else :
20812099 assert return_type is not None
20822100 fn = Function (
@@ -2210,7 +2228,9 @@ def _parse_cv_ptr_or_fn(
22102228 assert not isinstance (dtype , FunctionType )
22112229 dtype = dtype_fn = FunctionType (dtype , fn_params , vararg )
22122230 if self .lex .token_if ("ARROW" ):
2213- self ._parse_trailing_return_type (dtype_fn )
2231+ return_type = self ._parse_trailing_return_type (dtype_fn .return_type )
2232+ dtype_fn .has_trailing_return = True
2233+ dtype_fn .return_type = return_type
22142234
22152235 else :
22162236 msvc_convention = None
@@ -2391,6 +2411,7 @@ def _parse_decl(
23912411 destructor = False
23922412 op = None
23932413 msvc_convention = None
2414+ is_guide = False
23942415
23952416 # If we have a leading (, that's either an obnoxious grouping
23962417 # paren or it's a constructor
@@ -2441,8 +2462,15 @@ def _parse_decl(
24412462 # grouping paren like "void (name(int x));"
24422463 toks = self ._consume_balanced_tokens (tok )
24432464
2444- # .. not sure what it's grouping, so put it back?
2445- self .lex .return_tokens (toks [1 :- 1 ])
2465+ # check to see if the next token is an arrow, and thus a trailing return
2466+ if self .lex .token_peek_if ("ARROW" ):
2467+ self .lex .return_tokens (toks )
2468+ # the leading name of the class/ctor has been parsed as a type before the parens
2469+ pqname = parsed_type .typename
2470+ is_guide = True
2471+ else :
2472+ # .. not sure what it's grouping, so put it back?
2473+ self .lex .return_tokens (toks [1 :- 1 ])
24462474
24472475 if dtype :
24482476 msvc_convention = self .lex .token_if_val (* self ._msvc_conventions )
@@ -2473,6 +2501,7 @@ def _parse_decl(
24732501 is_friend ,
24742502 is_typedef ,
24752503 msvc_convention ,
2504+ is_guide ,
24762505 )
24772506 elif msvc_convention :
24782507 raise self ._parse_error (msvc_convention )
0 commit comments