Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit58669ae

Browse files
forkilatkin
authored andcommitted
Show warning when Record is accessed without type but RequireQualifiedAccess was set - relates todotnet#95
closesdotnet#137
1 parent7bf8158 commit58669ae

File tree

6 files changed

+41
-15
lines changed

6 files changed

+41
-15
lines changed

‎src/fsharp/FSComp.txt‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1022,7 +1022,8 @@ lexfltSeparatorTokensOfPatternMatchMisaligned,"The '|' tokens separating rules o
10221022
1130,nrInvalidFieldLabel,"Invalid field label"
10231023
1132,nrInvalidExpression,"Invalid expression '%s'"
10241024
1133,nrNoConstructorsAvailableForType,"No constructors are available for the type '%s'"
1025-
1134,nrUnionTypeNeedsQualifiedAccess,"The union type for union case '%s' was defined with the RequireQualifiedAccessAttribute. Include the name of the union type ('%s') in the name you are using.""
1025+
1134,nrUnionTypeNeedsQualifiedAccess,"The union type for union case '%s' was defined with the RequireQualifiedAccessAttribute. Include the name of the union type ('%s') in the name you are using."
1026+
1135,nrRecordTypeNeedsQualifiedAccess,"The record type for the record field '%s' was defined with the RequireQualifiedAccessAttribute. Include the name of the record type ('%s') in the name you are using."
10261027
# -----------------------------------------------------------------------------
10271028
# ilwrite.fs errors
10281029
# -----------------------------------------------------------------------------

‎src/fsharp/nameres.fs‎

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,9 @@ let valRefHash (vref: ValRef) =
221221
| None->0
222222
| Some v-> LanguagePrimitives.PhysicalHash v
223223

224+
/// Represents a record field resolution and the information if the usage is deprecated.
225+
typeFieldResolution= FieldResolutionofRecdFieldRef*bool
226+
224227
/// Information about an extension member held in the name resolution environment
225228
typeExtensionMember=
226229

