Skip to content

Commit

Permalink
Merge pull request #16249 from dotnet/merges/main-to-release/dev17.9
Browse files Browse the repository at this point in the history
Merge main to release/dev17.9
  • Loading branch information
vzarytovskii authored Nov 12, 2023
2 parents 9b11cb3 + 2aba8f1 commit 2050ecf
Show file tree
Hide file tree
Showing 40 changed files with 594 additions and 33 deletions.
4 changes: 2 additions & 2 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"type": "coreclr",
"request": "launch",
// TODO: Shall we assume that it's already been built, or build it every time we debug?
// "preLaunchTask": "Build (Debug)",
"preLaunchTask": "Build (Debug)",
// If you have changed target frameworks, make sure to update the program p
"program": "${workspaceFolder}/artifacts/bin/fsi/Debug/net8.0/fsi.dll",
"args": [
Expand Down Expand Up @@ -50,7 +50,7 @@
"type": "coreclr",
"request": "launch",
// TODO: Shall we assume that it's already been built, or build it every time we debug?
// "preLaunchTask": "Build (Debug)",
"preLaunchTask": "Build (Debug)",
// If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/artifacts/bin/fsc/Debug/net8.0/fsc.dll",
"args": [
Expand Down
21 changes: 17 additions & 4 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,18 @@
"-c",
"Debug",
"FSharp.Compiler.Service.sln"
],
]
},
"options": {
"env": {
"UpdateXlfOnBuild": "true"
}
},
"problemMatcher": "$msCompile",
"group": "build",
"group": {
"kind": "build",
"isDefault": true
}
},
{
"label": "Build (Release)",
Expand All @@ -53,10 +61,15 @@
"-c",
"Release",
"FSharp.Compiler.Service.sln"
],
]
},
"options": {
"env": {
"UpdateXlfOnBuild": "true"
}
},
"problemMatcher": "$msCompile",
"group": "build",
"group": "build"
},
{
"label": "Update xlf files",
Expand Down
2 changes: 1 addition & 1 deletion src/Compiler/Checking/CheckDeclarations.fs
Original file line number Diff line number Diff line change
Expand Up @@ -4418,7 +4418,7 @@ module TcDeclarations =
let isAtOriginalTyconDefn = true
let core = MutRecDefnsPhase1DataForTycon(synTyconInfo, SynTypeDefnSimpleRepr.Exception r, implements1, false, false, isAtOriginalTyconDefn)
core, extra_vals_Inherits_Abstractslots @ extraMembers

//-------------------------------------------------------------------------

/// Bind a collection of mutually recursive definitions in an implementation file
Expand Down
16 changes: 12 additions & 4 deletions src/Compiler/Checking/CheckExpressions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -7022,7 +7022,7 @@ and TcObjectExpr (cenv: cenv) env tpenv (objTy, realObjTy, argopt, binds, extraI
let overrides' =
[ for overrideMeth in overrides do
let overrideInfo, (_, thisVal, methodVars, bindingAttribs, bindingBody) = overrideMeth
let (Override(_, _, id, mtps, _, _, _, isFakeEventProperty, _)) = overrideInfo
let (Override(_, _, id, mtps, _, _, _, isFakeEventProperty, _, _)) = overrideInfo

if not isFakeEventProperty then
let searchForOverride =
Expand Down Expand Up @@ -11241,7 +11241,11 @@ and ApplyAbstractSlotInference (cenv: cenv) (envinner: TcEnv) (_: Val option) (a
let uniqueAbstractMethSigs =
match dispatchSlots with
| [] ->
errorR(Error(FSComp.SR.tcNoMemberFoundForOverride(), memberId.idRange))
let instanceExpected = memberFlags.IsInstance
if instanceExpected then
errorR(Error(FSComp.SR.tcNoMemberFoundForOverride(), memberId.idRange))
else
errorR (Error(FSComp.SR.tcNoStaticMemberFoundForOverride (), memberId.idRange))
[]

| slot :: _ as slots ->
Expand Down Expand Up @@ -11300,7 +11304,7 @@ and ApplyAbstractSlotInference (cenv: cenv) (envinner: TcEnv) (_: Val option) (a

| SynMemberKind.PropertyGet
| SynMemberKind.PropertySet as k ->
let dispatchSlots = GetAbstractPropInfosForSynPropertyDecl(cenv.infoReader, ad, memberId, m, typToSearchForAbstractMembers)
let dispatchSlots = GetAbstractPropInfosForSynPropertyDecl(cenv.infoReader, ad, memberId, m, typToSearchForAbstractMembers, memberFlags)

// Only consider those abstract slots where the get/set flags match the value we're defining
let dispatchSlots =
Expand All @@ -11313,7 +11317,11 @@ and ApplyAbstractSlotInference (cenv: cenv) (envinner: TcEnv) (_: Val option) (a
let uniqueAbstractPropSigs =
match dispatchSlots with
| [] when not (CompileAsEvent g attribs) ->
errorR(Error(FSComp.SR.tcNoPropertyFoundForOverride(), memberId.idRange))
let instanceExpected = memberFlags.IsInstance
if instanceExpected then
errorR(Error(FSComp.SR.tcNoPropertyFoundForOverride(), memberId.idRange))
else
errorR (Error(FSComp.SR.tcNoStaticPropertyFoundForOverride (), memberId.idRange))
[]
| [uniqueAbstractProp] -> [uniqueAbstractProp]
| _ ->
Expand Down
42 changes: 24 additions & 18 deletions src/Compiler/Checking/MethodOverrides.fs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@ type OverrideInfo =
argTypes: TType list list *
returnType: TType option *
isFakeEventProperty: bool *
isCompilerGenerated: bool
isCompilerGenerated: bool *
isInstance: bool


member x.CanImplement = let (Override(canImplement=a)) = x in a

Expand All @@ -61,6 +63,9 @@ type OverrideInfo =
member x.ReturnType = let (Override(returnType=b)) = x in b

member x.IsCompilerGenerated = let (Override(isCompilerGenerated=b)) = x in b

member x.IsInstance = let (Override(isInstance=b)) = x in b


type RequiredSlot =
| RequiredSlot of methodInfo: MethInfo * isOptional: bool
Expand Down Expand Up @@ -104,7 +109,7 @@ exception OverrideDoesntOverride of DisplayEnv * OverrideInfo * MethInfo option
module DispatchSlotChecking =

/// Print the signature of an override to a buffer as part of an error message
let PrintOverrideToBuffer denv os (Override(_, _, id, methTypars, memberToParentInst, argTys, retTy, _, _)) =
let PrintOverrideToBuffer denv os (Override(_, _, id, methTypars, memberToParentInst, argTys, retTy, _, _, _)) =
let denv = { denv with showTyparBinding = true }
let retTy = (retTy |> GetFSharpViewOfReturnType denv.g)
let argInfos =
Expand Down Expand Up @@ -136,7 +141,7 @@ module DispatchSlotChecking =
let (CompiledSig (argTys, retTy, fmethTypars, ttpinst)) = CompiledSigOfMeth g amap m minfo

let isFakeEventProperty = minfo.IsFSharpEventPropertyMethod
Override(parentType, minfo.ApparentEnclosingTyconRef, mkSynId m nm, fmethTypars, ttpinst, argTys, retTy, isFakeEventProperty, false)
Override(parentType, minfo.ApparentEnclosingTyconRef, mkSynId m nm, fmethTypars, ttpinst, argTys, retTy, isFakeEventProperty, false, minfo.IsInstance)

/// Get the override info for a value being used to implement a dispatch slot.
let GetTypeMemberOverrideInfo g reqdTy (overrideBy: ValRef) =
Expand Down Expand Up @@ -175,7 +180,7 @@ module DispatchSlotChecking =
//CanImplementAnySlot <<----- Change to this to enable implicit interface implementation

let isFakeEventProperty = overrideBy.IsFSharpEventProperty(g)
Override(implKind, overrideBy.MemberApparentEntity, mkSynId overrideBy.Range nm, memberMethodTypars, memberToParentInst, argTys, retTy, isFakeEventProperty, overrideBy.IsCompilerGenerated)
Override(implKind, overrideBy.MemberApparentEntity, mkSynId overrideBy.Range nm, memberMethodTypars, memberToParentInst, argTys, retTy, isFakeEventProperty, overrideBy.IsCompilerGenerated, overrideBy.IsInstanceMember)

/// Get the override information for an object expression method being used to implement dispatch slots
let GetObjectExprOverrideInfo g amap (implTy, id: Ident, memberFlags, ty, arityInfo, bindingAttribs, rhsExpr) =
Expand All @@ -200,7 +205,7 @@ module DispatchSlotChecking =
CanImplementAnyClassHierarchySlot
//CanImplementAnySlot <<----- Change to this to enable implicit interface implementation
let isFakeEventProperty = CompileAsEvent g bindingAttribs
let overrideByInfo = Override(implKind, tcrefOfAppTy g implTy, id, tps, [], argTys, retTy, isFakeEventProperty, false)
let overrideByInfo = Override(implKind, tcrefOfAppTy g implTy, id, tps, [], argTys, retTy, isFakeEventProperty, false, memberFlags.IsInstance)
overrideByInfo, (baseValOpt, thisv, vs, bindingAttribs, rhsExpr)
| _ ->
error(InternalError("Unexpected shape for object expression override", id.idRange))
Expand All @@ -227,7 +232,7 @@ module DispatchSlotChecking =

/// Check if an override is a partial match for the requirements for a dispatch slot except for the name.
let IsSigPartialMatch g (dispatchSlot: MethInfo) compiledSig overrideBy =
let (Override(_, _, _, methTypars, _, argTys, _retTy, _, _)) = overrideBy
let (Override(_, _, _, methTypars, _, argTys, _retTy, _, _, _)) = overrideBy
let (CompiledSig (vargTys, _, fvmethTypars, _)) = compiledSig
methTypars.Length = fvmethTypars.Length &&
IsTyparKindMatch compiledSig overrideBy &&
Expand All @@ -249,7 +254,7 @@ module DispatchSlotChecking =

/// Check if an override exactly matches the requirements for a dispatch slot except for the name.
let IsSigExactMatch g amap m dispatchSlot overrideBy =
let (Override(_, _, _, methTypars, memberToParentInst, argTys, retTy, _, _)) = overrideBy
let (Override(_, _, _, methTypars, memberToParentInst, argTys, retTy, _, _, _)) = overrideBy
let compiledSig = CompiledSigOfMeth g amap m dispatchSlot
IsSigPartialMatch g dispatchSlot compiledSig overrideBy &&
let (CompiledSig (vargTys, vrty, fvmethTypars, ttpinst)) = compiledSig
Expand Down Expand Up @@ -300,7 +305,8 @@ module DispatchSlotChecking =
/// Check if an override exactly matches the requirements for a dispatch slot.
let IsExactMatch g amap m dispatchSlot overrideBy =
IsNameMatch dispatchSlot overrideBy &&
IsSigExactMatch g amap m dispatchSlot overrideBy
IsSigExactMatch g amap m dispatchSlot overrideBy &&
dispatchSlot.IsInstance = overrideBy.IsInstance

/// Check if an override implements a dispatch slot
let OverrideImplementsDispatchSlot g amap m dispatchSlot availPriorOverride =
Expand All @@ -321,7 +327,7 @@ module DispatchSlotChecking =
reqdTy,
dispatchSlots: RequiredSlot list,
availPriorOverrides: OverrideInfo list,
overrides: OverrideInfo list) =
overrides: OverrideInfo list) =
let g = infoReader.g
let amap = infoReader.amap

Expand Down Expand Up @@ -353,8 +359,8 @@ module DispatchSlotChecking =
|> List.filter (OverrideImplementsDispatchSlot g amap m dispatchSlot)

match maybeResolvedSlot with
| [ovd] ->
if not ovd.IsCompilerGenerated then
| [ovd] ->
if not ovd.IsCompilerGenerated then
let item = Item.MethodGroup(ovd.LogicalName, [dispatchSlot],None)
CallNameResolutionSink sink (ovd.Range, nenv, item, dispatchSlot.FormalMethodTyparInst, ItemOccurence.Implemented, AccessorDomain.AccessibleFromSomewhere)
| [] ->
Expand Down Expand Up @@ -386,7 +392,7 @@ module DispatchSlotChecking =
noimpl()
| [ overrideBy ] ->

let (Override(_, _, _, methTypars, _, argTys, _, _, _)) = overrideBy
let (Override(_, _, _, methTypars, _, argTys, _, _, _, _)) = overrideBy

let moreThanOnePossibleDispatchSlot =
dispatchSlots
Expand Down Expand Up @@ -612,7 +618,8 @@ module DispatchSlotChecking =
if dispatchSlot.IsFinal && (isObjExpr || not (typeEquiv g reqdTy dispatchSlot.ApparentEnclosingType)) then
errorR(Error(FSComp.SR.typrelMethodIsSealed(NicePrint.stringOfMethInfo infoReader m denv dispatchSlot), m))
| dispatchSlots ->
match dispatchSlots |> List.filter (fun dispatchSlot ->
match dispatchSlots |> List.filter (fun dispatchSlot ->
(dispatchSlot.IsInstance = overrideBy.IsInstance) &&
isInterfaceTy g dispatchSlot.ApparentEnclosingType ||
not (DispatchSlotIsAlreadyImplemented g amap m availPriorOverridesKeyed dispatchSlot)) with
| h1 :: h2 :: _ ->
Expand Down Expand Up @@ -812,7 +819,7 @@ module DispatchSlotChecking =
// We don't give missing method errors for abstract classes

if isImplementation && not (isInterfaceTy g overallTy) then
let overrides = allImmediateMembersThatMightImplementDispatchSlots |> List.map snd
let overrides = allImmediateMembersThatMightImplementDispatchSlots |> List.map snd
let allCorrect = CheckDispatchSlotsAreImplemented (denv, infoReader, m, nenv, sink, tcaug.tcaug_abstract, reqdTy, dispatchSlots, availPriorOverrides, overrides)

// Tell the user to mark the thing abstract if it was missing implementations
Expand Down Expand Up @@ -940,7 +947,7 @@ let GetAbstractMethInfosForSynMethodDecl(infoReader: InfoReader, ad, memberName:
NameMultiMap.find memberName.idText dispatchSlotsKeyed |> List.map (fun reqdSlot -> reqdSlot.MethodInfo)
| ty, None ->
GetIntrinsicMethInfosOfType infoReader (Some memberName.idText) ad AllowMultiIntfInstantiations.Yes findFlag bindm ty
let dispatchSlots = minfos |> List.filter (fun minfo -> minfo.IsDispatchSlot)
let dispatchSlots = minfos |> List.filter (fun minfo -> minfo.IsDispatchSlot && minfo.IsInstance = memberFlags.IsInstance)
let valReprSynArities = SynInfo.AritiesOfArgs valSynData

// We only return everything if it's empty or if it's a non-instance member.
Expand All @@ -955,14 +962,13 @@ let GetAbstractMethInfosForSynMethodDecl(infoReader: InfoReader, ad, memberName:

/// Get the properties relevant to determining if a uniquely-identified-override exists based on the syntactic information
/// at the member signature prior to type inference. This is used to pre-assign type information if it does
let GetAbstractPropInfosForSynPropertyDecl(infoReader: InfoReader, ad, memberName: Ident, bindm, typToSearchForAbstractMembers) =
let GetAbstractPropInfosForSynPropertyDecl(infoReader: InfoReader, ad, memberName: Ident, bindm, typToSearchForAbstractMembers, memberFlags: SynMemberFlags) =
let pinfos =
match typToSearchForAbstractMembers with
| _, Some(SlotImplSet(_, _, _, reqdProps)) ->
reqdProps |> List.filter (fun pinfo -> pinfo.PropertyName = memberName.idText)
| ty, None ->
GetIntrinsicPropInfosOfType infoReader (Some memberName.idText) ad AllowMultiIntfInstantiations.Yes IgnoreOverrides bindm ty

let dispatchSlots = pinfos |> List.filter (fun pinfo -> pinfo.IsVirtualProperty)
let dispatchSlots = pinfos |> List.filter (fun pinfo -> pinfo.IsVirtualProperty && (not pinfo.IsStatic) = memberFlags.IsInstance)
dispatchSlots

8 changes: 6 additions & 2 deletions src/Compiler/Checking/MethodOverrides.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ type OverrideInfo =
argTypes: TType list list *
returnType: TType option *
isFakeEventProperty: bool *
isCompilerGenerated: bool
isCompilerGenerated: bool *
isInstance: bool

member ArgTypes: TType list list

Expand All @@ -42,6 +43,8 @@ type OverrideInfo =

member IsCompilerGenerated: bool

member IsInstance: bool

member IsFakeEventProperty: bool

member LogicalName: string
Expand Down Expand Up @@ -167,5 +170,6 @@ val GetAbstractPropInfosForSynPropertyDecl:
ad: AccessorDomain *
memberName: Ident *
bindm: range *
typToSearchForAbstractMembers: (TType * SlotImplSet option) ->
typToSearchForAbstractMembers: (TType * SlotImplSet option) *
memberFlags: SynMemberFlags ->
PropInfo list
10 changes: 10 additions & 0 deletions src/Compiler/Driver/CompilerDiagnostics.fs
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,8 @@ module OldStyleMessages =
let OverrideDoesntOverride2E () = Message("OverrideDoesntOverride2", "%s")
let OverrideDoesntOverride3E () = Message("OverrideDoesntOverride3", "%s")
let OverrideDoesntOverride4E () = Message("OverrideDoesntOverride4", "%s")
let OverrideShouldBeStatic () = Message("OverrideShouldBeStatic", "")
let OverrideShouldBeInstance () = Message("OverrideShouldBeInstance", "")
let UnionCaseWrongArgumentsE () = Message("UnionCaseWrongArguments", "%d%d")
let UnionPatternsBindDifferentNamesE () = Message("UnionPatternsBindDifferentNames", "")
let RequiredButNotSpecifiedE () = Message("RequiredButNotSpecified", "%s%s%s")
Expand Down Expand Up @@ -1548,6 +1550,14 @@ type Exception with
if sig1 <> sig2 then
os.AppendString(OverrideDoesntOverride3E().Format sig2)

// If implementation and required slot doesn't have same "instance-ness", then tell user that.
if impl.IsInstance <> minfoVirt.IsInstance then
// Requried slot is instance, meaning implementation is static, tell user that we expect instance.
if minfoVirt.IsInstance then
os.AppendString(OverrideShouldBeStatic().Format)
else
os.AppendString(OverrideShouldBeInstance().Format)

| UnionCaseWrongArguments (_, n1, n2, _) -> os.AppendString(UnionCaseWrongArgumentsE().Format n2 n1)

| UnionPatternsBindDifferentNames _ -> os.AppendString(UnionPatternsBindDifferentNamesE().Format)
Expand Down
2 changes: 2 additions & 0 deletions src/Compiler/FSComp.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1729,3 +1729,5 @@ featureUnmanagedConstraintCsharpInterop,"Interop between C#'s and F#'s unmanaged
3582,tcInfoIfFunctionShadowsUnionCase,"This is a function definition that shadows a union case. If this is what you want, ignore or suppress this warning. If you want it to be a union case deconstruction, add parentheses."
3583,unnecessaryParentheses,"Parentheses can be removed."
3584,tcDotLambdaAtNotSupportedExpression,"Shorthand lambda syntax is only supported for atomic expressions, such as method, property, field or indexer on the implied '_' argument. For example: 'let f = _.Length'."
3855,tcNoStaticMemberFoundForOverride,"No static abstract member was found that corresponds to this override"
3859,tcNoStaticPropertyFoundForOverride,"No static abstract property was found that corresponds to this override"
6 changes: 6 additions & 0 deletions src/Compiler/FSStrings.resx
Original file line number Diff line number Diff line change
Expand Up @@ -882,6 +882,12 @@
<data name="OverrideDoesntOverride4" xml:space="preserve">
<value>The member '{0}' is specialized with 'unit' but 'unit' can't be used as return type of an abstract method parameterized on return type.</value>
</data>
<data name="OverrideShouldBeStatic" xml:space="preserve">
<value> Static member is expected.</value>
</data>
<data name="OverrideShouldBeInstance" xml:space="preserve">
<value> Non-static member is expected.</value>
</data>
<data name="UnionCaseWrongArguments" xml:space="preserve">
<value>This constructor is applied to {0} argument(s) but expects {1}</value>
</data>
Expand Down
Loading

0 comments on commit 2050ecf

Please sign in to comment.