提交 cfa7b63c 编写于 作者: V VSadov

Couple more cases where HasIdentityConversion should be used instead of type equivalence.

The key difference is that HasIdentityConversions ignores object/dynamic distinction. (changeset 1208214)
上级 85e59563
......@@ -113,60 +113,6 @@ public static bool IsBaseClass(TypeSymbol derivedType, TypeSymbol baseType, ref
return false;
}
/// <summary>
/// Determines if a class, struct or interface (the base type) is identical to or
/// a base type of the derived type, considering only the declarations.
/// </summary>
/// <remarks>
/// Object is NOT considered a base of an interface but is considered as base of a struct.
/// </remarks>
public static bool IsBaseDefinitionOfDefinition(NamedTypeSymbol derivedType, NamedTypeSymbol baseType, ref HashSet<DiagnosticInfo> useSiteDiagnostics)
{
// For example, if class C<string> implements IEnumerable<D<string>>, then IEnumerable<T> is a
// "base definition" of C<T>.
Debug.Assert((object)derivedType != null);
Debug.Assert((object)baseType != null);
Debug.Assert(derivedType.IsDefinition);
Debug.Assert(baseType.IsDefinition);
Debug.Assert(!derivedType.IsEnumType());
Debug.Assert(!baseType.IsEnumType());
if (derivedType == baseType)
{
return true; // identity.
}
// refactoring error tolerance: structs and delegates can be base classes in error
// scenarios so we cannot filter on whether or not the base is marked as sealed.
if (baseType.IsInterfaceType())
{
// any implemented interface's original definition is 'baseType'
foreach (var iface in derivedType.AllInterfacesWithDefinitionUseSiteDiagnostics(ref useSiteDiagnostics))
{
if (iface.OriginalDefinition == baseType)
{
return true;
}
}
return false;
}
else
{
// any base class's original definition is 'baseType'
for (var type = derivedType.BaseTypeOriginalDefinition(ref useSiteDiagnostics); (object)type != null; type = type.BaseTypeOriginalDefinition(ref useSiteDiagnostics))
{
if (type == baseType)
{
return true;
}
}
return false;
}
}
/// <summary>
/// Determines if the source type is convertible to the destination type via
/// any conversion: implicit, explicit, user-defined or built-in.
......@@ -1804,7 +1750,7 @@ private bool HasExplicitReferenceTypeParameterConversion(TypeSymbol source, Type
{
for (var type = t.EffectiveBaseClass(ref useSiteDiagnostics); (object)type != null; type = type.BaseTypeWithDefinitionUseSiteDiagnostics(ref useSiteDiagnostics))
{
if (type == source)
if (HasIdentityConversion(type, source))
{
return true;
}
......@@ -2002,7 +1948,7 @@ private bool HasExplicitArrayConversion(TypeSymbol source, TypeSymbol destinatio
foreach (var iface in this.corLibrary.GetDeclaredSpecialType(SpecialType.System_Array).AllInterfacesWithDefinitionUseSiteDiagnostics(ref useSiteDiagnostics))
{
if (iface == source)
if (HasIdentityConversion(iface, source))
{
return true;
}
......
......@@ -5353,6 +5353,51 @@ public override void M<U>()
Diagnostic(ErrorCode.ERR_UnreachableCatch, "U").WithArguments("EG<dynamic>"));
}
[Fact]
public void TypeParameter_DynamicConversions()
{
string source = @"
using System;
public class EG<T> : Exception { }
public abstract class A<T>
{
public abstract void M<U>() where U : T;
}
public class B<V> : A<EG<dynamic>> where V : EG<object>
{
public override void M<U>()
{
V v = default(V);
U u = default(U);
// implicit
EG<dynamic> egd = v;
// implicit
egd = u;
//explicit
v = (V)egd;
//explicit
u = (U)egd;
//implicit array
V[] va = null;
EG<dynamic>[] egda = va;
// explicit array
va = (V[])egda;
}
void Foo() { }
}
";
CreateCompilationWithMscorlibAndSystemCore(source).VerifyDiagnostics();
}
[Fact]
public void CS0160ERR_UnreachableCatch_TypeParameter_Dynamic2()
{
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册