@@ -2144,7 +2147,8 @@ let rec ResolveFieldInModuleOrNamespace (ncenv:NameResolver) nenv ad (resInfo:Re
21442147
letmodulScopedFieldNames=
21452148
match TryFindTypeWithRecdField modref idwith
21462149
| Some tyconwhen IsEntityAccessible ncenv.amap m ad(modref.MkNestedTyconRef tycon)->
2147-
success(modref.MkNestedRecdFieldRef tycon id, rest)
2150+
letshowDeprecated= HasFSharpAttribute ncenv.g ncenv.g.attrib_RequireQualifiedAccessAttribute tycon.Attribs
2151+
success(FieldResolution(modref.MkNestedRecdFieldRef tycon id,showDeprecated), rest)
21482152
|_-> error
21492153
// search for type-qualified names, e.g. { Microsoft.FSharp.Core.Ref.contents = 1 }
21502154
lettyconSearch=
@@ -2154,7 +2158,7 @@ let rec ResolveFieldInModuleOrNamespace (ncenv:NameResolver) nenv ad (resInfo:Re
21542158
lettcrefs= tcrefs|> List.map(fun tcref->(ResolutionInfo.Empty,tcref))
21552159
lettyconSearch= ResolveLongIdentInTyconRefs ncenv nenv LookupKind.RecdField(depth+1) m ad rest typeNameResInfo id.idRange tcrefs
21562160
// choose only fields
2157-
lettyconSearch= tyconSearch|?> List.choose(function(_,Item.RecdField(RecdFieldInfo(_,rfref)),rest)-> Some(rfref,rest)|_-> None)
2161+
lettyconSearch= tyconSearch|?> List.choose(function(_,Item.RecdField(RecdFieldInfo(_,rfref)),rest)-> Some(FieldResolution(rfref,false),rest)|_-> None)
21582162
tyconSearch
21592163
|_->
21602164
NoResultsOrUsefulErrors
@@ -2181,15 +2185,16 @@ let ResolveField (ncenv:NameResolver) nenv ad typ (mp,id:Ident) =
21812185
|[]->
21822186
if isAppTy g typthen
21832187
match ncenv.InfoReader.TryFindRecdOrClassFieldInfoOfType(id.idText,m,typ)with
2184-
| Some(RecdFieldInfo(_,rfref))->[rfref]
2188+
| Some(RecdFieldInfo(_,rfref))->[FieldResolution(rfref,false)]
21852189
| None-> error(Error(FSComp.SR.nrTypeDoesNotContainSuchField((NicePrint.minimalStringOfType nenv.eDisplayEnv typ), id.idText),m))
21862190
else
21872191
letfrefs=
21882192
try Map.find id.idText nenv.eFieldLabels
21892193
with:? KeyNotFoundException-> error(UndefinedName(0,FSComp.SR.undefinedNameRecordLabel,id,NameMap.domainL nenv.eFieldLabels))
21902194
// Eliminate duplicates arising from multiple 'open'
2191-
letfrefs= frefs|> ListSet.setify(fun fref1 fref2-> tyconRefEq g fref1.TyconRef fref2.TyconRef)
2192-
frefs
2195+
frefs
2196+
|> ListSet.setify(fun fref1 fref2-> tyconRefEq g fref1.TyconRef fref2.TyconRef)
2197+
|> List.map(fun x-> FieldResolution(x,false))
21932198

21942199
|_->
21952200
letlid=(mp@[id])
@@ -2201,7 +2206,7 @@ let ResolveField (ncenv:NameResolver) nenv ad typ (mp,id:Ident) =
22012206
lettcrefs= tcrefs|> List.map(fun tcref->(ResolutionInfo.Empty,tcref))
22022207
lettyconSearch= ResolveLongIdentInTyconRefs ncenv nenv LookupKind.RecdField1 m ad rest typeNameResInfo tn.idRange tcrefs
22032208
// choose only fields
2204-
lettyconSearch= tyconSearch|?> List.choose(function(_,Item.RecdField(RecdFieldInfo(_,rfref)),rest)-> Some(rfref,rest)|_-> None)
2209+
lettyconSearch= tyconSearch|?> List.choose(function(_,Item.RecdField(RecdFieldInfo(_,rfref)),rest)-> Some(FieldResolution(rfref,false),rest)|_-> None)
22052210
tyconSearch
22062211
|_-> NoResultsOrUsefulErrors
22072212
letmodulSearch ad=

‎src/fsharp/nameres.fsi‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ type Item =
6868
| UnqualifiedTypeofTyconReflist
6969
memberDisplayName:TcGlobals->string
7070

71+
/// Represents a record field resolution and the information if the usage is deprecated.
72+
type FieldResolution= FieldResolutionofRecdFieldRef*bool
7173

7274
/// Information about an extension member held in the name resolution environment
7375
[<Sealed>]
@@ -263,7 +265,7 @@ val internal ResolveTypeLongIdentInTyconRef : TcResultsSink -> NameResol
263265
val internal ResolveTypeLongIdent: TcResultsSink-> NameResolver-> ItemOccurence-> FullyQualifiedFlag-> NameResolutionEnv-> AccessorDomain-> Ident list-> TypeNameResolutionStaticArgsInfo-> PermitDirectReferenceToGeneratedType-> ResultOrException<TyconRef>
264266

265267
/// Resolve a long identifier to a field
266-
val internal ResolveField: NameResolver-> NameResolutionEnv-> AccessorDomain-> TType-> Ident list* Ident->RecdFieldRef list
268+
val internal ResolveField: NameResolver-> NameResolutionEnv-> AccessorDomain-> TType-> Ident list* Ident->FieldResolution list
267269

268270
/// Resolve a long identifier occurring in an expression position
269271
val internal ResolveExprLongIdent: TcResultsSink-> NameResolver-> range-> AccessorDomain-> NameResolutionEnv-> TypeNameResolutionInfo-> Ident list-> Item* Ident list

‎src/fsharp/tc.fs‎

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1828,7 +1828,7 @@ let BuildFieldMap cenv env isPartial ty flds m =
18281828
let frefSet = ResolveField cenv.nameResolver env.eNameResEnv ad ty fld
18291829
fld,frefSet, fldExpr)
18301830
let relevantTypeSets =
1831-
frefSets |> List.map (fun (_,frefSet,_) -> frefSet |> List.choose (fun rfref -> Some rfref.TyconRef))
1831+
frefSets |> List.map (fun (_,frefSet,_) -> frefSet |> List.choose (fun(FieldResolution(rfref,_)) -> Some rfref.TyconRef))
18321832

18331833
let tcref =
18341834
match List.fold (ListSet.intersect (tyconRefEq cenv.g)) (List.head relevantTypeSets) (List.tail relevantTypeSets) with
@@ -1840,13 +1840,13 @@ let BuildFieldMap cenv env isPartial ty flds m =
18401840
// We're going to get an error of some kind below.
18411841
// Just choose one field ref and let the error come later
18421842
let (_,frefSet1,_) = List.head frefSets
1843-
let fref1= List.head frefSet1
1843+
let(FieldResolution(fref1,_))= List.head frefSet1
18441844
fref1.TyconRef
18451845

18461846
let fldsmap,rfldsList =
18471847
((Map.empty,[]), frefSets) ||> List.fold (fun (fs,rfldsList) (fld,frefs,fldExpr) ->
1848-
match frefs |> List.filter (fun fref2 -> tyconRefEq cenv.g tcref fref2.TyconRef) with
1849-
| [fref2] ->
1848+
match frefs |> List.filter (fun(FieldResolution(fref2,_)) -> tyconRefEq cenv.g tcref fref2.TyconRef) with
1849+
| [FieldResolution(fref2,showDeprecated)] ->
18501850

18511851
// Record the precise resolution of the field for intellisense
18521852
let item = FreshenRecdFieldRef cenv.nameResolver m fref2
@@ -1856,9 +1856,12 @@ let BuildFieldMap cenv env isPartial ty flds m =
18561856
CheckFSharpAttributes cenv.g fref2.PropertyAttribs m |> CommitOperationResult
18571857
if Map.containsKey fref2.FieldName fs then
18581858
errorR (Error(FSComp.SR.tcFieldAppearsTwiceInRecord(fref2.FieldName),m))
1859+
if showDeprecated then
1860+
warning(Deprecated(FSComp.SR.nrRecordTypeNeedsQualifiedAccess(fref2.FieldName,fref2.Tycon.DisplayName) |> snd,m))
1861+
18591862
if not (tyconRefEq cenv.g tcref fref2.TyconRef) then
18601863
let (_,frefSet1,_) = List.head frefSets
1861-
let fref1 = List.head frefSet1
1864+
let(FieldResolution(fref1,_)) = List.head frefSet1
18621865
errorR (FieldsFromDifferentTypes(env.DisplayEnv,fref1,fref2,m))
18631866
(fs,rfldsList)
18641867
else (Map.add fref2.FieldName fldExpr fs,

‎tests/fsharp/typecheck/sigs/neg90.bsl‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,6 @@ neg90.fs(7,22,7,25): typecheck error FS0039: The type 'foo' is not defined
55

66
neg90.fs(7,22,7,25): typecheck error FS0039: The type 'foo' isnot defined
77

8-
neg90.fs(16,9,16,21): typecheck error FS0035: This construct is deprecated: The union typefor union case 'Member' was defined with the RequireQualifiedAccessAttribute. Include the name of the uniontype('DU')in the name you are using.'
8+
neg90.fs(16,9,16,21): typecheck error FS0035: This construct is deprecated: The union typefor union case 'Member' was defined with the RequireQualifiedAccessAttribute. Include the name of the uniontype('DU')in the name you are using.
9+
10+
neg90.fs(28,9,28,41): typecheck error FS0035: This construct is deprecated: The record typefor the record field 'Field1' was defined with the RequireQualifiedAccessAttribute. Include the name of the recordtype('Record1')in the name you are using.

‎tests/fsharp/typecheck/sigs/neg90.fs‎

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,17 @@ module First =
1313
[<RequireQualifiedAccess>]
1414
typeDU= Memberofint
1515

16-
let_= First.Member(0)
16+
let_= First.Member(0)// compiles, but should not
17+
let_= First.DU.Member(0)// correct
18+
19+
// See https://github.com/Microsoft/visualfsharp/issues/95 - part 2
20+
moduleModuleWithRecord=
21+
[<RequireQualifiedAccess>]
22+
typeRecord1={ Field1:int}
23+
24+
let_={ ModuleWithRecord.Record1.Field1=42}// correct
25+
26+
openModuleWithRecord
27+
let_={ Record1.Field1=42}// correct
28+
let_={ ModuleWithRecord.Field1=42}// compiles, but should not
29+
let_={ ModuleWithRecord.Record1.Field1=42}// correct

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp