Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EE should ignore ValueTuple from mscorlib type when duplicate found in app #17192

Merged
merged 11 commits into from Feb 23, 2017

Conversation

jcouv
Copy link
Member

@jcouv jcouv commented Feb 16, 2017

Mitigates https://github.com/dotnet/corefx/issues/16195

Repro:

  1. Make a trivial app targeting 4.6 involving tuples (you must add a reference to ValueTuple package)
  2. On a machine with 4.7 installed, try to debug that program
  3. The program runs fine, with modules listed below (ValueTuple.dll from the corefx package included in the app, mscorlib.dll from desktop 4.7)
  4. In the EE (Immediate Window, Watch, QuickWatch) type something that involves tuple syntax
    This will give an error CS8179, because the compiler found two instances of the well-known type (that is ambiguity).

Fix:
The basic approach is to leverage the existing BinderFlags.IgnoreCorLibraryDuplicatedTypes flag from the Compilation and affect how ValueTuple types are loaded by GetWellKnownType.

I verified the fix in unittest and manually in VS.
VB has the same bug, so I will work on a fix for VB too.

@@ -798,6 +822,11 @@ private NamedTypeSymbol ApplyGenericArguments(NamedTypeSymbol symbol, Type[] typ
return result;
}

private bool IsInCorLib(NamedTypeSymbol type)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

static

@@ -75,7 +75,7 @@ internal Symbol GetWellKnownTypeMember(WellKnownMember member)
return _lazyWellKnownTypeMembers[(int)member];
}

internal NamedTypeSymbol GetWellKnownType(WellKnownType type)
internal NamedTypeSymbol GetWellKnownType(WellKnownType type, bool ignoreCorLibraryDuplicatedTypes = false)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aleksey pointed out that we are in a Compilation here, so no need to thread this through. We can just grab this option from the compilation.

@jcouv
Copy link
Member Author

jcouv commented Feb 21, 2017

FYI @tmat

' ignore candidate
Continue For
End If
If (IsInCorLib(result)) Then
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Parentheses are not needed.

@@ -89,6 +91,27 @@ internal DkmClrType GetType(string typeName, params System.Type[] typeArguments)
return null;
}

private IEnumerable<DkmClrModuleInstance> WithMscorlibLast(DkmClrModuleInstance[] list)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

static

DkmClrModuleInstance mscorlib = null;
foreach (var module in list)
{
if (module.Assembly.GetReferencedAssemblies().Length == 0)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TypeHelpers.IsMscorlib(module.Assembly)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had tried that, but they are actually different Assembly types.
One is System.Reflection.Assembly and the other is Microsoft.VisualStudio.Debugger.Metadata.Assembly.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I see. In that case, can TypeHelpers.IsMscorlib be private again?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops. Thanks. Fixed now

@jcouv jcouv force-pushed the tolerate-duplicates branch 2 times, most recently from 609d211 to 28abce3 Compare February 22, 2017 18:50
@jcouv
Copy link
Member Author

jcouv commented Feb 23, 2017

@cston @dotnet/roslyn-compiler This is ready for review when you have time. Thanks

@@ -11,6 +11,8 @@
using System.Linq;
using System.Reflection;
using Type = Microsoft.VisualStudio.Debugger.Metadata.Type;
using System.Collections.Generic;
using System.Diagnostics;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sort usings.

app.AssertTheseDiagnostics()

Dim runtime = CreateRuntimeInstance({app.ToModuleInstance(), corlibWithVT.ToModuleInstance()})
' Create EE context with app assembly (including ValueTuple) And a more recent corlib (also including ValueTuple)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo: and rather than And.

@@ -86,7 +86,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Scripting
xmlReferenceResolver:=Nothing, ' don't support XML file references in interactive (permissions & doc comment includes)
sourceReferenceResolver:=SourceFileResolver.Default,
metadataReferenceResolver:=script.Options.MetadataResolver,
assemblyIdentityComparer:=DesktopAssemblyIdentityComparer.Default),
assemblyIdentityComparer:=DesktopAssemblyIdentityComparer.Default).
WithIgnoreCorLibraryDuplicatedTypes(True),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was LookupOptions.IgnoreCorLibraryDuplicatedTypes used before in scripting?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VB scripting didn't use that option previously (only the expression compiler). I was a bug.
In C#, both scripting and EE use BinderFlags.IgnoreCorLibraryDuplicatedTypes.

