@@ -10982,47 +10982,15 @@ and TcNormalizedBinding declKind (cenv: cenv) env tpenv overallTy safeThisValOpt
1098210982 false, SynExpr.ObjExpr(targetType, Some(expr, None), None, [], [], [], m, rhsExpr.Range), overallTy, overallTy
1098310983 | e -> false, e, overallTy, overallTy
1098410984
10985- // Check the attributes of the binding, parameters or return value
10986- let TcAttrs tgt isRet attrs =
10987- // For all but attributes positioned at the return value, disallow implicitly
10988- // targeting the return value.
10989- let tgtEx = if isRet then enum 0 else AttributeTargets.ReturnValue
10990- let attrs, _ = TcAttributesMaybeFailEx TcCanFail.ReportAllErrors cenv envinner tgt tgtEx attrs
10991- let attrs: Attrib list = attrs
10992- if attrTgt = enum 0 && not (isNil attrs) then
10993- for attr in attrs do
10994- errorR(Error(FSComp.SR.tcAttributesAreNotPermittedOnLetBindings(), attr.Range))
10995- attrs
10996-
1099710985 // Rotate [<return:...>] from binding to return value
1099810986 // Also patch the syntactic representation
10999- let retAttribs, valAttribs, valSynData =
11000- let attribs = TcAttrs attrTgt false attrs
11001- let rotRetSynAttrs, rotRetAttribs, valAttribs =
11002- // Do not rotate if some attrs fail to typecheck...
11003- if attribs.Length <> attrs.Length then [], [], attribs
11004- else attribs
11005- |> List.zip attrs
11006- |> List.partition(function | _, Attrib(_, _, _, _, _, Some ts, _) -> ts &&& AttributeTargets.ReturnValue <> enum 0 | _ -> false)
11007- |> fun (r, v) -> (List.map fst r, List.map snd r, List.map snd v)
11008- let retAttribs =
11009- match rtyOpt with
11010- | Some (SynBindingReturnInfo(attributes = Attributes retAttrs)) ->
11011- rotRetAttribs @ TcAttrs AttributeTargets.ReturnValue true retAttrs
11012- | None -> rotRetAttribs
11013- let valSynData =
11014- match rotRetSynAttrs with
11015- | [] -> valSynData
11016- | {Range=mHead} :: _ ->
11017- let (SynValData(valMf, SynValInfo(args, SynArgInfo(attrs, opt, retId)), valId)) = valSynData
11018- SynValData(valMf, SynValInfo(args, SynArgInfo({Attributes=rotRetSynAttrs; Range=mHead} :: attrs, opt, retId)), valId)
11019- retAttribs, valAttribs, valSynData
10987+ let retAttribs, valAttribs, valSynData = TcNormalizeReturnAttribs cenv envinner attrTgt attrs valSynData rtyOpt
1102010988
1102110989 let isVolatile = HasFSharpAttribute g g.attrib_VolatileFieldAttribute valAttribs
1102210990 let inlineFlag = ComputeInlineFlag memberFlagsOpt isInline isMutable g valAttribs mBinding
1102310991
1102410992 let argAttribs =
11025- spatsL |> List.map (SynInfo.InferSynArgInfoFromSimplePats >> List.map (SynInfo.AttribsOfArgData >> TcAttrs AttributeTargets.Parameter false))
10993+ spatsL |> List.map (SynInfo.InferSynArgInfoFromSimplePats >> List.map (SynInfo.AttribsOfArgData >> TcAttrs cenv envinner attrTgt AttributeTargets.Parameter false))
1102610994
1102710995 // Assert the return type of an active pattern. A [<return:Struct>] attribute may be used on a partial active pattern.
1102810996 let isStructRetTy = HasFSharpAttribute g g.attrib_StructAttribute retAttribs
@@ -11220,6 +11188,30 @@ and TcNormalizedBinding declKind (cenv: cenv) env tpenv overallTy safeThisValOpt
1122011188
1122111189 CheckedBindingInfo(inlineFlag, valAttribs, xmlDoc, tcPatPhase2, explicitTyparInfo, nameToPrelimValSchemeMap, rhsExprChecked, argAndRetAttribs, overallPatTy, mBinding, debugPoint, isCompGen, literalValue, isFixed), tpenv
1122211190
11191+ // Rotate [<return:...>] from binding to return value
11192+ // Also patch the syntactic representation
11193+ and TcNormalizeReturnAttribs cenv env attrTgt attrs valSynData rtyOpt =
11194+ let attribs = TcAttrs cenv env attrTgt attrTgt false attrs
11195+ let rotRetSynAttrs, rotRetAttribs, valAttribs =
11196+ // Do not rotate if some attrs fail to typecheck...
11197+ if List.length attribs <> attrs.Length then [], [], attribs
11198+ else attribs
11199+ |> List.zip attrs
11200+ |> List.partition(function | _, Attrib(_, _, _, _, _, Some ts, _) -> ts &&& AttributeTargets.ReturnValue <> enum 0 | _ -> false)
11201+ |> fun (r, v) -> (List.map fst r, List.map snd r, List.map snd v)
11202+ let retAttribs =
11203+ match rtyOpt with
11204+ | Some (SynBindingReturnInfo(attributes = Attributes retAttrs)) ->
11205+ rotRetAttribs @ TcAttrs cenv env attrTgt AttributeTargets.ReturnValue true retAttrs
11206+ | None -> rotRetAttribs
11207+ let valSynData =
11208+ match rotRetSynAttrs with
11209+ | [] -> valSynData
11210+ | {Range=mHead} :: _ ->
11211+ let (SynValData(valMf, SynValInfo(args, SynArgInfo(attrs, opt, retId)), valId)) = valSynData
11212+ SynValData(valMf, SynValInfo(args, SynArgInfo({Attributes=rotRetSynAttrs; Range=mHead} :: attrs, opt, retId)), valId)
11213+ retAttribs, valAttribs, valSynData
11214+
1122311215// Note:
1122411216// - Let bound values can only have attributes that uses AttributeTargets.Field ||| AttributeTargets.Property ||| AttributeTargets.ReturnValue
1122511217// - Let function bindings can only have attributes that uses AttributeTargets.Method ||| AttributeTargets.ReturnValue
@@ -11547,6 +11539,17 @@ and TcAttributesCanFail cenv env attrTgt synAttribs =
1154711539and TcAttributes cenv env attrTgt synAttribs =
1154811540 TcAttributesMaybeFail TcCanFail.ReportAllErrors cenv env attrTgt synAttribs |> fst
1154911541
11542+ // Check the attributes of the binding, parameters or return value
11543+ and TcAttrs cenv env attrTgt tgt isRet attrs =
11544+ // For all but attributes positioned at the return value, disallow implicitly
11545+ // targeting the return value.
11546+ let tgtEx = if isRet then enum 0 else AttributeTargets.ReturnValue
11547+ let attrs, _ = TcAttributesMaybeFailEx TcCanFail.ReportAllErrors cenv env tgt tgtEx attrs
11548+ if attrTgt = enum 0 && not (isNil attrs) then
11549+ for attr in attrs do
11550+ errorR(Error(FSComp.SR.tcAttributesAreNotPermittedOnLetBindings(), attr.Range))
11551+ attrs
11552+
1155011553//-------------------------------------------------------------------------
1155111554// TcLetBinding
1155211555//------------------------------------------------------------------------
@@ -12246,14 +12249,18 @@ and AnalyzeAndMakeAndPublishRecursiveValue
1224612249
1224712250 // Pull apart the inputs
1224812251 let (NormalizedBinding(vis1, bindingKind, isInline, isMutable, bindingSynAttribs, bindingXmlDoc, synTyparDecls, valSynData, declPattern, bindingRhs, mBinding, debugPoint)) = binding
12249- let (NormalizedBindingRhs(_, _ , bindingExpr)) = bindingRhs
12250- let (SynValData(memberFlagsOpt, valSynInfo , thisIdOpt)) = valSynData
12252+ let (NormalizedBindingRhs(_, rtyOpt , bindingExpr)) = bindingRhs
12253+ let (SynValData(memberFlagsOpt, _ , thisIdOpt)) = valSynData
1225112254 let (ContainerInfo(altActualParent, tcrefContainerInfo)) = containerInfo
1225212255
1225312256 let attrTgt = declKind.AllowedAttribTargets memberFlagsOpt
1225412257
1225512258 // Check the attributes on the declaration
12256- let bindingAttribs = TcAttributes cenv env attrTgt bindingSynAttribs
12259+ let retAttribs, bindingAttribs, (SynValData(_, valSynInfo, _) as valSynData) = TcNormalizeReturnAttribs cenv env attrTgt bindingSynAttribs valSynData rtyOpt
12260+
12261+ // Add the return attributes back onto the binding attributes so that ActivePatternElemsOfValRef will see
12262+ // `[<return: Struct>]` as ValRef does not contain return attributes.
12263+ let bindingAttribs = retAttribs @ bindingAttribs
1225712264
1225812265 // Allocate the type inference variable for the inferred type
1225912266 let ty = NewInferenceType g
0 commit comments