Skip to content

Commit

Permalink
Merge pull request #17095 from dotnet/merges/main-to-release/dev17.11
Browse files Browse the repository at this point in the history
Merge main to release/dev17.11
  • Loading branch information
vzarytovskii authored Apr 29, 2024
2 parents 45ecd26 + d2ad3e1 commit 5a06d08
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 44 deletions.
15 changes: 12 additions & 3 deletions src/Compiler/Checking/CheckExpressions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -10625,6 +10625,11 @@ and TcNormalizedBinding declKind (cenv: cenv) env tpenv overallTy safeThisValOpt
| NormalizedBinding(vis, kind, isInline, isMutable, attrs, xmlDoc, _, valSynData, pat, NormalizedBindingRhs(spatsL, rtyOpt, rhsExpr), mBinding, debugPoint) ->
let (SynValData(memberFlags = memberFlagsOpt)) = valSynData

let isClassLetBinding =
match declKind, kind with
| ClassLetBinding _, SynBindingKind.Normal -> true
| _ -> false

let callerName =
match declKind, kind, pat with
| ExpressionBinding, _, _ -> envinner.eCallerMemberName
Expand Down Expand Up @@ -10880,14 +10885,14 @@ and TcNormalizedBinding declKind (cenv: cenv) env tpenv overallTy safeThisValOpt
errorR(Error(FSComp.SR.tcLiteralCannotHaveGenericParameters(), mBinding))

if g.langVersion.SupportsFeature(LanguageFeature.EnforceAttributeTargets) && memberFlagsOpt.IsNone && not attrs.IsEmpty then
TcAttributeTargetsOnLetBindings cenv env attrs overallPatTy overallExprTy (not declaredTypars.IsEmpty)
TcAttributeTargetsOnLetBindings cenv env attrs overallPatTy overallExprTy (not declaredTypars.IsEmpty) isClassLetBinding

CheckedBindingInfo(inlineFlag, valAttribs, xmlDoc, tcPatPhase2, explicitTyparInfo, nameToPrelimValSchemeMap, rhsExprChecked, argAndRetAttribs, overallPatTy, mBinding, debugPoint, isCompGen, literalValue, isFixed), tpenv

// Note:
// - Let bound values can only have attributes that uses AttributeTargets.Field ||| AttributeTargets.Property ||| AttributeTargets.ReturnValue
// - Let function bindings can only have attributes that uses AttributeTargets.Method ||| AttributeTargets.ReturnValue
and TcAttributeTargetsOnLetBindings (cenv: cenv) env attrs overallPatTy overallExprTy areTyparsDeclared =
and TcAttributeTargetsOnLetBindings (cenv: cenv) env attrs overallPatTy overallExprTy areTyparsDeclared isClassLetBinding =
let attrTgt =
if
// It's a type function:
Expand All @@ -10899,7 +10904,11 @@ and TcAttributeTargetsOnLetBindings (cenv: cenv) env attrs overallPatTy overallE
|| isFunTy cenv.g overallPatTy
|| isFunTy cenv.g overallExprTy
then
AttributeTargets.ReturnValue ||| AttributeTargets.Method
// Class let bindings are a special case, they can have attributes that target fields and properties, since they might be lifted to those and contain lambdas/functions.
if isClassLetBinding then
AttributeTargets.ReturnValue ||| AttributeTargets.Method ||| AttributeTargets.Field ||| AttributeTargets.Property
else
AttributeTargets.ReturnValue ||| AttributeTargets.Method
else
AttributeTargets.ReturnValue ||| AttributeTargets.Field ||| AttributeTargets.Property

Expand Down
4 changes: 3 additions & 1 deletion src/Compiler/Utilities/illib.fs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ open System.Runtime.CompilerServices
[<Class>]
type InterruptibleLazy<'T> private (value, valueFactory: unit -> 'T) =
let syncObj = obj ()

[<VolatileField>]
let mutable valueFactory = valueFactory

let mutable value = value

new(valueFactory: unit -> 'T) = InterruptibleLazy(Unchecked.defaultof<_>, valueFactory)
Expand All @@ -28,7 +31,6 @@ type InterruptibleLazy<'T> private (value, valueFactory: unit -> 'T) =
match box valueFactory with
| null -> value
| _ ->

Monitor.Enter(syncObj)

try
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,27 +171,7 @@ module CustomAttributes_AttributeUsage =
|> withLangVersionPreview
|> withOptions ["--nowarn:25"]
|> verifyCompile
|> shouldFail
|> withDiagnostics [
(Error 842, Line 11, Col 6, Line 11, Col 15, "This attribute is not valid for use on this language element")
(Error 842, Line 14, Col 6, Line 14, Col 15, "This attribute is not valid for use on this language element")
(Error 842, Line 17, Col 6, Line 17, Col 15, "This attribute is not valid for use on this language element")
(Error 842, Line 19, Col 10, Line 19, Col 19, "This attribute is not valid for use on this language element")
(Error 842, Line 21, Col 6, Line 21, Col 15, "This attribute is not valid for use on this language element")
(Error 842, Line 24, Col 6, Line 24, Col 15, "This attribute is not valid for use on this language element")
(Error 842, Line 27, Col 6, Line 27, Col 15, "This attribute is not valid for use on this language element")
(Error 842, Line 30, Col 6, Line 30, Col 15, "This attribute is not valid for use on this language element")
(Error 842, Line 33, Col 6, Line 33, Col 15, "This attribute is not valid for use on this language element")
(Error 842, Line 36, Col 6, Line 36, Col 15, "This attribute is not valid for use on this language element")
(Error 842, Line 39, Col 6, Line 39, Col 15, "This attribute is not valid for use on this language element")
(Error 842, Line 42, Col 6, Line 42, Col 15, "This attribute is not valid for use on this language element")
(Error 842, Line 45, Col 6, Line 45, Col 15, "This attribute is not valid for use on this language element")
(Error 842, Line 49, Col 6, Line 49, Col 15, "This attribute is not valid for use on this language element")
(Error 842, Line 56, Col 6, Line 56, Col 15, "This attribute is not valid for use on this language element")
(Error 842, Line 64, Col 6, Line 64, Col 15, "This attribute is not valid for use on this language element")
(Error 842, Line 66, Col 10, Line 66, Col 19, "This attribute is not valid for use on this language element")
(Error 842, Line 68, Col 6, Line 68, Col 15, "This attribute is not valid for use on this language element")
]
|> shouldSucceed

