Skip to content

Commit 1e9ccfd

Browse files
authored
Merge pull request #1283 from forki/record-1280
Better error message when a record was given
2 parents e7ff236 + 5eceaf1 commit 1e9ccfd

File tree

7 files changed

+27
-16
lines changed

7 files changed

+27
-16
lines changed

src/fsharp/FSComp.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -959,7 +959,6 @@ lexfltSeparatorTokensOfPatternMatchMisaligned,"The '|' tokens separating rules o
959959
1126,nrGlobalUsedOnlyAsFirstName,"'global' may only be used as the first name in a qualified path"
960960
1127,nrIsNotConstructorOrLiteral,"This is not a constructor or literal, or a constructor is being used incorrectly"
961961
1128,nrUnexpectedEmptyLongId,"Unexpected empty long identifier"
962-
1129,nrTypeDoesNotContainSuchField,"The type '%s' does not contain a field '%s'"
963962
1129,nrRecordDoesNotContainSuchLabel,"The record type '%s' does not contain a label '%s'."
964963
1130,nrInvalidFieldLabel,"Invalid field label"
965964
1132,nrInvalidExpression,"Invalid expression '%s'"

src/fsharp/NameResolution.fs

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2563,17 +2563,7 @@ let ResolveFieldPrim (ncenv:NameResolver) nenv ad typ (mp,id:Ident) allFields =
25632563
let m = id.idRange
25642564
match mp with
25652565
| [] ->
2566-
if isAppTy g typ then
2567-
match ncenv.InfoReader.TryFindRecdOrClassFieldInfoOfType(id.idText,m,typ) with
2568-
| Some (RecdFieldInfo(_,rfref)) -> [ResolutionInfo.Empty, FieldResolution(rfref,false)]
2569-
| None ->
2570-
let typeName = NicePrint.minimalStringOfType nenv.eDisplayEnv typ
2571-
if isRecdTy g typ then
2572-
// record label doesn't belong to record type -> predict other labels of same record
2573-
error(Error(SuggestOtherLabelsOfSameRecordType nenv typeName id allFields,m))
2574-
else
2575-
error(Error(FSComp.SR.nrTypeDoesNotContainSuchField(typeName, id.idText),m))
2576-
else
2566+
let lookup() =
25772567
let frefs =
25782568
try Map.find id.idText nenv.eFieldLabels
25792569
with :? KeyNotFoundException ->
@@ -2584,7 +2574,19 @@ let ResolveFieldPrim (ncenv:NameResolver) nenv ad typ (mp,id:Ident) allFields =
25842574
frefs
25852575
|> ListSet.setify (fun fref1 fref2 -> tyconRefEq g fref1.TyconRef fref2.TyconRef)
25862576
|> List.map (fun x -> ResolutionInfo.Empty, FieldResolution(x,false))
2587-
2577+
2578+
if isAppTy g typ then
2579+
match ncenv.InfoReader.TryFindRecdOrClassFieldInfoOfType(id.idText,m,typ) with
2580+
| Some (RecdFieldInfo(_,rfref)) -> [ResolutionInfo.Empty, FieldResolution(rfref,false)]
2581+
| None ->
2582+
let typeName = NicePrint.minimalStringOfType nenv.eDisplayEnv typ
2583+
if isRecdTy g typ then
2584+
// record label doesn't belong to record type -> predict other labels of same record
2585+
error(Error(SuggestOtherLabelsOfSameRecordType nenv typeName id allFields,m))
2586+
else
2587+
lookup()
2588+
else
2589+
lookup()
25882590
| _ ->
25892591
let lid = (mp@[id])
25902592
let tyconSearch ad =

src/fsharp/TypeChecker.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6647,7 +6647,7 @@ and TcRecdExpr cenv overallTy env tpenv (inherits, optOrigExpr, flds, mWholeExpr
66476647
]
66486648
match flds with
66496649
| [] -> []
6650-
| _ ->
6650+
| _ ->
66516651
let tcref,_,fldsList = BuildFieldMap cenv env (isSome optOrigExpr) overallTy flds mWholeExpr
66526652
let _,_,_,gtyp = infoOfTyconRef mWholeExpr tcref
66536653
UnifyTypes cenv env mWholeExpr overallTy gtyp

tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/RecordTypes/E_RecordCloning01.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// #Regression #Conformance #TypesAndModules #Records
22
// Verify error when trying to clone a non-record type
3-
//<Expects id="FS1129" status="error" span="(7,39)">The type 'int \[\]' does not contain a field 'B'$</Expects>
3+
//<Expects id="FS0001" status="error" span="(7,17)">This expression was expected to have type</Expects>
44

55
type RecType = { A : int; B : string }
66

tests/fsharpqa/Source/Conformance/DeclarationElements/MemberDefinitions/MethodsAndProperties/E_SettersMustHaveUnit01.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// #Regression #Conformance #DeclarationElements #MemberDefinitions #MethodsAndProperties
22
// Verify property setters must have type unit
3-
//<Expects id="FS1129" status="error" span="(10,67)">The type 'unit' does not contain a field 'immutStr'</Expects>
3+
//<Expects id="FS0001" status="error" span="(10,66)">This expression was expected to have type</Expects>
44

55
type immut =
66
{
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// #Warnings
2+
//<Expects status="Error" span="(7,13)" id="FS0001">This expression was expected to have type</Expects>
3+
4+
type Record = {field1:int; field2:int}
5+
let doSomething (xs) = List.map (fun {field1=x} -> x) xs
6+
7+
doSomething {Record.field1=0; field2=0}
8+
9+
exit 0

tests/fsharpqa/Source/Warnings/env.lst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
SOURCE=WarnIfMissingElseBranch.fs # WarnIfMissingElseBranch.fs
33
SOURCE=ReturnInsteadOfReturnBang.fs # ReturnInsteadOfReturnBang.fs
44
SOURCE=YieldInsteadOfYieldBang.fs # YieldInsteadOfYieldBang.fs
5+
SOURCE=InvalidRecord.fs # InvalidRecord.fs
56
SOURCE=CommaInRecCtor.fs # CommaInRecCtor.fs
67
SOURCE=ValidCommaInRecCtor.fs # ValidCommaInRecCtor.fs
78
SOURCE=AccessOfTypeAbbreviation.fs # AccessOfTypeAbbreviation.fs

0 commit comments

Comments
 (0)