diff --git a/src/Compiler/Checking/CheckDeclarations.fs b/src/Compiler/Checking/CheckDeclarations.fs index 2a30e9def85..920f595eb5f 100644 --- a/src/Compiler/Checking/CheckDeclarations.fs +++ b/src/Compiler/Checking/CheckDeclarations.fs @@ -3715,16 +3715,9 @@ module EstablishTypeDefinitionCores = let fparams = curriedArgInfos.Head |> List.map (fun (ty, argInfo: ArgReprInfo) -> - let ty = - if HasFSharpAttribute g g.attrib_OptionalArgumentAttribute argInfo.Attribs then - match TryFindFSharpAttribute g g.attrib_StructAttribute argInfo.Attribs with - | Some (Attrib(range=m)) -> - checkLanguageFeatureAndRecover g.langVersion LanguageFeature.SupportValueOptionsAsOptionalParameters m - mkValueOptionTy g ty - | _ -> - mkOptionTy g ty - else ty - + // For delegates, we don't use CrackParamAttribsInfo or isOptional + // Delegates with optional parameters should use the ?param syntax + // which is handled elsewhere in the compiler MakeSlotParam(ty, argInfo)) TFSharpDelegate (MakeSlotSig("Invoke", thisTy, ttps, [], [fparams], returnTy)) | _ -> diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/DelegateTypes/DelegateDefinition.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/DelegateTypes/DelegateDefinition.fs index 2fa6373a92c..bb7349a67ad 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/DelegateTypes/DelegateDefinition.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/DelegateTypes/DelegateDefinition.fs @@ -48,7 +48,7 @@ namespace FSharpTest |> shouldSucceed [] - let ``Delegate with optional parameter`` () = + let ``Delegate with optional parameter and CallerLineNumber`` () = FSharp """open System.Runtime.CompilerServices type A = delegate of [] ?a: int -> unit let f = fun (a: int option) -> defaultArg a 100 |> printf "line: %d" @@ -59,11 +59,49 @@ a.Invoke()""" |> verifyOutput "line: 5" [] - let ``Delegate with struct optional parameter`` () = - FSharp """type A = delegate of [] ?a: int -> unit -let f = fun (a: int voption) -> defaultValueArg a 100 |> printf "line: %d" + let ``Delegate with optional parameter and CallerFilePath`` () = + FSharp """open System.Runtime.CompilerServices +type A = delegate of [] ?path: string -> unit +let f = fun (path: string option) -> + match path with + | Some p -> if p.Contains("DelegateDefinition.fs") then printfn "SUCCESS" else printfn "FAIL: %s" p + | None -> printfn "FAIL: None" let a = A f -a.Invoke(5)""" +a.Invoke()""" |> compileExeAndRun |> shouldSucceed - |> verifyOutput "line: 5" + |> verifyOutput "SUCCESS" + + [] + let ``Delegate with CallerFilePath without optional should fail`` () = + FSharp """namespace Test +open System.Runtime.CompilerServices +type TestDelegate = delegate of [] path: string -> unit""" + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 1247, Line 3, Col 52, Line 3, Col 56, "'CallerFilePath' can only be applied to optional arguments") + ] + + [] + let ``Delegate with CallerFilePath on wrong type should fail`` () = + FSharp """namespace Test +open System.Runtime.CompilerServices +type TestDelegate = delegate of [] ?x: int -> unit""" + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 1246, Line 3, Col 53, Line 3, Col 54, "'CallerFilePath' must be applied to an argument of type 'string', but has been applied to an argument of type 'int'") + ] + + [] + let ``Delegate with CallerLineNumber on wrong type should fail`` () = + FSharp """namespace Test +open System.Runtime.CompilerServices +type TestDelegate = delegate of [] ?x: string -> unit""" + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 1246, Line 3, Col 54, Line 3, Col 55, "'CallerLineNumber' must be applied to an argument of type 'int', but has been applied to an argument of type 'string'") + ] +