diff --git a/src/fsharp/CompileOps.fs b/src/fsharp/CompileOps.fs
index 0d8ea5a3fa5..d79dd8eeda1 100755
--- a/src/fsharp/CompileOps.fs
+++ b/src/fsharp/CompileOps.fs
@@ -742,8 +742,12 @@ let OutputPhasedErrorR (os:System.Text.StringBuilder) (err:PhasedError) =
os.Append(Duplicate1E().Format (DecompileOpName s)) |> ignore
else
os.Append(Duplicate2E().Format k (DecompileOpName s)) |> ignore
- | UndefinedName(_,k,id,_) ->
+ | UndefinedName(_,k,id,predictions) ->
os.Append(k (DecompileOpName id.idText)) |> ignore
+ if Set.isEmpty predictions |> not then
+ let filtered = ErrorResolutionHints.FilterPredictions id.idText predictions
+ os.Append(ErrorResolutionHints.FormatPredictions filtered) |> ignore
+
| InternalUndefinedItemRef(f,smr,ccuName,s) ->
let _, errs = f(smr, ccuName, s)
os.Append(errs) |> ignore
diff --git a/src/fsharp/ErrorResolutionHints.fs b/src/fsharp/ErrorResolutionHints.fs
new file mode 100644
index 00000000000..28bb2ff2d6c
--- /dev/null
+++ b/src/fsharp/ErrorResolutionHints.fs
@@ -0,0 +1,29 @@
+// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+/// Functions to format error message details
+module internal Microsoft.FSharp.Compiler.ErrorResolutionHints
+
+/// Filters predictions based on edit distance to an unknown identifier.
+let FilterPredictions unknownIdent allPredictions =
+ let rec take n predictions =
+ predictions
+ |> Seq.mapi (fun i x -> i,x)
+ |> Seq.takeWhile (fun (i,_) -> i < n)
+ |> Seq.map snd
+ |> Seq.toList
+
+ allPredictions
+ |> Seq.toList
+ |> List.distinct
+ |> List.sortBy (fun s -> Internal.Utilities.EditDistance.CalcEditDistance(unknownIdent,s))
+ |> take 5
+
+let FormatPredictions predictions =
+ match predictions with
+ | [] -> System.String.Empty
+ | _ ->
+ let predictionText =
+ predictions
+ |> Seq.map (sprintf "%s %s" System.Environment.NewLine)
+ |> String.concat ""
+ System.Environment.NewLine + FSComp.SR.undefinedNameRecordLabelDetails() + predictionText
diff --git a/src/fsharp/FSComp.txt b/src/fsharp/FSComp.txt
index b05aaca7ae0..5575d29959f 100644
--- a/src/fsharp/FSComp.txt
+++ b/src/fsharp/FSComp.txt
@@ -9,8 +9,10 @@ undefinedNameValueOfConstructor,"The value or constructor '%s' is not defined"
undefinedNameValueNamespaceTypeOrModule,"The value, namespace, type or module '%s' is not defined"
undefinedNameConstructorModuleOrNamespace,"The constructor, module or namespace '%s' is not defined"
undefinedNameType,"The type '%s' is not defined"
+undefinedNameTypeIn,"The type '%s' is not defined in '%s'."
undefinedNameRecordLabelOrNamespace,"The record label or namespace '%s' is not defined"
-undefinedNameRecordLabel,"The record label '%s' is not defined"
+undefinedNameRecordLabel,"The record label '%s' is not defined."
+undefinedNameRecordLabelDetails,"Maybe you want one of the following:"
undefinedNameTypeParameter,"The type parameter '%s' is not defined"
undefinedNamePatternDiscriminator,"The pattern discriminator '%s' is not defined"
missingElseBranch,"The 'if' expression is missing an 'else' branch. The 'then' branch has type '%s'. Because 'if' is an expression, and not a statement, add an 'else' branch which returns a value of the same type."
@@ -951,6 +953,7 @@ lexfltSeparatorTokensOfPatternMatchMisaligned,"The '|' tokens separating rules o
1127,nrIsNotConstructorOrLiteral,"This is not a constructor or literal, or a constructor is being used incorrectly"
1128,nrUnexpectedEmptyLongId,"Unexpected empty long identifier"
1129,nrTypeDoesNotContainSuchField,"The type '%s' does not contain a field '%s'"
+1129,nrRecordDoesNotContainSuchLabel,"The record type '%s' does not contain a label '%s'."
1130,nrInvalidFieldLabel,"Invalid field label"
1132,nrInvalidExpression,"Invalid expression '%s'"
1133,nrNoConstructorsAvailableForType,"No constructors are available for the type '%s'"
diff --git a/src/fsharp/FSharp.Compiler-proto/FSharp.Compiler-proto.fsproj b/src/fsharp/FSharp.Compiler-proto/FSharp.Compiler-proto.fsproj
index 9731adc082c..7eb20114970 100644
--- a/src/fsharp/FSharp.Compiler-proto/FSharp.Compiler-proto.fsproj
+++ b/src/fsharp/FSharp.Compiler-proto/FSharp.Compiler-proto.fsproj
@@ -98,6 +98,9 @@
HashMultiMap.fs
+
+ Utilities\EditDistance.fs
+
TaggedCollections.fsi
@@ -211,6 +214,9 @@
ErrorLogger.fs
+
+ ErrorResolutionHints.fs
+
InternalCollections.fsi
diff --git a/src/fsharp/FSharp.Compiler/FSharp.Compiler.fsproj b/src/fsharp/FSharp.Compiler/FSharp.Compiler.fsproj
index 9ff448d299e..9ba9ef50d9f 100644
--- a/src/fsharp/FSharp.Compiler/FSharp.Compiler.fsproj
+++ b/src/fsharp/FSharp.Compiler/FSharp.Compiler.fsproj
@@ -1,4 +1,4 @@
-
+
@@ -84,6 +84,9 @@
Utilities\HashMultiMap.fs
+
+ Utilities\EditDistance.fs
+
Utilities\TaggedCollections.fsi
@@ -159,6 +162,9 @@
ErrorLogging\ErrorLogger.fs
+
+ ErrorLogging\ErrorResolutionHints.fs
+
ReferenceResolution\ReferenceResolution.fsi
diff --git a/src/fsharp/FSharp.LanguageService.Compiler/FSharp.LanguageService.Compiler.fsproj b/src/fsharp/FSharp.LanguageService.Compiler/FSharp.LanguageService.Compiler.fsproj
index 2ab989865f6..eae4ab21a55 100644
--- a/src/fsharp/FSharp.LanguageService.Compiler/FSharp.LanguageService.Compiler.fsproj
+++ b/src/fsharp/FSharp.LanguageService.Compiler/FSharp.LanguageService.Compiler.fsproj
@@ -80,6 +80,9 @@
Utilities\HashMultiMap.fs
+
+ Utilities\EditDistance.fs
+
Utilities\TaggedCollections.fsi
@@ -152,6 +155,9 @@
ErrorLogging\ErrorLogger.fs
+
+ ErrorLogging\ErrorResolutionHints.fs
+
ReferenceResolution\ReferenceResolution.fsi
diff --git a/src/fsharp/NameResolution.fs b/src/fsharp/NameResolution.fs
index 8c5b65ebd89..2dc05d9dc23 100755
--- a/src/fsharp/NameResolution.fs
+++ b/src/fsharp/NameResolution.fs
@@ -801,8 +801,11 @@ let AddResults res1 res2 =
| Result x,Result l -> Result (x @ l)
| Exception _,Result l -> Result l
| Result x,Exception _ -> Result x
+ // This prefers error messages with more predictions
+ | Exception (UndefinedName(n1,_,_,predictions1) as e1),Exception (UndefinedName(n2,_,_,predictions2) as e2) when n1 = n2 ->
+ if Set.count predictions1 < Set.count predictions2 then Exception e2 else Exception e1
// This prefers error messages coming from deeper failing long identifier paths
- | Exception (UndefinedName(n1,_,_,_) as e1),Exception (UndefinedName(n2,_,_,_) as e2) ->
+ | Exception (UndefinedName(n1,_,_,_) as e1),Exception (UndefinedName(n2,_,_,_) as e2) ->
if n1 < n2 then Exception e2 else Exception e1
// Prefer more concrete errors about things being undefined
| Exception (UndefinedName _ as e1),Exception (Error _) -> Exception e1
@@ -1610,15 +1613,15 @@ let rec ResolveLongIndentAsModuleOrNamespace amap m fullyQualified (nenv:NameRes
| Some mspec when IsEntityAccessible amap m ad (modref.NestedTyconRef mspec) ->
let subref = modref.NestedTyconRef mspec
look (depth+1) subref mspec.ModuleOrNamespaceType rest
- | _ -> raze (UndefinedName(depth,FSComp.SR.undefinedNameNamespace,id,[]))
+ | _ -> raze (UndefinedName(depth,FSComp.SR.undefinedNameNamespace,id,NoPredictions))
modrefs |> CollectResults (fun modref ->
if IsEntityAccessible amap m ad modref then
look 1 modref modref.ModuleOrNamespaceType rest
else
- raze (UndefinedName(0,FSComp.SR.undefinedNameNamespaceOrModule,id,[])))
+ raze (UndefinedName(0,FSComp.SR.undefinedNameNamespaceOrModule,id,NoPredictions)))
| None ->
- raze (UndefinedName(0,FSComp.SR.undefinedNameNamespaceOrModule,id,[]))
+ raze (UndefinedName(0,FSComp.SR.undefinedNameNamespaceOrModule,id,NoPredictions))
let ResolveLongIndentAsModuleOrNamespaceThen amap m fullyQualified (nenv:NameResolutionEnv) ad lid f =
@@ -1858,7 +1861,7 @@ let rec ResolveLongIdentInTypePrim (ncenv:NameResolver) nenv lookupKind (resInfo
// since later on this logic is used when giving preference to intrinsic definitions
match DecodeFSharpEvent (pinfos@extensionPropInfos) ad g ncenv m with
| Some x -> success (resInfo, x, rest)
- | None-> raze (UndefinedName (depth,FSComp.SR.undefinedNameFieldConstructorOrMember, id,[]))
+ | None -> raze (UndefinedName (depth,FSComp.SR.undefinedNameFieldConstructorOrMember, id,NoPredictions))
| Some(MethodItem msets) when (match lookupKind with LookupKind.Expr -> true | _ -> false) ->
let minfos = msets |> ExcludeHiddenOfMethInfos g ncenv.amap m
@@ -1883,7 +1886,7 @@ let rec ResolveLongIdentInTypePrim (ncenv:NameResolver) nenv lookupKind (resInfo
success (resInfo,Item.MakeMethGroup (nm,minfos),rest)
elif isTyparTy g typ then raze (IndeterminateType(unionRanges m id.idRange))
- else raze (UndefinedName (depth,FSComp.SR.undefinedNameFieldConstructorOrMember, id,[]))
+ else raze (UndefinedName (depth,FSComp.SR.undefinedNameFieldConstructorOrMember, id,NoPredictions))
let nestedSearchAccessible =
let nestedTypes = GetNestedTypesOfType (ad, ncenv, Some nm, (if isNil rest then typeNameResInfo.StaticArgsInfo else TypeNameResolutionStaticArgsInfo.Indefinite), true, m) typ
@@ -1995,7 +1998,7 @@ let rec ResolveExprLongIdentInModuleOrNamespace (ncenv:NameResolver) nenv (typeN
else
NoResultsOrUsefulErrors
- AtMostOneResult id.idRange ( tyconSearch +++ moduleSearch +++ raze (UndefinedName(depth,FSComp.SR.undefinedNameValueConstructorNamespaceOrType,id,[])))
+ AtMostOneResult id.idRange ( tyconSearch +++ moduleSearch +++ raze (UndefinedName(depth,FSComp.SR.undefinedNameValueConstructorNamespaceOrType,id,NoPredictions)))
/// An identifier has resolved to a type name in an expression (corresponding to one or more TyconRefs).
@@ -2076,7 +2079,7 @@ let rec ResolveExprLongIdentPrim sink (ncenv:NameResolver) fullyQualified m ad n
success [(resInfo,Item.ImplicitOp(id, ref None),[])]
else NoResultsOrUsefulErrors
- let failingCase = raze (UndefinedName(0,FSComp.SR.undefinedNameValueOfConstructor,id,[]))
+ let failingCase = raze (UndefinedName(0,FSComp.SR.undefinedNameValueOfConstructor,id,NoPredictions))
let search = ctorSearch +++ implicitOpSearch +++ failingCase
let resInfo,item,rest = ForceRaise (AtMostOneResult m search)
ResolutionInfo.SendToSink(sink,ncenv,nenv,ItemOccurence.Use,ad,resInfo,ResultTyparChecker(fun () -> CheckAllTyparsInferrable ncenv.amap m item));
@@ -2133,7 +2136,7 @@ let rec ResolveExprLongIdentPrim sink (ncenv:NameResolver) fullyQualified m ad n
| Result _ as res ->
ForceRaise res
| _ ->
- let failingCase = raze (UndefinedName(0,FSComp.SR.undefinedNameValueNamespaceTypeOrModule,id,[]))
+ let failingCase = raze (UndefinedName(0,FSComp.SR.undefinedNameValueNamespaceTypeOrModule,id,NoPredictions))
ForceRaise (AtMostOneResult m (search +++ moduleSearch AccessibleFromSomeFSharpCode +++ tyconSearch AccessibleFromSomeFSharpCode +++ failingCase))
ResolutionInfo.SendToSink(sink,ncenv,nenv,ItemOccurence.Use,ad,resInfo,ResultTyparChecker(fun () -> CheckAllTyparsInferrable ncenv.amap m item));
item,rest
@@ -2200,7 +2203,7 @@ let rec ResolvePatternLongIdentInModuleOrNamespace (ncenv:NameResolver) nenv num
| _ ->
NoResultsOrUsefulErrors
else NoResultsOrUsefulErrors
- let res = AtMostOneResult id.idRange ( tyconSearch +++ ctorSearch +++ moduleSearch +++ raze (UndefinedName(depth,FSComp.SR.undefinedNameConstructorModuleOrNamespace,id,[])))
+ let res = AtMostOneResult id.idRange ( tyconSearch +++ ctorSearch +++ moduleSearch +++ raze (UndefinedName(depth,FSComp.SR.undefinedNameConstructorModuleOrNamespace,id,NoPredictions)))
res
/// Used to report a warning condition for the use of upper-case identifiers in patterns
@@ -2296,7 +2299,7 @@ let rec ResolveTypeLongIdentInTyconRefPrim (ncenv:NameResolver) (typeNameResInfo
let tcrefs = CheckForTypeLegitimacyAndMultipleGenericTypeAmbiguities (tcrefs, typeNameResInfo, genOk, m)
match tcrefs with
| tcref :: _ -> success tcref
- | [] -> raze (UndefinedName(depth,FSComp.SR.undefinedNameType,id,[]))
+ | [] -> raze (UndefinedName(depth,FSComp.SR.undefinedNameType,id,NoPredictions))
| id::rest ->
#if EXTENSIONTYPING
// No dotting through type generators to get to a nested type!
@@ -2310,7 +2313,7 @@ let rec ResolveTypeLongIdentInTyconRefPrim (ncenv:NameResolver) (typeNameResInfo
let tcrefs = CheckForTypeLegitimacyAndMultipleGenericTypeAmbiguities (tcrefs, typeNameResInfo.DropStaticArgsInfo, genOk, m)
match tcrefs with
| _ :: _ -> tcrefs |> CollectResults (fun (resInfo,tcref) -> ResolveTypeLongIdentInTyconRefPrim ncenv typeNameResInfo ad resInfo genOk (depth+1) m tcref rest)
- | [] -> raze (UndefinedName(depth,FSComp.SR.undefinedNameType,id,[]))
+ | [] -> raze (UndefinedName(depth,FSComp.SR.undefinedNameType,id,NoPredictions))
AtMostOneResult m tyconSearch
@@ -2322,6 +2325,15 @@ let ResolveTypeLongIdentInTyconRef sink (ncenv:NameResolver) nenv typeNameResInf
CallNameResolutionSink sink (rangeOfLid lid,nenv,item,item,ItemOccurence.UseInType,nenv.eDisplayEnv,ad)
tcref
+/// Create an UndefinedName error with details
+let SuggestTypeLongIdentInModuleOrNamespace depth (modref:ModuleOrNamespaceRef) (id:Ident) =
+ let predictedPossibleTypes =
+ modref.ModuleOrNamespaceType.AllEntities
+ |> Seq.map (fun e -> e.DisplayName)
+ |> Set.ofSeq
+
+ let errorTextF s = FSComp.SR.undefinedNameTypeIn(s,fullDisplayTextOfModRef modref)
+ UndefinedName(depth,errorTextF,id,predictedPossibleTypes)
/// Resolve a long identifier representing a type in a module or namespace
let rec private ResolveTypeLongIdentInModuleOrNamespace (ncenv:NameResolver) (typeNameResInfo: TypeNameResolutionInfo) ad genOk (resInfo:ResolutionInfo) depth m modref _mty (lid: Ident list) =
@@ -2332,7 +2344,7 @@ let rec private ResolveTypeLongIdentInModuleOrNamespace (ncenv:NameResolver) (ty
let tcrefs = LookupTypeNameInEntityMaybeHaveArity (ncenv.amap, id.idRange, id.idText, typeNameResInfo.StaticArgsInfo, modref)
match tcrefs with
| _ :: _ -> tcrefs |> CollectResults (fun tcref -> success(resInfo,tcref))
- | [] -> raze (UndefinedName(depth,FSComp.SR.undefinedNameType,id,[]))
+ | [] -> raze (SuggestTypeLongIdentInModuleOrNamespace depth modref id)
| id::rest ->
let m = unionRanges m id.idRange
let modulSearch =
@@ -2341,12 +2353,12 @@ let rec private ResolveTypeLongIdentInModuleOrNamespace (ncenv:NameResolver) (ty
let resInfo = resInfo.AddEntity(id.idRange,submodref)
ResolveTypeLongIdentInModuleOrNamespace ncenv typeNameResInfo ad genOk resInfo (depth+1) m submodref submodref.ModuleOrNamespaceType rest
| _ ->
- raze (UndefinedName(depth,FSComp.SR.undefinedNameNamespaceOrModule,id,[]))
+ raze (UndefinedName(depth,FSComp.SR.undefinedNameNamespaceOrModule,id,NoPredictions))
let tyconSearch =
let tcrefs = LookupTypeNameInEntityMaybeHaveArity (ncenv.amap, id.idRange, id.idText, TypeNameResolutionStaticArgsInfo.Indefinite, modref)
match tcrefs with
| _ :: _ -> tcrefs |> CollectResults (fun tcref -> ResolveTypeLongIdentInTyconRefPrim ncenv typeNameResInfo ad resInfo genOk (depth+1) m tcref rest)
- | [] -> raze (UndefinedName(depth,FSComp.SR.undefinedNameType,id,[]))
+ | [] -> raze (UndefinedName(depth,FSComp.SR.undefinedNameType,id,NoPredictions))
tyconSearch +++ modulSearch
/// Resolve a long identifier representing a type
@@ -2376,7 +2388,7 @@ let rec ResolveTypeLongIdentPrim (ncenv:NameResolver) fullyQualified m nenv ad (
//CheckForTypeLegitimacyAndMultipleGenericTypeAmbiguities tcref rest typeNameResInfo m;
success(ResolutionInfo.Empty,tcref)
| [] ->
- raze (UndefinedName(0,FSComp.SR.undefinedNameType,id,[]))
+ raze (UndefinedName(0,FSComp.SR.undefinedNameType,id,NoPredictions))
| id::rest ->
let m = unionRanges m id.idRange
@@ -2440,14 +2452,13 @@ let rec ResolveFieldInModuleOrNamespace (ncenv:NameResolver) nenv ad (resInfo:Re
match lid with
| id::rest ->
let m = unionRanges m id.idRange
- let error = raze (UndefinedName(depth,FSComp.SR.undefinedNameRecordLabelOrNamespace,id,[]))
// search for module-qualified names, e.g. { Microsoft.FSharp.Core.contents = 1 }
let modulScopedFieldNames =
match TryFindTypeWithRecdField modref id with
| Some tycon when IsEntityAccessible ncenv.amap m ad (modref.NestedTyconRef tycon) ->
let showDeprecated = HasFSharpAttribute ncenv.g ncenv.g.attrib_RequireQualifiedAccessAttribute tycon.Attribs
success(resInfo, FieldResolution(modref.RecdFieldRefInNestedTycon tycon id,showDeprecated), rest)
- | _ -> error
+ | _ -> raze (UndefinedName(depth,FSComp.SR.undefinedNameRecordLabelOrNamespace,id,NoPredictions))
// search for type-qualified names, e.g. { Microsoft.FSharp.Core.Ref.contents = 1 }
let tyconSearch =
match lid with
@@ -2467,15 +2478,69 @@ let rec ResolveFieldInModuleOrNamespace (ncenv:NameResolver) nenv ad (resInfo:Re
| Some(AccessibleEntityRef ncenv.amap m ad modref submodref) ->
let resInfo = resInfo.AddEntity(id.idRange,submodref)
ResolveFieldInModuleOrNamespace ncenv nenv ad resInfo (depth+1) m submodref submodref.ModuleOrNamespaceType rest
- | _ ->
- error
- else error
+ | _ -> raze (UndefinedName(depth,FSComp.SR.undefinedNameRecordLabelOrNamespace,id,NoPredictions))
+ else raze (UndefinedName(depth,FSComp.SR.undefinedNameRecordLabelOrNamespace,id,NoPredictions))
AtMostOneResult m (OneResult modulScopedFieldNames +++ tyconSearch +++ OneResult modulSearch)
| [] ->
error(InternalError("ResolveFieldInModuleOrNamespace",m))
+/// Suggest other labels of the same record
+let SuggestOtherLabelsOfSameRecordType (nenv:NameResolutionEnv) typeName (id:Ident) (allFields:Ident list) =
+ let labelsOfPossibleRecord =
+ nenv.eFieldLabels
+ |> Seq.filter (fun kv ->
+ kv.Value
+ |> List.map (fun r -> r.TyconRef.DisplayName)
+ |> List.exists ((=) typeName))
+ |> Seq.map (fun kv -> kv.Key)
+ |> Set.ofSeq
+
+ let givenFields =
+ allFields
+ |> List.map (fun fld -> fld.idText)
+ |> List.filter ((<>) id.idText)
+ |> Set.ofList
+
+ let predictedLabels = Set.difference labelsOfPossibleRecord givenFields
+ let predictions = ErrorResolutionHints.FilterPredictions id.idText predictedLabels
+
+ let errorCode,text = FSComp.SR.nrRecordDoesNotContainSuchLabel(typeName, id.idText)
+ errorCode,text + ErrorResolutionHints.FormatPredictions predictions
+
+
+let SuggestLabelsOfRelatedRecords (nenv:NameResolutionEnv) (id:Ident) (allFields:Ident list) =
+ let predictedLabels =
+ let givenFields = allFields |> List.map (fun fld -> fld.idText) |> List.filter ((<>) id.idText) |> Set.ofList
+ if Set.isEmpty givenFields then
+ // return labels from all records
+ NameMap.domainL nenv.eFieldLabels |> Set.ofList |> Set.remove "contents"
+ else
+ let possibleRecords =
+ [for fld in givenFields do
+ match Map.tryFind fld nenv.eFieldLabels with
+ | None -> ()
+ | Some recordTypes -> yield! (recordTypes |> List.map (fun r -> r.TyconRef.DisplayName, fld)) ]
+ |> List.groupBy fst
+ |> List.map (fun (r,fields) -> r, fields |> List.map snd |> Set.ofList)
+ |> List.filter (fun (_,fields) -> Set.isSubset givenFields fields)
+ |> List.map fst
+ |> Set.ofList
+
+ let labelsOfPossibleRecords =
+ nenv.eFieldLabels
+ |> Seq.filter (fun kv ->
+ kv.Value
+ |> List.map (fun r -> r.TyconRef.DisplayName)
+ |> List.exists possibleRecords.Contains)
+ |> Seq.map (fun kv -> kv.Key)
+ |> Set.ofSeq
+
+ Set.difference labelsOfPossibleRecords givenFields
+
+ UndefinedName(0,FSComp.SR.undefinedNameRecordLabel, id, predictedLabels)
+
/// Resolve a long identifier representing a record field
-let ResolveFieldPrim (ncenv:NameResolver) nenv ad typ (mp,id:Ident) =
+let ResolveFieldPrim (ncenv:NameResolver) nenv ad typ (mp,id:Ident) allFields =
let typeNameResInfo = TypeNameResolutionInfo.Default
let g = ncenv.g
let m = id.idRange
@@ -2484,11 +2549,20 @@ let ResolveFieldPrim (ncenv:NameResolver) nenv ad typ (mp,id:Ident) =
if isAppTy g typ then
match ncenv.InfoReader.TryFindRecdOrClassFieldInfoOfType(id.idText,m,typ) with
| Some (RecdFieldInfo(_,rfref)) -> [ResolutionInfo.Empty, FieldResolution(rfref,false)]
- | None -> error(Error(FSComp.SR.nrTypeDoesNotContainSuchField((NicePrint.minimalStringOfType nenv.eDisplayEnv typ), id.idText),m))
+ | None ->
+ let typeName = NicePrint.minimalStringOfType nenv.eDisplayEnv typ
+ if isRecdTy g typ then
+ // record label doesn't belong to record type -> predict other labels of same record
+ error(Error(SuggestOtherLabelsOfSameRecordType nenv typeName id allFields,m))
+ else
+ error(Error(FSComp.SR.nrTypeDoesNotContainSuchField(typeName, id.idText),m))
else
let frefs =
try Map.find id.idText nenv.eFieldLabels
- with :? KeyNotFoundException -> error (UndefinedName(0,FSComp.SR.undefinedNameRecordLabel,id,NameMap.domainL nenv.eFieldLabels))
+ with :? KeyNotFoundException ->
+ // record label is unknown -> predict related labels and give a hint to the user
+ error(SuggestLabelsOfRelatedRecords nenv id allFields)
+
// Eliminate duplicates arising from multiple 'open'
frefs
|> ListSet.setify (fun fref1 fref2 -> tyconRefEq g fref1.TyconRef fref2.TyconRef)
@@ -2514,8 +2588,8 @@ let ResolveFieldPrim (ncenv:NameResolver) nenv ad typ (mp,id:Ident) =
if nonNil rest then errorR(Error(FSComp.SR.nrInvalidFieldLabel(),(List.head rest).idRange));
[(resInfo,item)]
-let ResolveField sink ncenv nenv ad typ (mp,id) =
- let res = ResolveFieldPrim ncenv nenv ad typ (mp,id)
+let ResolveField sink ncenv nenv ad typ (mp,id) allFields =
+ let res = ResolveFieldPrim ncenv nenv ad typ (mp,id) allFields
// Register the results of any field paths "Module.Type" in "Module.Type.field" as a name resolution. (Note, the path resolution
// info is only non-empty if there was a unique resolution of the field)
for (resInfo,_rfref) in res do
diff --git a/src/fsharp/NameResolution.fsi b/src/fsharp/NameResolution.fsi
index ccad006c207..590f8a07016 100755
--- a/src/fsharp/NameResolution.fsi
+++ b/src/fsharp/NameResolution.fsi
@@ -366,7 +366,7 @@ val internal ResolveTypeLongIdentInTyconRef : TcResultsSink -> NameResol
val internal ResolveTypeLongIdent : TcResultsSink -> NameResolver -> ItemOccurence -> FullyQualifiedFlag -> NameResolutionEnv -> AccessorDomain -> Ident list -> TypeNameResolutionStaticArgsInfo -> PermitDirectReferenceToGeneratedType -> ResultOrException
/// Resolve a long identifier to a field
-val internal ResolveField : TcResultsSink -> NameResolver -> NameResolutionEnv -> AccessorDomain -> TType -> Ident list * Ident -> FieldResolution list
+val internal ResolveField : TcResultsSink -> NameResolver -> NameResolutionEnv -> AccessorDomain -> TType -> Ident list * Ident -> Ident list -> FieldResolution list
/// Resolve a long identifier occurring in an expression position
val internal ResolveExprLongIdent : TcResultsSink -> NameResolver -> range -> AccessorDomain -> NameResolutionEnv -> TypeNameResolutionInfo -> Ident list -> Item * Ident list
diff --git a/src/fsharp/TypeChecker.fs b/src/fsharp/TypeChecker.fs
index ddcffab75a4..1229f890ee5 100755
--- a/src/fsharp/TypeChecker.fs
+++ b/src/fsharp/TypeChecker.fs
@@ -1855,8 +1855,9 @@ let BuildFieldMap cenv env isPartial ty flds m =
if isNil flds then invalidArg "flds" "BuildFieldMap"
let frefSets =
+ let allFields = flds |> List.map (fun ((_,ident),_) -> ident)
flds |> List.map (fun (fld,fldExpr) ->
- let frefSet = ResolveField cenv.tcSink cenv.nameResolver env.eNameResEnv ad ty fld
+ let frefSet = ResolveField cenv.tcSink cenv.nameResolver env.eNameResEnv ad ty fld allFields
fld,frefSet, fldExpr)
let relevantTypeSets =
frefSets |> List.map (fun (_,frefSet,_) -> frefSet |> List.choose (fun (FieldResolution(rfref,_)) -> Some rfref.TyconRef))
@@ -4146,7 +4147,7 @@ and TcTyparOrMeasurePar optKind cenv (env:TcEnv) newOk tpenv (Typar(id,_,_) as t
match TryFindUnscopedTypar key tpenv with
| Some res -> checkRes res
| None ->
- if newOk = NoNewTypars then error (UndefinedName(0,FSComp.SR.undefinedNameTypeParameter,id,[""]))
+ if newOk = NoNewTypars then error (UndefinedName(0,FSComp.SR.undefinedNameTypeParameter,id,NoPredictions))
// OK, this is an implicit declaration of a type parameter
// The kind defaults to Type
let tp' = NewTypar ((match optKind with None -> TyparKind.Type | Some kind -> kind), TyparRigidity.WarnIfNotRigid,tp,false,TyparDynamicReq.Yes,[],false,false)
@@ -4858,7 +4859,7 @@ and TcPat warnOnUpper cenv env topValInfo vFlags (tpenv,names,takenNames) ty pat
match args with
| SynConstructorArgs.Pats []
| SynConstructorArgs.NamePatPairs ([], _)-> TcPat warnOnUpperForId cenv env topValInfo vFlags (tpenv,names,takenNames) ty (mkSynPatVar vis id)
- | _ -> error (UndefinedName(0,FSComp.SR.undefinedNamePatternDiscriminator,id,[]))
+ | _ -> error (UndefinedName(0,FSComp.SR.undefinedNamePatternDiscriminator,id,NoPredictions))
| Item.ActivePatternCase(APElemRef(apinfo,vref,idx)) as item ->
let args = match args with SynConstructorArgs.Pats args -> args | _ -> failwith "impossible"
diff --git a/src/fsharp/tast.fs b/src/fsharp/tast.fs
index ad1f15cb268..e11004ab29b 100755
--- a/src/fsharp/tast.fs
+++ b/src/fsharp/tast.fs
@@ -384,7 +384,11 @@ assert (sizeof = 4)
let unassignedTyparName = "?"
-exception UndefinedName of int * (* error func that expects identifier name *)(string -> string) * Ident * string list
+type Predictions = Set
+
+let NoPredictions = Set.empty
+
+exception UndefinedName of int * (* error func that expects identifier name *)(string -> string) * Ident * Predictions
exception InternalUndefinedItemRef of (string * string * string -> int * string) * string * string * string
let KeyTyconByDemangledNameAndArity nm (typars: _ list) x =
diff --git a/src/utils/EditDistance.fs b/src/utils/EditDistance.fs
new file mode 100644
index 00000000000..b1271f1b76e
--- /dev/null
+++ b/src/utils/EditDistance.fs
@@ -0,0 +1,47 @@
+// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+/// Functions to compute the edit distance between two strings
+module internal Internal.Utilities.EditDistance
+
+/// Computes the DamerauLevenstein distance
+/// - read more at https://en.wikipedia.org/wiki/Damerau%E2%80%93Levenshtein_distance
+/// - Implementation taken from http://www.navision-blog.de/2008/11/01/damerau-levenshtein-distance-in-fsharp-part-ii/
+let private calcDamerauLevenshtein (a:string, b:string) =
+ let m = b.Length + 1
+ let mutable lastLine = Array.init m (fun i -> i)
+ let mutable lastLastLine = Array.create m 0
+ let mutable actLine = Array.create m 0
+
+ for i in [1..a.Length] do
+ actLine.[0] <- i
+ for j in [1..b.Length] do
+ let cost = if a.[i-1] = b.[j-1] then 0 else 1
+ let deletion = lastLine.[j] + 1
+ let insertion = actLine.[j-1] + 1
+ let substitution = lastLine.[j-1] + cost
+ actLine.[j] <-
+ deletion
+ |> min insertion
+ |> min substitution
+
+ if i > 1 && j > 1 then
+ if a.[i-1] = b.[j-2] && a.[i-2] = b.[j-1] then
+ let transposition = lastLastLine.[j-2] + cost
+ actLine.[j] <- min actLine.[j] transposition
+
+ // swap lines
+ let temp = lastLastLine
+ lastLastLine <- lastLine
+ lastLine <- actLine
+ actLine <- temp
+
+ lastLine.[b.Length]
+
+/// Calculates the edit distance between two strings.
+/// The edit distance is a metric that allows to measure the amount of difference between two strings
+/// and shows how many edit operations (insert, delete, substitution) are needed to transform one string into the other.
+let CalcEditDistance(a:string, b:string) =
+ if a.Length > b.Length then
+ calcDamerauLevenshtein(a, b)
+ else
+ calcDamerauLevenshtein(b, a)
\ No newline at end of file
diff --git a/tests/fsharp/typeProviders/negTests/EVIL_PROVIDER_ResolveTypeName_Exception.bsl b/tests/fsharp/typeProviders/negTests/EVIL_PROVIDER_ResolveTypeName_Exception.bsl
index d5c920e5f4b..4d1aed83136 100644
--- a/tests/fsharp/typeProviders/negTests/EVIL_PROVIDER_ResolveTypeName_Exception.bsl
+++ b/tests/fsharp/typeProviders/negTests/EVIL_PROVIDER_ResolveTypeName_Exception.bsl
@@ -7,7 +7,11 @@ EVIL_PROVIDER_ResolveTypeName_Exception.fsx(7,73,7,96): typecheck error FS3033:
EVIL_PROVIDER_ResolveTypeName_Exception.fsx(7,73,7,96): typecheck error FS3033: The type provider 'Provider.EvilProviderWhereResolveTypeNameRaisesException' reported an error: deliberate error for testing purposes
-EVIL_PROVIDER_ResolveTypeName_Exception.fsx(7,73,7,96): typecheck error FS0039: The type 'SomeNameThatDoesntExist' is not defined
+EVIL_PROVIDER_ResolveTypeName_Exception.fsx(7,73,7,96): typecheck error FS0039: The type 'SomeNameThatDoesntExist' is not defined in 'FSharp.EvilProviderWhereResolveTypeNameRaisesException'.
+
+Maybe you want one of the following:
+
+ TheType
EVIL_PROVIDER_ResolveTypeName_Exception.fsx(7,73,7,96): typecheck error FS3033: The type provider 'Provider.EvilProviderWhereResolveTypeNameRaisesException' reported an error: deliberate error for testing purposes
@@ -17,4 +21,8 @@ EVIL_PROVIDER_ResolveTypeName_Exception.fsx(7,73,7,96): typecheck error FS3033:
EVIL_PROVIDER_ResolveTypeName_Exception.fsx(7,73,7,96): typecheck error FS3033: The type provider 'Provider.EvilProviderWhereResolveTypeNameRaisesException' reported an error: deliberate error for testing purposes
-EVIL_PROVIDER_ResolveTypeName_Exception.fsx(7,73,7,96): typecheck error FS0039: The type 'SomeNameThatDoesntExist' is not defined
+EVIL_PROVIDER_ResolveTypeName_Exception.fsx(7,73,7,96): typecheck error FS0039: The type 'SomeNameThatDoesntExist' is not defined in 'FSharp.EvilProviderWhereResolveTypeNameRaisesException'.
+
+Maybe you want one of the following:
+
+ TheType
diff --git a/tests/fsharp/typeProviders/negTests/EVIL_PROVIDER_ResolveTypeName_Null.bsl b/tests/fsharp/typeProviders/negTests/EVIL_PROVIDER_ResolveTypeName_Null.bsl
index 03beeb13246..b299ed7e461 100644
--- a/tests/fsharp/typeProviders/negTests/EVIL_PROVIDER_ResolveTypeName_Null.bsl
+++ b/tests/fsharp/typeProviders/negTests/EVIL_PROVIDER_ResolveTypeName_Null.bsl
@@ -1,4 +1,12 @@
-EVIL_PROVIDER_ResolveTypeName_Null.fsx(7,69,7,92): typecheck error FS0039: The type 'SomeNameThatDoesntExist' is not defined
+EVIL_PROVIDER_ResolveTypeName_Null.fsx(7,69,7,92): typecheck error FS0039: The type 'SomeNameThatDoesntExist' is not defined in 'FSharp.EvilProviderWhereResolveTypeNameReturnsNull'.
-EVIL_PROVIDER_ResolveTypeName_Null.fsx(7,69,7,92): typecheck error FS0039: The type 'SomeNameThatDoesntExist' is not defined
+Maybe you want one of the following:
+
+ TheType
+
+EVIL_PROVIDER_ResolveTypeName_Null.fsx(7,69,7,92): typecheck error FS0039: The type 'SomeNameThatDoesntExist' is not defined in 'FSharp.EvilProviderWhereResolveTypeNameReturnsNull'.
+
+Maybe you want one of the following:
+
+ TheType
diff --git a/tests/fsharp/typeProviders/negTests/neg1.bsl b/tests/fsharp/typeProviders/negTests/neg1.bsl
index 07d2d8a4da1..64fd3e58aef 100644
--- a/tests/fsharp/typeProviders/negTests/neg1.bsl
+++ b/tests/fsharp/typeProviders/negTests/neg1.bsl
@@ -28,7 +28,15 @@ neg1.fsx(11,38,11,66): typecheck error FS3072: The type provider 'Provider.EvilP
neg1.fsx(11,38,11,66): typecheck error FS3072: The type provider 'Provider.EvilProvider' reported an error: An exception occurred when accessing the 'Name' of a provided type: deliberate error for testing purposes
-neg1.fsx(11,38,11,66): typecheck error FS0039: The type 'TypeWhereNameRaisesException' is not defined
+neg1.fsx(11,38,11,66): typecheck error FS0039: The type 'TypeWhereNameRaisesException' is not defined in 'FSharp.EvilProvider'.
+
+Maybe you want one of the following:
+
+ IsArrayTypeRaisesException
+
+ TheType
+
+ IsArrayTypeReturnsTrue
neg1.fsx(11,38,11,66): typecheck error FS3072: The type provider 'Provider.EvilProvider' reported an error: An exception occurred when accessing the 'Name' of a provided type: deliberate error for testing purposes
@@ -38,7 +46,15 @@ neg1.fsx(11,38,11,66): typecheck error FS3072: The type provider 'Provider.EvilP
neg1.fsx(11,38,11,66): typecheck error FS3072: The type provider 'Provider.EvilProvider' reported an error: An exception occurred when accessing the 'Name' of a provided type: deliberate error for testing purposes
-neg1.fsx(11,38,11,66): typecheck error FS0039: The type 'TypeWhereNameRaisesException' is not defined
+neg1.fsx(11,38,11,66): typecheck error FS0039: The type 'TypeWhereNameRaisesException' is not defined in 'FSharp.EvilProvider'.
+
+Maybe you want one of the following:
+
+ IsArrayTypeRaisesException
+
+ TheType
+
+ IsArrayTypeReturnsTrue
neg1.fsx(12,38,12,62): typecheck error FS3073: The type provider 'Provider.EvilProvider' reported an error: The 'Name' of a provided type was null or empty.
@@ -48,7 +64,15 @@ neg1.fsx(12,38,12,62): typecheck error FS3073: The type provider 'Provider.EvilP
neg1.fsx(12,38,12,62): typecheck error FS3073: The type provider 'Provider.EvilProvider' reported an error: The 'Name' of a provided type was null or empty.
-neg1.fsx(12,38,12,62): typecheck error FS0039: The type 'TypeWhereNameReturnsNull' is not defined
+neg1.fsx(12,38,12,62): typecheck error FS0039: The type 'TypeWhereNameReturnsNull' is not defined in 'FSharp.EvilProvider'.
+
+Maybe you want one of the following:
+
+ IsArrayTypeReturnsTrue
+
+ TheType
+
+ IsArrayTypeRaisesException
neg1.fsx(12,38,12,62): typecheck error FS3073: The type provider 'Provider.EvilProvider' reported an error: The 'Name' of a provided type was null or empty.
@@ -58,7 +82,15 @@ neg1.fsx(12,38,12,62): typecheck error FS3073: The type provider 'Provider.EvilP
neg1.fsx(12,38,12,62): typecheck error FS3073: The type provider 'Provider.EvilProvider' reported an error: The 'Name' of a provided type was null or empty.
-neg1.fsx(12,38,12,62): typecheck error FS0039: The type 'TypeWhereNameReturnsNull' is not defined
+neg1.fsx(12,38,12,62): typecheck error FS0039: The type 'TypeWhereNameReturnsNull' is not defined in 'FSharp.EvilProvider'.
+
+Maybe you want one of the following:
+
+ IsArrayTypeReturnsTrue
+
+ TheType
+
+ IsArrayTypeRaisesException
neg1.fsx(13,38,13,66): typecheck error FS3021: Unexpected exception from provided type 'FSharp.EvilProvider.IsGenericTypeRaisesException' member 'IsGenericType': The type provider 'Provider.EvilProvider' reported an error: deliberate error for testing purposes
@@ -92,7 +124,19 @@ neg1.fsx(15,38,15,70): typecheck error FS3021: Unexpected exception from provide
neg1.fsx(15,38,15,70): typecheck error FS3072: The type provider 'Provider.EvilProvider' reported an error: An exception occurred when accessing the 'FullName' of a provided type: deliberate error for testing purposes
-neg1.fsx(15,38,15,70): typecheck error FS0039: The type 'TypeWhereFullNameRaisesException' is not defined
+neg1.fsx(15,38,15,70): typecheck error FS0039: The type 'TypeWhereFullNameRaisesException' is not defined in 'FSharp.EvilProvider'.
+
+Maybe you want one of the following:
+
+ IsGenericTypeRaisesException
+
+ IsArrayTypeRaisesException
+
+ IsGenericTypeReturnsTrue
+
+ IsArrayTypeReturnsTrue
+
+ TheType
neg1.fsx(15,38,15,70): typecheck error FS3021: Unexpected exception from provided type 'TypeWhereFullNameRaisesException' member 'FullName': The type provider 'Provider.EvilProvider' reported an error: deliberate error for testing purposes
@@ -110,7 +154,19 @@ neg1.fsx(15,38,15,70): typecheck error FS3021: Unexpected exception from provide
neg1.fsx(15,38,15,70): typecheck error FS3072: The type provider 'Provider.EvilProvider' reported an error: An exception occurred when accessing the 'FullName' of a provided type: deliberate error for testing purposes
-neg1.fsx(15,38,15,70): typecheck error FS0039: The type 'TypeWhereFullNameRaisesException' is not defined
+neg1.fsx(15,38,15,70): typecheck error FS0039: The type 'TypeWhereFullNameRaisesException' is not defined in 'FSharp.EvilProvider'.
+
+Maybe you want one of the following:
+
+ IsGenericTypeRaisesException
+
+ IsArrayTypeRaisesException
+
+ IsGenericTypeReturnsTrue
+
+ IsArrayTypeReturnsTrue
+
+ TheType
neg1.fsx(16,38,16,66): typecheck error FS3042: Unexpected 'null' return value from provided type 'TypeWhereFullNameReturnsNull' member 'FullName'
@@ -128,7 +184,19 @@ neg1.fsx(16,38,16,66): typecheck error FS3042: Unexpected 'null' return value fr
neg1.fsx(16,38,16,66): typecheck error FS3073: The type provider 'Provider.EvilProvider' reported an error: The 'FullName' of a provided type was null or empty.
-neg1.fsx(16,38,16,66): typecheck error FS0039: The type 'TypeWhereFullNameReturnsNull' is not defined
+neg1.fsx(16,38,16,66): typecheck error FS0039: The type 'TypeWhereFullNameReturnsNull' is not defined in 'FSharp.EvilProvider'.
+
+Maybe you want one of the following:
+
+ IsGenericTypeReturnsTrue
+
+ IsArrayTypeReturnsTrue
+
+ TheType
+
+ IsGenericTypeRaisesException
+
+ IsArrayTypeRaisesException
neg1.fsx(16,38,16,66): typecheck error FS3042: Unexpected 'null' return value from provided type 'TypeWhereFullNameReturnsNull' member 'FullName'
@@ -146,7 +214,19 @@ neg1.fsx(16,38,16,66): typecheck error FS3042: Unexpected 'null' return value fr
neg1.fsx(16,38,16,66): typecheck error FS3073: The type provider 'Provider.EvilProvider' reported an error: The 'FullName' of a provided type was null or empty.
-neg1.fsx(16,38,16,66): typecheck error FS0039: The type 'TypeWhereFullNameReturnsNull' is not defined
+neg1.fsx(16,38,16,66): typecheck error FS0039: The type 'TypeWhereFullNameReturnsNull' is not defined in 'FSharp.EvilProvider'.
+
+Maybe you want one of the following:
+
+ IsGenericTypeReturnsTrue
+
+ IsArrayTypeReturnsTrue
+
+ TheType
+
+ IsGenericTypeRaisesException
+
+ IsArrayTypeRaisesException
neg1.fsx(17,38,17,71): typecheck error FS3021: Unexpected exception from provided type 'TypeWhereNamespaceRaisesException' member 'Namespace': The type provider 'Provider.EvilProvider' reported an error: deliberate error for testing purposes
@@ -184,9 +264,33 @@ neg1.fsx(17,38,17,71): typecheck error FS3004: The provided type 'FSharp.EvilPro
neg1.fsx(17,38,17,71): typecheck error FS3033: The type provider 'Provider.EvilProvider' reported an error: deliberate error for testing purposes
-neg1.fsx(18,39,18,68): typecheck error FS0039: The type 'TypeWhereNamespaceReturnsNull' is not defined
+neg1.fsx(18,39,18,68): typecheck error FS0039: The type 'TypeWhereNamespaceReturnsNull' is not defined in 'FSharp.EvilProvider'.
+
+Maybe you want one of the following:
+
+ IsGenericTypeReturnsTrue
+
+ IsArrayTypeReturnsTrue
-neg1.fsx(18,39,18,68): typecheck error FS0039: The type 'TypeWhereNamespaceReturnsNull' is not defined
+ IsArrayTypeRaisesException
+
+ IsGenericTypeRaisesException
+
+ TheType
+
+neg1.fsx(18,39,18,68): typecheck error FS0039: The type 'TypeWhereNamespaceReturnsNull' is not defined in 'FSharp.EvilProvider'.
+
+Maybe you want one of the following:
+
+ IsGenericTypeReturnsTrue
+
+ IsArrayTypeReturnsTrue
+
+ IsArrayTypeRaisesException
+
+ IsGenericTypeRaisesException
+
+ TheType
neg1.fsx(19,39,19,67): typecheck error FS3021: Unexpected exception from provided type 'DeclaringTypeRaisesException' member 'DeclaringType': The type provider 'Provider.EvilProvider' reported an error: deliberate error for testing purposes
@@ -216,7 +320,19 @@ neg1.fsx(20,39,20,73): typecheck error FS3021: Unexpected exception from provide
neg1.fsx(20,39,20,73): typecheck error FS3021: Unexpected exception from provided type 'FSharp.EvilProvider.TypeWhereGetMethodsRaisesException' member 'GetMethods': The type provider 'Provider.EvilProvider' reported an error: deliberate error for testing purposes
-neg1.fsx(20,39,20,73): typecheck error FS0039: The type 'TypeWhereGetMethodsRaisesException' is not defined
+neg1.fsx(20,39,20,73): typecheck error FS0039: The type 'TypeWhereGetMethodsRaisesException' is not defined in 'FSharp.EvilProvider'.
+
+Maybe you want one of the following:
+
+ IsGenericTypeRaisesException
+
+ IsArrayTypeRaisesException
+
+ IsGenericTypeReturnsTrue
+
+ IsArrayTypeReturnsTrue
+
+ TheType
neg1.fsx(20,39,20,73): typecheck error FS3021: Unexpected exception from provided type 'FSharp.EvilProvider.TypeWhereGetMethodsRaisesException' member 'GetMethods': The type provider 'Provider.EvilProvider' reported an error: deliberate error for testing purposes
@@ -226,7 +342,19 @@ neg1.fsx(20,39,20,73): typecheck error FS3021: Unexpected exception from provide
neg1.fsx(20,39,20,73): typecheck error FS3021: Unexpected exception from provided type 'FSharp.EvilProvider.TypeWhereGetMethodsRaisesException' member 'GetMethods': The type provider 'Provider.EvilProvider' reported an error: deliberate error for testing purposes
-neg1.fsx(20,39,20,73): typecheck error FS0039: The type 'TypeWhereGetMethodsRaisesException' is not defined
+neg1.fsx(20,39,20,73): typecheck error FS0039: The type 'TypeWhereGetMethodsRaisesException' is not defined in 'FSharp.EvilProvider'.
+
+Maybe you want one of the following:
+
+ IsGenericTypeRaisesException
+
+ IsArrayTypeRaisesException
+
+ IsGenericTypeReturnsTrue
+
+ IsArrayTypeReturnsTrue
+
+ TheType
neg1.fsx(21,39,21,72): typecheck error FS3021: Unexpected exception from provided type 'FSharp.EvilProvider.TypeWhereGetEventsRaisesException' member 'GetEvents': The type provider 'Provider.EvilProvider' reported an error: deliberate error for testing purposes
@@ -236,7 +364,19 @@ neg1.fsx(21,39,21,72): typecheck error FS3021: Unexpected exception from provide
neg1.fsx(21,39,21,72): typecheck error FS3021: Unexpected exception from provided type 'FSharp.EvilProvider.TypeWhereGetEventsRaisesException' member 'GetEvents': The type provider 'Provider.EvilProvider' reported an error: deliberate error for testing purposes
-neg1.fsx(21,39,21,72): typecheck error FS0039: The type 'TypeWhereGetEventsRaisesException' is not defined
+neg1.fsx(21,39,21,72): typecheck error FS0039: The type 'TypeWhereGetEventsRaisesException' is not defined in 'FSharp.EvilProvider'.
+
+Maybe you want one of the following:
+
+ IsGenericTypeRaisesException
+
+ IsArrayTypeRaisesException
+
+ IsGenericTypeReturnsTrue
+
+ IsArrayTypeReturnsTrue
+
+ TheType
neg1.fsx(21,39,21,72): typecheck error FS3021: Unexpected exception from provided type 'FSharp.EvilProvider.TypeWhereGetEventsRaisesException' member 'GetEvents': The type provider 'Provider.EvilProvider' reported an error: deliberate error for testing purposes
@@ -246,7 +386,19 @@ neg1.fsx(21,39,21,72): typecheck error FS3021: Unexpected exception from provide
neg1.fsx(21,39,21,72): typecheck error FS3021: Unexpected exception from provided type 'FSharp.EvilProvider.TypeWhereGetEventsRaisesException' member 'GetEvents': The type provider 'Provider.EvilProvider' reported an error: deliberate error for testing purposes
-neg1.fsx(21,39,21,72): typecheck error FS0039: The type 'TypeWhereGetEventsRaisesException' is not defined
+neg1.fsx(21,39,21,72): typecheck error FS0039: The type 'TypeWhereGetEventsRaisesException' is not defined in 'FSharp.EvilProvider'.
+
+Maybe you want one of the following:
+
+ IsGenericTypeRaisesException
+
+ IsArrayTypeRaisesException
+
+ IsGenericTypeReturnsTrue
+
+ IsArrayTypeReturnsTrue
+
+ TheType
neg1.fsx(22,39,22,72): typecheck error FS3021: Unexpected exception from provided type 'FSharp.EvilProvider.TypeWhereGetFieldsRaisesException' member 'GetFields': The type provider 'Provider.EvilProvider' reported an error: deliberate error for testing purposes
@@ -256,7 +408,19 @@ neg1.fsx(22,39,22,72): typecheck error FS3021: Unexpected exception from provide
neg1.fsx(22,39,22,72): typecheck error FS3021: Unexpected exception from provided type 'FSharp.EvilProvider.TypeWhereGetFieldsRaisesException' member 'GetFields': The type provider 'Provider.EvilProvider' reported an error: deliberate error for testing purposes
-neg1.fsx(22,39,22,72): typecheck error FS0039: The type 'TypeWhereGetFieldsRaisesException' is not defined
+neg1.fsx(22,39,22,72): typecheck error FS0039: The type 'TypeWhereGetFieldsRaisesException' is not defined in 'FSharp.EvilProvider'.
+
+Maybe you want one of the following:
+
+ IsGenericTypeRaisesException
+
+ IsArrayTypeRaisesException
+
+ IsGenericTypeReturnsTrue
+
+ IsArrayTypeReturnsTrue
+
+ TheType
neg1.fsx(22,39,22,72): typecheck error FS3021: Unexpected exception from provided type 'FSharp.EvilProvider.TypeWhereGetFieldsRaisesException' member 'GetFields': The type provider 'Provider.EvilProvider' reported an error: deliberate error for testing purposes
@@ -266,7 +430,19 @@ neg1.fsx(22,39,22,72): typecheck error FS3021: Unexpected exception from provide
neg1.fsx(22,39,22,72): typecheck error FS3021: Unexpected exception from provided type 'FSharp.EvilProvider.TypeWhereGetFieldsRaisesException' member 'GetFields': The type provider 'Provider.EvilProvider' reported an error: deliberate error for testing purposes
-neg1.fsx(22,39,22,72): typecheck error FS0039: The type 'TypeWhereGetFieldsRaisesException' is not defined
+neg1.fsx(22,39,22,72): typecheck error FS0039: The type 'TypeWhereGetFieldsRaisesException' is not defined in 'FSharp.EvilProvider'.
+
+Maybe you want one of the following:
+
+ IsGenericTypeRaisesException
+
+ IsArrayTypeRaisesException
+
+ IsGenericTypeReturnsTrue
+
+ IsArrayTypeReturnsTrue
+
+ TheType
neg1.fsx(23,39,23,76): typecheck error FS3021: Unexpected exception from provided type 'FSharp.EvilProvider.TypeWhereGetPropertiesRaisesException' member 'GetProperties': The type provider 'Provider.EvilProvider' reported an error: deliberate error for testing purposes
@@ -276,7 +452,19 @@ neg1.fsx(23,39,23,76): typecheck error FS3021: Unexpected exception from provide
neg1.fsx(23,39,23,76): typecheck error FS3021: Unexpected exception from provided type 'FSharp.EvilProvider.TypeWhereGetPropertiesRaisesException' member 'GetProperties': The type provider 'Provider.EvilProvider' reported an error: deliberate error for testing purposes
-neg1.fsx(23,39,23,76): typecheck error FS0039: The type 'TypeWhereGetPropertiesRaisesException' is not defined
+neg1.fsx(23,39,23,76): typecheck error FS0039: The type 'TypeWhereGetPropertiesRaisesException' is not defined in 'FSharp.EvilProvider'.
+
+Maybe you want one of the following:
+
+ IsGenericTypeRaisesException
+
+ IsArrayTypeRaisesException
+
+ IsGenericTypeReturnsTrue
+
+ IsArrayTypeReturnsTrue
+
+ TheType
neg1.fsx(23,39,23,76): typecheck error FS3021: Unexpected exception from provided type 'FSharp.EvilProvider.TypeWhereGetPropertiesRaisesException' member 'GetProperties': The type provider 'Provider.EvilProvider' reported an error: deliberate error for testing purposes
@@ -286,7 +474,19 @@ neg1.fsx(23,39,23,76): typecheck error FS3021: Unexpected exception from provide
neg1.fsx(23,39,23,76): typecheck error FS3021: Unexpected exception from provided type 'FSharp.EvilProvider.TypeWhereGetPropertiesRaisesException' member 'GetProperties': The type provider 'Provider.EvilProvider' reported an error: deliberate error for testing purposes
-neg1.fsx(23,39,23,76): typecheck error FS0039: The type 'TypeWhereGetPropertiesRaisesException' is not defined
+neg1.fsx(23,39,23,76): typecheck error FS0039: The type 'TypeWhereGetPropertiesRaisesException' is not defined in 'FSharp.EvilProvider'.
+
+Maybe you want one of the following:
+
+ IsGenericTypeRaisesException
+
+ IsArrayTypeRaisesException
+
+ IsGenericTypeReturnsTrue
+
+ IsArrayTypeReturnsTrue
+
+ TheType
neg1.fsx(24,39,24,77): typecheck error FS3004: The provided type 'FSharp.EvilProvider.TypeWhereGetNestedTypesRaisesException' has member 'Boo' which has declaring type 'FSharp.EvilProvider.TheType'. Expected declaring type to be the same as provided type.
@@ -300,7 +500,19 @@ neg1.fsx(25,39,25,78): typecheck error FS3021: Unexpected exception from provide
neg1.fsx(25,39,25,78): typecheck error FS3021: Unexpected exception from provided type 'FSharp.EvilProvider.TypeWhereGetConstructorsRaisesException' member 'GetConstructors': The type provider 'Provider.EvilProvider' reported an error: deliberate error for testing purposes
-neg1.fsx(25,39,25,78): typecheck error FS0039: The type 'TypeWhereGetConstructorsRaisesException' is not defined
+neg1.fsx(25,39,25,78): typecheck error FS0039: The type 'TypeWhereGetConstructorsRaisesException' is not defined in 'FSharp.EvilProvider'.
+
+Maybe you want one of the following:
+
+ TypeWhereGetNestedTypesRaisesException
+
+ IsGenericTypeRaisesException
+
+ IsArrayTypeRaisesException
+
+ IsGenericTypeReturnsTrue
+
+ IsArrayTypeReturnsTrue
neg1.fsx(25,39,25,78): typecheck error FS3021: Unexpected exception from provided type 'FSharp.EvilProvider.TypeWhereGetConstructorsRaisesException' member 'GetConstructors': The type provider 'Provider.EvilProvider' reported an error: deliberate error for testing purposes
@@ -310,7 +522,19 @@ neg1.fsx(25,39,25,78): typecheck error FS3021: Unexpected exception from provide
neg1.fsx(25,39,25,78): typecheck error FS3021: Unexpected exception from provided type 'FSharp.EvilProvider.TypeWhereGetConstructorsRaisesException' member 'GetConstructors': The type provider 'Provider.EvilProvider' reported an error: deliberate error for testing purposes
-neg1.fsx(25,39,25,78): typecheck error FS0039: The type 'TypeWhereGetConstructorsRaisesException' is not defined
+neg1.fsx(25,39,25,78): typecheck error FS0039: The type 'TypeWhereGetConstructorsRaisesException' is not defined in 'FSharp.EvilProvider'.
+
+Maybe you want one of the following:
+
+ TypeWhereGetNestedTypesRaisesException
+
+ IsGenericTypeRaisesException
+
+ IsArrayTypeRaisesException
+
+ IsGenericTypeReturnsTrue
+
+ IsArrayTypeReturnsTrue
neg1.fsx(27,39,27,69): typecheck error FS3021: Unexpected exception from provided type 'FSharp.EvilProvider.TypeWhereGetMethodsReturnsNull' member 'GetMethods': The type provider 'Provider.EvilProvider' reported an error: The type provider returned 'null', which is not a valid return value from 'GetMethods'
@@ -320,7 +544,19 @@ neg1.fsx(27,39,27,69): typecheck error FS3021: Unexpected exception from provide
neg1.fsx(27,39,27,69): typecheck error FS3021: Unexpected exception from provided type 'FSharp.EvilProvider.TypeWhereGetMethodsReturnsNull' member 'GetMethods': The type provider 'Provider.EvilProvider' reported an error: The type provider returned 'null', which is not a valid return value from 'GetMethods'
-neg1.fsx(27,39,27,69): typecheck error FS0039: The type 'TypeWhereGetMethodsReturnsNull' is not defined
+neg1.fsx(27,39,27,69): typecheck error FS0039: The type 'TypeWhereGetMethodsReturnsNull' is not defined in 'FSharp.EvilProvider'.
+
+Maybe you want one of the following:
+
+ IsGenericTypeReturnsTrue
+
+ IsArrayTypeReturnsTrue
+
+ TypeWhereGetNestedTypesRaisesException
+
+ IsGenericTypeRaisesException
+
+ TheType
neg1.fsx(27,39,27,69): typecheck error FS3021: Unexpected exception from provided type 'FSharp.EvilProvider.TypeWhereGetMethodsReturnsNull' member 'GetMethods': The type provider 'Provider.EvilProvider' reported an error: The type provider returned 'null', which is not a valid return value from 'GetMethods'
@@ -330,7 +566,19 @@ neg1.fsx(27,39,27,69): typecheck error FS3021: Unexpected exception from provide
neg1.fsx(27,39,27,69): typecheck error FS3021: Unexpected exception from provided type 'FSharp.EvilProvider.TypeWhereGetMethodsReturnsNull' member 'GetMethods': The type provider 'Provider.EvilProvider' reported an error: The type provider returned 'null', which is not a valid return value from 'GetMethods'
-neg1.fsx(27,39,27,69): typecheck error FS0039: The type 'TypeWhereGetMethodsReturnsNull' is not defined
+neg1.fsx(27,39,27,69): typecheck error FS0039: The type 'TypeWhereGetMethodsReturnsNull' is not defined in 'FSharp.EvilProvider'.
+
+Maybe you want one of the following:
+
+ IsGenericTypeReturnsTrue
+
+ IsArrayTypeReturnsTrue
+
+ TypeWhereGetNestedTypesRaisesException
+
+ IsGenericTypeRaisesException
+
+ TheType
neg1.fsx(28,39,28,68): typecheck error FS3021: Unexpected exception from provided type 'FSharp.EvilProvider.TypeWhereGetEventsReturnsNull' member 'GetEvents': The type provider 'Provider.EvilProvider' reported an error: The type provider returned 'null', which is not a valid return value from 'GetEvents'
@@ -340,7 +588,19 @@ neg1.fsx(28,39,28,68): typecheck error FS3021: Unexpected exception from provide
neg1.fsx(28,39,28,68): typecheck error FS3021: Unexpected exception from provided type 'FSharp.EvilProvider.TypeWhereGetEventsReturnsNull' member 'GetEvents': The type provider 'Provider.EvilProvider' reported an error: The type provider returned 'null', which is not a valid return value from 'GetEvents'
-neg1.fsx(28,39,28,68): typecheck error FS0039: The type 'TypeWhereGetEventsReturnsNull' is not defined
+neg1.fsx(28,39,28,68): typecheck error FS0039: The type 'TypeWhereGetEventsReturnsNull' is not defined in 'FSharp.EvilProvider'.
+
+Maybe you want one of the following:
+
+ IsGenericTypeReturnsTrue
+
+ IsArrayTypeReturnsTrue
+
+ TypeWhereGetNestedTypesRaisesException
+
+ IsGenericTypeRaisesException
+
+ TheType
neg1.fsx(28,39,28,68): typecheck error FS3021: Unexpected exception from provided type 'FSharp.EvilProvider.TypeWhereGetEventsReturnsNull' member 'GetEvents': The type provider 'Provider.EvilProvider' reported an error: The type provider returned 'null', which is not a valid return value from 'GetEvents'
@@ -350,7 +610,19 @@ neg1.fsx(28,39,28,68): typecheck error FS3021: Unexpected exception from provide
neg1.fsx(28,39,28,68): typecheck error FS3021: Unexpected exception from provided type 'FSharp.EvilProvider.TypeWhereGetEventsReturnsNull' member 'GetEvents': The type provider 'Provider.EvilProvider' reported an error: The type provider returned 'null', which is not a valid return value from 'GetEvents'
-neg1.fsx(28,39,28,68): typecheck error FS0039: The type 'TypeWhereGetEventsReturnsNull' is not defined
+neg1.fsx(28,39,28,68): typecheck error FS0039: The type 'TypeWhereGetEventsReturnsNull' is not defined in 'FSharp.EvilProvider'.
+
+Maybe you want one of the following:
+
+ IsGenericTypeReturnsTrue
+
+ IsArrayTypeReturnsTrue
+
+ TypeWhereGetNestedTypesRaisesException
+
+ IsGenericTypeRaisesException
+
+ TheType
neg1.fsx(29,39,29,68): typecheck error FS3021: Unexpected exception from provided type 'FSharp.EvilProvider.TypeWhereGetFieldsReturnsNull' member 'GetFields': The type provider 'Provider.EvilProvider' reported an error: The type provider returned 'null', which is not a valid return value from 'GetFields'
@@ -360,7 +632,19 @@ neg1.fsx(29,39,29,68): typecheck error FS3021: Unexpected exception from provide
neg1.fsx(29,39,29,68): typecheck error FS3021: Unexpected exception from provided type 'FSharp.EvilProvider.TypeWhereGetFieldsReturnsNull' member 'GetFields': The type provider 'Provider.EvilProvider' reported an error: The type provider returned 'null', which is not a valid return value from 'GetFields'
-neg1.fsx(29,39,29,68): typecheck error FS0039: The type 'TypeWhereGetFieldsReturnsNull' is not defined
+neg1.fsx(29,39,29,68): typecheck error FS0039: The type 'TypeWhereGetFieldsReturnsNull' is not defined in 'FSharp.EvilProvider'.
+
+Maybe you want one of the following:
+
+ IsGenericTypeReturnsTrue
+
+ IsArrayTypeReturnsTrue
+
+ TypeWhereGetNestedTypesRaisesException
+
+ IsArrayTypeRaisesException
+
+ IsGenericTypeRaisesException
neg1.fsx(29,39,29,68): typecheck error FS3021: Unexpected exception from provided type 'FSharp.EvilProvider.TypeWhereGetFieldsReturnsNull' member 'GetFields': The type provider 'Provider.EvilProvider' reported an error: The type provider returned 'null', which is not a valid return value from 'GetFields'
@@ -370,7 +654,19 @@ neg1.fsx(29,39,29,68): typecheck error FS3021: Unexpected exception from provide
neg1.fsx(29,39,29,68): typecheck error FS3021: Unexpected exception from provided type 'FSharp.EvilProvider.TypeWhereGetFieldsReturnsNull' member 'GetFields': The type provider 'Provider.EvilProvider' reported an error: The type provider returned 'null', which is not a valid return value from 'GetFields'
-neg1.fsx(29,39,29,68): typecheck error FS0039: The type 'TypeWhereGetFieldsReturnsNull' is not defined
+neg1.fsx(29,39,29,68): typecheck error FS0039: The type 'TypeWhereGetFieldsReturnsNull' is not defined in 'FSharp.EvilProvider'.
+
+Maybe you want one of the following:
+
+ IsGenericTypeReturnsTrue
+
+ IsArrayTypeReturnsTrue
+
+ TypeWhereGetNestedTypesRaisesException
+
+ IsArrayTypeRaisesException
+
+ IsGenericTypeRaisesException
neg1.fsx(30,39,30,72): typecheck error FS3021: Unexpected exception from provided type 'FSharp.EvilProvider.TypeWhereGetPropertiesReturnsNull' member 'GetProperties': The type provider 'Provider.EvilProvider' reported an error: The type provider returned 'null', which is not a valid return value from 'GetProperties'
@@ -380,7 +676,19 @@ neg1.fsx(30,39,30,72): typecheck error FS3021: Unexpected exception from provide
neg1.fsx(30,39,30,72): typecheck error FS3021: Unexpected exception from provided type 'FSharp.EvilProvider.TypeWhereGetPropertiesReturnsNull' member 'GetProperties': The type provider 'Provider.EvilProvider' reported an error: The type provider returned 'null', which is not a valid return value from 'GetProperties'
-neg1.fsx(30,39,30,72): typecheck error FS0039: The type 'TypeWhereGetPropertiesReturnsNull' is not defined
+neg1.fsx(30,39,30,72): typecheck error FS0039: The type 'TypeWhereGetPropertiesReturnsNull' is not defined in 'FSharp.EvilProvider'.
+
+Maybe you want one of the following:
+
+ IsGenericTypeReturnsTrue
+
+ TypeWhereGetNestedTypesRaisesException
+
+ IsArrayTypeReturnsTrue
+
+ IsGenericTypeRaisesException
+
+ IsArrayTypeRaisesException
neg1.fsx(30,39,30,72): typecheck error FS3021: Unexpected exception from provided type 'FSharp.EvilProvider.TypeWhereGetPropertiesReturnsNull' member 'GetProperties': The type provider 'Provider.EvilProvider' reported an error: The type provider returned 'null', which is not a valid return value from 'GetProperties'
@@ -390,7 +698,19 @@ neg1.fsx(30,39,30,72): typecheck error FS3021: Unexpected exception from provide
neg1.fsx(30,39,30,72): typecheck error FS3021: Unexpected exception from provided type 'FSharp.EvilProvider.TypeWhereGetPropertiesReturnsNull' member 'GetProperties': The type provider 'Provider.EvilProvider' reported an error: The type provider returned 'null', which is not a valid return value from 'GetProperties'
-neg1.fsx(30,39,30,72): typecheck error FS0039: The type 'TypeWhereGetPropertiesReturnsNull' is not defined
+neg1.fsx(30,39,30,72): typecheck error FS0039: The type 'TypeWhereGetPropertiesReturnsNull' is not defined in 'FSharp.EvilProvider'.
+
+Maybe you want one of the following:
+
+ IsGenericTypeReturnsTrue
+
+ TypeWhereGetNestedTypesRaisesException
+
+ IsArrayTypeReturnsTrue
+
+ IsGenericTypeRaisesException
+
+ IsArrayTypeRaisesException
neg1.fsx(31,39,31,73): typecheck error FS3004: The provided type 'FSharp.EvilProvider.TypeWhereGetNestedTypesReturnsNull' has member 'Boo' which has declaring type 'FSharp.EvilProvider.TheType'. Expected declaring type to be the same as provided type.
@@ -404,7 +724,19 @@ neg1.fsx(32,39,32,74): typecheck error FS3021: Unexpected exception from provide
neg1.fsx(32,39,32,74): typecheck error FS3021: Unexpected exception from provided type 'FSharp.EvilProvider.TypeWhereGetConstructorsReturnsNull' member 'GetConstructors': The type provider 'Provider.EvilProvider' reported an error: The type provider returned 'null', which is not a valid return value from 'GetConstructors'
-neg1.fsx(32,39,32,74): typecheck error FS0039: The type 'TypeWhereGetConstructorsReturnsNull' is not defined
+neg1.fsx(32,39,32,74): typecheck error FS0039: The type 'TypeWhereGetConstructorsReturnsNull' is not defined in 'FSharp.EvilProvider'.
+
+Maybe you want one of the following:
+
+ TypeWhereGetNestedTypesReturnsNull
+
+ TypeWhereGetNestedTypesRaisesException
+
+ IsGenericTypeReturnsTrue
+
+ IsArrayTypeReturnsTrue
+
+ IsGenericTypeRaisesException
neg1.fsx(32,39,32,74): typecheck error FS3021: Unexpected exception from provided type 'FSharp.EvilProvider.TypeWhereGetConstructorsReturnsNull' member 'GetConstructors': The type provider 'Provider.EvilProvider' reported an error: The type provider returned 'null', which is not a valid return value from 'GetConstructors'
@@ -414,7 +746,19 @@ neg1.fsx(32,39,32,74): typecheck error FS3021: Unexpected exception from provide
neg1.fsx(32,39,32,74): typecheck error FS3021: Unexpected exception from provided type 'FSharp.EvilProvider.TypeWhereGetConstructorsReturnsNull' member 'GetConstructors': The type provider 'Provider.EvilProvider' reported an error: The type provider returned 'null', which is not a valid return value from 'GetConstructors'
-neg1.fsx(32,39,32,74): typecheck error FS0039: The type 'TypeWhereGetConstructorsReturnsNull' is not defined
+neg1.fsx(32,39,32,74): typecheck error FS0039: The type 'TypeWhereGetConstructorsReturnsNull' is not defined in 'FSharp.EvilProvider'.
+
+Maybe you want one of the following:
+
+ TypeWhereGetNestedTypesReturnsNull
+
+ TypeWhereGetNestedTypesRaisesException
+
+ IsGenericTypeReturnsTrue
+
+ IsArrayTypeReturnsTrue
+
+ IsGenericTypeRaisesException
neg1.fsx(33,39,33,72): typecheck error FS3042: Unexpected 'null' return value from provided type 'FSharp.EvilProvider.TypeWhereGetInterfacesReturnsNull' member 'GetInterfaces'
diff --git a/tests/fsharp/typecheck/sigs/neg07.bsl b/tests/fsharp/typecheck/sigs/neg07.bsl
index 4551e7a9487..a040fd5bc56 100644
--- a/tests/fsharp/typecheck/sigs/neg07.bsl
+++ b/tests/fsharp/typecheck/sigs/neg07.bsl
@@ -19,9 +19,9 @@ neg07.fs(36,11,36,21): typecheck error FS0049: Uppercase variable identifiers sh
neg07.fs(36,11,36,21): typecheck error FS0026: This rule will never be matched
-neg07.fs(46,15,46,27): typecheck error FS0039: The record label 'RecordLabel1' is not defined
+neg07.fs(46,15,46,27): typecheck error FS0039: The record label 'RecordLabel1' is not defined.
-neg07.fs(47,19,47,31): typecheck error FS0039: The record label 'RecordLabel1' is not defined
+neg07.fs(47,19,47,31): typecheck error FS0039: The record label 'RecordLabel1' is not defined.
neg07.fs(57,10,57,17): typecheck error FS1196: The 'UseNullAsTrueValue' attribute flag may only be used with union types that have one nullary case and at least one non-nullary case
diff --git a/tests/fsharp/typecheck/sigs/neg17.bsl b/tests/fsharp/typecheck/sigs/neg17.bsl
index 66590123741..a74ee616628 100644
--- a/tests/fsharp/typecheck/sigs/neg17.bsl
+++ b/tests/fsharp/typecheck/sigs/neg17.bsl
@@ -27,10 +27,34 @@ neg17b.fs(29,31,29,61): typecheck error FS0072: Lookup on object of indeterminat
neg17b.fs(30,31,30,84): typecheck error FS0072: Lookup on object of indeterminate type based on information prior to this program point. A type annotation may be needed prior to this program point to constrain the type of the object. This may allow the lookup to be resolved.
-neg17b.fs(32,24,32,50): typecheck error FS0039: The type 'RecordTypeWithPrivateField' is not defined
+neg17b.fs(32,24,32,50): typecheck error FS0039: The type 'RecordTypeWithPrivateField' is not defined in 'Neg17.M'.
+
+Maybe you want one of the following:
+
+ RecordTypeWithPrivateRepresentation
+
+ UnionTypeWithPrivateRepresentation
+
+ InternalRecordType
+
+ PrivateRecordType
+
+ PrivateUnionType
neg17b.fs(43,30,43,60): typecheck error FS0072: Lookup on object of indeterminate type based on information prior to this program point. A type annotation may be needed prior to this program point to constrain the type of the object. This may allow the lookup to be resolved.
-neg17b.fs(45,23,45,49): typecheck error FS0039: The type 'RecordTypeWithPrivateField' is not defined
+neg17b.fs(45,23,45,49): typecheck error FS0039: The type 'RecordTypeWithPrivateField' is not defined in 'Neg17.M'.
+
+Maybe you want one of the following:
+
+ RecordTypeWithPrivateRepresentation
+
+ UnionTypeWithPrivateRepresentation
+
+ InternalRecordType
+
+ PrivateRecordType
+
+ PrivateUnionType
neg17b.fs(54,20,54,50): typecheck error FS0072: Lookup on object of indeterminate type based on information prior to this program point. A type annotation may be needed prior to this program point to constrain the type of the object. This may allow the lookup to be resolved.
diff --git a/tests/fsharpqa/Source/Conformance/InferenceProcedures/NameResolution/RequireQualifiedAccess/E_OnRecord.fs b/tests/fsharpqa/Source/Conformance/InferenceProcedures/NameResolution/RequireQualifiedAccess/E_OnRecord.fs
index 85282204720..fa7973cdf0d 100644
--- a/tests/fsharpqa/Source/Conformance/InferenceProcedures/NameResolution/RequireQualifiedAccess/E_OnRecord.fs
+++ b/tests/fsharpqa/Source/Conformance/InferenceProcedures/NameResolution/RequireQualifiedAccess/E_OnRecord.fs
@@ -2,8 +2,8 @@
// Verify error when not fully qualifying a record field when it
// has the RequireQualifiedAccess attribute.
-//The record label 'Field1' is not defined$
-//The record label 'Field1' is not defined$
+//The record label 'Field1' is not defined\.$
+//The record label 'Field1' is not defined\.$
[]
type R = { Field1 : int; Field2 : string }
diff --git a/tests/fsharpqa/Source/Conformance/PatternMatching/Record/E_RecTypesNotMatch01.fs b/tests/fsharpqa/Source/Conformance/PatternMatching/Record/E_RecTypesNotMatch01.fs
index fb7527d54ce..9297cb34285 100644
--- a/tests/fsharpqa/Source/Conformance/PatternMatching/Record/E_RecTypesNotMatch01.fs
+++ b/tests/fsharpqa/Source/Conformance/PatternMatching/Record/E_RecTypesNotMatch01.fs
@@ -1,7 +1,7 @@
// #Regression #Conformance #PatternMatching #Records
// Verify error if two record types in a pattern match don't match
// Verify error if type of a record field is incorrect.
-//The type 'R1' does not contain a field 'A'
+//The record type 'R1' does not contain a label 'A'\.
type R1 = { X : int; Y : int }
diff --git a/tests/fsharpqa/Source/Diagnostics/General/E_matrix_LetBinding01.fs b/tests/fsharpqa/Source/Diagnostics/General/E_matrix_LetBinding01.fs
index 63af47e7f92..86fd6bc7b85 100644
--- a/tests/fsharpqa/Source/Diagnostics/General/E_matrix_LetBinding01.fs
+++ b/tests/fsharpqa/Source/Diagnostics/General/E_matrix_LetBinding01.fs
@@ -1,6 +1,6 @@
// #Regression #Diagnostics
// Regression test for FSHARP1.0:3175
-//The type 'matrix' is not defined$
+//The type 'matrix' is not defined in 'Microsoft.FSharp.Math'\.$
let f ( m : Math.matrix) = 12
diff --git a/tests/fsharpqa/Source/Diagnostics/General/E_matrix_class01.fs b/tests/fsharpqa/Source/Diagnostics/General/E_matrix_class01.fs
index afa10b64e17..806c444041d 100644
--- a/tests/fsharpqa/Source/Diagnostics/General/E_matrix_class01.fs
+++ b/tests/fsharpqa/Source/Diagnostics/General/E_matrix_class01.fs
@@ -1,6 +1,6 @@
// #Regression #Diagnostics
// Regression test for FSHARP1.0:3175
-//The type 'matrix' is not defined$
+//The type 'matrix' is not defined in 'Microsoft.FSharp.Math'\.$
type C = class
diff --git a/tests/fsharpqa/Source/Diagnostics/General/E_matrix_interface01.fs b/tests/fsharpqa/Source/Diagnostics/General/E_matrix_interface01.fs
index eb6df520402..59b2c81ed70 100644
--- a/tests/fsharpqa/Source/Diagnostics/General/E_matrix_interface01.fs
+++ b/tests/fsharpqa/Source/Diagnostics/General/E_matrix_interface01.fs
@@ -1,7 +1,7 @@
// #Regression #Diagnostics
// Regression test for FSHARP1.0:3175
-//The type 'matrix' is not defined$
-//The type 'matrix' is not defined$
+//The type 'matrix' is not defined in 'Microsoft.FSharp.Math'\.$
+//The type 'matrix' is not defined in 'Microsoft.FSharp.Math'\.$
type I = interface
diff --git a/tests/fsharpqa/Source/Diagnostics/General/E_matrix_struct01.fs b/tests/fsharpqa/Source/Diagnostics/General/E_matrix_struct01.fs
index e9938175d2a..b7b48288559 100644
--- a/tests/fsharpqa/Source/Diagnostics/General/E_matrix_struct01.fs
+++ b/tests/fsharpqa/Source/Diagnostics/General/E_matrix_struct01.fs
@@ -1,6 +1,6 @@
// #Regression #Diagnostics
// Regression test for FSHARP1.0:3175
-//The type 'matrix' is not defined$
+//The type 'matrix' is not defined in 'Microsoft.FSharp.Math'\.$
type S = struct
val a : Math.matrix
diff --git a/tests/fsharpqa/Source/ErrorMessages/NameResolution/E_FieldNotInRecord.fs b/tests/fsharpqa/Source/ErrorMessages/NameResolution/E_FieldNotInRecord.fs
new file mode 100644
index 00000000000..4a5361f8f67
--- /dev/null
+++ b/tests/fsharpqa/Source/ErrorMessages/NameResolution/E_FieldNotInRecord.fs
@@ -0,0 +1,13 @@
+// #ErrorMessages #NameResolution
+//The record type 'F' does not contain a label 'Wall'\.
+
+type A = { Hello:string; World:string }
+type B = { Size:int; Height:int }
+type C = { Wheels:int }
+type D = { Size:int; Height:int; Walls:int }
+type E = { Unknown:string }
+type F = { Wallis:int; Size:int; Height:int; }
+
+let r:F = { Size=3; Height=4; Wall=1 }
+
+exit 0
diff --git a/tests/fsharpqa/Source/ErrorMessages/NameResolution/E_RecordFieldProposal.fs b/tests/fsharpqa/Source/ErrorMessages/NameResolution/E_RecordFieldProposal.fs
new file mode 100644
index 00000000000..ca73d5c1e54
--- /dev/null
+++ b/tests/fsharpqa/Source/ErrorMessages/NameResolution/E_RecordFieldProposal.fs
@@ -0,0 +1,13 @@
+// #ErrorMessages #NameResolution
+//The record label 'Wall' is not defined\.
+
+type A = { Hello:string; World:string }
+type B = { Size:int; Height:int }
+type C = { Wheels:int }
+type D = { Size:int; Height:int; Walls:int }
+type E = { Unknown:string }
+type F = { Wallis:int; Size:int; Height:int; }
+
+let r = { Size=3; Height=4; Wall=1 }
+
+exit 0
diff --git a/tests/fsharpqa/Source/ErrorMessages/NameResolution/env.lst b/tests/fsharpqa/Source/ErrorMessages/NameResolution/env.lst
new file mode 100644
index 00000000000..435fb96c42b
--- /dev/null
+++ b/tests/fsharpqa/Source/ErrorMessages/NameResolution/env.lst
@@ -0,0 +1,2 @@
+ SOURCE=E_RecordFieldProposal.fs # E_RecordFieldProposal
+ SOURCE=E_FieldNotInRecord.fs # E_FieldNotInRecord
\ No newline at end of file
diff --git a/tests/fsharpqa/Source/test.lst b/tests/fsharpqa/Source/test.lst
index 5072d02cac3..b9391dc0801 100644
--- a/tests/fsharpqa/Source/test.lst
+++ b/tests/fsharpqa/Source/test.lst
@@ -258,6 +258,7 @@ Misc01 Libraries\Core\Operators
Misc01 Libraries\Core\Reflection
Misc01 Libraries\Core\Unchecked
Misc01 Warnings
+Misc01 ErrorMessages\NameResolution
Misc02 Libraries\Portable
Misc02 Misc