Skip to content

Commit c8fbed0

Browse files
Account for VolatileAttribute when checking attribute targets (#17595)
* Account for `VolatileAttribute` when checking attribute targets * Update tests * add more tests --------- Co-authored-by: Kevin Ransom (msft) <[email protected]>
1 parent 758f039 commit c8fbed0

File tree

5 files changed

+105
-4
lines changed

5 files changed

+105
-4
lines changed

src/Compiler/Checking/Expressions/CheckExpressions.fs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11086,7 +11086,11 @@ and TcNormalizedBinding declKind (cenv: cenv) env tpenv overallTy safeThisValOpt
1108611086
if not (isNil declaredTypars) then
1108711087
errorR(Error(FSComp.SR.tcLiteralCannotHaveGenericParameters(), mBinding))
1108811088

11089-
if g.langVersion.SupportsFeature(LanguageFeature.EnforceAttributeTargets) && memberFlagsOpt.IsNone && not attrs.IsEmpty then
11089+
let supportEnforceAttributeTargets =
11090+
(g.langVersion.SupportsFeature(LanguageFeature.EnforceAttributeTargets) && memberFlagsOpt.IsNone && not attrs.IsEmpty)
11091+
&& not isVolatile // // VolatileFieldAttribute has a special treatment(specific error FS823)
11092+
11093+
if supportEnforceAttributeTargets then
1109011094
TcAttributeTargetsOnLetBindings { cenv with tcSink = TcResultsSink.NoSink } env attrs overallPatTy overallExprTy (not declaredTypars.IsEmpty) isClassLetBinding
1109111095

1109211096
CheckedBindingInfo(inlineFlag, valAttribs, xmlDoc, tcPatPhase2, explicitTyparInfo, nameToPrelimValSchemeMap, rhsExprChecked, argAndRetAttribs, overallPatTy, mBinding, debugPoint, isCompGen, literalValue, isFixed), tpenv
@@ -11114,7 +11118,7 @@ and TcAttributeTargetsOnLetBindings (cenv: cenv) env attrs overallPatTy overallE
1111411118
else
1111511119
AttributeTargets.ReturnValue ||| AttributeTargets.Field ||| AttributeTargets.Property
1111611120

11117-
TcAttributes cenv env attrTgt attrs |> ignore
11121+
TcAttributesWithPossibleTargets false cenv env attrTgt attrs |> ignore
1111811122

1111911123
and TcLiteral (cenv: cenv) overallTy env tpenv (attrs, synLiteralValExpr) =
1112011124

tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -787,6 +787,62 @@ type InterruptibleLazy<'T> private (valueFactory: unit -> 'T) =
787787
// SOURCE=AllowNullLiteral01.fs # AllowNullLiteral01.fs
788788
[<Theory; Directory(__SOURCE_DIRECTORY__, Includes=[|"AllowNullLiteral01.fs"|])>]
789789
let ``AllowNullLiteral01 preview`` compilation =
790+
compilation
791+
|> withLangVersionPreview
792+
|> verifyCompile
793+
|> shouldSucceed
794+
795+
// SOURCE= E_VolatileField.fs # E_VolatileField.fs
796+
[<Theory; Directory(__SOURCE_DIRECTORY__, Includes=[|"E_VolatileField.fs"|])>]
797+
let ``E_VolatileField 9.0`` compilation =
798+
compilation
799+
|> withLangVersion90
800+
|> verifyCompile
801+
|> shouldFail
802+
|> withDiagnostics [
803+
(Error 823, Line 3, Col 3, Line 4, Col 16, "The 'VolatileField' attribute may only be used on 'let' bindings in classes")
804+
(Error 823, Line 6, Col 3, Line 7, Col 14, "The 'VolatileField' attribute may only be used on 'let' bindings in classes")
805+
(Error 879, Line 6, Col 3, Line 7, Col 14, "Volatile fields must be marked 'mutable' and cannot be thread-static")
806+
(Error 823, Line 9, Col 3, Line 10, Col 9, "The 'VolatileField' attribute may only be used on 'let' bindings in classes")
807+
(Error 879, Line 9, Col 3, Line 10, Col 9, "Volatile fields must be marked 'mutable' and cannot be thread-static")
808+
(Error 823, Line 26, Col 17, Line 26, Col 18, "The 'VolatileField' attribute may only be used on 'let' bindings in classes")
809+
(Error 879, Line 13, Col 5, Line 14, Col 19, "Volatile fields must be marked 'mutable' and cannot be thread-static")
810+
(Error 879, Line 16, Col 5, Line 17, Col 20, "Volatile fields must be marked 'mutable' and cannot be thread-static")
811+
(Error 879, Line 19, Col 5, Line 20, Col 11, "Volatile fields must be marked 'mutable' and cannot be thread-static")
812+
(Error 879, Line 22, Col 5, Line 23, Col 13, "Volatile fields must be marked 'mutable' and cannot be thread-static")
813+
]
814+
815+
// SOURCE=E_VolatileField.fs # E_VolatileField.fs
816+
[<Theory; Directory(__SOURCE_DIRECTORY__, Includes=[|"E_VolatileField.fs"|])>]
817+
let ``E_VolatileField preview`` compilation =
818+
compilation
819+
|> withLangVersionPreview
820+
|> verifyCompile
821+
|> shouldFail
822+
|> withDiagnostics [
823+
(Error 823, Line 3, Col 3, Line 4, Col 16, "The 'VolatileField' attribute may only be used on 'let' bindings in classes")
824+
(Error 823, Line 6, Col 3, Line 7, Col 14, "The 'VolatileField' attribute may only be used on 'let' bindings in classes")
825+
(Error 879, Line 6, Col 3, Line 7, Col 14, "Volatile fields must be marked 'mutable' and cannot be thread-static")
826+
(Error 823, Line 9, Col 3, Line 10, Col 9, "The 'VolatileField' attribute may only be used on 'let' bindings in classes")
827+
(Error 879, Line 9, Col 3, Line 10, Col 9, "Volatile fields must be marked 'mutable' and cannot be thread-static")
828+
(Error 823, Line 26, Col 17, Line 26, Col 18, "The 'VolatileField' attribute may only be used on 'let' bindings in classes")
829+
(Error 879, Line 13, Col 5, Line 14, Col 19, "Volatile fields must be marked 'mutable' and cannot be thread-static")
830+
(Error 879, Line 16, Col 5, Line 17, Col 20, "Volatile fields must be marked 'mutable' and cannot be thread-static")
831+
(Error 879, Line 19, Col 5, Line 20, Col 11, "Volatile fields must be marked 'mutable' and cannot be thread-static")
832+
(Error 879, Line 22, Col 5, Line 23, Col 13, "Volatile fields must be marked 'mutable' and cannot be thread-static")
833+
]
834+
835+
// SOURCE= VolatileField01.fs # VolatileField01.fs
836+
[<Theory; Directory(__SOURCE_DIRECTORY__, Includes=[|"VolatileField01.fs"|])>]
837+
let ``VolatileField01 9.0`` compilation =
838+
compilation
839+
|> withLangVersion90
840+
|> verifyCompile
841+
|> shouldSucceed
842+
843+
// SOURCE=VolatileField01.fs # VolatileField01.fs
844+
[<Theory; Directory(__SOURCE_DIRECTORY__, Includes=[|"VolatileField01.fs"|])>]
845+
let ``VolatileField01 preview`` compilation =
790846
compilation
791847
|> withLangVersionPreview
792848
|> verifyCompile
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
module VolatileFieldSanityChecks = begin
2+
3+
[<VolatileField>]
4+
let mutable x = 1
5+
6+
[<VolatileField>]
7+
let rec f x = 1
8+
9+
[<VolatileField>]
10+
let x2 = 1
11+
12+
type C() =
13+
[<VolatileField>]
14+
static let sx2 = 1 // expect an error - not mutable
15+
16+
[<VolatileField>]
17+
static let f x2 = 1 // expect an error - not mutable
18+
19+
[<VolatileField>]
20+
let x2 = 1 // expect an error - not mutable
21+
22+
[<VolatileField>]
23+
let f x2 = 1 // expect an error - not mutable
24+
25+
[<VolatileField>]
26+
val mutable x : int // expect an error - not supported
27+
28+
member x.P = 1
29+
30+
end
31+
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
type InterruptibleLazy (value) =
2+
[<VolatileField>]
3+
let mutable valueFactory = value
4+
5+
[<VolatileField>]
6+
static let mutable valueFactory2 = Unchecked.defaultof<_>
7+
8+
[<VolatileField>]
9+
let mutable add1 = fun x -> x + 1
10+
11+
[<VolatileField>]
12+
static let mutable add2 = fun x -> x + 1

tests/fsharp/typecheck/sigs/neg16.bsl

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,6 @@ neg16.fs(90,7,90,22): typecheck error FS0025: Incomplete pattern matches on this
7373

7474
neg16.fs(96,3,97,16): typecheck error FS0823: The 'VolatileField' attribute may only be used on 'let' bindings in classes
7575

76-
neg16.fs(99,5,99,18): typecheck error FS0842: This attribute is not valid for use on this language element
77-
7876
neg16.fs(99,3,100,14): typecheck error FS0823: The 'VolatileField' attribute may only be used on 'let' bindings in classes
7977

8078
neg16.fs(99,3,100,14): typecheck error FS0879: Volatile fields must be marked 'mutable' and cannot be thread-static

0 commit comments

Comments
 (0)