Skip to content

Commit

Permalink
Merge pull request #18489 from dopare/bugfix/18311
Browse files Browse the repository at this point in the history
Fixes #18311 - Incorrect quick info for ValueTuple<T>
  • Loading branch information
sharwell authored Apr 7, 2017
2 parents d14741f + 37ae596 commit b6f7c5c
Show file tree
Hide file tree
Showing 11 changed files with 301 additions and 57 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,11 @@ private bool CanUseTupleTypeName(INamedTypeSymbol tupleSymbol)
{
INamedTypeSymbol currentUnderlying = tupleSymbol.TupleUnderlyingType;

if (currentUnderlying.Arity == 1)
{
return false;
}

while (currentUnderlying.Arity == TupleTypeSymbol.RestPosition)
{
tupleSymbol = (INamedTypeSymbol)currentUnderlying.TypeArguments[TupleTypeSymbol.RestPosition - 1];
Expand Down
46 changes: 23 additions & 23 deletions src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenTupleTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -825,13 +825,13 @@ .maxstack 8
var partialParamType = partialNamesMethod.Parameters.Single().Type;
Assert.False(partialParamType.IsErrorType());
Assert.True(partialParamType.IsTupleType);
Assert.Equal("((System.Int32 e1, System.Int32))", partialParamType.ToTestDisplayString());
Assert.Equal("ValueTuple<(System.Int32 e1, System.Int32)>", partialParamType.ToTestDisplayString());

var allNullNamesMethod = c.GetMember<MethodSymbol>("AllNullNamesMethod");
var allNullParamType = allNullNamesMethod.Parameters.Single().Type;
Assert.False(allNullParamType.IsErrorType());
Assert.True(allNullParamType.IsTupleType);
Assert.Equal("((System.Int32, System.Int32))", allNullParamType.ToTestDisplayString());
Assert.Equal("ValueTuple<(System.Int32, System.Int32)>", allNullParamType.ToTestDisplayString());
}

[Fact]
Expand Down Expand Up @@ -8870,19 +8870,19 @@ void M((int, int, int, int, int, int, int, int) p)
comp.VerifyDiagnostics(
// (42,53): error CS0452: The type '(int)' must be a reference type in order to use it as parameter 'TRest' in the generic type or method 'ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest>'
// void M((int, int, int, int, int, int, int, int) p)
Diagnostic(ErrorCode.ERR_RefConstraintNotSatisfied, "p").WithArguments("System.ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest>", "TRest", "(int)").WithLocation(42, 53),
Diagnostic(ErrorCode.ERR_RefConstraintNotSatisfied, "p").WithArguments("System.ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest>", "TRest", "ValueTuple<int>").WithLocation(42, 53),
// (42,53): error CS0452: The type 'int' must be a reference type in order to use it as parameter 'T1' in the generic type or method 'ValueTuple<T1>'
// void M((int, int, int, int, int, int, int, int) p)
Diagnostic(ErrorCode.ERR_RefConstraintNotSatisfied, "p").WithArguments("System.ValueTuple<T1>", "T1", "int").WithLocation(42, 53),
// (44,18): error CS0452: The type '(int)' must be a reference type in order to use it as parameter 'TRest' in the generic type or method 'ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest>'
// var t0 = (1, 2, 3, 4, 5, 6, 7, 8);
Diagnostic(ErrorCode.ERR_RefConstraintNotSatisfied, "(1, 2, 3, 4, 5, 6, 7, 8)").WithArguments("System.ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest>", "TRest", "(int)").WithLocation(44, 18),
Diagnostic(ErrorCode.ERR_RefConstraintNotSatisfied, "(1, 2, 3, 4, 5, 6, 7, 8)").WithArguments("System.ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest>", "TRest", "ValueTuple<int>").WithLocation(44, 18),
// (44,40): error CS0452: The type 'int' must be a reference type in order to use it as parameter 'T1' in the generic type or method 'ValueTuple<T1>'
// var t0 = (1, 2, 3, 4, 5, 6, 7, 8);
Diagnostic(ErrorCode.ERR_RefConstraintNotSatisfied, "8").WithArguments("System.ValueTuple<T1>", "T1", "int").WithLocation(44, 40),
// (45,9): error CS0452: The type '(int)' must be a reference type in order to use it as parameter 'TRest' in the generic type or method 'ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest>'
// (int, int, int, int, int, int, int, int) t1 = t0;
Diagnostic(ErrorCode.ERR_RefConstraintNotSatisfied, "(int, int, int, int, int, int, int, int)").WithArguments("System.ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest>", "TRest", "(int)").WithLocation(45, 9),
Diagnostic(ErrorCode.ERR_RefConstraintNotSatisfied, "(int, int, int, int, int, int, int, int)").WithArguments("System.ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest>", "TRest", "ValueTuple<int>").WithLocation(45, 9),
// (45,45): error CS0452: The type 'int' must be a reference type in order to use it as parameter 'T1' in the generic type or method 'ValueTuple<T1>'
// (int, int, int, int, int, int, int, int) t1 = t0;
Diagnostic(ErrorCode.ERR_RefConstraintNotSatisfied, "int").WithArguments("System.ValueTuple<T1>", "T1", "int").WithLocation(45, 45)
Expand Down Expand Up @@ -10541,9 +10541,9 @@ static void Main()
"System.Int32 (System.Int32 a1, System.Int32 a2, System.Int32 a3, System.Int32 a4, System.Int32 a5, System.Int32 a6, System.Int32 a7, System.Int32 Item1).a6",
"System.Int32 (System.Int32 a1, System.Int32 a2, System.Int32 a3, System.Int32 a4, System.Int32 a5, System.Int32 a6, System.Int32 a7, System.Int32 Item1).Item7",
"System.Int32 (System.Int32 a1, System.Int32 a2, System.Int32 a3, System.Int32 a4, System.Int32 a5, System.Int32 a6, System.Int32 a7, System.Int32 Item1).a7",
"(System.Int32) (System.Int32 a1, System.Int32 a2, System.Int32 a3, System.Int32 a4, System.Int32 a5, System.Int32 a6, System.Int32 a7, System.Int32 Item1).Rest",
"ValueTuple<System.Int32> (System.Int32 a1, System.Int32 a2, System.Int32 a3, System.Int32 a4, System.Int32 a5, System.Int32 a6, System.Int32 a7, System.Int32 Item1).Rest",
"(System.Int32 a1, System.Int32 a2, System.Int32 a3, System.Int32 a4, System.Int32 a5, System.Int32 a6, System.Int32 a7, System.Int32 Item1)..ctor()",
"(System.Int32 a1, System.Int32 a2, System.Int32 a3, System.Int32 a4, System.Int32 a5, System.Int32 a6, System.Int32 a7, System.Int32 Item1)..ctor(System.Int32 item1, System.Int32 item2, System.Int32 item3, System.Int32 item4, System.Int32 item5, System.Int32 item6, System.Int32 item7, (System.Int32) rest)",
"(System.Int32 a1, System.Int32 a2, System.Int32 a3, System.Int32 a4, System.Int32 a5, System.Int32 a6, System.Int32 a7, System.Int32 Item1)..ctor(System.Int32 item1, System.Int32 item2, System.Int32 item3, System.Int32 item4, System.Int32 item5, System.Int32 item6, System.Int32 item7, ValueTuple<System.Int32> rest)",
"System.Boolean (System.Int32 a1, System.Int32 a2, System.Int32 a3, System.Int32 a4, System.Int32 a5, System.Int32 a6, System.Int32 a7, System.Int32 Item1).Equals(System.Object obj)",
"System.Boolean (System.Int32 a1, System.Int32 a2, System.Int32 a3, System.Int32 a4, System.Int32 a5, System.Int32 a6, System.Int32 a7, System.Int32 Item1).Equals((System.Int32, System.Int32, System.Int32, System.Int32, System.Int32, System.Int32, System.Int32, System.Int32) other)",
"System.Boolean (System.Int32 a1, System.Int32 a2, System.Int32 a3, System.Int32 a4, System.Int32 a5, System.Int32 a6, System.Int32 a7, System.Int32 Item1).System.Collections.IStructuralEquatable.Equals(System.Object other, System.Collections.IEqualityComparer comparer)",
Expand Down Expand Up @@ -10606,22 +10606,22 @@ static void Main()
AssertTupleTypeEquality(m8TupleRestTuple);

AssertTestDisplayString(m8TupleRestTuple.GetMembers(),
"System.Int32 (System.Int32).Item1",
"(System.Int32)..ctor()",
"(System.Int32)..ctor(System.Int32 item1)",
"System.Boolean (System.Int32).Equals(System.Object obj)",
"System.Boolean (System.Int32).Equals((System.Int32) other)",
"System.Boolean (System.Int32).System.Collections.IStructuralEquatable.Equals(System.Object other, System.Collections.IEqualityComparer comparer)",
"System.Int32 (System.Int32).System.IComparable.CompareTo(System.Object other)",
"System.Int32 (System.Int32).CompareTo((System.Int32) other)",
"System.Int32 (System.Int32).System.Collections.IStructuralComparable.CompareTo(System.Object other, System.Collections.IComparer comparer)",
"System.Int32 (System.Int32).GetHashCode()",
"System.Int32 (System.Int32).System.Collections.IStructuralEquatable.GetHashCode(System.Collections.IEqualityComparer comparer)",
"System.Int32 (System.Int32).System.ITupleInternal.GetHashCode(System.Collections.IEqualityComparer comparer)",
"System.String (System.Int32).ToString()",
"System.String (System.Int32).System.ITupleInternal.ToStringEnd()",
"System.Int32 (System.Int32).System.ITupleInternal.Size.get",
"System.Int32 (System.Int32).System.ITupleInternal.Size { get; }");
"System.Int32 ValueTuple<System.Int32>.Item1",
"ValueTuple<System.Int32>..ctor()",
"ValueTuple<System.Int32>..ctor(System.Int32 item1)",
"System.Boolean ValueTuple<System.Int32>.Equals(System.Object obj)",
"System.Boolean ValueTuple<System.Int32>.Equals(ValueTuple<System.Int32> other)",
"System.Boolean ValueTuple<System.Int32>.System.Collections.IStructuralEquatable.Equals(System.Object other, System.Collections.IEqualityComparer comparer)",
"System.Int32 ValueTuple<System.Int32>.System.IComparable.CompareTo(System.Object other)",
"System.Int32 ValueTuple<System.Int32>.CompareTo(ValueTuple<System.Int32> other)",
"System.Int32 ValueTuple<System.Int32>.System.Collections.IStructuralComparable.CompareTo(System.Object other, System.Collections.IComparer comparer)",
"System.Int32 ValueTuple<System.Int32>.GetHashCode()",
"System.Int32 ValueTuple<System.Int32>.System.Collections.IStructuralEquatable.GetHashCode(System.Collections.IEqualityComparer comparer)",
"System.Int32 ValueTuple<System.Int32>.System.ITupleInternal.GetHashCode(System.Collections.IEqualityComparer comparer)",
"System.String ValueTuple<System.Int32>.ToString()",
"System.String ValueTuple<System.Int32>.System.ITupleInternal.ToStringEnd()",
"System.Int32 ValueTuple<System.Int32>.System.ITupleInternal.Size.get",
"System.Int32 ValueTuple<System.Int32>.System.ITupleInternal.Size { get; }");
}

