@@ -4918,6 +4918,63 @@ impl<'a> Hash for &'a TemplateParam {
49184918 }
49194919}
49204920
4921+ /// The `<template-param-decl>` production.
4922+ ///
4923+ /// ```text
4924+ /// <template-param-decl> ::= Ty # type parameter
4925+ /// ::= Tn <type> # non-type parameter
4926+ /// ::= Tt <template-param-decl>* E # template parameter
4927+ /// ::= Tp <template-param-decl> # parameter pack
4928+ /// ```
4929+ #[ derive( Clone , Debug , PartialEq , Eq ) ]
4930+ pub enum TemplateParamDecl {
4931+ /// Type Parameter (numbered)
4932+ Type ( u8 ) ,
4933+ }
4934+
4935+ impl Parse for TemplateParamDecl {
4936+ fn parse < ' a , ' b > (
4937+ ctx : & ' a ParseContext ,
4938+ _subs : & ' a mut SubstitutionTable ,
4939+ input : IndexStr < ' b > ,
4940+ ) -> Result < ( TemplateParamDecl , IndexStr < ' b > ) > {
4941+ try_begin_parse ! ( "TemplateParamDecl" , ctx, input) ;
4942+
4943+ let tail = consume ( b"T" , input) ?;
4944+
4945+ if let Ok ( tail) = consume ( b"y" , tail) {
4946+ // TODO: implement a counter
4947+ return Ok ( ( TemplateParamDecl :: Type ( 0 ) , tail) ) ;
4948+ }
4949+
4950+ // TODO: implement other types as well
4951+ Err ( error:: Error :: UnexpectedText )
4952+ }
4953+ }
4954+
4955+ impl < ' subs , W > Demangle < ' subs , W > for TemplateParamDecl
4956+ where
4957+ W : ' subs + DemangleWrite ,
4958+ {
4959+ fn demangle < ' prev , ' ctx > (
4960+ & ' subs self ,
4961+ ctx : & ' ctx mut DemangleContext < ' subs , W > ,
4962+ scope : Option < ArgScopeStack < ' prev , ' subs > > ,
4963+ ) -> fmt:: Result {
4964+ let ctx = try_begin_demangle ! ( self , ctx, scope) ;
4965+
4966+ match self {
4967+ TemplateParamDecl :: Type ( n) => {
4968+ write ! ( ctx, "typename $T" ) ?;
4969+ if * n > 0 {
4970+ write ! ( ctx, "{}" , n - 1 ) ?;
4971+ }
4972+ }
4973+ }
4974+ Ok ( ( ) )
4975+ }
4976+ }
4977+
49214978/// The `<template-template-param>` production.
49224979///
49234980/// ```text
@@ -6912,7 +6969,7 @@ impl Parse for Discriminator {
69126969/// <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _
69136970/// ```
69146971#[ derive( Clone , Debug , PartialEq , Eq ) ]
6915- pub struct ClosureTypeName ( LambdaSig , Option < usize > ) ;
6972+ pub struct ClosureTypeName ( Vec < TemplateParamDecl > , LambdaSig , Option < usize > ) ;
69166973
69176974impl Parse for ClosureTypeName {
69186975 fn parse < ' a , ' b > (
@@ -6922,7 +6979,13 @@ impl Parse for ClosureTypeName {
69226979 ) -> Result < ( ClosureTypeName , IndexStr < ' b > ) > {
69236980 try_begin_parse ! ( "ClosureTypeName" , ctx, input) ;
69246981
6925- let tail = consume ( b"Ul" , input) ?;
6982+ let mut tail = consume ( b"Ul" , input) ?;
6983+ let mut params = vec ! [ ] ;
6984+ while let Ok ( _) = consume ( b"T" , tail) {
6985+ let ( decl, _tail) = TemplateParamDecl :: parse ( ctx, subs, tail) ?;
6986+ params. push ( decl) ;
6987+ tail = _tail;
6988+ }
69266989 let ( sig, tail) = LambdaSig :: parse ( ctx, subs, tail) ?;
69276990 let tail = consume ( b"E" , tail) ?;
69286991 let ( num, tail) = if let Ok ( ( num, tail) ) = parse_number ( 10 , false , tail) {
@@ -6931,7 +6994,7 @@ impl Parse for ClosureTypeName {
69316994 ( None , tail)
69326995 } ;
69336996 let tail = consume ( b"_" , tail) ?;
6934- Ok ( ( ClosureTypeName ( sig, num) , tail) )
6997+ Ok ( ( ClosureTypeName ( params , sig, num) , tail) )
69356998 }
69366999}
69377000
@@ -6946,9 +7009,22 @@ where
69467009 ) -> fmt:: Result {
69477010 let ctx = try_begin_demangle ! ( self , ctx, scope) ;
69487011
6949- write ! ( ctx, "{{lambda(" ) ?;
6950- self . 0 . demangle ( ctx, scope) ?;
6951- write ! ( ctx, ")#{}}}" , self . 1 . map_or( 1 , |n| n + 2 ) ) ?;
7012+ write ! ( ctx, "{{lambda" ) ?;
7013+ if !self . 0 . is_empty ( ) {
7014+ write ! ( ctx, "<" ) ?;
7015+ let mut need_comma = false ;
7016+ for arg in & self . 0 {
7017+ if need_comma {
7018+ write ! ( ctx, ", " ) ?;
7019+ }
7020+ arg. demangle ( ctx, scope) ?;
7021+ need_comma = true ;
7022+ }
7023+ write ! ( ctx, ">" ) ?;
7024+ }
7025+ write ! ( ctx, "(" ) ?;
7026+ self . 1 . demangle ( ctx, scope) ?;
7027+ write ! ( ctx, ")#{}}}" , self . 2 . map_or( 1 , |n| n + 2 ) ) ?;
69527028 Ok ( ( ) )
69537029 }
69547030}
@@ -10307,11 +10383,11 @@ mod tests {
1030710383 assert_parse ! ( ClosureTypeName {
1030810384 Ok => {
1030910385 b"UlvE_..." => {
10310- ClosureTypeName ( LambdaSig ( vec![ ] ) , None ) ,
10386+ ClosureTypeName ( vec! [ ] , LambdaSig ( vec![ ] ) , None ) ,
1031110387 b"..."
1031210388 }
1031310389 b"UlvE36_..." => {
10314- ClosureTypeName ( LambdaSig ( vec![ ] ) , Some ( 36 ) ) ,
10390+ ClosureTypeName ( vec! [ ] , LambdaSig ( vec![ ] ) , Some ( 36 ) ) ,
1031510391 b"..."
1031610392 }
1031710393 }
@@ -10835,6 +10911,7 @@ mod tests {
1083510911 b"UllE_..." => {
1083610912 UnqualifiedName :: ClosureType (
1083710913 ClosureTypeName (
10914+ vec![ ] ,
1083810915 LambdaSig ( vec![
1083910916 TypeHandle :: Builtin (
1084010917 BuiltinType :: Standard (
0 commit comments