@tmat may want to comment.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, both VB and C# should use it.

@cston
Copy link
Member

cston commented Feb 23, 2017

LGTM

Copy link
Member

@VSadov VSadov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@jcouv jcouv merged commit 8003aca into dotnet:master Feb 23, 2017
@jcouv jcouv deleted the tolerate-duplicates branch February 23, 2017 22:07
@@ -778,6 +787,21 @@ private NamedTypeSymbol ApplyGenericArguments(NamedTypeSymbol symbol, Type[] typ
if ((object)result != null)
{
// duplicate
if (ignoreCorLibraryDuplicatedTypes)
{
if (IsInCorLib(candidate))
Copy link
Contributor

@AlekseyTs AlekseyTs Feb 23, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if (IsInCorLib(candidate)) [](start = 24, length = 26)

Are tests cover bodies of both if statements (this one and the next)? #Closed

@@ -798,6 +822,11 @@ private NamedTypeSymbol ApplyGenericArguments(NamedTypeSymbol symbol, Type[] typ
return result;
}

private static bool IsInCorLib(NamedTypeSymbol type)
{
return type.ContainingAssembly == type.ContainingAssembly.CorLibrary;
Copy link
Contributor

@AlekseyTs AlekseyTs Feb 23, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

type.ContainingAssembly == type.ContainingAssembly.CorLibrary [](start = 19, length = 61)

(object)type.ContainingAssembly ==CorLibrary ? #Closed

@AlekseyTs
Copy link
Contributor

AlekseyTs commented Feb 23, 2017

    internal NamedTypeSymbol GetWellKnownType(WellKnownType type)

At this point it feels like we can benefit from a comment describing how exactly ambiguity is handled by this method #Closed


Refers to: src/Compilers/CSharp/Portable/Symbols/Compilation_WellKnownMembers.cs:78 in f33c1bc. [](commit_id = f33c1bc, deletion_comment = False)

@@ -527,6 +541,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols
Return result
End Function

Private Shared Function IsInCorLib(type As NamedTypeSymbol) As Boolean
Return type.ContainingAssembly = type.ContainingAssembly.CorLibrary
Copy link
Contributor

@AlekseyTs AlekseyTs Feb 23, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

type.ContainingAssembly = type.ContainingAssembly.CorLibrary [](start = 19, length = 60)

type.ContainingAssembly Is CorLibrary ? #Closed

@AlekseyTs
Copy link
Contributor

AlekseyTs commented Feb 23, 2017

    Friend Function GetWellKnownType(type As WellKnownType) As NamedTypeSymbol

Consider adding a comment what effect does IgnoreCorLibraryDuplicatedTypes option have. #Closed


Refers to: src/Compilers/VisualBasic/Portable/Symbols/WellKnownMembers.vb:348 in f33c1bc. [](commit_id = f33c1bc, deletion_comment = False)

@AlekseyTs
Copy link
Contributor

AlekseyTs commented Feb 23, 2017

    Public Overloads Function Equals(other As VisualBasicCompilationOptions) As Boolean Implements IEquatable(Of VisualBasicCompilationOptions).Equals

It feels like an implementation of this function should be adjusted and relevant tests added. #Closed


Refers to: src/Compilers/VisualBasic/Portable/VisualBasicCompilationOptions.vb:964 in f33c1bc. [](commit_id = f33c1bc, deletion_comment = False)

DkmClrModuleInstance mscorlib = null;
foreach (var module in list)
{
if (module.Assembly.GetReferencedAssemblies().Length == 0)
Copy link
Contributor

@AlekseyTs AlekseyTs Feb 23, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if (module.Assembly.GetReferencedAssemblies().Length == 0) [](start = 16, length = 58)

This check is not accurate. I think it is possible to have an assembly without references that is not Core Library. #Closed

Copy link
Contributor

@AlekseyTs AlekseyTs Feb 23, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should at least check whether it defines the object type. #Closed

@AlekseyTs
Copy link
Contributor

AlekseyTs commented Feb 23, 2017

It looks like we are missing direct tests for GetWellknownType API. #Closed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants