Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/release-notes/.FSharp.Compiler.Service/11.0.100.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
### Fixed

* Fix attributes on return type of unparenthesized tuple methods being silently dropped from IL. ([Issue #462](https://github.com/dotnet/fsharp/issues/462), [PR #19714](https://github.com/dotnet/fsharp/pull/19714))
* Fix internal error FS0073 "Undefined or unsolved type variable" in IlxGen when nested inline SRTP functions with multiple overloads leave unsolved typars in the non-witness codegen path. ([Issue #19709](https://github.com/dotnet/fsharp/issues/19709), [PR #19710](https://github.com/dotnet/fsharp/pull/19710))
* Fix NRE when calling virtual Object methods on value types through inline SRTP functions. ([Issue #8098](https://github.com/dotnet/fsharp/issues/8098), [PR #19511](https://github.com/dotnet/fsharp/pull/19511))
* Fix DU case names matching IWSAM member names no longer cause duplicate property entries. (Issue [#14321](https://github.com/dotnet/fsharp/issues/14321), [PR #19341](https://github.com/dotnet/fsharp/pull/19341))
Expand Down
7 changes: 6 additions & 1 deletion src/Compiler/pars.fsy
Original file line number Diff line number Diff line change
Expand Up @@ -6066,7 +6066,12 @@ topType:

| topTupleType
{ let ty, rmdata = $1
ty, (SynValInfo([], (match rmdata with [md] -> md | _ -> SynInfo.unnamedRetVal))) }
let retArgInfo =
match rmdata with
| [md] -> md
| SynArgInfo(attrs, _, _) :: _ when not attrs.IsEmpty -> SynArgInfo(attrs, false, None)
| _ -> SynInfo.unnamedRetVal
ty, SynValInfo([], retArgInfo) }

topTupleType:
| topAppType STAR topTupleTypeElements
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,14 @@ module CustomAttributes_Basic =
|> verifyCompileAndRun
|> shouldSucceed

// SOURCE=ReturnType04.fs # ReturnType04.fs
// Regression test for https://github.com/dotnet/fsharp/issues/462
[<Theory; Directory(__SOURCE_DIRECTORY__, Includes=[|"ReturnType04.fs"|])>]
let ``ReturnType04_fs`` compilation =
compilation
|> verifyCompileAndRun
|> shouldSucceed

// SOURCE=SanityCheck01.fs # SanityCheck01.fs
[<Theory; Directory(__SOURCE_DIRECTORY__, Includes=[|"SanityCheck01.fs"|])>]
let ``SanityCheck01_fs`` compilation =
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// #Regression #Conformance #DeclarationElements #Attributes
// Regression test for https://github.com/dotnet/fsharp/issues/462
// Attributes on return type of unparenthesized tuple must not be silently dropped.
//<Expects status="success"></Expects>

open System

[<AttributeUsage(AttributeTargets.ReturnValue, AllowMultiple = true, Inherited = false)>]
type ReturnDescriptionAttribute(info: string) =
inherit Attribute()
member _.Info = info

type T =
static member Parenthesized(name: string) :
[<ReturnDescription("first")>]
[<ReturnDescription("second")>]
(string * string) =
name, name

static member Bare(name: string) :
[<ReturnDescription("first")>]
[<ReturnDescription("second")>]
string * string =
name, name

let getAttrs (methodName: string) =
typeof<T>
.GetMethod(methodName)
.ReturnParameter
.GetCustomAttributes(typeof<ReturnDescriptionAttribute>, false)
|> Array.map (fun a -> (a :?> ReturnDescriptionAttribute).Info)
|> Array.sort

let parenthesized = getAttrs "Parenthesized"
if parenthesized.Length <> 2 then failwithf "Parenthesized: expected 2 attributes, got %d" parenthesized.Length

let bare = getAttrs "Bare"
if bare.Length <> 2 then failwithf "Bare: expected 2 attributes, got %d (bug #462 — attributes on unparenthesized tuple return type are silently dropped)" bare.Length
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module M

type T =
static member GetPair() :
[<A>]
string * string =
"", ""
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
ImplFile
(ParsedImplFileInput
("/root/Attribute/ReturnTypeAttributeOnBareTuple.fs", false,
QualifiedNameOfFile M, [],
[SynModuleOrNamespace
([M], false, NamedModule,
[Types
([SynTypeDefn
(SynComponentInfo
([], None, [], [T],
PreXmlDoc ((3,0), FSharp.Compiler.Xml.XmlDocCollector),
false, None, (3,5--3,6)),
ObjectModel
(Unspecified,
[Member
(SynBinding
(None, Normal, false, false, [],
PreXmlDoc ((4,4), FSharp.Compiler.Xml.XmlDocCollector),
SynValData
(Some { IsInstance = false
IsDispatchSlot = false
IsOverrideOrExplicitImpl = false
IsFinal = false
GetterOrSetterIsCompilerGenerated = false
MemberKind = Member },
SynValInfo
([[]],
SynArgInfo
([{ Attributes =
[{ TypeName =
SynLongIdent ([A], [], [None])
ArgExpr = Const (Unit, (5,10--5,11))
Target = None
AppliesToGetterAndSetter = false
Range = (5,10--5,11) }]
Range = (5,8--5,13) }], false, None)),
None),
LongIdent
(SynLongIdent ([GetPair], [], [None]), None, None,
Pats
[Paren
(Const (Unit, (4,25--4,27)), (4,25--4,27))],
None, (4,18--4,27)),
Some
(SynBindingReturnInfo
(Tuple
(false,
[Type
(SignatureParameter
([{ Attributes =
[{ TypeName =
SynLongIdent
([A], [], [None])
ArgExpr =
Const (Unit, (5,10--5,11))
Target = None
AppliesToGetterAndSetter =
false
Range = (5,10--5,11) }]
Range = (5,8--5,13) }], false,
None,
LongIdent
(SynLongIdent
([string], [], [None])),
(5,8--6,14))); Star (6,15--6,16);
Type
(LongIdent
(SynLongIdent ([string], [], [None])))],
(5,8--6,23)), (5,8--6,23),
[{ Attributes =
[{ TypeName =
SynLongIdent ([A], [], [None])
ArgExpr = Const (Unit, (5,10--5,11))
Target = None
AppliesToGetterAndSetter = false
Range = (5,10--5,11) }]
Range = (5,8--5,13) }],
{ ColonRange = Some (4,28--4,29) })),
Typed
(Tuple
(false,
[Const
(String ("", Regular, (7,12--7,14)),
(7,12--7,14));
Const
(String ("", Regular, (7,16--7,18)),
(7,16--7,18))], [(7,14--7,15)],
(7,12--7,18)),
Tuple
(false,
[Type
(SignatureParameter
([{ Attributes =
[{ TypeName =
SynLongIdent ([A], [], [None])
ArgExpr =
Const (Unit, (5,10--5,11))
Target = None
AppliesToGetterAndSetter = false
Range = (5,10--5,11) }]
Range = (5,8--5,13) }], false, None,
LongIdent
(SynLongIdent ([string], [], [None])),
(5,8--6,14))); Star (6,15--6,16);
Type
(LongIdent
(SynLongIdent ([string], [], [None])))],
(5,8--6,23)), (7,12--7,18)), (4,18--4,27),
NoneAtInvisible,
{ LeadingKeyword =
StaticMember ((4,4--4,10), (4,11--4,17))
InlineKeyword = None
EqualsRange = Some (6,24--6,25) }), (4,4--7,18))],
(4,4--7,18)), [], None, (3,5--7,18),
{ LeadingKeyword = Type (3,0--3,4)
EqualsRange = Some (3,7--3,8)
WithKeyword = None })], (3,0--7,18))],
PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None,
(1,0--7,18), { LeadingKeyword = Module (1,0--1,6) })], (true, true),
{ ConditionalDirectives = []
WarnDirectives = []
CodeComments = [] }, set []))
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module M

type T =
static member GetPair() :
[<A>]
(string * string) =
"", ""
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
ImplFile
(ParsedImplFileInput
("/root/Attribute/ReturnTypeAttributeOnParenthesizedTuple.fs", false,
QualifiedNameOfFile M, [],
[SynModuleOrNamespace
([M], false, NamedModule,
[Types
([SynTypeDefn
(SynComponentInfo
([], None, [], [T],
PreXmlDoc ((3,0), FSharp.Compiler.Xml.XmlDocCollector),
false, None, (3,5--3,6)),
ObjectModel
(Unspecified,
[Member
(SynBinding
(None, Normal, false, false, [],
PreXmlDoc ((4,4), FSharp.Compiler.Xml.XmlDocCollector),
SynValData
(Some { IsInstance = false
IsDispatchSlot = false
IsOverrideOrExplicitImpl = false
IsFinal = false
GetterOrSetterIsCompilerGenerated = false
MemberKind = Member },
SynValInfo
([[]],
SynArgInfo
([{ Attributes =
[{ TypeName =
SynLongIdent ([A], [], [None])
ArgExpr = Const (Unit, (5,10--5,11))
Target = None
AppliesToGetterAndSetter = false
Range = (5,10--5,11) }]
Range = (5,8--5,13) }], false, None)),
None),
LongIdent
(SynLongIdent ([GetPair], [], [None]), None, None,
Pats
[Paren
(Const (Unit, (4,25--4,27)), (4,25--4,27))],
None, (4,18--4,27)),
Some
(SynBindingReturnInfo
(SignatureParameter
([{ Attributes =
[{ TypeName =
SynLongIdent ([A], [], [None])
ArgExpr = Const (Unit, (5,10--5,11))
Target = None
AppliesToGetterAndSetter = false
Range = (5,10--5,11) }]
Range = (5,8--5,13) }], false, None,
Paren
(Tuple
(false,
[Type
(LongIdent
(SynLongIdent
([string], [], [None])));
Star (6,16--6,17);
Type
(LongIdent
(SynLongIdent
([string], [], [None])))],
(6,9--6,24)), (6,8--6,25)),
(5,8--6,25)), (5,8--6,25),
[{ Attributes =
[{ TypeName =
SynLongIdent ([A], [], [None])
ArgExpr = Const (Unit, (5,10--5,11))
Target = None
AppliesToGetterAndSetter = false
Range = (5,10--5,11) }]
Range = (5,8--5,13) }],
{ ColonRange = Some (4,28--4,29) })),
Typed
(Tuple
(false,
[Const
(String ("", Regular, (7,12--7,14)),
(7,12--7,14));
Const
(String ("", Regular, (7,16--7,18)),
(7,16--7,18))], [(7,14--7,15)],
(7,12--7,18)),
SignatureParameter
([{ Attributes =
[{ TypeName =
SynLongIdent ([A], [], [None])
ArgExpr = Const (Unit, (5,10--5,11))
Target = None
AppliesToGetterAndSetter = false
Range = (5,10--5,11) }]
Range = (5,8--5,13) }], false, None,
Paren
(Tuple
(false,
[Type
(LongIdent
(SynLongIdent
([string], [], [None])));
Star (6,16--6,17);
Type
(LongIdent
(SynLongIdent
([string], [], [None])))],
(6,9--6,24)), (6,8--6,25)), (5,8--6,25)),
(7,12--7,18)), (4,18--4,27), NoneAtInvisible,
{ LeadingKeyword =
StaticMember ((4,4--4,10), (4,11--4,17))
InlineKeyword = None
EqualsRange = Some (6,26--6,27) }), (4,4--7,18))],
(4,4--7,18)), [], None, (3,5--7,18),
{ LeadingKeyword = Type (3,0--3,4)
EqualsRange = Some (3,7--3,8)
WithKeyword = None })], (3,0--7,18))],
PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None,
(1,0--7,18), { LeadingKeyword = Module (1,0--1,6) })], (true, true),
{ ConditionalDirectives = []
WarnDirectives = []
CodeComments = [] }, set []))
Loading