// SOURCE=E_AttributeTargetIsMethod02.fs # E_AttributeTargetIsMethod02.fs
[<Theory; Directory(__SOURCE_DIRECTORY__, Includes=[|"E_AttributeTargetIsMethod02.fs"|])>]
Expand Down Expand Up @@ -591,4 +571,16 @@ module CustomAttributes_AttributeUsage =
(Error 842, Line 20, Col 3, Line 20, Col 15, "This attribute is not valid for use on this language element")
(Error 842, Line 21, Col 3, Line 21, Col 18, "This attribute is not valid for use on this language element")
(Error 842, Line 22, Col 3, Line 22, Col 13, "This attribute is not valid for use on this language element")
]
]

[<Fact>]
let ``Type-level let bindings allowed to use attribute with Field target`` () =
FSharp"""
module Foo
type InterruptibleLazy<'T> private (valueFactory: unit -> 'T) =
[<VolatileField>]
let mutable valueFactory = valueFactory
"""
|> withLangVersionPreview
|> compile
|> shouldSucceed
Original file line number Diff line number Diff line change
Expand Up @@ -8,62 +8,62 @@ type FieldOnlyAttribute() =
inherit Attribute()

type TestClass() =
[<FieldOnly>] // Should fail
[<FieldOnly>] // Should succeed (special exception when function can be lifted to a field)
static let func1() = "someFunction"

[<FieldOnly>] // Should fail
[<FieldOnly>] // Should succeed (special exception when function can be lifted to a field)
static let rec func2() = "someFunction"

[<FieldOnly>]// Should fail
[<FieldOnly>]// Should succeed (special exception when function can be lifted to a field)
static let rec func3() = "someFunction"
and [<FieldOnly>] fun4() = "someFunction" // Should fail
and [<FieldOnly>] fun4() = "someFunction" // Should succeed (special exception when function can be lifted to a field)

[<FieldOnly>] // Should fail
[<FieldOnly>] // Should succeed (special exception when function can be lifted to a field)
let func5 () = "someFunction"

[<FieldOnly>] // Should fail
[<FieldOnly>] // Should succeed (special exception when function can be lifted to a field)
let func6 a = a + 1

[<FieldOnly>] // Should fail
[<FieldOnly>] // Should succeed (special exception when function can be lifted to a field)
let func7 (a, b) = a + b

[<FieldOnly>] // Should fail
[<FieldOnly>] // Should succeed (special exception when function can be lifted to a field)
let func8 (a: int) : int = a + 1

[<FieldOnly>] // Should fail
[<FieldOnly>] // Should succeed (special exception when function can be lifted to a field)
let func9 a b = [ a; b ]

[<FieldOnly>] // Should fail
[<FieldOnly>] // Should succeed (special exception when function can be lifted to a field)
let func10 = fun x -> x

[<FieldOnly>] // Should fail
[<FieldOnly>] // Should succeed (special exception when function can be lifted to a field)
let func11 = id

[<FieldOnly>] // Should fail
[<FieldOnly>] // Should succeed (special exception when function can be lifted to a field)
let (|Bool|_|) = function "true" -> Some true | "false" -> Some false | _ -> None

[<FieldOnly>] // Should fail
[<FieldOnly>] // Should succeed (special exception when function can be lifted to a field)
[<return: Struct>]
let (|BoolExpr2|_|) = function "true" -> ValueSome true | "false" -> ValueSome false | _ -> ValueNone

[<FieldOnly>] // Should fail
[<FieldOnly>] // Should succeed (special exception when function can be lifted to a field)
let (|BoolExpr3|_|) x =
match x with
| "true" -> Some true
| "false" -> Some false
| _ -> None

[<FieldOnly>] // Should fail
[<FieldOnly>] // Should succeed (special exception when function can be lifted to a field)
[<return: Struct>]
let (|BoolExpr4|_|) x =
match x with
| "true" -> ValueSome true
| "false" -> ValueSome false
| _ -> ValueNone

[<FieldOnly>] // Should fail
[<FieldOnly>] // Should succeed (special exception when function can be lifted to a field)
let rec func12() = 0
and [<FieldOnly>] func13() = [] // Should fail
and [<FieldOnly>] func13() = [] // Should succeed (special exception when function can be lifted to a field)

[<FieldOnly>] // Should fail
[<FieldOnly>] // Should succeed (special exception when function can be lifted to a field)
let rec func14() = 0

0 comments on commit 5a06d08

Please sign in to comment.