diff --git a/src/Compilers/CSharp/Portable/Binder/Semantics/Conversions/Conversions.cs b/src/Compilers/CSharp/Portable/Binder/Semantics/Conversions/Conversions.cs index d1fd763c7b9fd..1dda2dd2c9090 100644 --- a/src/Compilers/CSharp/Portable/Binder/Semantics/Conversions/Conversions.cs +++ b/src/Compilers/CSharp/Portable/Binder/Semantics/Conversions/Conversions.cs @@ -382,7 +382,13 @@ public static bool ReportDelegateOrFunctionPointerMethodGroupDiagnostics(Binder typeContainingConstructor: null, delegateTypeBeingInvoked: null, isMethodGroupConversion: true, returnRefKind: invokeMethodOpt?.RefKind, delegateOrFunctionPointerType: targetType); - hasErrors = overloadDiagnostics.HasAnyErrors(); + // Even if no diagnostics were reported, check if any candidate method has error types + // in its return type or parameters. This can happen when ERR_BadRetType or similar errors + // are suppressed for methods with omitted type arguments. + hasErrors = overloadDiagnostics.HasAnyErrors() + || result.Results.Any(static candidate => candidate.Member.ReturnType.ContainsErrorType() + || candidate.Member.Parameters.Any(static p => p.Type.ContainsErrorType())); + diagnostics.AddRangeAndFree(overloadDiagnostics); } } diff --git a/src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/OverloadResolutionResult.cs b/src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/OverloadResolutionResult.cs index 7982f26bcba47..66791be64d1e8 100644 --- a/src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/OverloadResolutionResult.cs +++ b/src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/OverloadResolutionResult.cs @@ -726,7 +726,13 @@ private bool HadReturnMismatch(Location location, BindingDiagnosticBag diagnosti if (!mismatch.IsNull) { var method = (MethodSymbol)(Symbol)mismatch.Member; - diagnostics.Add(ErrorCode.ERR_BadRetType, location, method, method.ReturnType); + // Only report ERR_BadRetType if the return type is well-defined. + // If the return type is an error type (from omitted type arguments like Method<>), + // there's already a more specific error reported elsewhere (e.g., ERR_OmittedTypeArgument). + if (!method.ReturnType.ContainsErrorType()) + { + diagnostics.Add(ErrorCode.ERR_BadRetType, location, method, method.ReturnType); + } return true; } diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/BindingTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/BindingTests.cs index be2dc6665b3b0..4999166309c14 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/BindingTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/BindingTests.cs @@ -3860,9 +3860,6 @@ public void Test() // (33,51): error CS8389: Omitting the type argument is not allowed in the current context // System.Func delegateConversion1 = "string literal".ExtensionMethod1<>; Diagnostic(ErrorCode.ERR_OmittedTypeArgument, @"""string literal"".ExtensionMethod1<>").WithLocation(33, 51), - // (33,51): error CS0407: '? FooExtensions.ExtensionMethod1(object)' has the wrong return type - // System.Func delegateConversion1 = "string literal".ExtensionMethod1<>; - Diagnostic(ErrorCode.ERR_BadRetType, @"""string literal"".ExtensionMethod1<>").WithArguments("FooExtensions.ExtensionMethod1(object)", "?").WithLocation(33, 51), // (34,51): error CS8389: Omitting the type argument is not allowed in the current context // System.Func delegateConversion2 = "string literal".ExtensionMethod2<>; Diagnostic(ErrorCode.ERR_OmittedTypeArgument, @"""string literal"".ExtensionMethod2<>").WithLocation(34, 51), @@ -3871,6 +3868,32 @@ public void Test() Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "ExtensionMethod2<>").WithArguments("string", "ExtensionMethod2").WithLocation(34, 68)); } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/16041")] + public void MissingTypeArgumentInGenericExtensionMethod_ParameterType() + { + var source = + """ + public static class GooExtensions + { + public static void ExtensionMethod1(this object obj, T t) { } + } + + public class Class1 + { + public void Test() + { + System.Action delegateConversion1 = "literal".ExtensionMethod1<>; + } + } + """; + var compilation = CreateCompilationWithMscorlib40AndSystemCore(source); + + compilation.VerifyDiagnostics( + // (10,53): error CS8389: Omitting the type argument is not allowed in the current context + // System.Action delegateConversion1 = "literal".ExtensionMethod1<>; + Diagnostic(ErrorCode.ERR_OmittedTypeArgument, @"""literal"".ExtensionMethod1<>").WithLocation(10, 53)); + } + [WorkItem(22757, "https://github.com/dotnet/roslyn/issues/22757")] [Fact] public void MethodGroupConversionNoReceiver()