Skip to content

Commit 3e7ddee

Browse files
committed
If the member is not abstract then give better error
1 parent bfbc3e9 commit 3e7ddee

File tree

6 files changed

+39
-5
lines changed

6 files changed

+39
-5
lines changed

src/fsharp/FSComp.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,7 @@ tcExpressionWithIfRequiresParenthesis,"This list or array expression includes an
589589
765,tcExtraneousFieldsGivenValues,"Extraneous fields have been given values"
590590
766,tcObjectExpressionsCanOnlyOverrideAbstractOrVirtual,"Only overrides of abstract and virtual members may be specified in object expressions"
591591
767,tcNoAbstractOrVirtualMemberFound,"The member '%s' does not correspond to any abstract or virtual method available to override or implement.%s"
592+
767,tcMemberFoundIsNotAbstractOrVirtual,"The type %s contains the member '%s' but it is not a virtual or abstract method that is available to override or implement.%s"
592593
768,tcArgumentArityMismatch,"The member '%s' does not accept the correct number of arguments, %d arguments are expected"
593594
769,tcArgumentArityMismatchOneOverload,"The member '%s' does not accept the correct number of arguments. One overload accepts %d arguments."
594595
770,tcSimpleMethodNameRequired,"A simple method name is required here"

src/fsharp/TypeChecker.fs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6202,20 +6202,28 @@ and GetNameAndArityOfObjExprBinding _cenv _env b =
62026202
lookPat pat
62036203

62046204

6205-
and FreshenObjExprAbstractSlot cenv (_env: TcEnv) implty virtNameAndArityPairs (bind,bindAttribs,bindName,absSlots:(_ * MethInfo) list) =
6205+
and FreshenObjExprAbstractSlot cenv (_env: TcEnv) (implty:TType) virtNameAndArityPairs (bind,bindAttribs,bindName,absSlots:(_ * MethInfo) list) =
62066206
let (NormalizedBinding (_,_,_,_,_,_,synTyparDecls,_,_,_,mBinding,_)) = bind
62076207
match absSlots with
62086208
| [] when not (CompileAsEvent cenv.g bindAttribs) ->
62096209
let absSlotsByName = List.filter (fst >> fst >> (=) bindName) virtNameAndArityPairs
62106210

62116211
match absSlotsByName with
6212-
| [] ->
6212+
| [] ->
6213+
let tcref = tcrefOfAppTy cenv.g implty
6214+
let containsNonAbstractMemberWithSameName =
6215+
tcref.MembersOfFSharpTyconByName
6216+
|> Seq.exists (fun kv -> kv.Value |> List.exists (fun valRef -> valRef.DisplayName = bindName))
6217+
62136218
let predictions =
62146219
virtNameAndArityPairs
62156220
|> List.map (fst >> fst)
62166221
|> ErrorResolutionHints.FilterPredictions bindName
62176222

6218-
errorR(Error(FSComp.SR.tcNoAbstractOrVirtualMemberFound(bindName, ErrorResolutionHints.FormatPredictions predictions),mBinding))
6223+
if containsNonAbstractMemberWithSameName then
6224+
errorR(Error(FSComp.SR.tcMemberFoundIsNotAbstractOrVirtual(tcref.DisplayName, bindName, ErrorResolutionHints.FormatPredictions predictions),mBinding))
6225+
else
6226+
errorR(Error(FSComp.SR.tcNoAbstractOrVirtualMemberFound(bindName, ErrorResolutionHints.FormatPredictions predictions),mBinding))
62196227
| [(_,absSlot:MethInfo)] -> errorR(Error(FSComp.SR.tcArgumentArityMismatch(bindName, (List.sum absSlot.NumArgs)),mBinding))
62206228
| (_,absSlot:MethInfo) :: _ -> errorR(Error(FSComp.SR.tcArgumentArityMismatchOneOverload(bindName, (List.sum absSlot.NumArgs)),mBinding))
62216229

tests/fsharp/typecheck/sigs/neg10.bsl

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,17 @@ neg10.fs(174,9,175,20): typecheck error FS0951: Literal enumerations must have t
6969

7070
neg10.fs(180,10,180,11): typecheck error FS0866: Interfaces cannot contain definitions of object constructors
7171

72-
neg10.fs(193,39,193,46): typecheck error FS0767: The member 'MyX' does not correspond to any abstract or virtual method available to override or implement
72+
neg10.fs(193,39,193,46): typecheck error FS0767: The type Foo contains the member 'MyX' but it is not a virtual or abstract method that is available to override or implement.
73+
74+
Maybe you want one of the following:
75+
76+
Equals
77+
78+
ToString
79+
80+
Finalize
81+
82+
GetHashCode
7383

7484
neg10.fs(193,41,193,44): typecheck error FS0017: The member 'MyX : unit -> int' does not have the correct type to override any given virtual method
7585

tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ObjectExpressions/E_MembersMustBeVirtual01.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// #Regression #Conformance #DataExpressions #ObjectConstructors
22
// FSB 1683, dispatch slot checking in object expression manages to match non-virtual member
33

4-
//<Expects id="FS0767" status="error" span="(11,35-11,42)">The member 'MyX' does not correspond to any abstract or virtual method available to override or implement$</Expects>
4+
//<Expects id="FS0767" status="error" span="(11,35-11,42)">The type Foo contains the member 'MyX' but it is not a virtual or abstract method that is available to override or implement.</Expects>
55
//<Expects id="FS0017" status="error" span="(11,37-11,40)">The member 'MyX : unit -> int' does not have the correct type to override any given virtual method$</Expects>
66
//<Expects id="FS0783" status="error" span="(11,16-11,19)">At least one override did not correctly implement its corresponding abstract member$</Expects>
77

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// #Warnings
2+
//<Expects status="Error" span="(11,16)" id="FS0767">The type Foo contains the member 'MyX' but it is not a virtual or abstract method that is available to override or implement.</Expects>
3+
//<Expects>ToString</Expects>
4+
5+
type Foo(x : int) =
6+
member v.MyX() = x
7+
8+
let foo =
9+
{ new Foo(3)
10+
with
11+
member v.MyX() = 4 }
12+
13+
14+
exit 0

tests/fsharpqa/Source/Warnings/env.lst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
SOURCE=CommaInRecCtor.fs # CommaInRecCtor.fs
66
SOURCE=ValidCommaInRecCtor.fs # ValidCommaInRecCtor.fs
77
SOURCE=ElseBranchHasWrongType.fs # ElseBranchHasWrongType.fs
8+
SOURCE=MatchingMethodWithSameNameIsNotAbstract.fs # MatchingMethodWithSameNameIsNotAbstract.fs
89
SOURCE=NoMatchingAbstractMethodWithSameName.fs # NoMatchingAbstractMethodWithSameName.fs
910
SOURCE=MissingExpressionAfterLet.fs # MissingExpressionAfterLet.fs
1011
SOURCE=AssignmentOnImmutable.fs # AssignmentOnImmutable.fs

0 commit comments

Comments
 (0)