Skip to content

Commit

Permalink
Improve error reporting for abstract members when used in classes
Browse files Browse the repository at this point in the history
  • Loading branch information
edgarfgp committed Apr 17, 2024
1 parent 273cea5 commit 49f4722
Show file tree
Hide file tree
Showing 5 changed files with 15 additions and 16 deletions.
15 changes: 11 additions & 4 deletions src/Compiler/Checking/CheckDeclarations.fs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ type cenv = TcFileState
type MutRecDataForOpen = MutRecDataForOpen of SynOpenDeclTarget * range * appliedScope: range * OpenDeclaration list ref
type MutRecDataForModuleAbbrev = MutRecDataForModuleAbbrev of Ident * LongIdent * range

exception TypeIsImplicitlyAbstract of range

/// Represents the shape of a mutually recursive group of declarations including nested modules
[<RequireQualifiedAccess>]
type MutRecShape<'TypeData, 'LetsData, 'ModuleData> =
Expand Down Expand Up @@ -3629,8 +3631,10 @@ module EstablishTypeDefinitionCores =
noSealedAttributeCheck FSComp.SR.tcTypesAreAlwaysSealedStruct
noAbstractClassAttributeCheck()
noAllowNullLiteralAttributeCheck()
if not (isNil slotsigs) then
errorR (Error(FSComp.SR.tcStructTypesCannotContainAbstractMembers(), m))

for slot in abstractSlots do
errorR (Error(FSComp.SR.tcStructTypesCannotContainAbstractMembers(), slot.Range))

structLayoutAttributeCheck true

TFSharpStruct
Expand All @@ -3647,8 +3651,11 @@ module EstablishTypeDefinitionCores =
structLayoutAttributeCheck(not isIncrClass)
allowNullLiteralAttributeCheck()
for slot in abstractSlots do
if not slot.IsInstanceMember then
errorR(Error(FSComp.SR.chkStaticAbstractMembersOnClasses(), slot.Range))
if not slot.IsInstanceMember then
errorR(Error(FSComp.SR.chkStaticAbstractMembersOnClasses(), slot.Range))
elif not hasAbstractAttr then
errorR(TypeIsImplicitlyAbstract(slot.Range))

TFSharpClass
| SynTypeDefnKind.Delegate (ty, arity) ->
noCLIMutableAttributeCheck()
Expand Down
2 changes: 2 additions & 0 deletions src/Compiler/Checking/CheckDeclarations.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,5 @@ val CheckOneSigFile:
exception NotUpperCaseConstructor of range: range

exception NotUpperCaseConstructorWithoutRQA of range: range

exception TypeIsImplicitlyAbstract of range
9 changes: 2 additions & 7 deletions src/Compiler/Checking/MethodOverrides.fs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,6 @@ type SlotImplSet =
availablePriorOverrides: OverrideInfo list *
requiredProperties: PropInfo list

exception TypeIsImplicitlyAbstract of range
exception OverrideDoesntOverride of DisplayEnv * OverrideInfo * MethInfo option * TcGlobals * Import.ImportMap * range

module DispatchSlotChecking =
Expand Down Expand Up @@ -828,11 +827,7 @@ module DispatchSlotChecking =

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

// Tell the user to mark the thing abstract if it was missing implementations
if not allCorrect && not tcaug.tcaug_abstract && not (isInterfaceTy g reqdTy) then
errorR(TypeIsImplicitlyAbstract(m))
let _ = CheckDispatchSlotsAreImplemented (denv, infoReader, m, nenv, sink, tcaug.tcaug_abstract, false, reqdTy, dispatchSlots, availPriorOverrides, overrides)

let overridesToCheck =
allImmediateMembersThatMightImplementDispatchSlots
Expand Down Expand Up @@ -882,7 +877,7 @@ module DispatchSlotChecking =
overrideBy.MemberInfo.Value.ImplementedSlotSigs <- overriden)

/// "Type Completion" inference and a few other checks at the end of the inference scope
let FinalTypeDefinitionChecksAtEndOfInferenceScope (infoReader: InfoReader, nenv, sink, isImplementation, denv, tycon: Tycon) =
let FinalTypeDefinitionChecksAtEndOfInferenceScope (infoReader: InfoReader, nenv: NameResolutionEnv, sink: TcResultsSink, isImplementation, denv: DisplayEnv, tycon: Tycon) =

let g = infoReader.g
let amap = infoReader.amap
Expand Down
2 changes: 0 additions & 2 deletions src/Compiler/Checking/MethodOverrides.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,6 @@ type SlotImplSet =
availablePriorOverrides: OverrideInfo list *
requiredProperties: PropInfo list

exception TypeIsImplicitlyAbstract of range

exception OverrideDoesntOverride of DisplayEnv * OverrideInfo * MethInfo option * TcGlobals * ImportMap * range

module DispatchSlotChecking =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,15 +62,12 @@ module Basic =
(Error 344, Line 13, Col 6, Line 13, Col 7, "The struct, record or union type 'R' has an explicit implementation of 'Object.GetHashCode' or 'Object.Equals'. You must apply the 'CustomEquality' attribute to the type")
(Warning 345, Line 13, Col 6, Line 13, Col 7, "The struct, record or union type 'R' has an explicit implementation of 'Object.GetHashCode'. Consider implementing a matching override for 'Object.Equals(obj)'")
(Error 359, Line 13, Col 6, Line 13, Col 7, "More than one override implements 'GetHashCode: unit -> int'")
(Error 54, Line 13, Col 6, Line 13, Col 7, "This type is 'abstract' since some abstract members have not been given an implementation. If this is intentional then add the '[<AbstractClass>]' attribute to your type.")
(Error 344, Line 17, Col 6, Line 17, Col 7, "The struct, record or union type 'U' has an explicit implementation of 'Object.GetHashCode' or 'Object.Equals'. You must apply the 'CustomEquality' attribute to the type")
(Warning 345, Line 17, Col 6, Line 17, Col 7, "The struct, record or union type 'U' has an explicit implementation of 'Object.GetHashCode'. Consider implementing a matching override for 'Object.Equals(obj)'")
(Error 359, Line 17, Col 6, Line 17, Col 7, "More than one override implements 'GetHashCode: unit -> int'")
(Error 54, Line 17, Col 6, Line 17, Col 7, "This type is 'abstract' since some abstract members have not been given an implementation. If this is intentional then add the '[<AbstractClass>]' attribute to your type.")
(Error 344, Line 21, Col 6, Line 21, Col 7, "The struct, record or union type 'S' has an explicit implementation of 'Object.GetHashCode' or 'Object.Equals'. You must apply the 'CustomEquality' attribute to the type")
(Warning 345, Line 21, Col 6, Line 21, Col 7, "The struct, record or union type 'S' has an explicit implementation of 'Object.GetHashCode'. Consider implementing a matching override for 'Object.Equals(obj)'")
(Error 359, Line 21, Col 6, Line 21, Col 7, "More than one override implements 'GetHashCode: unit -> int'")
(Error 54, Line 21, Col 6, Line 21, Col 7, "This type is 'abstract' since some abstract members have not been given an implementation. If this is intentional then add the '[<AbstractClass>]' attribute to your type.")
]

// SOURCE=E_ExceptionsNoComparison.fs SCFLAGS="--test:ErrorRanges" # E_ExceptionsNoComparison.fs
Expand Down

0 comments on commit 49f4722

Please sign in to comment.