diff --git a/src/Compiler/AbstractIL/il.fs b/src/Compiler/AbstractIL/il.fs index 2321a26bf0..23e6186253 100644 --- a/src/Compiler/AbstractIL/il.fs +++ b/src/Compiler/AbstractIL/il.fs @@ -1203,10 +1203,11 @@ type ILAttribute = [] type ILAttributes(array: ILAttribute[]) = + member _.AsArray() = array - member x.AsArray() = array + member _.AsList() = array |> Array.toList - member x.AsList() = array |> Array.toList + static member val internal Empty = ILAttributes([||]) [] type ILAttributesStored = diff --git a/src/Compiler/AbstractIL/il.fsi b/src/Compiler/AbstractIL/il.fsi index 12067f8911..8b5a3160c0 100644 --- a/src/Compiler/AbstractIL/il.fsi +++ b/src/Compiler/AbstractIL/il.fsi @@ -855,6 +855,8 @@ type ILAttributes = member AsList: unit -> ILAttribute list + static member internal Empty: ILAttributes + /// Represents the efficiency-oriented storage of ILAttributes in another item. [] type ILAttributesStored diff --git a/src/Compiler/Checking/AttributeChecking.fs b/src/Compiler/Checking/AttributeChecking.fs index 0e013980da..7731b83c25 100644 --- a/src/Compiler/Checking/AttributeChecking.fs +++ b/src/Compiler/Checking/AttributeChecking.fs @@ -21,6 +21,8 @@ open FSharp.Compiler.TypeHierarchy #if !NO_TYPEPROVIDERS open FSharp.Compiler.TypeProviders open FSharp.Core.CompilerServices +open Features + #endif exception ObsoleteWarning of string * range @@ -229,22 +231,36 @@ let MethInfoHasAttribute g m attribSpec minfo = |> Option.isSome +let private CheckCompilerFeatureRequiredAttribute (g: TcGlobals) cattrs msg m = + // In some cases C# will generate both ObsoleteAttribute and CompilerFeatureRequiredAttribute. + // Specifically, when default constructor is generated for class with any reqired members in them. + // ObsoleteAttribute should be ignored if CompilerFeatureRequiredAttribute is present, and its name is "RequiredMembers". + let (AttribInfo(tref,_)) = g.attrib_CompilerFeatureRequiredAttribute + match TryDecodeILAttribute tref cattrs with + | Some([ILAttribElem.String (Some featureName) ], _) when featureName = "RequiredMembers" -> + CompleteD + | _ -> + ErrorD (ObsoleteError(msg, m)) + /// Check IL attributes for 'ObsoleteAttribute', returning errors and warnings as data -let private CheckILAttributes (g: TcGlobals) isByrefLikeTyconRef cattrs m = +let private CheckILAttributes (g: TcGlobals) isByrefLikeTyconRef cattrs m = let (AttribInfo(tref,_)) = g.attrib_SystemObsolete - match TryDecodeILAttribute tref cattrs with - | Some ([ILAttribElem.String (Some msg) ], _) when not isByrefLikeTyconRef -> + match TryDecodeILAttribute tref cattrs with + | Some ([ILAttribElem.String (Some msg) ], _) when not isByrefLikeTyconRef -> WarnD(ObsoleteWarning(msg, m)) - | Some ([ILAttribElem.String (Some msg); ILAttribElem.Bool isError ], _) when not isByrefLikeTyconRef -> - if isError then - ErrorD (ObsoleteError(msg, m)) - else + | Some ([ILAttribElem.String (Some msg); ILAttribElem.Bool isError ], _) when not isByrefLikeTyconRef -> + if isError then + if g.langVersion.SupportsFeature(LanguageFeature.RequiredPropertiesSupport) then + CheckCompilerFeatureRequiredAttribute g cattrs msg m + else + ErrorD (ObsoleteError(msg, m)) + else WarnD (ObsoleteWarning(msg, m)) - | Some ([ILAttribElem.String None ], _) when not isByrefLikeTyconRef -> + | Some ([ILAttribElem.String None ], _) when not isByrefLikeTyconRef -> WarnD(ObsoleteWarning("", m)) - | Some _ when not isByrefLikeTyconRef -> + | Some _ when not isByrefLikeTyconRef -> WarnD(ObsoleteWarning("", m)) - | _ -> + | _ -> CompleteD let langVersionPrefix = "--langversion:preview" diff --git a/src/Compiler/Checking/CheckExpressions.fs b/src/Compiler/Checking/CheckExpressions.fs index 7004439ef0..fe124187b6 100644 --- a/src/Compiler/Checking/CheckExpressions.fs +++ b/src/Compiler/Checking/CheckExpressions.fs @@ -1497,6 +1497,44 @@ let CheckForAbnormalOperatorNames (cenv: cenv) (idRange: range) coreDisplayName warning(StandardOperatorRedefinitionWarning(FSComp.SR.tcInvalidMemberNameFixedTypes opName, idRange)) | Other -> () +let CheckInitProperties (g: TcGlobals) (minfo: MethInfo) methodName mItem = + if g.langVersion.SupportsFeature(LanguageFeature.InitPropertiesSupport) then + // Check, wheter this method has external init, emit an error diagnostic in this case. + if minfo.HasExternalInit then + errorR (Error (FSComp.SR.tcSetterForInitOnlyPropertyCannotBeCalled1 methodName, mItem)) + +let CheckRequiredProperties (g:TcGlobals) (env: TcEnv) (cenv: TcFileState) (minfo: MethInfo) finalAssignedItemSetters mMethExpr = + // Make sure, if apparent type has any required properties, they all are in the `finalAssignedItemSetters`. + // If it is a constructor, and it is not marked with `SetsRequiredMembersAttributeAttribute`, then: + // 1. Get all properties of the type. + // 2. Check if any of them has `IsRequired` set. + // 2.1. If there are none, proceed as usual + // 2.2. If there are any, make sure all of them (or their setters) are in `finalAssignedItemSetters`. + // 3. If some are missing, produce a diagnostic which missing ones. + if g.langVersion.SupportsFeature(LanguageFeature.RequiredPropertiesSupport) + && minfo.IsConstructor + && not (TryFindILAttribute g.attrib_SetsRequiredMembersAttribute (minfo.GetCustomAttrs())) then + + let requiredProps = + [ + let props = GetImmediateIntrinsicPropInfosOfType (None, AccessibleFromSomeFSharpCode) g cenv.amap range0 minfo.ApparentEnclosingType + for prop in props do + if prop.IsRequired then + prop + ] + + if requiredProps.Length > 0 then + let setterPropNames = + finalAssignedItemSetters + |> List.choose (function | AssignedItemSetter(_, AssignedPropSetter (pinfo, _, _), _) -> Some pinfo.PropertyName | _ -> None) + + let missingProps = + requiredProps + |> List.filter (fun pinfo -> not (List.contains pinfo.PropertyName setterPropNames)) + if missingProps.Length > 0 then + let details = NicePrint.multiLineStringOfPropInfos g cenv.amap mMethExpr env.DisplayEnv missingProps + errorR(Error(FSComp.SR.tcMissingRequiredMembers details, mMethExpr)) + let MakeAndPublishVal (cenv: cenv) env (altActualParent, inSig, declKind, valRecInfo, vscheme, attrs, xmlDoc, konst, isGeneratedEventVal) = let g = cenv.g @@ -8978,6 +9016,9 @@ and TcLookupThen cenv overallTy env tpenv mObjExpr objExpr objExprTy longId dela // To get better warnings we special case some of the few known mutate-a-struct method names let mutates = (if methodName = "MoveNext" || methodName = "GetNextArg" then DefinitelyMutates else PossiblyMutates) + // Check if we have properties with "init-only" setters, which we try to call after init is done. + CheckInitProperties g (List.head minfos) methodName mItem + #if !NO_TYPEPROVIDERS match TryTcMethodAppToStaticConstantArgs cenv env tpenv (minfos, tyArgsOpt, mExprAndItem, mItem) with | Some minfoAfterStaticArguments -> @@ -9024,6 +9065,10 @@ and TcLookupThen cenv overallTy env tpenv mObjExpr objExpr objExprTy longId dela if isNil meths then error (Error (FSComp.SR.tcPropertyIsNotReadable nm, mItem)) TcMethodApplicationThen cenv env overallTy None tpenv tyArgsOpt objArgs mExprAndItem mItem nm ad PossiblyMutates true meths afterResolution NormalValUse args atomicFlag delayed else + + if g.langVersion.SupportsFeature(LanguageFeature.RequiredPropertiesSupport) && pinfo.IsSetterInitOnly then + errorR (Error (FSComp.SR.tcInitOnlyPropertyCannotBeSet1 nm, mItem)) + let args = if pinfo.IsIndexer then args else [] let mut = (if isStructTy g (tyOfExpr g objExpr) then DefinitelyMutates else PossiblyMutates) TcMethodApplicationThen cenv env overallTy None tpenv tyArgsOpt objArgs mStmt mItem nm ad mut true meths afterResolution NormalValUse (args @ [expr2]) atomicFlag [] @@ -9727,6 +9772,9 @@ and TcMethodApplication // Handle post-hoc property assignments let setterExprPrebinders, callExpr3 = let expr = callExpr2b + + CheckRequiredProperties g env cenv finalCalledMethInfo finalAssignedItemSetters mMethExpr + if isCheckingAttributeCall then [], expr elif isNil finalAssignedItemSetters then @@ -9738,7 +9786,7 @@ and TcMethodApplication // Build the expression that mutates the properties on the result of the call let setterExprPrebinders, propSetExpr = (mkUnit g mMethExpr, finalAssignedItemSetters) ||> List.mapFold (fun acc assignedItemSetter -> - let argExprPrebinder, action, m = TcSetterArgExpr cenv env denv objExpr ad assignedItemSetter + let argExprPrebinder, action, m = TcSetterArgExpr cenv env denv objExpr ad assignedItemSetter finalCalledMethInfo.IsConstructor argExprPrebinder, mkCompGenSequential m acc action) // now put them together @@ -9784,7 +9832,7 @@ and TcMethodApplication (callExpr6, finalAttributeAssignedNamedItems, delayed), tpenv /// For Method(X = expr) 'X' can be a property, IL Field or F# record field -and TcSetterArgExpr cenv env denv objExpr ad (AssignedItemSetter(id, setter, CallerArg(callerArgTy, m, isOptCallerArg, argExpr))) = +and TcSetterArgExpr cenv env denv objExpr ad (AssignedItemSetter(id, setter, CallerArg(callerArgTy, m, isOptCallerArg, argExpr))) calledFromConstructor = let g = cenv.g if isOptCallerArg then @@ -9793,6 +9841,10 @@ and TcSetterArgExpr cenv env denv objExpr ad (AssignedItemSetter(id, setter, Cal let argExprPrebinder, action, defnItem = match setter with | AssignedPropSetter (pinfo, pminfo, pminst) -> + + if g.langVersion.SupportsFeature(LanguageFeature.RequiredPropertiesSupport) && pinfo.IsSetterInitOnly && not calledFromConstructor then + errorR (Error (FSComp.SR.tcInitOnlyPropertyCannotBeSet1 pinfo.PropertyName, m)) + MethInfoChecks g cenv.amap true None [objExpr] ad m pminfo let calledArgTy = List.head (List.head (pminfo.GetParamTypes(cenv.amap, m, pminst))) let tcVal = LightweightTcValForUsingInBuildMethodCall g diff --git a/src/Compiler/Checking/NicePrint.fs b/src/Compiler/Checking/NicePrint.fs index df08572483..f9ede5721e 100644 --- a/src/Compiler/Checking/NicePrint.fs +++ b/src/Compiler/Checking/NicePrint.fs @@ -1556,6 +1556,10 @@ module InfoMemberPrinting = layoutType denv retTy ^^ getterSetter + let formatPropInfoToBufferFreeStyle g amap m denv os (pinfo: PropInfo) = + let resL = prettyLayoutOfPropInfoFreeStyle g amap m denv pinfo + resL |> bufferL os + let formatMethInfoToBufferFreeStyle amap m denv os (minfo: MethInfo) = let _, resL = prettyLayoutOfMethInfoFreeStyle amap m denv emptyTyparInst minfo resL |> bufferL os @@ -2472,6 +2476,16 @@ let multiLineStringOfMethInfos infoReader m denv minfos = |> List.map (sprintf "%s %s" Environment.NewLine) |> String.concat "" +let stringOfPropInfo g amap m denv pinfo = + buildString (fun buf -> InfoMemberPrinting.formatPropInfoToBufferFreeStyle g amap m denv buf pinfo) + +/// Convert PropInfos to lines separated by newline including a newline as the first character +let multiLineStringOfPropInfos g amap m denv pinfos = + pinfos + |> List.map (stringOfPropInfo g amap m denv) + |> List.map (sprintf "%s %s" Environment.NewLine) + |> String.concat "" + /// Convert a ParamData to a string let stringOfParamData denv paramData = buildString (fun buf -> InfoMemberPrinting.formatParamDataToBuffer denv buf paramData) diff --git a/src/Compiler/Checking/NicePrint.fsi b/src/Compiler/Checking/NicePrint.fsi index 523202af9b..f00cd3395e 100644 --- a/src/Compiler/Checking/NicePrint.fsi +++ b/src/Compiler/Checking/NicePrint.fsi @@ -82,6 +82,11 @@ val stringOfMethInfo: infoReader: InfoReader -> m: range -> denv: DisplayEnv -> val multiLineStringOfMethInfos: infoReader: InfoReader -> m: range -> denv: DisplayEnv -> minfos: MethInfo list -> string +val stringOfPropInfo: g: TcGlobals -> amap: ImportMap -> m: range -> denv: DisplayEnv -> pinfo: PropInfo -> string + +val multiLineStringOfPropInfos: + g: TcGlobals -> amap: ImportMap -> m: range -> denv: DisplayEnv -> pinfos: PropInfo list -> string + val stringOfParamData: denv: DisplayEnv -> paramData: ParamData -> string val layoutOfParamData: denv: DisplayEnv -> paramData: ParamData -> Layout diff --git a/src/Compiler/Checking/infos.fs b/src/Compiler/Checking/infos.fs index c5d45e95e3..ddaf2e35b0 100644 --- a/src/Compiler/Checking/infos.fs +++ b/src/Compiler/Checking/infos.fs @@ -22,6 +22,8 @@ open FSharp.Compiler.Xml #if !NO_TYPEPROVIDERS open FSharp.Compiler.TypeProviders +open FSharp.Compiler.AbstractIL + #endif //------------------------------------------------------------------------- @@ -152,6 +154,11 @@ let private GetInstantiationForPropertyVal g (ty, vref) = let memberParentTypars, memberMethodTypars, _retTy, parentTyArgs = AnalyzeTypeOfMemberVal false g (ty, vref) CombineMethInsts memberParentTypars memberMethodTypars parentTyArgs (generalizeTypars memberMethodTypars) +let private HasExternalInit (mref: ILMethodRef) : bool = + match mref.ReturnType with + | ILType.Modified(_, cls, _) -> cls.FullName = "System.Runtime.CompilerServices.IsExternalInit" + | _ -> false + /// Describes the sequence order of the introduction of an extension method. Extension methods that are introduced /// later through 'open' get priority in overload resolution. type ExtensionMethodPriority = uint64 @@ -933,6 +940,12 @@ type MethInfo = | FSMeth _ -> false // F# defined methods not supported yet. Must be a language feature. | _ -> false + /// Indicates, wheter this method has `IsExternalInit` modreq. + member x.HasExternalInit = + match x with + | ILMeth (_, ilMethInfo, _) -> HasExternalInit ilMethInfo.ILMethodRef + | _ -> false + /// Indicates if this method is an extension member that is read-only. /// An extension member is considered read-only if the first argument is a read-only byref (inref) type. member x.IsReadOnlyExtensionMember (amap: ImportMap, m) = @@ -1053,6 +1066,12 @@ type MethInfo = else [] #endif + /// Get custom attributes for method (only applicable for IL methods) + member x.GetCustomAttrs() = + match x with + | ILMeth(_, ilMethInfo, _) -> ilMethInfo.RawMetadata.CustomAttrs + | _ -> ILAttributes.Empty + /// Get the parameter attributes of a method info, which get combined with the parameter names and types member x.GetParamAttribs(amap, m) = match x with @@ -1562,6 +1581,10 @@ type ILPropInfo = /// Indicates if the IL property has a 'set' method member x.HasSetter = Option.isSome x.RawMetadata.SetMethod + /// Indidcates whether IL property has an init-only setter (i.e. has the `System.Runtime.CompilerServices.IsExternalInit` modifer) + member x.IsSetterInitOnly = + x.HasSetter && HasExternalInit x.SetterMethod.ILMethodRef + /// Indicates if the IL property is static member x.IsStatic = (x.RawMetadata.CallingConv = ILThisConvention.Static) @@ -1575,6 +1598,9 @@ type ILPropInfo = (x.HasGetter && x.GetterMethod.IsNewSlot) || (x.HasSetter && x.SetterMethod.IsNewSlot) + /// Indicates if the property is required, i.e. has RequiredMemberAttribute applied. + member x.IsRequired = TryFindILAttribute x.TcGlobals.attrib_RequiredMemberAttribute x.RawMetadata.CustomAttrs + /// Get the names and types of the indexer arguments associated with the IL property. /// /// Any type parameters of the enclosing type are instantiated in the type returned. @@ -1688,6 +1714,22 @@ type PropInfo = | ProvidedProp(_, pi, m) -> pi.PUntaint((fun pi -> pi.CanWrite), m) #endif + member x.IsSetterInitOnly = + match x with + | ILProp ilpinfo -> ilpinfo.IsSetterInitOnly + | FSProp _ -> false +#if !NO_TYPEPROVIDERS + | ProvidedProp _ -> false +#endif + + member x.IsRequired = + match x with + | ILProp ilpinfo -> ilpinfo.IsRequired + | FSProp _ -> false +#if !NO_TYPEPROVIDERS + | ProvidedProp _ -> false +#endif + /// Indicates if this is an extension member member x.IsExtensionMember = match x.ArbitraryValRef with @@ -2263,4 +2305,4 @@ let PropInfosEquivByNameAndSig erasureFlag g amap m (pinfo: PropInfo) (pinfo2: P let SettersOfPropInfos (pinfos: PropInfo list) = pinfos |> List.choose (fun pinfo -> if pinfo.HasSetter then Some(pinfo.SetterMethod, Some pinfo) else None) -let GettersOfPropInfos (pinfos: PropInfo list) = pinfos |> List.choose (fun pinfo -> if pinfo.HasGetter then Some(pinfo.GetterMethod, Some pinfo) else None) +let GettersOfPropInfos (pinfos: PropInfo list) = pinfos |> List.choose (fun pinfo -> if pinfo.HasGetter then Some(pinfo.GetterMethod, Some pinfo) else None) \ No newline at end of file diff --git a/src/Compiler/Checking/infos.fsi b/src/Compiler/Checking/infos.fsi index dba5200afb..9d4fd965a6 100644 --- a/src/Compiler/Checking/infos.fsi +++ b/src/Compiler/Checking/infos.fsi @@ -423,6 +423,9 @@ type MethInfo = /// Receiver must be a struct type. member IsReadOnly: bool + /// Indicates, wheter this method has `IsExternalInit` modreq. + member HasExternalInit: bool + /// Indicates if the enclosing type for the method is a value type. /// /// For an extension method, this indicates if the method extends a struct type. @@ -493,6 +496,9 @@ type MethInfo = /// An instance method returns one object argument. member GetObjArgTypes: amap: ImportMap * m: range * minst: TypeInst -> TType list + /// Get custom attributes for method (only applicable for IL methods) + member GetCustomAttrs: unit -> ILAttributes + /// Get the parameter attributes of a method info, which get combined with the parameter names and types member GetParamAttribs: amap: ImportMap * m: range -> (bool * bool * bool * OptionalArgInfo * CallerInfo * ReflectedArgInfo) list list @@ -695,6 +701,9 @@ type ILPropInfo = /// Get the declaring IL type of the IL property, including any generic instantiation member ILTypeInfo: ILTypeInfo + /// Is the property requied (has the RequiredMemberAttribute). + member IsRequired: bool + /// Indicates if the IL property is logically a 'newslot', i.e. hides any previous slots of the same name. member IsNewSlot: bool @@ -787,6 +796,12 @@ type PropInfo = /// Indicates if this property has an associated setter method. member HasSetter: bool + /// Indidcates whether IL property has an init-only setter (i.e. has the `System.Runtime.CompilerServices.IsExternalInit` modifer) + member IsSetterInitOnly: bool + + /// Is the property requied (has the RequiredMemberAttribute). + member IsRequired: bool + member ImplementedSlotSignatures: SlotSig list /// Indicates if this property is marked 'override' and thus definitely overrides another property. diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt index bb407db779..60e5702d44 100644 --- a/src/Compiler/FSComp.txt +++ b/src/Compiler/FSComp.txt @@ -652,6 +652,8 @@ tcExpressionWithIfRequiresParenthesis,"This list or array expression includes an 808,tcLookupMayNotBeUsedHere,"This lookup cannot be used here" 809,tcPropertyIsStatic,"Property '%s' is static" 810,tcPropertyCannotBeSet1,"Property '%s' cannot be set" +810,tcInitOnlyPropertyCannotBeSet1,"Init-only property '%s' cannot be set outside the initialization code. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization" +810,tcSetterForInitOnlyPropertyCannotBeCalled1,"Cannot call '%s' - a setter for init-only property, please use object initialization instead. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization" 811,tcConstructorsCannotBeFirstClassValues,"Constructors must be applied to arguments and cannot be used as first-class values. If necessary use an anonymous function '(fun arg1 ... argN -> new Type(arg1,...,argN))'." 812,tcSyntaxFormUsedOnlyWithRecordLabelsPropertiesAndFields,"The syntax 'expr.id' may only be used with record labels, properties and fields" 813,tcEventIsStatic,"Event '%s' is static" @@ -1537,6 +1539,8 @@ featureStructActivePattern,"struct representation for active patterns" featureRelaxWhitespace2,"whitespace relaxation v2" featureReallyLongList,"list literals of any size" featureErrorOnDeprecatedRequireQualifiedAccess,"give error on deprecated access of construct with RequireQualifiedAccess attribute" +featureRequiredProperties,"support for required properties" +featureInitProperties,"support for consuming init properties" featureLowercaseDUWhenRequireQualifiedAccess,"Allow lowercase DU when RequireQualifiedAccess attribute" 3353,fsiInvalidDirective,"Invalid directive '#%s %s'" 3354,tcNotAFunctionButIndexerNamedIndexingNotYetEnabled,"This value supports indexing, e.g. '%s.[index]'. The syntax '%s[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation." @@ -1627,3 +1631,4 @@ reprStateMachineInvalidForm,"The state machine has an unexpected form" 3522,tcAnonRecdDuplicateFieldId,"The field '%s' appears multiple times in this record expression." 3523,tcAnonRecdTypeDuplicateFieldId,"The field '%s' appears multiple times in this anonymous record type." 3524,parsExpectingExpressionInTuple,"Expecting expression" +3545,tcMissingRequiredMembers,"The following required properties have to be initalized:%s" \ No newline at end of file diff --git a/src/Compiler/Facilities/LanguageFeatures.fs b/src/Compiler/Facilities/LanguageFeatures.fs index 77b93032ba..03401823c1 100644 --- a/src/Compiler/Facilities/LanguageFeatures.fs +++ b/src/Compiler/Facilities/LanguageFeatures.fs @@ -49,6 +49,8 @@ type LanguageFeature = | DelegateTypeNameResolutionFix | ReallyLongLists | ErrorOnDeprecatedRequireQualifiedAccess + | RequiredPropertiesSupport + | InitPropertiesSupport | LowercaseDUWhenRequireQualifiedAccess /// LanguageVersion management @@ -112,6 +114,8 @@ type LanguageVersion(versionText) = LanguageFeature.BetterExceptionPrinting, previewVersion LanguageFeature.ReallyLongLists, previewVersion LanguageFeature.ErrorOnDeprecatedRequireQualifiedAccess, previewVersion + LanguageFeature.RequiredPropertiesSupport, previewVersion + LanguageFeature.InitPropertiesSupport, previewVersion LanguageFeature.LowercaseDUWhenRequireQualifiedAccess, previewVersion ] @@ -212,6 +216,8 @@ type LanguageVersion(versionText) = | LanguageFeature.DelegateTypeNameResolutionFix -> FSComp.SR.featureDelegateTypeNameResolutionFix () | LanguageFeature.ReallyLongLists -> FSComp.SR.featureReallyLongList () | LanguageFeature.ErrorOnDeprecatedRequireQualifiedAccess -> FSComp.SR.featureErrorOnDeprecatedRequireQualifiedAccess () + | LanguageFeature.RequiredPropertiesSupport -> FSComp.SR.featureRequiredProperties () + | LanguageFeature.InitPropertiesSupport -> FSComp.SR.featureInitProperties () | LanguageFeature.LowercaseDUWhenRequireQualifiedAccess -> FSComp.SR.featureLowercaseDUWhenRequireQualifiedAccess () /// Get a version string associated with the given feature. diff --git a/src/Compiler/Facilities/LanguageFeatures.fsi b/src/Compiler/Facilities/LanguageFeatures.fsi index 8227c947c7..1e2c977a4a 100644 --- a/src/Compiler/Facilities/LanguageFeatures.fsi +++ b/src/Compiler/Facilities/LanguageFeatures.fsi @@ -39,6 +39,8 @@ type LanguageFeature = | DelegateTypeNameResolutionFix | ReallyLongLists | ErrorOnDeprecatedRequireQualifiedAccess + | RequiredPropertiesSupport + | InitPropertiesSupport | LowercaseDUWhenRequireQualifiedAccess /// LanguageVersion management diff --git a/src/Compiler/TypedTree/TcGlobals.fs b/src/Compiler/TypedTree/TcGlobals.fs index 9c1a92d221..31e0068d79 100755 --- a/src/Compiler/TypedTree/TcGlobals.fs +++ b/src/Compiler/TypedTree/TcGlobals.fs @@ -983,6 +983,9 @@ type TcGlobals( tryFindSysAttrib "System.Runtime.CompilerServices.ModuleInitializerAttribute" tryFindSysAttrib "System.Runtime.CompilerServices.CallerArgumentExpressionAttribute" tryFindSysAttrib "System.Runtime.InteropServices.UnmanagedCallersOnlyAttribute" + tryFindSysAttrib "System.Runtime.CompilerServices.CompilerFeatureRequiredAttribute" + tryFindSysAttrib "System.Diagnostics.CodeAnalysis.SetsRequiredMembersAttribute" + tryFindSysAttrib "System.Runtime.CompilerServices.RequiredMemberAttribute" ] |> List.choose (Option.map (fun x -> x.TyconRef)) override _.ToString() = "" @@ -1425,6 +1428,9 @@ type TcGlobals( member val attrib_SecurityCriticalAttribute = findSysAttrib "System.Security.SecurityCriticalAttribute" member val attrib_SecuritySafeCriticalAttribute = findSysAttrib "System.Security.SecuritySafeCriticalAttribute" member val attrib_ComponentModelEditorBrowsableAttribute = findSysAttrib "System.ComponentModel.EditorBrowsableAttribute" + member val attrib_CompilerFeatureRequiredAttribute = findSysAttrib "System.Runtime.CompilerServices.CompilerFeatureRequiredAttribute" + member val attrib_SetsRequiredMembersAttribute = findSysAttrib "System.Diagnostics.CodeAnalysis.SetsRequiredMembersAttribute" + member val attrib_RequiredMemberAttribute = findSysAttrib "System.Runtime.CompilerServices.RequiredMemberAttribute" member g.improveType tcref tinst = improveTy tcref tinst diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf index bf85ca9433..8052182cec 100644 --- a/src/Compiler/xlf/FSComp.txt.cs.xlf +++ b/src/Compiler/xlf/FSComp.txt.cs.xlf @@ -187,6 +187,11 @@ Notace expr[idx] pro indexování a vytváření řezů + + support for consuming init properties + support for consuming init properties + + interfaces with multiple generic instantiation rozhraní s vícenásobným obecným vytvářením instancí @@ -257,6 +262,11 @@ relaxace whitespace v2 + + support for required properties + support for required properties + + resumable state machines obnovitelné stavové stroje @@ -707,6 +717,11 @@ Tento výraz používá implicitní převod {0} pro převod typu {1} na typ {2}. Přečtěte si téma https://aka.ms/fsharp-implicit-convs. Toto upozornění může být vypnuté pomocí '#nowarn \"3391\". + + Init-only property '{0}' cannot be set outside the initialization code. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization + Init-only property '{0}' cannot be set outside the initialization code. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization + + The 'InlineIfLambda' attribute may only be used on parameters of inlined functions of methods whose type is a function or F# delegate type. Atribut InlineIfLambda je možné použít pouze u parametrů vložených funkcí metod s typem funkce nebo typem delegáta F#. @@ -772,6 +787,11 @@ K hodnotě označené jako literál se {0} nedá přiřadit. + + The following required properties have to be initalized:{0} + The following required properties have to be initalized:{0} + + Using methods with 'NoEagerConstraintApplicationAttribute' requires /langversion:6.0 or later Použití metod s atributem NoEagerConstraintApplicationAttribute vyžaduje /langversion:6.0 nebo novější. @@ -852,6 +872,11 @@ Použití obnovitelného kódu nebo obnovitelných stavových strojů vyžaduje /langversion:preview. + + Cannot call '{0}' - a setter for init-only property, please use object initialization instead. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization + Cannot call '{0}' - a setter for init-only property, please use object initialization instead. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization + + This expression implicitly converts type '{0}' to type '{1}'. See https://aka.ms/fsharp-implicit-convs. Tento výraz implicitně převede typ {0} na typ {1}. Přečtěte si téma https://aka.ms/fsharp-implicit-convs. diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf index 9f1ac3fe78..3d3dc8c260 100644 --- a/src/Compiler/xlf/FSComp.txt.de.xlf +++ b/src/Compiler/xlf/FSComp.txt.de.xlf @@ -187,6 +187,11 @@ expr[idx]-Notation zum Indizieren und Aufteilen + + support for consuming init properties + support for consuming init properties + + interfaces with multiple generic instantiation Schnittstellen mit mehrfacher generischer Instanziierung @@ -257,6 +262,11 @@ whitespace relaxation v2 + + support for required properties + support for required properties + + resumable state machines Fortsetzbarer Zustand-Maschinen @@ -707,6 +717,11 @@ Dieser Ausdruck verwendet die implizite Konvertierung "{0}", um den Typ "{1}" in den Typ "{2}" zu konvertieren. Siehe https://aka.ms/fsharp-implicit-convs. Diese Warnung kann durch "#nowarn \" 3391 \ " deaktiviert werden. + + Init-only property '{0}' cannot be set outside the initialization code. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization + Init-only property '{0}' cannot be set outside the initialization code. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization + + The 'InlineIfLambda' attribute may only be used on parameters of inlined functions of methods whose type is a function or F# delegate type. Das "InlineIfLambda-Attribut" darf nur für Parameter von Inlinefunktionen von Methoden verwendet werden, deren Typ ein Funktions-oder F #-Delegattyp ist. @@ -772,6 +787,11 @@ "{0}" kann keinem als Literal markierten Wert zugewiesen werden. + + The following required properties have to be initalized:{0} + The following required properties have to be initalized:{0} + + Using methods with 'NoEagerConstraintApplicationAttribute' requires /langversion:6.0 or later Die Verwendung von Methoden mit "NoEagerConstraintApplicationAttribute" erfordert /langversion:6.0 oder höher. @@ -852,6 +872,11 @@ Die Verwendung von Fortsetzbarem Code oder fortsetzbaren Zustandscomputern erfordert /langversion:preview + + Cannot call '{0}' - a setter for init-only property, please use object initialization instead. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization + Cannot call '{0}' - a setter for init-only property, please use object initialization instead. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization + + This expression implicitly converts type '{0}' to type '{1}'. See https://aka.ms/fsharp-implicit-convs. Dieser Ausdruck konvertiert den Typ "{0}" implizit in den Typ "{1}". Siehe https://aka.ms/fsharp-implicit-convs. diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf index 86d3eea300..ba19316436 100644 --- a/src/Compiler/xlf/FSComp.txt.es.xlf +++ b/src/Compiler/xlf/FSComp.txt.es.xlf @@ -187,6 +187,11 @@ Notación para indexación y segmentación expr[idx] + + support for consuming init properties + support for consuming init properties + + interfaces with multiple generic instantiation interfaces con creación de instancias genéricas múltiples @@ -257,6 +262,11 @@ relajación de espacios en blanco v2 + + support for required properties + support for required properties + + resumable state machines máquinas de estado reanudables @@ -707,6 +717,11 @@ Esta expresión usa la conversión implícita '{0}' para convertir el tipo '{1}' al tipo '{2}'. Consulte https://aka.ms/fsharp-implicit-convs. Esta advertencia se puede deshabilitar mediante '#nowarn \"3391\". + + Init-only property '{0}' cannot be set outside the initialization code. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization + Init-only property '{0}' cannot be set outside the initialization code. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization + + The 'InlineIfLambda' attribute may only be used on parameters of inlined functions of methods whose type is a function or F# delegate type. El atributo "InlineIfLambda" solo se puede usar en los parámetros de funciones insertadas de métodos cuyo tipo es una función o un tipo de delegado F#. @@ -772,6 +787,11 @@ No se puede asignar "{0}" a un valor marcado como literal + + The following required properties have to be initalized:{0} + The following required properties have to be initalized:{0} + + Using methods with 'NoEagerConstraintApplicationAttribute' requires /langversion:6.0 or later El uso de métodos con "NoEagerConstraintApplicationAttribute" requiere /langversion:6.0 o posteriores @@ -852,6 +872,11 @@ El uso de código reanudable o de máquinas de estado reanudables requiere /langversion:preview + + Cannot call '{0}' - a setter for init-only property, please use object initialization instead. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization + Cannot call '{0}' - a setter for init-only property, please use object initialization instead. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization + + This expression implicitly converts type '{0}' to type '{1}'. See https://aka.ms/fsharp-implicit-convs. Esta expresión convierte implícitamente el tipo '{0}' al tipo '{1}'. Consulte https://aka.ms/fsharp-implicit-convs. diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf index 7b1a397388..4ed2c0da2a 100644 --- a/src/Compiler/xlf/FSComp.txt.fr.xlf +++ b/src/Compiler/xlf/FSComp.txt.fr.xlf @@ -187,6 +187,11 @@ Notation expr[idx] pour l’indexation et le découpage + + support for consuming init properties + support for consuming init properties + + interfaces with multiple generic instantiation interfaces avec plusieurs instanciations génériques @@ -257,6 +262,11 @@ relaxation des espaces blancs v2 + + support for required properties + support for required properties + + resumable state machines ordinateurs d’état pouvant être repris @@ -707,6 +717,11 @@ Cette expression utilise la conversion implicite « {0}<» pour convertir le type « {1} » en type « {2} ». Voir https://aka.ms/fsharp-implicit-convs. Cet avertissement peut être désactivé à l’aide de '#nowarn \"3391\". + + Init-only property '{0}' cannot be set outside the initialization code. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization + Init-only property '{0}' cannot be set outside the initialization code. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization + + The 'InlineIfLambda' attribute may only be used on parameters of inlined functions of methods whose type is a function or F# delegate type. L’attribut « InlineIfLambda » ne peut être utilisé que sur les paramètres des fonctions incorporées des méthodes dont le type est une fonction ou un type délégué F#. @@ -772,6 +787,11 @@ Impossible d'affecter '{0}' à une valeur marquée comme littérale + + The following required properties have to be initalized:{0} + The following required properties have to be initalized:{0} + + Using methods with 'NoEagerConstraintApplicationAttribute' requires /langversion:6.0 or later L’utilisation de méthodes avec « NoEagerConstraintApplicationAttribute » requiert/langversion:6.0 ou ultérieur @@ -852,6 +872,11 @@ L’utilisation de code pouvant être repris ou de machines d’état pouvant être reprises nécessite /langversion:preview + + Cannot call '{0}' - a setter for init-only property, please use object initialization instead. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization + Cannot call '{0}' - a setter for init-only property, please use object initialization instead. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization + + This expression implicitly converts type '{0}' to type '{1}'. See https://aka.ms/fsharp-implicit-convs. Cette expression convertit implicitement le type « {0} » en type « {1} ». Voir https://aka.ms/fsharp-implicit-convs. diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf index 2e60f3efcf..01af391840 100644 --- a/src/Compiler/xlf/FSComp.txt.it.xlf +++ b/src/Compiler/xlf/FSComp.txt.it.xlf @@ -187,6 +187,11 @@ Notazione expr[idx] per l'indicizzazione e il sezionamento + + support for consuming init properties + support for consuming init properties + + interfaces with multiple generic instantiation interfacce con più creazioni di istanze generiche @@ -257,6 +262,11 @@ uso meno restrittivo degli spazi vuoti v2 + + support for required properties + support for required properties + + resumable state machines macchine a stati ripristinabili @@ -707,6 +717,11 @@ Questa espressione usa la conversione implicita '{0}' per convertire il tipo '{1}' nel tipo '{2}'. Vedere https://aka.ms/fsharp-implicit-convs. Per disabilitare questo avviso, usare '#nowarn \"3391\"'. + + Init-only property '{0}' cannot be set outside the initialization code. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization + Init-only property '{0}' cannot be set outside the initialization code. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization + + The 'InlineIfLambda' attribute may only be used on parameters of inlined functions of methods whose type is a function or F# delegate type. L'attributo 'InlineIfLambda' può essere usato solo in parametri di funzioni impostate come inline di metodi il cui tipo è un tipo di funzione o delegato F#. @@ -772,6 +787,11 @@ Non è possibile assegnare '{0}' a un valore contrassegnato come letterale + + The following required properties have to be initalized:{0} + The following required properties have to be initalized:{0} + + Using methods with 'NoEagerConstraintApplicationAttribute' requires /langversion:6.0 or later L'utilizzo di metodi con 'NoEagerConstraintApplicationAttribute' richiede /langversion: 6.0 o versione successiva @@ -852,6 +872,11 @@ Per l'uso del codice ripristinabile o delle macchine a stati ripristinabili è richiesto /langversion:preview + + Cannot call '{0}' - a setter for init-only property, please use object initialization instead. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization + Cannot call '{0}' - a setter for init-only property, please use object initialization instead. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization + + This expression implicitly converts type '{0}' to type '{1}'. See https://aka.ms/fsharp-implicit-convs. Questa espressione converte in modo implicito il tipo '{0}' nel tipo '{1}'. Vedere https://aka.ms/fsharp-implicit-convs. diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf index 247420814f..54fbab4b51 100644 --- a/src/Compiler/xlf/FSComp.txt.ja.xlf +++ b/src/Compiler/xlf/FSComp.txt.ja.xlf @@ -187,6 +187,11 @@ インデックス作成とスライス用の expr[idx] 表記 + + support for consuming init properties + support for consuming init properties + + interfaces with multiple generic instantiation 複数のジェネリックのインスタンス化を含むインターフェイス @@ -257,6 +262,11 @@ whitespace relaxation v2 + + support for required properties + support for required properties + + resumable state machines 再開可能なステート マシン @@ -707,6 +717,11 @@ この式では、暗黙的な変換 '{0}' を使用して、型 '{1}' を型 '{2}' に変換しています。https://aka.ms/fsharp-implicit-convs をご確認ください。'#nowarn\"3391\" を使用して、この警告を無効にできる可能性があります。 + + Init-only property '{0}' cannot be set outside the initialization code. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization + Init-only property '{0}' cannot be set outside the initialization code. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization + + The 'InlineIfLambda' attribute may only be used on parameters of inlined functions of methods whose type is a function or F# delegate type. 'InlineIfLambda' 属性を使用できるのは、型が関数または F# デリゲート型であるメソッドのインライン関数のパラメーターに対してのみです。 @@ -772,6 +787,11 @@ リテラルとしてマークされた値に '{0}' を割り当てることはできません + + The following required properties have to be initalized:{0} + The following required properties have to be initalized:{0} + + Using methods with 'NoEagerConstraintApplicationAttribute' requires /langversion:6.0 or later 'NoEagerConstraintApplicationAttribute' を指定してメソッドを使用するには、/langversion:6.0 以降が必要です @@ -852,6 +872,11 @@ 再開可能なコードまたは再開可能なステート マシンを使用するには、/langversion:preview が必要です + + Cannot call '{0}' - a setter for init-only property, please use object initialization instead. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization + Cannot call '{0}' - a setter for init-only property, please use object initialization instead. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization + + This expression implicitly converts type '{0}' to type '{1}'. See https://aka.ms/fsharp-implicit-convs. この式は、型 '{0}' を型 '{1}' に暗黙的に変換します。https://aka.ms/fsharp-implicit-convs を参照してください。 diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf index 98b6ca41d7..7ed437b276 100644 --- a/src/Compiler/xlf/FSComp.txt.ko.xlf +++ b/src/Compiler/xlf/FSComp.txt.ko.xlf @@ -187,6 +187,11 @@ 인덱싱 및 슬라이싱을 위한 expr[idx] 표기법 + + support for consuming init properties + support for consuming init properties + + interfaces with multiple generic instantiation 여러 제네릭 인스턴스화가 포함된 인터페이스 @@ -257,6 +262,11 @@ 공백 relaxation v2 + + support for required properties + support for required properties + + resumable state machines 다시 시작 가능한 상태 시스템 @@ -707,6 +717,11 @@ 이 식은 암시적 변환 '{0}'을 사용하여 '{1}' 형식을 '{2}' 형식으로 변환 합니다. https://aka.ms/fsharp-implicit-convs 참조. ’#Nowarn \ "3391\"을 (를) 사용하여 이 경고를 사용 하지 않도록 설정할 수 있습니다. + + Init-only property '{0}' cannot be set outside the initialization code. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization + Init-only property '{0}' cannot be set outside the initialization code. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization + + The 'InlineIfLambda' attribute may only be used on parameters of inlined functions of methods whose type is a function or F# delegate type. 'InlineIfLambda' 특성은 형식이 함수 또는 F# 대리자 형식인 메서드의 인라인 함수 매개 변수에만 사용할 수 있습니다. @@ -772,6 +787,11 @@ 리터럴로 표시된 값에 '{0}'을(를) 할당할 수 없습니다. + + The following required properties have to be initalized:{0} + The following required properties have to be initalized:{0} + + Using methods with 'NoEagerConstraintApplicationAttribute' requires /langversion:6.0 or later 'NoEagerConstraintApplicationAttribute'와 함께 메서드를 사용하려면 /langversion:6.0 이상이 필요합니다. @@ -852,6 +872,11 @@ 다시 시작 가능한 코드 또는 다시 시작 가능한 상태 시스템을 사용하려면 /langversion:preview가 필요합니다. + + Cannot call '{0}' - a setter for init-only property, please use object initialization instead. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization + Cannot call '{0}' - a setter for init-only property, please use object initialization instead. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization + + This expression implicitly converts type '{0}' to type '{1}'. See https://aka.ms/fsharp-implicit-convs. 이 식은 암시적으로 '{0}' 형식을 '{1}' 형식으로 변환 합니다. https://aka.ms/fsharp-implicit-convs 참조 diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf index 033128cec2..19e01c9148 100644 --- a/src/Compiler/xlf/FSComp.txt.pl.xlf +++ b/src/Compiler/xlf/FSComp.txt.pl.xlf @@ -187,6 +187,11 @@ notacja wyrażenia expr[idx] do indeksowania i fragmentowania + + support for consuming init properties + support for consuming init properties + + interfaces with multiple generic instantiation interfejsy z wieloma ogólnymi wystąpieniami @@ -257,6 +262,11 @@ łagodzenie odstępów wer 2 + + support for required properties + support for required properties + + resumable state machines automaty stanów z możliwością wznowienia @@ -707,6 +717,11 @@ W tym wyrażeniu jest używana bezwzględna konwersja "{0}" w celu przekonwertowania typu "{1}" na typ "{2}". Zobacz https://aka.ms/fsharp-implicit-convs. To ostrzeżenie można wyłączyć przy użyciu polecenia "#nowarn \" 3391 \ ". + + Init-only property '{0}' cannot be set outside the initialization code. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization + Init-only property '{0}' cannot be set outside the initialization code. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization + + The 'InlineIfLambda' attribute may only be used on parameters of inlined functions of methods whose type is a function or F# delegate type. Atrybut "InlineIfLambda" może być używany tylko w przypadku parametrów funkcji z podkreśleniem metod, których typ to funkcja lub typ delegata języka F #. @@ -772,6 +787,11 @@ Nie można przypisać elementu „{0}” do wartości oznaczonej jako literał + + The following required properties have to be initalized:{0} + The following required properties have to be initalized:{0} + + Using methods with 'NoEagerConstraintApplicationAttribute' requires /langversion:6.0 or later Używanie metod z atrybutem "NoEagerConstraintApplicationAttribute" wymaga parametru /langversion:6.0 lub nowszego @@ -852,6 +872,11 @@ Używanie kodu z możliwością wznowienia lub automatów stanów z możliwością wznowienia wymaga parametru /langversion: wersja zapoznawcza + + Cannot call '{0}' - a setter for init-only property, please use object initialization instead. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization + Cannot call '{0}' - a setter for init-only property, please use object initialization instead. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization + + This expression implicitly converts type '{0}' to type '{1}'. See https://aka.ms/fsharp-implicit-convs. To wyrażenie bezwzględnie konwertuje typ "{0}" na typ "{1}". Zobacz https://aka.ms/fsharp-implicit-convs. diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf index ac0f596fbb..615e716bd0 100644 --- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf +++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf @@ -187,6 +187,11 @@ notação expr[idx] para indexação e fatia + + support for consuming init properties + support for consuming init properties + + interfaces with multiple generic instantiation interfaces com várias instanciações genéricas @@ -257,6 +262,11 @@ relaxamento de espaço em branco v2 + + support for required properties + support for required properties + + resumable state machines máquinas de estado retomável @@ -707,6 +717,11 @@ Essa expressão usa a conversão implícita '{0}' para converter o tipo '{1}' ao tipo '{2}'. Consulte https://aka.ms/fsharp-implicit-convs. Este aviso pode ser desabilitado usando '#nowarn\"3391\". + + Init-only property '{0}' cannot be set outside the initialization code. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization + Init-only property '{0}' cannot be set outside the initialization code. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization + + The 'InlineIfLambda' attribute may only be used on parameters of inlined functions of methods whose type is a function or F# delegate type. O atributo 'InlineIfLambda' só pode ser usado em parâmetros de funções de métodos em linha cujo tipo seja uma função ou F# tipo delegado. @@ -772,6 +787,11 @@ Não é possível atribuir '{0}' a um valor marcado como literal + + The following required properties have to be initalized:{0} + The following required properties have to be initalized:{0} + + Using methods with 'NoEagerConstraintApplicationAttribute' requires /langversion:6.0 or later Usar métodos com 'NoEagerConstraintApplicationAttribute' requer /langversion:6.0 ou posterior @@ -852,6 +872,11 @@ Usar código retomável ou máquinas de estado retomável requer /langversion:preview + + Cannot call '{0}' - a setter for init-only property, please use object initialization instead. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization + Cannot call '{0}' - a setter for init-only property, please use object initialization instead. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization + + This expression implicitly converts type '{0}' to type '{1}'. See https://aka.ms/fsharp-implicit-convs. Essa expressão converte implicitamente o tipo '{0}' ao tipo '{1}'. Consulte https://aka.ms/fsharp-implicit-convs. diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf index 754431737a..f534378e99 100644 --- a/src/Compiler/xlf/FSComp.txt.ru.xlf +++ b/src/Compiler/xlf/FSComp.txt.ru.xlf @@ -187,6 +187,11 @@ expr[idx] для индексации и среза + + support for consuming init properties + support for consuming init properties + + interfaces with multiple generic instantiation интерфейсы с множественным универсальным созданием экземпляра @@ -257,6 +262,11 @@ смягчение требований по использованию пробелов, версия 2 + + support for required properties + support for required properties + + resumable state machines возобновляемые конечные автоматы @@ -707,6 +717,11 @@ Это выражение использует неявное преобразование "{0}" для преобразования типа "{1}" в тип "{2}". См. сведения на странице https://aka.ms/fsharp-implicit-convs. Это предупреждение можно отключить, используя параметр '#nowarn \"3391\" + + Init-only property '{0}' cannot be set outside the initialization code. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization + Init-only property '{0}' cannot be set outside the initialization code. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization + + The 'InlineIfLambda' attribute may only be used on parameters of inlined functions of methods whose type is a function or F# delegate type. Атрибут "InlineIfLambda" может использоваться только в параметрах встраиваемых функций методов, типом которых является функция или делегат F#. @@ -772,6 +787,11 @@ Невозможно присвоить "{0}" значению, помеченному как литерал + + The following required properties have to be initalized:{0} + The following required properties have to be initalized:{0} + + Using methods with 'NoEagerConstraintApplicationAttribute' requires /langversion:6.0 or later Для использования методов с "NoEagerConstraintApplicationAttribute" требуется /langversion:6.0 или более поздняя версия @@ -852,6 +872,11 @@ Для использования возобновляемого кода или возобновляемых конечных автоматов требуется /langversion:preview + + Cannot call '{0}' - a setter for init-only property, please use object initialization instead. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization + Cannot call '{0}' - a setter for init-only property, please use object initialization instead. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization + + This expression implicitly converts type '{0}' to type '{1}'. See https://aka.ms/fsharp-implicit-convs. Это выражение неявно преобразует тип "{0}" в тип "{1}". См. сведения на странице https://aka.ms/fsharp-implicit-convs. diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf index 90c225e392..70335d09d9 100644 --- a/src/Compiler/xlf/FSComp.txt.tr.xlf +++ b/src/Compiler/xlf/FSComp.txt.tr.xlf @@ -187,6 +187,11 @@ Dizin oluşturma ve dilimleme için expr[idx] gösterimi + + support for consuming init properties + support for consuming init properties + + interfaces with multiple generic instantiation birden çok genel örnek oluşturma içeren arabirimler @@ -257,6 +262,11 @@ boşluk ilişkilendirme v2 + + support for required properties + support for required properties + + resumable state machines sürdürülebilir durum makineleri @@ -707,6 +717,11 @@ Bu ifade '{1}' türünü '{2}' türüne dönüştürmek için '{0}' örtük dönüştürmesini kullanır. https://aka.ms/fsharp-implicit-convs adresine bakın. Bu uyarı '#nowarn \"3391\" kullanılarak devre dışı bırakılabilir. + + Init-only property '{0}' cannot be set outside the initialization code. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization + Init-only property '{0}' cannot be set outside the initialization code. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization + + The 'InlineIfLambda' attribute may only be used on parameters of inlined functions of methods whose type is a function or F# delegate type. 'InlineIfLambda' özniteliği yalnızca işlev veya F# temsilci türündeki yöntemlerin satır içine alınmış işlev parametrelerinde kullanılabilir. @@ -772,6 +787,11 @@ Sabit değer olarak işaretlenen bir değere '{0}' atanamaz + + The following required properties have to be initalized:{0} + The following required properties have to be initalized:{0} + + Using methods with 'NoEagerConstraintApplicationAttribute' requires /langversion:6.0 or later 'NoEagerConstraintApplicationAttribute' içeren yöntemlerin kullanılması /langversion:6.0 veya üstünü gerektiriyor @@ -852,6 +872,11 @@ Sürdürülebilir kod veya sürdürülebilir durum makinelerini kullanmak için /langversion:preview gerekir + + Cannot call '{0}' - a setter for init-only property, please use object initialization instead. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization + Cannot call '{0}' - a setter for init-only property, please use object initialization instead. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization + + This expression implicitly converts type '{0}' to type '{1}'. See https://aka.ms/fsharp-implicit-convs. Bu ifade '{0}' türünü örtülü olarak '{1}' türüne dönüştürür. https://aka.ms/fsharp-implicit-convs adresine bakın. diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf index f0d4d5b817..4e7e55a375 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf @@ -187,6 +187,11 @@ 用于索引和切片的 expr[idx] 表示法 + + support for consuming init properties + support for consuming init properties + + interfaces with multiple generic instantiation 具有多个泛型实例化的接口 @@ -257,6 +262,11 @@ 空格放空 v2 + + support for required properties + support for required properties + + resumable state machines 可恢复状态机 @@ -707,6 +717,11 @@ 此表达式使用隐式转换“{0}”将类型“{1}”转换为类型“{2}”。请参阅 https://aka.ms/fsharp-implicit-convs。可使用 '#nowarn \"3391\" 禁用此警告。 + + Init-only property '{0}' cannot be set outside the initialization code. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization + Init-only property '{0}' cannot be set outside the initialization code. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization + + The 'InlineIfLambda' attribute may only be used on parameters of inlined functions of methods whose type is a function or F# delegate type. "InlineIfLambda" 特性只能用于类型为函数或 F# 委托类型的方法的内联函数的参数。 @@ -772,6 +787,11 @@ 无法将“{0}”分配给标记为文本的值 + + The following required properties have to be initalized:{0} + The following required properties have to be initalized:{0} + + Using methods with 'NoEagerConstraintApplicationAttribute' requires /langversion:6.0 or later 将方法与 “NoEagerConstraintApplicationAttribute” 配合使用需要 /langversion:6.0 或更高版本 @@ -852,6 +872,11 @@ 使用可恢复代码或可恢复状态机需要 /langversion:preview + + Cannot call '{0}' - a setter for init-only property, please use object initialization instead. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization + Cannot call '{0}' - a setter for init-only property, please use object initialization instead. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization + + This expression implicitly converts type '{0}' to type '{1}'. See https://aka.ms/fsharp-implicit-convs. 此表达式将类型“{0}”隐式转换为类型“{1}”。请参阅 https://aka.ms/fsharp-implicit-convs。 diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf index a4de4d17e8..965a9c231b 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf @@ -187,6 +187,11 @@ 用於編製索引和分割的 expr[idx] 註釋 + + support for consuming init properties + support for consuming init properties + + interfaces with multiple generic instantiation 具有多個泛型具現化的介面 @@ -257,6 +262,11 @@ 空格鍵放鬆 v2 + + support for required properties + support for required properties + + resumable state machines 可繼續的狀態機器 @@ -707,6 +717,11 @@ 此運算式使用隱含轉換 '{0}' 將類型 '{1}' 轉換為類型 '{2}'。請參閱 https://aka.ms/fsharp-implicit-convs。可使用 '#nowarn \"3391\" 停用此警告。 + + Init-only property '{0}' cannot be set outside the initialization code. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization + Init-only property '{0}' cannot be set outside the initialization code. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization + + The 'InlineIfLambda' attribute may only be used on parameters of inlined functions of methods whose type is a function or F# delegate type. 'InlineIfLambda' 屬性只能用於類型為函式或 F# 委派類型之方法的內嵌函式參數。 @@ -772,6 +787,11 @@ 無法將 '{0}' 指派給標記為常值的值 + + The following required properties have to be initalized:{0} + The following required properties have to be initalized:{0} + + Using methods with 'NoEagerConstraintApplicationAttribute' requires /langversion:6.0 or later 使用具有 'NoEagerConstraintApplicationAttribute' 的方法需要 /langversion:6.0 或更新版本 @@ -852,6 +872,11 @@ 使用可繼續的程式碼或可繼續的狀態機器需要 /langversion:preview + + Cannot call '{0}' - a setter for init-only property, please use object initialization instead. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization + Cannot call '{0}' - a setter for init-only property, please use object initialization instead. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization + + This expression implicitly converts type '{0}' to type '{1}'. See https://aka.ms/fsharp-implicit-convs. 此運算式將類型 '{0}' 隱含轉換為類型 '{1}'。請參閱 https://aka.ms/fsharp-implicit-convs。 diff --git a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj index 6ca61dc0c0..cb6d840987 100644 --- a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj +++ b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj @@ -123,7 +123,6 @@ - @@ -159,8 +158,15 @@ + + %(RelativeDir)\TestSource\%(Filename)%(Extension) + + + %(RelativeDir)\TestSource\%(Filename)%(Extension) + - + + @@ -184,12 +190,6 @@ %(RelativeDir)\BaseLine\%(Filename)%(Extension) - - %(RelativeDir)\TestSource\%(Filename)%(Extension) - - - %(RelativeDir)\TestSource\%(Filename)%(Extension) - diff --git a/tests/FSharp.Compiler.ComponentTests/Interop/RequiredAndInitOnlyProperties.fs b/tests/FSharp.Compiler.ComponentTests/Interop/RequiredAndInitOnlyProperties.fs new file mode 100644 index 0000000000..90ba169931 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Interop/RequiredAndInitOnlyProperties.fs @@ -0,0 +1,486 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. +namespace FSharp.Compiler.ComponentTests.Interop + +open Xunit +open FSharp.Test.Compiler +open FSharp.Test +open System + +module ``Required and init-only properties`` = + + let csharpBaseClass = + CSharp """ + namespace RequiredAndInitOnlyProperties + { + public sealed class RAIO + { + public int GetSet { get; set; } + public int GetInit { get; init; } + public RAIO GetThis() => this; + } + + }""" |> withCSharpLanguageVersion CSharpLanguageVersion.Preview |> withName "csLib" + + let csharpRBaseClass = + CSharp """ + // Until we move to .NET7 runtime (or use experimental) + namespace System.Runtime.CompilerServices + { + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = false)] + public sealed class RequiredMemberAttribute : Attribute { } + [AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = false)] + public sealed class CompilerFeatureRequiredAttribute : Attribute + { + public CompilerFeatureRequiredAttribute(string featureName) + { + FeatureName = featureName; + } + public string FeatureName { get; } + public bool IsOptional { get; init; } + public const string RefStructs = nameof(RefStructs); + public const string RequiredMembers = nameof(RequiredMembers); + } + } + + namespace RequiredAndInitOnlyProperties + { + public sealed class RAIO + { + public required int GetSet { get; set; } + public required int GetInit { get; init; } + } + + }""" |> withCSharpLanguageVersion CSharpLanguageVersion.Preview |> withName "csLib" + + +#if !NETCOREAPP + [] +#else + [] +#endif + let ``F# can init both set and init-only`` () = + + let csharpLib = csharpBaseClass + + let fsharpSource = + """ +open System +open RequiredAndInitOnlyProperties + +[] +let main _ = + + let raio = RAIO(GetSet = 1, GetInit = 2) + + if raio.GetSet <> 1 then + failwith $"Unexpected result %d{raio.GetSet}" + 0 +""" + FSharp fsharpSource + |> asExe + |> withLangVersionPreview + |> withReferences [csharpLib] + |> compileAndRun + |> shouldSucceed + +#if !NETCOREAPP + [] +#else + [] +#endif + let ``F# can change set property`` () = + + let csharpLib = csharpBaseClass + + let fsharpSource = + """ +open System +open RequiredAndInitOnlyProperties + +[] +let main _ = + + let raio = RAIO(GetSet = 1, GetInit = 2) + + if raio.GetSet <> 1 then + failwith $"Unexpected result %d{raio.GetSet}" + + raio.GetSet <- 0 + + if raio.GetSet <> 0 then + failwith $"Unexpected result %d{raio.GetSet}" + 0 +""" + FSharp fsharpSource + |> asExe + |> withLangVersionPreview + |> withReferences [csharpLib] + |> compileAndRun + |> shouldSucceed + +#if !NETCOREAPP + [] +#else + [] +#endif + let ``F# can change set property via calling an explicit setter`` () = + + let csharpLib = csharpBaseClass + + let fsharpSource = + """ +open System +open RequiredAndInitOnlyProperties + +[] +let main _ = + + let raio = RAIO(GetSet = 1, GetInit = 2) + + if raio.GetSet <> 1 then + failwith $"Unexpected result %d{raio.GetSet}" + + raio.set_GetSet(0) + + if raio.GetSet <> 0 then + failwith $"Unexpected result %d{raio.GetSet}" + 0 +""" + FSharp fsharpSource + |> asExe + |> withLangVersionPreview + |> withReferences [csharpLib] + |> compileAndRun + |> shouldSucceed + +#if !NETCOREAPP + [] +#else + [] +#endif + let ``F# can get property via calling an explicit getter`` () = + + let csharpLib = csharpBaseClass + + let fsharpSource = + """ +open System +open RequiredAndInitOnlyProperties + +[] +let main _ = + + let raio = RAIO(GetSet = 1, GetInit = 2) + + if raio.get_GetSet() <> 1 then + failwith $"Unexpected result %d{raio.GetSet}" + 0 +""" + FSharp fsharpSource + |> asExe + |> withLangVersionPreview + |> withReferences [csharpLib] + |> compileAndRun + |> shouldSucceed + +#if !NETCOREAPP + [] +#else + [] +#endif + let ``F# cannot change init-only property`` () = + + let csharpLib = csharpBaseClass + + let fsharpSource = + """ +open System +open RequiredAndInitOnlyProperties + +[] +let main _ = + + let raio = RAIO(GetSet = 1, GetInit = 2) + raio.GetInit <- 0 + + 0 +""" + FSharp fsharpSource + |> asExe + |> withLangVersionPreview + |> withReferences [csharpLib] + |> compile + |> shouldFail + |> withDiagnostics [ + Error 810, Line 9, Col 5, Line 9, Col 17, "Init-only property 'GetInit' cannot be set outside the initialization code. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization" + ] + +#if !NETCOREAPP + [] +#else + [] +#endif + let ``F# cannot change init-only property via calling an explicit setter`` () = + + let csharpLib = csharpBaseClass + + let fsharpSource = + """ +open System +open RequiredAndInitOnlyProperties + +[] +let main _ = + + let raio = RAIO(GetSet = 1, GetInit = 2) + raio.set_GetInit(0) + + 0 +""" + FSharp fsharpSource + |> asExe + |> withLangVersionPreview + |> withReferences [csharpLib] + |> compile + |> shouldFail + |> withDiagnostics [ + Error 810, Line 9, Col 5, Line 9, Col 21, "Cannot call 'set_GetInit' - a setter for init-only property, please use object initialization instead. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization" + ] + + #if !NETCOREAPP + [] +#else + [] +#endif + let ``F# cannot change init-only property via calling an initializer on instance`` () = + + let csharpLib = csharpBaseClass + + let fsharpSource = + """ +open System +open RequiredAndInitOnlyProperties + +[] +let main _ = + + let raio = RAIO() + raio.GetThis(GetSet=2, GetInit = 42) |> ignore + 0 +""" + FSharp fsharpSource + |> asExe + |> withLangVersionPreview + |> withReferences [csharpLib] + |> compile + |> shouldFail + |> withDiagnostics [ + Error 810, Line 9, Col 38, Line 9, Col 40, "Init-only property 'GetInit' cannot be set outside the initialization code. See https://aka.ms/fsharp-assigning-values-to-properties-at-initialization" + ] + + +#if !NETCOREAPP + [] +#else + [] +#endif + let ``F# should produce compile-time error when required properties are not specified in the initializer`` () = + + let csharpLib = csharpRBaseClass + + let fsharpSource = + """ +open System +open RequiredAndInitOnlyProperties + +[] +let main _ = + + let raio = RAIO() + + 0 +""" + FSharp fsharpSource + |> asExe + |> withLangVersionPreview + |> withReferences [csharpLib] + |> compile + |> shouldFail + |> withDiagnostics [ + Error 3545, Line 8, Col 16, Line 8, Col 22, "The following required properties have to be initalized:" + Environment.NewLine + " property RAIO.GetSet: int with get, set" + Environment.NewLine + " property RAIO.GetInit: int with get, set" + ] + +#if !NETCOREAPP + [] +#else + [] +#endif + let ``F# should produce compile-time error when some required properties are not specified in the initializer`` () = + + let csharpLib = csharpRBaseClass + + let fsharpSource = + """ +open System +open RequiredAndInitOnlyProperties + +[] +let main _ = + + let raio = RAIO(GetSet=1) + + 0 +""" + FSharp fsharpSource + |> asExe + |> withLangVersionPreview + |> withReferences [csharpLib] + |> compile + |> shouldFail + |> withDiagnostics [ + Error 3545, Line 8, Col 16, Line 8, Col 30, "The following required properties have to be initalized:" + Environment.NewLine + " property RAIO.GetInit: int with get, set" + ] + +#if !NETCOREAPP + [] +#else + [] +#endif + let ``F# should not produce compile-time error when all required properties are specified in the initializer`` () = + + let csharpLib = csharpRBaseClass + + let fsharpSource = + """ +open System +open RequiredAndInitOnlyProperties + +[] +let main _ = + + let raio = RAIO(GetSet=1, GetInit=2) + + if raio.GetSet <> 1 then + failwith "Unexpected value" + + if raio.GetInit <> 2 then + failwith "Unexpected value" + 0 +""" + FSharp fsharpSource + |> asExe + |> withLangVersionPreview + |> withReferences [csharpLib] + |> compileAndRun + |> shouldSucceed + + #if !NETCOREAPP + [] + #else + [] + #endif + let ``F# should only be able to explicitly call constructors which set SetsRequiredMembersAttribute`` () = + + let csharpLib = + CSharp """ + // Until we move to .NET7 runtime (or use experimental) + namespace System.Runtime.CompilerServices + { + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = false)] + public sealed class RequiredMemberAttribute : Attribute { } + [AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = false)] + public sealed class CompilerFeatureRequiredAttribute : Attribute + { + public CompilerFeatureRequiredAttribute(string featureName) + { + FeatureName = featureName; + } + public string FeatureName { get; } + public bool IsOptional { get; init; } + public const string RefStructs = nameof(RefStructs); + public const string RequiredMembers = nameof(RequiredMembers); + } + } + + namespace System.Diagnostics.CodeAnalysis + { + [AttributeUsage(AttributeTargets.Constructor, AllowMultiple=false, Inherited=false)] + public sealed class SetsRequiredMembersAttribute : Attribute {} + } + + namespace RequiredAndInitOnlyProperties + { + using System.Runtime.CompilerServices; + using System.Diagnostics.CodeAnalysis; + + public sealed class RAIO + { + public required int GetSet { get; set; } + public required int GetInit { get; init; } + [SetsRequiredMembers] + public RAIO(int foo) {} // Should be legal to call any constructor which does have "SetsRequiredMembersAttribute" + public RAIO(int foo, int bar) {} // Should be illegal to call any constructor which does not have "SetsRequiredMembersAttribute" + } + + }""" |> withCSharpLanguageVersion CSharpLanguageVersion.Preview |> withName "csLib" + + let fsharpSource = + """ + open System + open RequiredAndInitOnlyProperties + + [] + let main _ = + let _raio = RAIO(1) + 0 + """ + FSharp fsharpSource + |> asExe + |> withLangVersionPreview + |> withReferences [csharpLib] + |> compileAndRun + |> shouldSucceed + |> ignore + + let fsharpSource2 = + """ + open System + open RequiredAndInitOnlyProperties + + [] + let main _ = + let _raio = RAIO(1,2) + 0 + """ + FSharp fsharpSource2 + |> asExe + |> withLangVersionPreview + |> withReferences [csharpLib] + |> compile + |> shouldFail + |> withSingleDiagnostic (Error 3545, Line 7, Col 21, Line 7, Col 30, "The following required properties have to be initalized:" + Environment.NewLine + " property RAIO.GetSet: int with get, set" + Environment.NewLine + " property RAIO.GetInit: int with get, set") + +#if !NETCOREAPP + [] +#else + [] +#endif + let ``F# should produce a warning if RequiredMemberAttribute is specified`` () = + // TODO: This test will start failing with different reason when we will move to .NET7, since RequiredMemberArgument will be in System.Runtime.*.dll. + // It will needs to be fixed then. + let fsharpSource = + """ +namespace FooBarBaz +open System +open System.Runtime.CompilerServices + +type RAIOFS() = + [] + member val GetSet = 0 with get, set +""" + FSharp fsharpSource + |> asLibrary + |> withLangVersionPreview + |> compile + |> shouldFail + |> withErrorCode 39 \ No newline at end of file diff --git a/tests/FSharp.Test.Utilities/Compiler.fs b/tests/FSharp.Test.Utilities/Compiler.fs index 54822b93d8..574d7dae1e 100644 --- a/tests/FSharp.Test.Utilities/Compiler.fs +++ b/tests/FSharp.Test.Utilities/Compiler.fs @@ -452,6 +452,11 @@ module rec Compiler = let withRefOut (name:string) (cUnit: CompilationUnit) : CompilationUnit = withOptionsHelper [ $"--refout:{name}" ] "withNoInterfaceData is only supported for F#" cUnit + let withCSharpLanguageVersion (ver: CSharpLanguageVersion) (cUnit: CompilationUnit) : CompilationUnit = + match cUnit with + | CS cs -> CS { cs with LangVersion = ver } + | _ -> failwith "Only supported in C#" + let asLibrary (cUnit: CompilationUnit) : CompilationUnit = match cUnit with | FS fs -> FS { fs with OutputType = CompileOutput.Library } diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/ApplicationPropPageBase.vb b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/ApplicationPropPageBase.vb index f8633f96b7..98df251d91 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/ApplicationPropPageBase.vb +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/ApplicationPropPageBase.vb @@ -4,11 +4,11 @@ Imports EnvDTE Imports Microsoft.VisualBasic Imports System -Imports System.IO Imports System.Collections Imports System.ComponentModel Imports System.Diagnostics Imports System.Drawing +Imports System.IO Imports System.Windows.Forms Imports System.Runtime.InteropServices