From a069866ae962dbfe57367b0ef1c08b29001fc15e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20K=C3=A4ll=C3=A9n?= Date: Fri, 11 Jan 2013 23:16:16 +0100 Subject: [PATCH] Return ambiguous conversions when no most specific source and/or destination could be found. --- .../Resolver/CSharpConversions.cs | 20 +++++++++++++------ .../CSharp/Resolver/ConversionsTest.cs | 4 ++-- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/ICSharpCode.NRefactory.CSharp/Resolver/CSharpConversions.cs b/ICSharpCode.NRefactory.CSharp/Resolver/CSharpConversions.cs index 0178ba2584..cd20d63cbd 100644 --- a/ICSharpCode.NRefactory.CSharp/Resolver/CSharpConversions.cs +++ b/ICSharpCode.NRefactory.CSharp/Resolver/CSharpConversions.cs @@ -819,10 +819,14 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver if (operators.Count > 0) { var mostSpecificSource = operators.Any(op => op.SourceType.Equals(fromType)) ? fromType : FindMostEncompassedType(operators.Select(op => op.SourceType)); if (mostSpecificSource == null) - return Conversion.None; + return Conversion.UserDefinedConversion(operators[0].Method, isImplicit: true, isLifted: operators[0].IsLifted, isAmbiguous: true); var mostSpecificTarget = operators.Any(op => op.TargetType.Equals(toType)) ? toType : FindMostEncompassingType(operators.Select(op => op.TargetType)); - if (mostSpecificTarget == null) - return NullableType.IsNullable(toType) ? UserDefinedImplicitConversion(fromResult, fromType, NullableType.GetUnderlyingType(toType)) : Conversion.None; + if (mostSpecificTarget == null) { + if (NullableType.IsNullable(toType)) + return UserDefinedImplicitConversion(fromResult, fromType, NullableType.GetUnderlyingType(toType)); + else + return Conversion.UserDefinedConversion(operators[0].Method, isImplicit: true, isLifted: operators[0].IsLifted, isAmbiguous: true); + } var selected = SelectOperator(mostSpecificSource, mostSpecificTarget, operators, true); if (selected != Conversion.None) { @@ -860,7 +864,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver mostSpecificSource = FindMostEncompassingType(operators.Select(op => op.SourceType)); } if (mostSpecificSource == null) - return Conversion.None; + return Conversion.UserDefinedConversion(operators[0].Method, isImplicit: false, isLifted: operators[0].IsLifted, isAmbiguous: true); IType mostSpecificTarget; if (operators.Any(op => op.TargetType.Equals(toType))) @@ -869,8 +873,12 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver mostSpecificTarget = FindMostEncompassingType(operators.Where(op => IsEncompassedBy(op.TargetType, toType)).Select(op => op.TargetType)); else mostSpecificTarget = FindMostEncompassedType(operators.Select(op => op.TargetType)); - if (mostSpecificTarget == null) - return NullableType.IsNullable(toType) ? UserDefinedExplicitConversion(fromResult, fromType, NullableType.GetUnderlyingType(toType)) : Conversion.None; + if (mostSpecificTarget == null) { + if (NullableType.IsNullable(toType)) + return UserDefinedExplicitConversion(fromResult, fromType, NullableType.GetUnderlyingType(toType)); + else + return Conversion.UserDefinedConversion(operators[0].Method, isImplicit: false, isLifted: operators[0].IsLifted, isAmbiguous: true); + } var selected = SelectOperator(mostSpecificSource, mostSpecificTarget, operators, false); if (selected != Conversion.None) { diff --git a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/ConversionsTest.cs b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/ConversionsTest.cs index 9d57780beb..4f32000037 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/ConversionsTest.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/ConversionsTest.cs @@ -1144,7 +1144,7 @@ class Program { Assert.AreEqual("i", c.Method.Parameters[0].Name); } - [Test, Ignore("This is currently broken. The conversion is invalid because there is no most encompassed type (options are int?, long? and long), but we report it as Conversion.None")] + [Test] public void UserDefinedImplicitConversion_NullableInt_Or_Long_Source() { string program = @"using System; @@ -1163,7 +1163,7 @@ class Program { Assert.IsTrue(c.IsUserDefined); } - [Test, Ignore("This is currently broken. Should be an ambiguous conversion but returns Conversion.None")] + [Test] public void UserDefinedImplicitConversion_NullableInt_Or_Long_Constant_Source() { string program = @"using System; class Test {