diff --git a/src/Compiler/Checking/NicePrint.fs b/src/Compiler/Checking/NicePrint.fs index 572dfa451cc..7f0779c062e 100644 --- a/src/Compiler/Checking/NicePrint.fs +++ b/src/Compiler/Checking/NicePrint.fs @@ -997,34 +997,46 @@ module PrintTypes = and layoutType denv ty = layoutTypeWithInfo denv SimplifyTypes.typeSimplificationInfo0 ty + /// Layout '[]' for parameters + and layoutAttribsOneline denv attribs = + match attribs with + | [] -> emptyL + | attribs -> + let attrsL = + [ for attr in attribs do layoutAttrib denv attr ] + + squareAngleL (sepListL (rightL (tagPunctuation ";")) attrsL) + // Format each argument, including its name and type let layoutArgInfo denv env (ty, argInfo: ArgReprInfo) = let g = denv.g // Detect an optional argument let isOptionalArg = HasFSharpAttribute g g.attrib_OptionalArgumentAttribute argInfo.Attribs - let isParamArray = HasFSharpAttribute g g.attrib_ParamArrayAttribute argInfo.Attribs - match argInfo.Name, isOptionalArg, isParamArray, tryDestOptionTy g ty with + match argInfo.Name, isOptionalArg, tryDestOptionTy g ty with // Layout an optional argument - | Some id, true, _, ValueSome ty -> + | Some id, true, ValueSome ty -> let idL = ConvertValLogicalNameToDisplayLayout false (tagParameter >> rightL) id.idText + let attrsLayout = + argInfo.Attribs + |> List.filter (fun a -> not (IsMatchingFSharpAttribute g g.attrib_OptionalArgumentAttribute a)) + |> layoutAttribsOneline denv + + attrsLayout ^^ LeftL.questionMark ^^ (idL |> addColonL) ^^ layoutTypeWithInfoAndPrec denv env 2 ty - // Layout an unnamed argument - | None, _, _, _ -> + // Layout an unnamed argument + // Cannot have any attributes + | None, _, _ -> layoutTypeWithInfoAndPrec denv env 2 ty // Layout a named argument - | Some id, _, isParamArray, _ -> + | Some id, _, _ -> let idL = ConvertValLogicalNameToDisplayLayout false (tagParameter >> wordL) id.idText - let prefix = - if isParamArray then - layoutBuiltinAttribute denv g.attrib_ParamArrayAttribute ^^ idL - else - idL + let prefix = layoutAttribsOneline denv argInfo.Attribs ^^ idL (prefix |> addColonL) ^^ layoutTypeWithInfoAndPrec denv env 2 ty let layoutCurriedArgInfos denv env argInfos = diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/MethodResolution/ParametersResolution.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/MethodResolution/ParametersResolution.fs index 0e10f091e80..5cf79baa88b 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/MethodResolution/ParametersResolution.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/MethodResolution/ParametersResolution.fs @@ -266,6 +266,6 @@ let _, _ = Thing.Do() |> typecheck |> shouldFail |> withDiagnostics [ - (Error 501, Line 6, Col 12, Line 6, Col 22, "The member or object constructor 'Do' takes 1 argument(s) but is here given 0. The required signature is 'static member Thing.Do: i: outref -> bool'.") + (Error 501, Line 6, Col 12, Line 6, Col 22, "The member or object constructor 'Do' takes 1 argument(s) but is here given 0. The required signature is 'static member Thing.Do: [] i: outref -> bool'.") ] diff --git a/tests/FSharp.Compiler.ComponentTests/Signatures/TestCasesForGenerationRoundTrip/attributes.fsx b/tests/FSharp.Compiler.ComponentTests/Signatures/TestCasesForGenerationRoundTrip/attributes.fsx new file mode 100644 index 00000000000..7095b4a77ca --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Signatures/TestCasesForGenerationRoundTrip/attributes.fsx @@ -0,0 +1,23 @@ +module Attributes + +open System + +type XAttribute() = + inherit Attribute() + +let a ([] b: int) : int = 0 + +type YAttribute(y: string) = + inherit Attribute() + +let a2 ([] g: string) ([] h) ([] i: int) = + printfn "h is %i" h + g + +type Boo() = + member _.Do ([] g: string) ([] h) = + printfn "h is %i" h + g + + member _.Maybe([] ?s: int) = () + member _.Forever([][][] args: string array) = () diff --git a/tests/fsharp/typecheck/overloads/neg_generic_known_argument_types.bsl b/tests/fsharp/typecheck/overloads/neg_generic_known_argument_types.bsl index fcd4fb9de75..4b256a7c3b8 100644 --- a/tests/fsharp/typecheck/overloads/neg_generic_known_argument_types.bsl +++ b/tests/fsharp/typecheck/overloads/neg_generic_known_argument_types.bsl @@ -4,5 +4,5 @@ neg_generic_known_argument_types.fsx(9,16,9,49): typecheck error FS0041: A uniqu Known types of arguments: ^fa * 'fb * 'a * argD: 'c when ^fa: (member X: ^b -> ^b) and ^b: (member BBBB: unit -> unit) Candidates: - - static member A.Foo: argA1: 'a * argB1: ('a -> 'b) * argC1: ('a -> 'b) * argD: ('a -> 'b) * argZ1: 'zzz -> 'b - - static member A.Foo: argA2: 'a * argB2: ('a -> 'b) * argC2: ('b -> 'c) * argD: ('c -> 'd) * argZ2: 'zzz -> 'd + - static member A.Foo: argA1: 'a * argB1: ('a -> 'b) * argC1: ('a -> 'b) * argD: ('a -> 'b) * [] argZ1: 'zzz -> 'b + - static member A.Foo: argA2: 'a * argB2: ('a -> 'b) * argC2: ('b -> 'c) * argD: ('c -> 'd) * [] argZ2: 'zzz -> 'd diff --git a/tests/fsharp/typecheck/sigs/neg106.bsl b/tests/fsharp/typecheck/sigs/neg106.bsl index 6630d22d110..b683af334ee 100644 --- a/tests/fsharp/typecheck/sigs/neg106.bsl +++ b/tests/fsharp/typecheck/sigs/neg106.bsl @@ -46,16 +46,16 @@ neg106.fs(40,18,40,32): typecheck error FS0041: No overloads match for method 'M Known types of arguments: string * inref Available overloads: - - static member C.M: a: int * x: byref -> unit // Argument 'a' doesn't match - - static member C.M: a: string * x: byref -> unit // Argument 'x' doesn't match + - static member C.M: a: int * [] x: byref -> unit // Argument 'a' doesn't match + - static member C.M: a: string * [] x: byref -> unit // Argument 'x' doesn't match neg106.fs(41,19,41,31): typecheck error FS0041: No overloads match for method 'M'. Known types of arguments: int * inref Available overloads: - - static member C.M: a: int * x: byref -> unit // Argument 'x' doesn't match - - static member C.M: a: string * x: byref -> unit // Argument 'a' doesn't match + - static member C.M: a: int * [] x: byref -> unit // Argument 'x' doesn't match + - static member C.M: a: string * [] x: byref -> unit // Argument 'a' doesn't match neg106.fs(49,22,49,26): typecheck error FS0001: Type mismatch. Expecting a 'byref' diff --git a/tests/fsharp/typecheck/sigs/neg106.vsbsl b/tests/fsharp/typecheck/sigs/neg106.vsbsl index 6630d22d110..b683af334ee 100644 --- a/tests/fsharp/typecheck/sigs/neg106.vsbsl +++ b/tests/fsharp/typecheck/sigs/neg106.vsbsl @@ -46,16 +46,16 @@ neg106.fs(40,18,40,32): typecheck error FS0041: No overloads match for method 'M Known types of arguments: string * inref Available overloads: - - static member C.M: a: int * x: byref -> unit // Argument 'a' doesn't match - - static member C.M: a: string * x: byref -> unit // Argument 'x' doesn't match + - static member C.M: a: int * [] x: byref -> unit // Argument 'a' doesn't match + - static member C.M: a: string * [] x: byref -> unit // Argument 'x' doesn't match neg106.fs(41,19,41,31): typecheck error FS0041: No overloads match for method 'M'. Known types of arguments: int * inref Available overloads: - - static member C.M: a: int * x: byref -> unit // Argument 'x' doesn't match - - static member C.M: a: string * x: byref -> unit // Argument 'a' doesn't match + - static member C.M: a: int * [] x: byref -> unit // Argument 'x' doesn't match + - static member C.M: a: string * [] x: byref -> unit // Argument 'a' doesn't match neg106.fs(49,22,49,26): typecheck error FS0001: Type mismatch. Expecting a 'byref' diff --git a/tests/service/Symbols.fs b/tests/service/Symbols.fs index d6b5bffb956..75f22d768d2 100644 --- a/tests/service/Symbols.fs +++ b/tests/service/Symbols.fs @@ -663,4 +663,18 @@ type ImmutableArrayViaBuilder<'T>(builder: ImmutableArray<'T>.Builder) = class end """ (8, 29, "type ImmutableArrayViaBuilder<'T>(builder: ImmutableArray<'T>.Builder) =", ".ctor") -#endif \ No newline at end of file +#endif + + [] + let ``Includes attribute for parameter`` () = + assertSignature + "val a: [] c: int -> int" + """ +module Telplin + +type BAttribute() = + inherit System.Attribute() + +let a ([] c: int) : int = 0 +""" + (7, 5, "let a ([] c: int) : int = 0", "a")