From 1b8d3f37ea8b194ee395b69cf9b2a70c845999bd Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Tue, 17 Oct 2023 14:50:31 +0100 Subject: [PATCH 01/15] Enforce attribute targets on let values --- src/Compiler/Checking/CheckExpressions.fs | 25 ++++++++++++++----- .../AttributeUsage/AttributeUsage.fs | 2 ++ .../AttributeUsage/E_AttributeTargets01.fs | 10 ++++++++ 3 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/Compiler/Checking/CheckExpressions.fs b/src/Compiler/Checking/CheckExpressions.fs index 496081df39d..20546cd3967 100644 --- a/src/Compiler/Checking/CheckExpressions.fs +++ b/src/Compiler/Checking/CheckExpressions.fs @@ -6820,7 +6820,7 @@ and TcObjectExprBinding (cenv: cenv) (env: TcEnv) implTy tpenv (absSlotInfo, bin let CheckedBindingInfo(inlineFlag, bindingAttribs, _, _, ExplicitTyparInfo(_, declaredTypars, _), nameToPrelimValSchemeMap, rhsExpr, _, _, m, _, _, _, _), tpenv = let explicitTyparInfo, tpenv = TcNonrecBindingTyparDecls cenv env tpenv bind - TcNormalizedBinding ObjectExpressionOverrideBinding cenv env tpenv bindingTy None NoSafeInitInfo ([], explicitTyparInfo) bind + TcNormalizedBinding ObjectExpressionOverrideBinding cenv env tpenv bindingTy None NoSafeInitInfo ([], explicitTyparInfo) bind None // 4c. generalize the binding - only relevant when implementing a generic virtual method @@ -10458,7 +10458,7 @@ and TcAndBuildFixedExpr (cenv: cenv) env (overallPatTy, fixedExpr, overallExprTy /// Binding checking code, for all bindings including let bindings, let-rec bindings, member bindings and object-expression bindings and -and TcNormalizedBinding declKind (cenv: cenv) env tpenv overallTy safeThisValOpt safeInitInfo (enclosingDeclaredTypars, (ExplicitTyparInfo(_, declaredTypars, _) as explicitTyparInfo)) bind = +and TcNormalizedBinding declKind (cenv: cenv) env tpenv overallTy safeThisValOpt safeInitInfo (enclosingDeclaredTypars, (ExplicitTyparInfo(_, declaredTypars, _) as explicitTyparInfo)) bind (attrTgt: AttributeTargets option) = let g = cenv.g @@ -10487,7 +10487,10 @@ and TcNormalizedBinding declKind (cenv: cenv) env tpenv overallTy safeThisValOpt let envinner = {envinner with eCallerMemberName = callerName } - let attrTgt = declKind.AllowedAttribTargets memberFlagsOpt + let attrTgt = + match attrTgt with + | Some v -> v + | None -> declKind.AllowedAttribTargets memberFlagsOpt let isFixed, rhsExpr, overallPatTy, overallExprTy = match rhsExpr with @@ -10758,7 +10761,7 @@ and TcNonrecBindingTyparDecls cenv env tpenv bind = let (NormalizedBinding(_, _, _, _, _, _, synTyparDecls, _, _, _, _, _)) = bind TcBindingTyparDecls true cenv env tpenv synTyparDecls -and TcNonRecursiveBinding declKind cenv env tpenv ty binding = +and TcNonRecursiveBinding (declKind: DeclKind) cenv env tpenv ty binding = // Check for unintended shadowing match binding with | SynBinding(headPat = SynPat.LongIdent(longDotId = SynLongIdent(id = [ident]); range = headPatRange)) -> @@ -10768,9 +10771,19 @@ and TcNonRecursiveBinding declKind cenv env tpenv ty binding = | _ -> () | _ -> () + let attrTgt = + match binding with + | SynBinding(headPat = pat; expr= rhsExpr) -> + match pat with + | SynPat.Named _ | SynPat.As _ -> + match rhsExpr with + | SynExpr.Lambda _ -> None + | _ -> Some(AttributeTargets.Field ||| AttributeTargets.Property ||| AttributeTargets.ReturnValue) + | _ -> None + let binding = BindingNormalization.NormalizeBinding ValOrMemberBinding cenv env binding let explicitTyparInfo, tpenv = TcNonrecBindingTyparDecls cenv env tpenv binding - TcNormalizedBinding declKind cenv env tpenv ty None NoSafeInitInfo ([], explicitTyparInfo) binding + TcNormalizedBinding declKind cenv env tpenv ty None NoSafeInitInfo ([], explicitTyparInfo) binding attrTgt //------------------------------------------------------------------------- // TcAttribute* @@ -11812,7 +11825,7 @@ and TcLetrecBinding let envRec = MakeInnerEnvForMember envRec vspec let checkedBind, tpenv = - TcNormalizedBinding declKind cenv envRec tpenv tau safeThisValOpt safeInitInfo (enclosingDeclaredTypars, explicitTyparInfo) rbind.SyntacticBinding + TcNormalizedBinding declKind cenv envRec tpenv tau safeThisValOpt safeInitInfo (enclosingDeclaredTypars, explicitTyparInfo) rbind.SyntacticBinding None (try UnifyTypes cenv envRec vspec.Range (allDeclaredTypars +-> tau) vspec.Type with e -> error (Recursion(envRec.DisplayEnv, vspec.Id, tau, vspec.Type, vspec.Range))) diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs index cddee9f80ab..a88372e0ead 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs @@ -81,6 +81,8 @@ module CustomAttributes_AttributeUsage = (Error 842, Line 21, Col 21, Line 21, Col 22, "This attribute is not valid for use on this language element") (Error 842, Line 24, Col 21, Line 24, Col 29, "This attribute is not valid for use on this language element") (Error 842, Line 27, Col 7, Line 27, Col 16, "This attribute is not valid for use on this language element") + (Error 842, Line 18, Col 7, Line 18, Col 8, "This attribute is not valid for use on this language element") + (Error 842, Line 38, Col 3, Line 38, Col 13, "This attribute is not valid for use on this language element") ] // SOURCE=E_AttributeTargets02.fs # E_AttributeTargets02.fs diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargets01.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargets01.fs index 15bfe1a8e1d..bd7d3c0bfcd 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargets01.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargets01.fs @@ -30,3 +30,13 @@ type A() = [] static member (+) (op1 : A, op2 : A) = new A() + +[] +type MethodOnlyAttribute() = + inherit Attribute() + +[] +let def = "def" + +[] +let abc () = "abc" From 2724872c7fc04a0de58c0ca4bc35316acf531788 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Wed, 1 Nov 2023 14:08:44 +0000 Subject: [PATCH 02/15] Add LanguageFeatures --- src/Compiler/FSComp.txt | 1 + src/Compiler/Facilities/LanguageFeatures.fs | 3 +++ src/Compiler/Facilities/LanguageFeatures.fsi | 1 + src/Compiler/xlf/FSComp.txt.cs.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.de.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.es.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.fr.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.it.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.ja.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.ko.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.pl.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.pt-BR.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.ru.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.tr.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.zh-Hans.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.zh-Hant.xlf | 5 +++++ 16 files changed, 70 insertions(+) diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt index 92e7cda05de..e6bdb41c25c 100644 --- a/src/Compiler/FSComp.txt +++ b/src/Compiler/FSComp.txt @@ -1588,6 +1588,7 @@ featureChkNotTailRecursive,"Raises warnings if a member or function has the 'Tai featureWhileBang,"'while!' expression" featureExtendedFixedBindings,"extended fixed bindings for byref and GetPinnableReference" featurePreferStringGetPinnableReference,"prefer String.GetPinnableReference in fixed bindings" +featureEnforceAttributeTargetsOnLetValues,"Enforce AttributeTargets on let values" 3354,tcNotAFunctionButIndexerNamedIndexingNotYetEnabled,"This value supports indexing, e.g. '%s.[index]'. The syntax '%s[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation." 3354,tcNotAFunctionButIndexerIndexingNotYetEnabled,"This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation." 3355,tcNotAnIndexerNamedIndexingNotYetEnabled,"The value '%s' is not a function and does not support index notation." diff --git a/src/Compiler/Facilities/LanguageFeatures.fs b/src/Compiler/Facilities/LanguageFeatures.fs index 0cc5370d570..139673318e2 100644 --- a/src/Compiler/Facilities/LanguageFeatures.fs +++ b/src/Compiler/Facilities/LanguageFeatures.fs @@ -79,6 +79,7 @@ type LanguageFeature = | WhileBang | ExtendedFixedBindings | PreferStringGetPinnableReference + | EnforceAttributeTargetsOnLetValues /// LanguageVersion management type LanguageVersion(versionText) = @@ -185,6 +186,7 @@ type LanguageVersion(versionText) = // F# preview LanguageFeature.FromEndSlicing, previewVersion LanguageFeature.UnmanagedConstraintCsharpInterop, previewVersion + LanguageFeature.EnforceAttributeTargetsOnLetValues, previewVersion ] static let defaultLanguageVersion = LanguageVersion("default") @@ -321,6 +323,7 @@ type LanguageVersion(versionText) = | LanguageFeature.WhileBang -> FSComp.SR.featureWhileBang () | LanguageFeature.ExtendedFixedBindings -> FSComp.SR.featureExtendedFixedBindings () | LanguageFeature.PreferStringGetPinnableReference -> FSComp.SR.featurePreferStringGetPinnableReference () + | LanguageFeature.EnforceAttributeTargetsOnLetValues -> FSComp.SR.featureEnforceAttributeTargetsOnLetValues () /// Get a version string associated with the given feature. static member GetFeatureVersionString feature = diff --git a/src/Compiler/Facilities/LanguageFeatures.fsi b/src/Compiler/Facilities/LanguageFeatures.fsi index c1cb2378d4e..79595fc82a9 100644 --- a/src/Compiler/Facilities/LanguageFeatures.fsi +++ b/src/Compiler/Facilities/LanguageFeatures.fsi @@ -69,6 +69,7 @@ type LanguageFeature = | WhileBang | ExtendedFixedBindings | PreferStringGetPinnableReference + | EnforceAttributeTargetsOnLetValues /// LanguageVersion management type LanguageVersion = diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf index 0de0dda3fcb..8966903a43d 100644 --- a/src/Compiler/xlf/FSComp.txt.cs.xlf +++ b/src/Compiler/xlf/FSComp.txt.cs.xlf @@ -262,6 +262,11 @@ literál float32 bez tečky + + Enforce AttributeTargets on let values + Enforce AttributeTargets on let values + + Raises errors for non-virtual members overrides Vyvolá chyby pro přepsání jiných než virtuálních členů diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf index ace9ad92933..7b94fc1ebc7 100644 --- a/src/Compiler/xlf/FSComp.txt.de.xlf +++ b/src/Compiler/xlf/FSComp.txt.de.xlf @@ -262,6 +262,11 @@ punktloses float32-Literal + + Enforce AttributeTargets on let values + Enforce AttributeTargets on let values + + Raises errors for non-virtual members overrides Löst Fehler für Außerkraftsetzungen nicht virtueller Member aus. diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf index 286598c9988..406a5359767 100644 --- a/src/Compiler/xlf/FSComp.txt.es.xlf +++ b/src/Compiler/xlf/FSComp.txt.es.xlf @@ -262,6 +262,11 @@ literal float32 sin punto + + Enforce AttributeTargets on let values + Enforce AttributeTargets on let values + + Raises errors for non-virtual members overrides Genera errores para invalidaciones de miembros no virtuales diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf index e3f9f534475..837766942ab 100644 --- a/src/Compiler/xlf/FSComp.txt.fr.xlf +++ b/src/Compiler/xlf/FSComp.txt.fr.xlf @@ -262,6 +262,11 @@ littéral float32 sans point + + Enforce AttributeTargets on let values + Enforce AttributeTargets on let values + + Raises errors for non-virtual members overrides Déclenche des erreurs pour les remplacements de membres non virtuels diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf index fefdc56090c..260c9a0c734 100644 --- a/src/Compiler/xlf/FSComp.txt.it.xlf +++ b/src/Compiler/xlf/FSComp.txt.it.xlf @@ -262,6 +262,11 @@ valore letterale float32 senza punti + + Enforce AttributeTargets on let values + Enforce AttributeTargets on let values + + Raises errors for non-virtual members overrides Genera errori per gli override dei membri non virtuali diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf index 547baf049f7..08a049cb317 100644 --- a/src/Compiler/xlf/FSComp.txt.ja.xlf +++ b/src/Compiler/xlf/FSComp.txt.ja.xlf @@ -262,6 +262,11 @@ ドットなしの float32 リテラル + + Enforce AttributeTargets on let values + Enforce AttributeTargets on let values + + Raises errors for non-virtual members overrides 仮想メンバー以外のオーバーライドに対してエラーを発生させます diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf index 51ed5cd562a..09e69c3d372 100644 --- a/src/Compiler/xlf/FSComp.txt.ko.xlf +++ b/src/Compiler/xlf/FSComp.txt.ko.xlf @@ -262,6 +262,11 @@ 점이 없는 float32 리터럴 + + Enforce AttributeTargets on let values + Enforce AttributeTargets on let values + + Raises errors for non-virtual members overrides 비가상 멤버 재정의에 대한 오류 발생 diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf index 4fe31c3a96b..af87c4afcae 100644 --- a/src/Compiler/xlf/FSComp.txt.pl.xlf +++ b/src/Compiler/xlf/FSComp.txt.pl.xlf @@ -262,6 +262,11 @@ bezkropkowy literał float32 + + Enforce AttributeTargets on let values + Enforce AttributeTargets on let values + + Raises errors for non-virtual members overrides Zgłasza błędy w przypadku przesłonięć elementów innych niż wirtualne diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf index b80b7cb1665..d6ee01eea38 100644 --- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf +++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf @@ -262,6 +262,11 @@ literal float32 sem ponto + + Enforce AttributeTargets on let values + Enforce AttributeTargets on let values + + Raises errors for non-virtual members overrides Gera erros para substituições de membros não virtuais diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf index a70e6137577..0abb4b2d93e 100644 --- a/src/Compiler/xlf/FSComp.txt.ru.xlf +++ b/src/Compiler/xlf/FSComp.txt.ru.xlf @@ -262,6 +262,11 @@ литерал float32 без точки + + Enforce AttributeTargets on let values + Enforce AttributeTargets on let values + + Raises errors for non-virtual members overrides Вызывает ошибки при переопределениях невиртуальных элементов diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf index b5588a963ff..290f3b95c85 100644 --- a/src/Compiler/xlf/FSComp.txt.tr.xlf +++ b/src/Compiler/xlf/FSComp.txt.tr.xlf @@ -262,6 +262,11 @@ noktasız float32 sabit değeri + + Enforce AttributeTargets on let values + Enforce AttributeTargets on let values + + Raises errors for non-virtual members overrides Sanal olmayan üyelerde geçersiz kılmalar için hatalar oluştur diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf index 804aefd5e43..33ba880ce8b 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf @@ -262,6 +262,11 @@ 无点 float32 文本 + + Enforce AttributeTargets on let values + Enforce AttributeTargets on let values + + Raises errors for non-virtual members overrides 引发非虚拟成员替代的错误 diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf index 3e5f30fb7a6..31ba0674382 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf @@ -262,6 +262,11 @@ 無點號的 float32 常值 + + Enforce AttributeTargets on let values + Enforce AttributeTargets on let values + + Raises errors for non-virtual members overrides 引發非虛擬成員覆寫的錯誤 From 760247df5ee5c2d3e7801894ab18076ff0a9f4e7 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Wed, 1 Nov 2023 19:10:18 +0000 Subject: [PATCH 03/15] Add LanguageFeature preview --- src/Compiler/Checking/CheckExpressions.fs | 28 ++++++++----------- .../AttributeUsage/AttributeUsage.fs | 13 +++++++++ 2 files changed, 24 insertions(+), 17 deletions(-) diff --git a/src/Compiler/Checking/CheckExpressions.fs b/src/Compiler/Checking/CheckExpressions.fs index dd3b4a9fd02..f3c7cee3ce9 100644 --- a/src/Compiler/Checking/CheckExpressions.fs +++ b/src/Compiler/Checking/CheckExpressions.fs @@ -6820,7 +6820,7 @@ and TcObjectExprBinding (cenv: cenv) (env: TcEnv) implTy tpenv (absSlotInfo, bin let CheckedBindingInfo(inlineFlag, bindingAttribs, _, _, ExplicitTyparInfo(_, declaredTypars, _), nameToPrelimValSchemeMap, rhsExpr, _, _, m, _, _, _, _), tpenv = let explicitTyparInfo, tpenv = TcNonrecBindingTyparDecls cenv env tpenv bind - TcNormalizedBinding ObjectExpressionOverrideBinding cenv env tpenv bindingTy None NoSafeInitInfo ([], explicitTyparInfo) bind None + TcNormalizedBinding ObjectExpressionOverrideBinding cenv env tpenv bindingTy None NoSafeInitInfo ([], explicitTyparInfo) bind // 4c. generalize the binding - only relevant when implementing a generic virtual method @@ -10458,7 +10458,7 @@ and TcAndBuildFixedExpr (cenv: cenv) env (overallPatTy, fixedExpr, overallExprTy /// Binding checking code, for all bindings including let bindings, let-rec bindings, member bindings and object-expression bindings and -and TcNormalizedBinding declKind (cenv: cenv) env tpenv overallTy safeThisValOpt safeInitInfo (enclosingDeclaredTypars, (ExplicitTyparInfo(_, declaredTypars, _) as explicitTyparInfo)) bind (attrTgt: AttributeTargets option) = +and TcNormalizedBinding declKind (cenv: cenv) env tpenv overallTy safeThisValOpt safeInitInfo (enclosingDeclaredTypars, (ExplicitTyparInfo(_, declaredTypars, _) as explicitTyparInfo)) bind = let g = cenv.g @@ -10488,9 +10488,13 @@ and TcNormalizedBinding declKind (cenv: cenv) env tpenv overallTy safeThisValOpt let envinner = {envinner with eCallerMemberName = callerName } let attrTgt = - match attrTgt with - | Some v -> v - | None -> declKind.AllowedAttribTargets memberFlagsOpt + if g.langVersion.SupportsFeature(LanguageFeature.EnforceAttributeTargetsOnLetValues) then + match pat, rhsExpr with + | SynPat.Named _ , SynExpr.Lambda _ -> declKind.AllowedAttribTargets memberFlagsOpt + | SynPat.Named _, _ -> AttributeTargets.Field ||| AttributeTargets.Property ||| AttributeTargets.ReturnValue + | _ -> declKind.AllowedAttribTargets memberFlagsOpt + else + declKind.AllowedAttribTargets memberFlagsOpt let isFixed, rhsExpr, overallPatTy, overallExprTy = match rhsExpr with @@ -10770,20 +10774,10 @@ and TcNonRecursiveBinding (declKind: DeclKind) cenv env tpenv ty binding = warning(Error(FSComp.SR.tcInfoIfFunctionShadowsUnionCase(), headPatRange)) | _ -> () | _ -> () - - let attrTgt = - match binding with - | SynBinding(headPat = pat; expr= rhsExpr) -> - match pat with - | SynPat.Named _ | SynPat.As _ -> - match rhsExpr with - | SynExpr.Lambda _ -> None - | _ -> Some(AttributeTargets.Field ||| AttributeTargets.Property ||| AttributeTargets.ReturnValue) - | _ -> None let binding = BindingNormalization.NormalizeBinding ValOrMemberBinding cenv env binding let explicitTyparInfo, tpenv = TcNonrecBindingTyparDecls cenv env tpenv binding - TcNormalizedBinding declKind cenv env tpenv ty None NoSafeInitInfo ([], explicitTyparInfo) binding attrTgt + TcNormalizedBinding declKind cenv env tpenv ty None NoSafeInitInfo ([], explicitTyparInfo) binding //------------------------------------------------------------------------- // TcAttribute* @@ -11825,7 +11819,7 @@ and TcLetrecBinding let envRec = MakeInnerEnvForMember envRec vspec let checkedBind, tpenv = - TcNormalizedBinding declKind cenv envRec tpenv tau safeThisValOpt safeInitInfo (enclosingDeclaredTypars, explicitTyparInfo) rbind.SyntacticBinding None + TcNormalizedBinding declKind cenv envRec tpenv tau safeThisValOpt safeInitInfo (enclosingDeclaredTypars, explicitTyparInfo) rbind.SyntacticBinding (try UnifyTypes cenv envRec vspec.Range (allDeclaredTypars +-> tau) vspec.Type with e -> error (Recursion(envRec.DisplayEnv, vspec.Id, tau, vspec.Type, vspec.Range))) diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs index a88372e0ead..3a0ff854b59 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs @@ -77,6 +77,19 @@ module CustomAttributes_AttributeUsage = compilation |> verifyCompile |> shouldFail + |> withDiagnostics [ + (Error 842, Line 21, Col 21, Line 21, Col 22, "This attribute is not valid for use on this language element") + (Error 842, Line 24, Col 21, Line 24, Col 29, "This attribute is not valid for use on this language element") + (Error 842, Line 27, Col 7, Line 27, Col 16, "This attribute is not valid for use on this language element") + ] + + // SOURCE=E_AttributeTargets01.fs # E_AttributeTargets01.fs + [] + let ``E_AttributeTargets01_fs preview lang`` compilation = + compilation + |> withLangVersionPreview + |> verifyCompile + |> shouldFail |> withDiagnostics [ (Error 842, Line 21, Col 21, Line 21, Col 22, "This attribute is not valid for use on this language element") (Error 842, Line 24, Col 21, Line 24, Col 29, "This attribute is not valid for use on this language element") From 36667c077d89958e5dbd48ed8cfb8b241d2b0d41 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Wed, 29 Nov 2023 18:28:26 +0000 Subject: [PATCH 04/15] Check declaredTypars for type functions --- src/Compiler/Checking/CheckExpressions.fs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Compiler/Checking/CheckExpressions.fs b/src/Compiler/Checking/CheckExpressions.fs index 5eda7a46a5b..77b56e106c1 100644 --- a/src/Compiler/Checking/CheckExpressions.fs +++ b/src/Compiler/Checking/CheckExpressions.fs @@ -10487,7 +10487,7 @@ and TcAndBuildFixedExpr (cenv: cenv) env (overallPatTy, fixedExpr, overallExprTy /// Binding checking code, for all bindings including let bindings, let-rec bindings, member bindings and object-expression bindings and -and TcNormalizedBinding declKind (cenv: cenv) env tpenv overallTy safeThisValOpt safeInitInfo (enclosingDeclaredTypars, (ExplicitTyparInfo(_, declaredTypars, _) as explicitTyparInfo)) bind = +and TcNormalizedBinding declKind (cenv: cenv) env tpenv overallTy safeThisValOpt safeInitInfo (enclosingDeclaredTypars, (ExplicitTyparInfo(_, declaredTypars, _) as explicitTyparInfo)) bind = let g = cenv.g @@ -10520,7 +10520,7 @@ and TcNormalizedBinding declKind (cenv: cenv) env tpenv overallTy safeThisValOpt if g.langVersion.SupportsFeature(LanguageFeature.EnforceAttributeTargetsOnLetValues) then match pat, rhsExpr with | SynPat.Named _ , SynExpr.Lambda _ -> declKind.AllowedAttribTargets memberFlagsOpt - | SynPat.Named _, _ -> AttributeTargets.Field ||| AttributeTargets.Property ||| AttributeTargets.ReturnValue + | SynPat.Named _, _ when isNil declaredTypars -> AttributeTargets.Field ||| AttributeTargets.Property ||| AttributeTargets.ReturnValue | _ -> declKind.AllowedAttribTargets memberFlagsOpt else declKind.AllowedAttribTargets memberFlagsOpt From 816e2c1156426f59c42b2aa7114a441edb1937ae Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Wed, 29 Nov 2023 18:55:53 +0000 Subject: [PATCH 05/15] WIP adding more tests --- .../AttributeTargetsIsMethod02.fs | 48 +++++++++++++++++++ .../AttributeUsage/AttributeUsage.fs | 27 +++++------ .../AttributeUsage/E_AttributeTargets01.fs | 12 +---- 3 files changed, 61 insertions(+), 26 deletions(-) create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeTargetsIsMethod02.fs diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeTargetsIsMethod02.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeTargetsIsMethod02.fs new file mode 100644 index 00000000000..939020aee5e --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeTargetsIsMethod02.fs @@ -0,0 +1,48 @@ +// #Regression #Conformance #DeclarationElements #Attributes +// Regression test for FSharp1.0:5172 +// Title: "method" attribute target is not recognized +// Descr: Verify that attribute target 'method' is recognized by F# compiler correctly. +open System + +[] +type MethodOnlyAttribute() = + inherit Attribute() + +[] +let someValue = "someValue" + +[] +let i, j, k = (1, 2, 3) + +[] +let someFunction () = "someFunction" + +[] +let someFunction2 a = a + 1 + +[] +let someFunction3 (a, b) = a + b + +[] +let someFunction4 (a: int) : int = a + 1 + +[] +let makeList a b = [ a; b ] + +[] +let someTypedFunction<'a> = "someTypedFunction" + +[] +let someTypedFunction2<'a> (x : 'a) = "someTypedFunction2" + +[] +let someTypedFunction3 = fun x -> x + +[] +let someTypedFunction4 = id + +[] +let __someTypedFunction5<'a> = false + +[] +let __someTypedFunction6<'a> : bool = false \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs index 3a0ff854b59..8969cd9fc03 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs @@ -63,6 +63,18 @@ module CustomAttributes_AttributeUsage = compilation |> verifyCompileAndRun |> shouldSucceed + + // SOURCE=AttributeTargetsIsMethod02.fs # AttributeTargetsIsMethod02.fs + [] + let ``AttributeTargetsIsMethod02_fs preview lang`` compilation = + compilation + |> withLangVersionPreview + |> verifyCompile + |> shouldFail + |> withDiagnostics [ + (Error 842, Line 11, Col 3, Line 11, Col 13, "This attribute is not valid for use on this language element"); + (Error 842, Line 41, Col 3, Line 41, Col 13, "This attribute is not valid for use on this language element") + ] // SOURCE=ConditionalAttribute.fs # ConditionalAttribute.fs [] @@ -83,21 +95,6 @@ module CustomAttributes_AttributeUsage = (Error 842, Line 27, Col 7, Line 27, Col 16, "This attribute is not valid for use on this language element") ] - // SOURCE=E_AttributeTargets01.fs # E_AttributeTargets01.fs - [] - let ``E_AttributeTargets01_fs preview lang`` compilation = - compilation - |> withLangVersionPreview - |> verifyCompile - |> shouldFail - |> withDiagnostics [ - (Error 842, Line 21, Col 21, Line 21, Col 22, "This attribute is not valid for use on this language element") - (Error 842, Line 24, Col 21, Line 24, Col 29, "This attribute is not valid for use on this language element") - (Error 842, Line 27, Col 7, Line 27, Col 16, "This attribute is not valid for use on this language element") - (Error 842, Line 18, Col 7, Line 18, Col 8, "This attribute is not valid for use on this language element") - (Error 842, Line 38, Col 3, Line 38, Col 13, "This attribute is not valid for use on this language element") - ] - // SOURCE=E_AttributeTargets02.fs # E_AttributeTargets02.fs [] let ``E_AttributeTargets02_fs`` compilation = diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargets01.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargets01.fs index bd7d3c0bfcd..c96c7e51232 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargets01.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargets01.fs @@ -29,14 +29,4 @@ type A() = and [] set (x : int) = () [] - static member (+) (op1 : A, op2 : A) = new A() - -[] -type MethodOnlyAttribute() = - inherit Attribute() - -[] -let def = "def" - -[] -let abc () = "abc" + static member (+) (op1 : A, op2 : A) = new A() \ No newline at end of file From 815b2a6e74b0f9d5570db2cb45668ba746c8ff3f Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Wed, 29 Nov 2023 19:02:03 +0000 Subject: [PATCH 06/15] minimize diff --- src/Compiler/Checking/CheckExpressions.fs | 4 ++-- .../CustomAttributes/AttributeUsage/E_AttributeTargets01.fs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Compiler/Checking/CheckExpressions.fs b/src/Compiler/Checking/CheckExpressions.fs index 385d92a0dbf..6e35ed7960a 100644 --- a/src/Compiler/Checking/CheckExpressions.fs +++ b/src/Compiler/Checking/CheckExpressions.fs @@ -10813,7 +10813,7 @@ and TcNonrecBindingTyparDecls cenv env tpenv bind = let (NormalizedBinding(_, _, _, _, _, _, synTyparDecls, _, _, _, _, _)) = bind TcBindingTyparDecls true cenv env tpenv synTyparDecls -and TcNonRecursiveBinding (declKind: DeclKind) cenv env tpenv ty binding = +and TcNonRecursiveBinding declKind cenv env tpenv ty binding = // Check for unintended shadowing match binding with | SynBinding(headPat = SynPat.LongIdent(longDotId = SynLongIdent(id = [ident]); range = headPatRange)) -> @@ -10822,7 +10822,7 @@ and TcNonRecursiveBinding (declKind: DeclKind) cenv env tpenv ty binding = warning(Error(FSComp.SR.tcInfoIfFunctionShadowsUnionCase(), headPatRange)) | _ -> () | _ -> () - + let binding = BindingNormalization.NormalizeBinding ValOrMemberBinding cenv env binding let explicitTyparInfo, tpenv = TcNonrecBindingTyparDecls cenv env tpenv binding TcNormalizedBinding declKind cenv env tpenv ty None NoSafeInitInfo ([], explicitTyparInfo) binding diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargets01.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargets01.fs index c96c7e51232..15bfe1a8e1d 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargets01.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargets01.fs @@ -29,4 +29,4 @@ type A() = and [] set (x : int) = () [] - static member (+) (op1 : A, op2 : A) = new A() \ No newline at end of file + static member (+) (op1 : A, op2 : A) = new A() From 8c8e95b55ecef792ff14cabff6510d0d8e62450d Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Wed, 29 Nov 2023 22:40:02 +0000 Subject: [PATCH 07/15] WIP more tests --- src/Compiler/Checking/CheckExpressions.fs | 2 ++ .../AttributeUsage/AttributeTargetsIsMethod02.fs | 4 ++-- .../CustomAttributes/AttributeUsage/AttributeUsage.fs | 8 +++++++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/Compiler/Checking/CheckExpressions.fs b/src/Compiler/Checking/CheckExpressions.fs index 385d92a0dbf..4bd712cbcbc 100644 --- a/src/Compiler/Checking/CheckExpressions.fs +++ b/src/Compiler/Checking/CheckExpressions.fs @@ -10538,6 +10538,8 @@ and TcNormalizedBinding declKind (cenv: cenv) env tpenv overallTy safeThisValOpt let attrTgt = if g.langVersion.SupportsFeature(LanguageFeature.EnforceAttributeTargetsOnLetValues) then match pat, rhsExpr with + // TODO: Find out a better way to check for the identity function aka id or fun x -> x + | SynPat.Named _ , SynExpr.Ident(ident = ident) when ident.idText = "id" -> declKind.AllowedAttribTargets memberFlagsOpt | SynPat.Named _ , SynExpr.Lambda _ -> declKind.AllowedAttribTargets memberFlagsOpt | SynPat.Named _, _ when isNil declaredTypars -> AttributeTargets.Field ||| AttributeTargets.Property ||| AttributeTargets.ReturnValue | _ -> declKind.AllowedAttribTargets memberFlagsOpt diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeTargetsIsMethod02.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeTargetsIsMethod02.fs index 939020aee5e..796b1ffe486 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeTargetsIsMethod02.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeTargetsIsMethod02.fs @@ -9,10 +9,10 @@ type MethodOnlyAttribute() = inherit Attribute() [] -let someValue = "someValue" +let someValue = "someValue" // Should fail [] -let i, j, k = (1, 2, 3) +let i, j, k = (1, 2, 3) // Should fail [] let someFunction () = "someFunction" diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs index 8969cd9fc03..c4962a222c5 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs @@ -64,6 +64,13 @@ module CustomAttributes_AttributeUsage = |> verifyCompileAndRun |> shouldSucceed + // SOURCE=AttributeTargetsIsMethod02.fs # AttributeTargetsIsMethod02.fs + [] + let ``AttributeTargetsIsMethod02_fs`` compilation = + compilation + |> verifyCompile + |> shouldSucceed + // SOURCE=AttributeTargetsIsMethod02.fs # AttributeTargetsIsMethod02.fs [] let ``AttributeTargetsIsMethod02_fs preview lang`` compilation = @@ -73,7 +80,6 @@ module CustomAttributes_AttributeUsage = |> shouldFail |> withDiagnostics [ (Error 842, Line 11, Col 3, Line 11, Col 13, "This attribute is not valid for use on this language element"); - (Error 842, Line 41, Col 3, Line 41, Col 13, "This attribute is not valid for use on this language element") ] // SOURCE=ConditionalAttribute.fs # ConditionalAttribute.fs From 0f4879bdafdce41dad24e1da954dd2799a8c2c43 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Thu, 30 Nov 2023 11:31:48 +0000 Subject: [PATCH 08/15] More tests --- src/Compiler/Checking/CheckExpressions.fs | 1 + .../AttributeUsage/AttributeUsage.fs | 3 ++- .../ErrorMessages/TailCallAttribute.fs | 24 ++++--------------- 3 files changed, 7 insertions(+), 21 deletions(-) diff --git a/src/Compiler/Checking/CheckExpressions.fs b/src/Compiler/Checking/CheckExpressions.fs index 00130be6594..39d5b902057 100644 --- a/src/Compiler/Checking/CheckExpressions.fs +++ b/src/Compiler/Checking/CheckExpressions.fs @@ -10541,6 +10541,7 @@ and TcNormalizedBinding declKind (cenv: cenv) env tpenv overallTy safeThisValOpt // TODO: Find out a better way to check for the identity function aka id or fun x -> x | SynPat.Named _ , SynExpr.Ident(ident = ident) when ident.idText = "id" -> declKind.AllowedAttribTargets memberFlagsOpt | SynPat.Named _ , SynExpr.Lambda _ -> declKind.AllowedAttribTargets memberFlagsOpt + | SynPat.Tuple _ , _ | SynPat.Named _, _ when isNil declaredTypars -> AttributeTargets.Field ||| AttributeTargets.Property ||| AttributeTargets.ReturnValue | _ -> declKind.AllowedAttribTargets memberFlagsOpt else diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs index c4962a222c5..7d89d1cf84b 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs @@ -79,7 +79,8 @@ module CustomAttributes_AttributeUsage = |> verifyCompile |> shouldFail |> withDiagnostics [ - (Error 842, Line 11, Col 3, Line 11, Col 13, "This attribute is not valid for use on this language element"); + (Error 842, Line 11, Col 3, Line 11, Col 13, "This attribute is not valid for use on this language element") + (Error 842, Line 14, Col 3, Line 14, Col 13, "This attribute is not valid for use on this language element") ] // SOURCE=ConditionalAttribute.fs # ConditionalAttribute.fs diff --git a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/TailCallAttribute.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/TailCallAttribute.fs index 3366ed91c3f..8399a5b37f6 100644 --- a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/TailCallAttribute.fs +++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/TailCallAttribute.fs @@ -1440,7 +1440,7 @@ namespace N ] [] - let ``Warn about attribute on non-recursive let-bound value`` () = + let ``Error about using attribute with AttributeTargets.Method on non-recursive let-bound value`` () = """ namespace N @@ -1453,18 +1453,10 @@ namespace N |> withLangVersionPreview |> compile |> shouldFail - |> withResults [ - { Error = Warning 3861 - Range = { StartLine = 7 - StartColumn = 13 - EndLine = 7 - EndColumn = 18 } - Message = - "The TailCall attribute should only be applied to recursive functions." } - ] + |> withSingleDiagnostic (Error 842, Line 6, Col 11, Line 6, Col 19, "This attribute is not valid for use on this language element") [] - let ``Warn about attribute on recursive let-bound value`` () = + let ``Error about using attribute with AttributeTargets.Method on recursive let-bound value`` () = """ namespace N @@ -1477,12 +1469,4 @@ namespace N |> withLangVersionPreview |> compile |> shouldFail - |> withResults [ - { Error = Warning 3861 - Range = { StartLine = 7 - StartColumn = 17 - EndLine = 7 - EndColumn = 37 } - Message = - "The TailCall attribute should only be applied to recursive functions." } - ] + |> withSingleDiagnostic (Error 842, Line 6, Col 11, Line 6, Col 19, "This attribute is not valid for use on this language element") From a3392f94301f55012ed1bb789b27b8d7c7379c73 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Thu, 30 Nov 2023 14:14:16 +0000 Subject: [PATCH 09/15] Fix ProjectAnalysisTests --- tests/service/ProjectAnalysisTests.fs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/service/ProjectAnalysisTests.fs b/tests/service/ProjectAnalysisTests.fs index d6211dda1dc..35b2a74f2a8 100644 --- a/tests/service/ProjectAnalysisTests.fs +++ b/tests/service/ProjectAnalysisTests.fs @@ -4724,17 +4724,17 @@ type TestRecord = { B : int } module Test = [)>] - let withType = 0 + let withType() = 0 [>)>] - let withGenericType = 0 + let withGenericType() = 0 [)>] - let withTupleType = 0 + let withTupleType() = 0 [ int>)>] - let withFuncType = 0 + let withFuncType() = 0 [; typeof |])>] - let withTypeArray = 0 + let withTypeArray() = 0 [] - let withIntArray = 0 + let withIntArray() = 0 module NestedModule = type NestedRecordType = { B : int } From a9854c1fb25df6fc388be1f4a1fba785f3457a2a Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Thu, 30 Nov 2023 16:17:26 +0000 Subject: [PATCH 10/15] Fix CompletionProviderTests --- .../tests/FSharp.Editor.Tests/CompletionProviderTests.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vsintegration/tests/FSharp.Editor.Tests/CompletionProviderTests.fs b/vsintegration/tests/FSharp.Editor.Tests/CompletionProviderTests.fs index e94a5f69436..b6c9ec1dadb 100644 --- a/vsintegration/tests/FSharp.Editor.Tests/CompletionProviderTests.fs +++ b/vsintegration/tests/FSharp.Editor.Tests/CompletionProviderTests.fs @@ -423,7 +423,7 @@ xVal**y Assert.True(triggered, "Completion should trigger after typing an identifier that follows a mathematical operation") [] - let ShouldTriggerCompletionAtStartOfFileWithInsertion = + let ShouldTriggerCompletionAtStartOfFileWithInsertion () = let fileContents = """ l""" From fe334b9a0f2453df25ac8b4cbfe6baf41f67fa2a Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Thu, 30 Nov 2023 16:34:17 +0000 Subject: [PATCH 11/15] more tests --- .../AttributeUsage/AttributeTargetsIsMethod02.fs | 5 ++++- .../CustomAttributes/AttributeUsage/AttributeUsage.fs | 1 + .../tests/FSharp.Editor.Tests/CompletionProviderTests.fs | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeTargetsIsMethod02.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeTargetsIsMethod02.fs index 796b1ffe486..84a87ca0867 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeTargetsIsMethod02.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeTargetsIsMethod02.fs @@ -45,4 +45,7 @@ let someTypedFunction4 = id let __someTypedFunction5<'a> = false [] -let __someTypedFunction6<'a> : bool = false \ No newline at end of file +let __someTypedFunction6<'a> : bool = false + +[] +let ``someValue2`` = "someValue" // Should fail \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs index 7d89d1cf84b..5c82841ccb5 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs @@ -81,6 +81,7 @@ module CustomAttributes_AttributeUsage = |> withDiagnostics [ (Error 842, Line 11, Col 3, Line 11, Col 13, "This attribute is not valid for use on this language element") (Error 842, Line 14, Col 3, Line 14, Col 13, "This attribute is not valid for use on this language element") + (Error 842, Line 50, Col 3, Line 50, Col 13, "This attribute is not valid for use on this language element") ] // SOURCE=ConditionalAttribute.fs # ConditionalAttribute.fs diff --git a/vsintegration/tests/FSharp.Editor.Tests/CompletionProviderTests.fs b/vsintegration/tests/FSharp.Editor.Tests/CompletionProviderTests.fs index b6c9ec1dadb..551b804bc37 100644 --- a/vsintegration/tests/FSharp.Editor.Tests/CompletionProviderTests.fs +++ b/vsintegration/tests/FSharp.Editor.Tests/CompletionProviderTests.fs @@ -888,7 +888,7 @@ type T() = VerifyNoCompletionList(fileContents, "member this.M(p") [] - let ``Completion list on abstract member type signature contains modules and types but not keywords or functions`` = + let ``Completion list on abstract member type signature contains modules and types but not keywords or functions`` () = let fileContents = """ type Interface = From 26e577970a7effa3c84d71e243fb6503e7b9b811 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Thu, 30 Nov 2023 20:28:22 +0000 Subject: [PATCH 12/15] Use AttributeTargets.FieldDecl --- src/Compiler/Checking/CheckExpressions.fs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Compiler/Checking/CheckExpressions.fs b/src/Compiler/Checking/CheckExpressions.fs index 39d5b902057..ef761045699 100644 --- a/src/Compiler/Checking/CheckExpressions.fs +++ b/src/Compiler/Checking/CheckExpressions.fs @@ -10538,11 +10538,10 @@ and TcNormalizedBinding declKind (cenv: cenv) env tpenv overallTy safeThisValOpt let attrTgt = if g.langVersion.SupportsFeature(LanguageFeature.EnforceAttributeTargetsOnLetValues) then match pat, rhsExpr with - // TODO: Find out a better way to check for the identity function aka id or fun x -> x | SynPat.Named _ , SynExpr.Ident(ident = ident) when ident.idText = "id" -> declKind.AllowedAttribTargets memberFlagsOpt | SynPat.Named _ , SynExpr.Lambda _ -> declKind.AllowedAttribTargets memberFlagsOpt | SynPat.Tuple _ , _ - | SynPat.Named _, _ when isNil declaredTypars -> AttributeTargets.Field ||| AttributeTargets.Property ||| AttributeTargets.ReturnValue + | SynPat.Named _, _ when isNil declaredTypars -> AttributeTargets.FieldDecl | _ -> declKind.AllowedAttribTargets memberFlagsOpt else declKind.AllowedAttribTargets memberFlagsOpt From 2adfaa02f0fe05429db6b41b2b43f1a9b521e766 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Thu, 30 Nov 2023 20:29:14 +0000 Subject: [PATCH 13/15] Remove unnecessary check in TailCall CheckModuleBinding --- src/Compiler/Checking/TailCallChecks.fs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/Compiler/Checking/TailCallChecks.fs b/src/Compiler/Checking/TailCallChecks.fs index 1faa9a50a35..b8f697ded37 100644 --- a/src/Compiler/Checking/TailCallChecks.fs +++ b/src/Compiler/Checking/TailCallChecks.fs @@ -733,13 +733,8 @@ let CheckModuleBinding cenv (isRec: bool) (TBind _ as bind) = cenv.reportErrors && cenv.g.langVersion.SupportsFeature LanguageFeature.WarningWhenTailCallAttrOnNonRec then - let isNotAFunction = - match bind.Var.ValReprInfo with - | Some info -> info.HasNoArgs - | _ -> false - if - (not isRec || isNotAFunction) + not isRec && HasFSharpAttribute cenv.g cenv.g.attrib_TailCallAttribute bind.Var.Attribs then warning (Error(FSComp.SR.chkTailCallAttrOnNonRec (), bind.Var.Range)) From ebe76a0258c163711c678656412366a5fae4c39f Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Thu, 30 Nov 2023 21:43:04 +0000 Subject: [PATCH 14/15] more tests --- src/Compiler/Checking/CheckExpressions.fs | 3 +- .../AttributeTargetsIsMethod02.fs | 36 ++++++++++++++++++- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/src/Compiler/Checking/CheckExpressions.fs b/src/Compiler/Checking/CheckExpressions.fs index ef761045699..4d985c86781 100644 --- a/src/Compiler/Checking/CheckExpressions.fs +++ b/src/Compiler/Checking/CheckExpressions.fs @@ -10538,8 +10538,9 @@ and TcNormalizedBinding declKind (cenv: cenv) env tpenv overallTy safeThisValOpt let attrTgt = if g.langVersion.SupportsFeature(LanguageFeature.EnforceAttributeTargetsOnLetValues) then match pat, rhsExpr with + | SynPat.Named _ , SynExpr.Lambda _ + | SynPat.Named _ , SynExpr.MatchLambda _ -> declKind.AllowedAttribTargets memberFlagsOpt | SynPat.Named _ , SynExpr.Ident(ident = ident) when ident.idText = "id" -> declKind.AllowedAttribTargets memberFlagsOpt - | SynPat.Named _ , SynExpr.Lambda _ -> declKind.AllowedAttribTargets memberFlagsOpt | SynPat.Tuple _ , _ | SynPat.Named _, _ when isNil declaredTypars -> AttributeTargets.FieldDecl | _ -> declKind.AllowedAttribTargets memberFlagsOpt diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeTargetsIsMethod02.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeTargetsIsMethod02.fs index 84a87ca0867..70d13fd0618 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeTargetsIsMethod02.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeTargetsIsMethod02.fs @@ -48,4 +48,38 @@ let __someTypedFunction5<'a> = false let __someTypedFunction6<'a> : bool = false [] -let ``someValue2`` = "someValue" // Should fail \ No newline at end of file +let ``someValue2`` = "someValue" // Should fail + +type TestConst = + | Bool of bool + +[] +type TestExpr = + | Const of TestConst * Type * int + | Var of string * Type * int + +[] +let (|BoolExpr|_|) = + function + | TestExpr.Const (TestConst.Bool b, _, _) -> Some b + | _ -> None + +[] +[] +let (|BoolExpr2|_|) = + function + | TestExpr.Const(TestConst.Bool b1, _, _) -> ValueSome b1 + | _ -> ValueNone + +[] +let (|BoolExpr3|_|) x = + match x with + | TestExpr.Const (TestConst.Bool b, _, _) -> Some b + | _ -> None + +[] +[] +let (|BoolExpr4|_|) x = + match x with + | TestExpr.Const(TestConst.Bool b1, _, _) -> ValueSome b1 + | _ -> ValueNone \ No newline at end of file From bb447dec9eba0b9e9cf95ea675ee8882c97631ce Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Fri, 1 Dec 2023 06:09:25 +0000 Subject: [PATCH 15/15] more tests --- src/Compiler/Checking/CheckExpressions.fs | 7 ++-- .../AttributeTargetsIsMethod02.fs | 20 ++++++++++- .../AttributeUsage/AttributeUsage.fs | 36 ++++++++++++++++++- 3 files changed, 59 insertions(+), 4 deletions(-) diff --git a/src/Compiler/Checking/CheckExpressions.fs b/src/Compiler/Checking/CheckExpressions.fs index 4d985c86781..2decf1d668c 100644 --- a/src/Compiler/Checking/CheckExpressions.fs +++ b/src/Compiler/Checking/CheckExpressions.fs @@ -10539,8 +10539,11 @@ and TcNormalizedBinding declKind (cenv: cenv) env tpenv overallTy safeThisValOpt if g.langVersion.SupportsFeature(LanguageFeature.EnforceAttributeTargetsOnLetValues) then match pat, rhsExpr with | SynPat.Named _ , SynExpr.Lambda _ - | SynPat.Named _ , SynExpr.MatchLambda _ -> declKind.AllowedAttribTargets memberFlagsOpt - | SynPat.Named _ , SynExpr.Ident(ident = ident) when ident.idText = "id" -> declKind.AllowedAttribTargets memberFlagsOpt + | SynPat.Named _ , SynExpr.App _ + | SynPat.Named _ , SynExpr.MatchLambda _ -> AttributeTargets.Method ||| AttributeTargets.ReturnValue + | SynPat.Named _, _ when not declaredTypars.IsEmpty -> AttributeTargets.Method ||| AttributeTargets.ReturnValue + | SynPat.Named _ , SynExpr.Ident(ident = ident) when ident.idText = "id" -> AttributeTargets.Method ||| AttributeTargets.ReturnValue + | SynPat.Tuple _ , _ | SynPat.Named _, _ when isNil declaredTypars -> AttributeTargets.FieldDecl | _ -> declKind.AllowedAttribTargets memberFlagsOpt diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeTargetsIsMethod02.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeTargetsIsMethod02.fs index 70d13fd0618..7280f2abbc0 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeTargetsIsMethod02.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeTargetsIsMethod02.fs @@ -82,4 +82,22 @@ let (|BoolExpr3|_|) x = let (|BoolExpr4|_|) x = match x with | TestExpr.Const(TestConst.Bool b1, _, _) -> ValueSome b1 - | _ -> ValueNone \ No newline at end of file + | _ -> ValueNone + +let private dangling (target: TestExpr -> TestExpr voption) = + function + | TestExpr.Const (TestConst.Bool _, _, _) as b -> ValueSome b + | _ -> ValueNone + +[] +[] +let (|IfThen|_|) = + dangling (function + | TestExpr.Const(TestConst.Bool b1, _, _) as expr -> ValueSome expr + | _ -> ValueNone) + +[] +let someRecLetBoundValue = nameof(MethodOnlyAttribute) // Should fail + +[] +let rec someRecLetBoundValue2 = nameof(someRecLetBoundValue2) // Should fail \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs index 5c82841ccb5..56af7f9f0ac 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs @@ -64,11 +64,19 @@ module CustomAttributes_AttributeUsage = |> verifyCompileAndRun |> shouldSucceed + // SOURCE=AttributeTargetsIsMethod01.fs # AttributeTargetsIsMethod01.fs + [] + let ``AttributeTargetsIsMethod01_fs preview`` compilation = + compilation + |> withLangVersionPreview + |> verifyCompileAndRun + |> shouldSucceed + // SOURCE=AttributeTargetsIsMethod02.fs # AttributeTargetsIsMethod02.fs [] let ``AttributeTargetsIsMethod02_fs`` compilation = compilation - |> verifyCompile + |> verifyCompileAndRun |> shouldSucceed // SOURCE=AttributeTargetsIsMethod02.fs # AttributeTargetsIsMethod02.fs @@ -103,6 +111,20 @@ module CustomAttributes_AttributeUsage = (Error 842, Line 27, Col 7, Line 27, Col 16, "This attribute is not valid for use on this language element") ] + // SOURCE=E_AttributeTargets01.fs # E_AttributeTargets01.fs + [] + let ``E_AttributeTargets01_fs preview`` compilation = + compilation + |> withLangVersionPreview + |> verifyCompile + |> shouldFail + |> withDiagnostics [ + (Error 842, Line 21, Col 21, Line 21, Col 22, "This attribute is not valid for use on this language element"); + (Error 842, Line 24, Col 21, Line 24, Col 29, "This attribute is not valid for use on this language element"); + (Error 842, Line 27, Col 7, Line 27, Col 16, "This attribute is not valid for use on this language element"); + (Error 842, Line 18, Col 7, Line 18, Col 8, "This attribute is not valid for use on this language element") + ] + // SOURCE=E_AttributeTargets02.fs # E_AttributeTargets02.fs [] let ``E_AttributeTargets02_fs`` compilation = @@ -114,6 +136,18 @@ module CustomAttributes_AttributeUsage = (Error 842, Line 24, Col 7, Line 24, Col 36, "This attribute is not valid for use on this language element") (Error 842, Line 29, Col 15, Line 29, Col 47, "This attribute is not valid for use on this language element") ] + + // SOURCE=E_AttributeTargets02.fs # E_AttributeTargets02.fs + [] + let ``E_AttributeTargets02_fs preview`` compilation = + compilation + |> verifyCompile + |> shouldFail + |> withDiagnostics [ + (Error 842, Line 14, Col 7, Line 14, Col 34, "This attribute is not valid for use on this language element") + (Error 842, Line 24, Col 7, Line 24, Col 36, "This attribute is not valid for use on this language element") + (Error 842, Line 29, Col 15, Line 29, Col 47, "This attribute is not valid for use on this language element") + ] // SOURCE=E_ConditionalAttribute.fs SCFLAGS="--test:ErrorRanges" # E_ConditionalAttribute.fs []