@@ -117,7 +117,7 @@ bool IdDependsOnImpl(ITypeSymbol type)
117117 case TypeKind . Delegate :
118118 case TypeKind . Error :
119119 var named = ( INamedTypeSymbol ) type ;
120- if ( named . IsTupleType )
120+ if ( named . IsTupleType && named . TupleUnderlyingType is object )
121121 named = named . TupleUnderlyingType ;
122122 if ( IdDependsOnImpl ( named . ContainingType ) )
123123 return true ;
@@ -152,10 +152,11 @@ bool IdDependsOnImpl(ITypeSymbol type)
152152 /// <param name="cx">The extraction context.</param>
153153 /// <param name="trapFile">The trap builder used to store the result.</param>
154154 /// <param name="symbolBeingDefined">The outer symbol being defined (to avoid recursive ids).</param>
155- public static void BuildTypeId ( this ITypeSymbol type , Context cx , TextWriter trapFile , ISymbol symbolBeingDefined ) =>
156- type . BuildTypeId ( cx , trapFile , symbolBeingDefined , true ) ;
155+ /// <param name="constructUnderlyingTupleType">Whether to build a type ID for the underlying `System.ValueTuple` struct in the case of tuple types.</param>
156+ public static void BuildTypeId ( this ITypeSymbol type , Context cx , TextWriter trapFile , ISymbol symbolBeingDefined , bool constructUnderlyingTupleType = false ) =>
157+ type . BuildTypeId ( cx , trapFile , symbolBeingDefined , true , constructUnderlyingTupleType ) ;
157158
158- static void BuildTypeId ( this ITypeSymbol type , Context cx , TextWriter trapFile , ISymbol symbolBeingDefined , bool addBaseClass )
159+ static void BuildTypeId ( this ITypeSymbol type , Context cx , TextWriter trapFile , ISymbol symbolBeingDefined , bool addBaseClass , bool constructUnderlyingTupleType )
159160 {
160161 using ( cx . StackGuard )
161162 {
@@ -173,7 +174,7 @@ static void BuildTypeId(this ITypeSymbol type, Context cx, TextWriter trapFile,
173174 case TypeKind . Delegate :
174175 case TypeKind . Error :
175176 var named = ( INamedTypeSymbol ) type ;
176- named . BuildNamedTypeId ( cx , trapFile , symbolBeingDefined , addBaseClass ) ;
177+ named . BuildNamedTypeId ( cx , trapFile , symbolBeingDefined , addBaseClass , constructUnderlyingTupleType ) ;
177178 return ;
178179 case TypeKind . Pointer :
179180 var ptr = ( IPointerTypeSymbol ) type ;
@@ -195,7 +196,7 @@ static void BuildTypeId(this ITypeSymbol type, Context cx, TextWriter trapFile,
195196 }
196197 }
197198
198- static void BuildOrWriteId ( this ISymbol symbol , Context cx , TextWriter trapFile , ISymbol symbolBeingDefined , bool addBaseClass )
199+ static void BuildOrWriteId ( this ISymbol symbol , Context cx , TextWriter trapFile , ISymbol symbolBeingDefined , bool addBaseClass , bool constructUnderlyingTupleType = false )
199200 {
200201 // We need to keep track of the symbol being defined in order to avoid cyclic labels.
201202 // For example, in
@@ -210,11 +211,13 @@ static void BuildOrWriteId(this ISymbol symbol, Context cx, TextWriter trapFile,
210211 //
211212 // ```
212213 // #123 = @"C`1 : IEnumerable<__self___T>"
213- // ```
214+ // ```
214215 if ( SymbolEqualityComparer . Default . Equals ( symbol , symbolBeingDefined ) )
215216 trapFile . Write ( "__self__" ) ;
216217 else if ( symbol is ITypeSymbol type && type . IdDependsOn ( cx , symbolBeingDefined ) )
217- type . BuildTypeId ( cx , trapFile , symbolBeingDefined , addBaseClass ) ;
218+ type . BuildTypeId ( cx , trapFile , symbolBeingDefined , addBaseClass , constructUnderlyingTupleType ) ;
219+ else if ( symbol is INamedTypeSymbol namedType && namedType . IsTupleType && constructUnderlyingTupleType )
220+ trapFile . WriteSubId ( NamedType . CreateNamedTypeFromTupleType ( cx , namedType ) ) ;
218221 else
219222 trapFile . WriteSubId ( CreateEntity ( cx , symbol ) ) ;
220223 }
@@ -262,9 +265,9 @@ private static void BuildAssembly(IAssemblySymbol asm, TextWriter trapFile, bool
262265 trapFile . Write ( "::" ) ;
263266 }
264267
265- static void BuildNamedTypeId ( this INamedTypeSymbol named , Context cx , TextWriter trapFile , ISymbol symbolBeingDefined , bool addBaseClass )
268+ static void BuildNamedTypeId ( this INamedTypeSymbol named , Context cx , TextWriter trapFile , ISymbol symbolBeingDefined , bool addBaseClass , bool constructUnderlyingTupleType )
266269 {
267- if ( named . IsTupleType )
270+ if ( ! constructUnderlyingTupleType && named . IsTupleType )
268271 {
269272 trapFile . Write ( '(' ) ;
270273 trapFile . BuildList ( "," , named . TupleElements ,
@@ -308,10 +311,10 @@ void AddContaining()
308311 }
309312 else
310313 {
311- named . ConstructedFrom . BuildOrWriteId ( cx , trapFile , symbolBeingDefined , addBaseClass ) ;
314+ named . ConstructedFrom . BuildOrWriteId ( cx , trapFile , symbolBeingDefined , addBaseClass , constructUnderlyingTupleType ) ;
312315 trapFile . Write ( '<' ) ;
313316 // Encode the nullability of the type arguments in the label.
314- // Type arguments with different nullability can result in
317+ // Type arguments with different nullability can result in
315318 // a constructed type with different nullability of its members and methods,
316319 // so we need to create a distinct database entity for it.
317320 trapFile . BuildList ( "," , named . GetAnnotatedTypeArguments ( ) ,
@@ -360,7 +363,7 @@ static void BuildAnonymousName(this INamedTypeSymbol type, Context cx, TextWrite
360363 /// Constructs a display name string for this type symbol.
361364 /// </summary>
362365 /// <param name="trapFile">The trap builder used to store the result.</param>
363- public static void BuildDisplayName ( this ITypeSymbol type , Context cx , TextWriter trapFile )
366+ public static void BuildDisplayName ( this ITypeSymbol type , Context cx , TextWriter trapFile , bool constructUnderlyingTupleType = false )
364367 {
365368 using ( cx . StackGuard )
366369 {
@@ -384,7 +387,7 @@ public static void BuildDisplayName(this ITypeSymbol type, Context cx, TextWrite
384387 case TypeKind . Delegate :
385388 case TypeKind . Error :
386389 var named = ( INamedTypeSymbol ) type ;
387- named . BuildNamedTypeDisplayName ( cx , trapFile ) ;
390+ named . BuildNamedTypeDisplayName ( cx , trapFile , constructUnderlyingTupleType ) ;
388391 return ;
389392 case TypeKind . Pointer :
390393 var ptr = ( IPointerTypeSymbol ) type ;
@@ -403,9 +406,9 @@ public static void BuildDisplayName(this ITypeSymbol type, Context cx, TextWrite
403406 }
404407 }
405408
406- public static void BuildNamedTypeDisplayName ( this INamedTypeSymbol namedType , Context cx , TextWriter trapFile )
409+ public static void BuildNamedTypeDisplayName ( this INamedTypeSymbol namedType , Context cx , TextWriter trapFile , bool constructUnderlyingTupleType )
407410 {
408- if ( namedType . IsTupleType )
411+ if ( ! constructUnderlyingTupleType && namedType . IsTupleType )
409412 {
410413 trapFile . Write ( '(' ) ;
411414 trapFile . BuildList ( "," , namedType . TupleElements . Select ( f => f . Type ) ,
0 commit comments