[Fact]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4549,6 +4549,39 @@ public class C
SymbolDisplayPartKind.FieldName);
}

[WorkItem(18311, "https://github.com/dotnet/roslyn/issues/18311")]
[Fact, CompilerTrait(CompilerFeature.Tuples)]
public void TupleWith1Arity()
{
var text = @"
using System;
public class C
{
public ValueTuple<int> f;
}
" + TestResources.NetFX.ValueTuple.tuplelib_cs;
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.
GetTypeMembers("C").Single().
GetMembers("f").Single();

var format = new SymbolDisplayFormat(memberOptions: SymbolDisplayMemberOptions.IncludeType,
genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters);

TestSymbolDescription(
text,
findSymbol,
format,
TestOptions.Regular,
"ValueTuple<Int32> f",
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.StructName,
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.FieldName);
}

[Fact, CompilerTrait(CompilerFeature.Tuples)]
public void TupleWithNames()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Private Shared Function CanUseTupleTypeName(tupleSymbol As INamedTypeSymbol) As Boolean
Dim currentUnderlying As INamedTypeSymbol = tupleSymbol.TupleUnderlyingType

If currentUnderlying.Arity = 1 Then
Return False
End If

While currentUnderlying.Arity = TupleTypeSymbol.RestPosition
tupleSymbol = DirectCast(currentUnderlying.TypeArguments(TupleTypeSymbol.RestPosition - 1), INamedTypeSymbol)
Debug.Assert(tupleSymbol.IsTupleType)
Expand Down
Loading

0 comments on commit b6f7c5c

Please sign in to comment.