diff --git a/src/Compiler/Checking/CheckExpressions.fs b/src/Compiler/Checking/CheckExpressions.fs index 4c1c47f53b..332cea0987 100644 --- a/src/Compiler/Checking/CheckExpressions.fs +++ b/src/Compiler/Checking/CheckExpressions.fs @@ -6565,8 +6565,14 @@ and TcRecordConstruction (cenv: cenv) (overallTy: TType) env tpenv withExprInfoO let ns1 = NameSet.ofList (List.map fst fldsList) let ns2 = NameSet.ofList (List.map (fun x -> x.rfield_id.idText) fspecs) - if withExprInfoOpt.IsNone && not (Zset.subset ns2 ns1) then - error (MissingFields(Zset.elements (Zset.diff ns2 ns1), m)) + match withExprInfoOpt with + | None -> + if not (Zset.subset ns2 ns1) then + error(MissingFields(Zset.elements (Zset.diff ns2 ns1), m)) + | _ -> + if oldFldsList.IsEmpty then + let enabledByLangFeature = g.langVersion.SupportsFeature LanguageFeature.WarningWhenCopyAndUpdateRecordChangesAllFields + warning(ErrorEnabledWithLanguageFeature(FSComp.SR.tcCopyAndUpdateRecordChangesAllFields(fullDisplayTextOfTyconRef tcref), m, enabledByLangFeature)) if not (Zset.subset ns1 ns2) then error (Error(FSComp.SR.tcExtraneousFieldsGivenValues(), m)) diff --git a/src/Compiler/Driver/CompilerDiagnostics.fs b/src/Compiler/Driver/CompilerDiagnostics.fs index c0f373553e..f57b44c471 100644 --- a/src/Compiler/Driver/CompilerDiagnostics.fs +++ b/src/Compiler/Driver/CompilerDiagnostics.fs @@ -128,6 +128,7 @@ type Exception with | LetRecEvaluatedOutOfOrder (_, _, _, m) | DiagnosticWithText (_, _, m) | DiagnosticWithSuggestions (_, _, m, _, _) + | DiagnosticEnabledWithLanguageFeature (_, _, m, _) | SyntaxError (_, m) | InternalError (_, m) | InterfaceNotRevealed (_, _, m) @@ -330,6 +331,7 @@ type Exception with | WrappedError (e, _) -> e.DiagnosticNumber | DiagnosticWithText (n, _, _) -> n | DiagnosticWithSuggestions (n, _, _, _, _) -> n + | DiagnosticEnabledWithLanguageFeature (n, _, _, _) -> n | Failure _ -> 192 | IllegalFileNameChar (fileName, invalidChar) -> fst (FSComp.SR.buildUnexpectedFileNameCharacter (fileName, string invalidChar)) #if !NO_TYPEPROVIDERS @@ -353,6 +355,7 @@ type PhasedDiagnostic with | DefensiveCopyWarning _ -> 5 | DiagnosticWithText (n, _, _) + | DiagnosticEnabledWithLanguageFeature (n, _, _, _) | DiagnosticWithSuggestions (n, _, _, _, _) -> // 1178, tcNoComparisonNeeded1, "The struct, record or union type '%s' is not structurally comparable because the type parameter %s does not satisfy the 'comparison' constraint..." // 1178, tcNoComparisonNeeded2, "The struct, record or union type '%s' is not structurally comparable because the type '%s' does not satisfy the 'comparison' constraint...." @@ -382,8 +385,11 @@ type PhasedDiagnostic with | 3395 -> false // tcImplicitConversionUsedForMethodArg - off by default | 3559 -> false // typrelNeverRefinedAwayFromTop - off by default | _ -> - (severity = FSharpDiagnosticSeverity.Info) - || (severity = FSharpDiagnosticSeverity.Warning && level >= x.WarningLevel) + match x.Exception with + | DiagnosticEnabledWithLanguageFeature (_, _, _, enabled) -> enabled + | _ -> + (severity = FSharpDiagnosticSeverity.Info) + || (severity = FSharpDiagnosticSeverity.Warning && level >= x.WarningLevel) /// Indicates if a diagnostic should be reported as an informational member x.ReportAsInfo(options, severity) = @@ -1655,7 +1661,8 @@ type Exception with os.AppendString(NonUniqueInferredAbstractSlot4E().Format) - | DiagnosticWithText (_, s, _) -> os.AppendString s + | DiagnosticWithText (_, s, _) + | DiagnosticEnabledWithLanguageFeature (_, s, _, _) -> os.AppendString s | DiagnosticWithSuggestions (_, s, _, idText, suggestionF) -> os.AppendString(ConvertValLogicalNameToDisplayNameCore s) diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt index 74ce729746..e0297df382 100644 --- a/src/Compiler/FSComp.txt +++ b/src/Compiler/FSComp.txt @@ -1561,6 +1561,7 @@ featureErrorForNonVirtualMembersOverrides,"Raises errors for non-virtual members featureWarningWhenInliningMethodImplNoInlineMarkedFunction,"Raises warnings when 'let inline ... =' is used together with [] attribute. Function is not getting inlined." featureArithmeticInLiterals,"Allow arithmetic and logical operations in literals" featureErrorReportingOnStaticClasses,"Error reporting on static classes" +featureWarningWhenCopyAndUpdateRecordChangesAllFields,"Raises warnings when an copy-and-update record expression changes all fields of a record." 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." 3354,tcNotAFunctionButIndexerIndexingNotYetEnabled,"This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation." @@ -1674,3 +1675,4 @@ featureEscapeBracesInFormattableString,"Escapes curly braces before calling Form 3557,chkAbstractMembersDeclarationsOnStaticClasses,"If a type uses both [] and [] attributes, it means it is static. Abstract member declarations are not allowed." 3558,chkExplicitFieldsDeclarationsOnStaticClasses,"If a type uses both [] and [] attributes, it means it is static. Explicit field declarations are not allowed." 3559,typrelNeverRefinedAwayFromTop,"A type has been implicitly inferred as 'obj', which may be unintended. Consider adding explicit type annotations. You can disable this warning by using '#nowarn \"3559\"' or '--nowarn:3559'." +3560,tcCopyAndUpdateRecordChangesAllFields,"This copy-and-update record expression changes all fields of record type '%s'. Consider using the record construction syntax instead." diff --git a/src/Compiler/Facilities/DiagnosticsLogger.fs b/src/Compiler/Facilities/DiagnosticsLogger.fs index af937a2815..83f59e5216 100644 --- a/src/Compiler/Facilities/DiagnosticsLogger.fs +++ b/src/Compiler/Facilities/DiagnosticsLogger.fs @@ -113,6 +113,9 @@ exception DiagnosticWithSuggestions of number: int * message: string * range: ra | DiagnosticWithSuggestions (_, msg, _, _, _) -> msg | _ -> "impossible" +/// A diagnostic that is raised when enabled manually, or by default with a language feature +exception DiagnosticEnabledWithLanguageFeature of number: int * message: string * range: range * enabledByLangFeature: bool + /// The F# compiler code currently uses 'Error(...)' in many places to create /// an DiagnosticWithText as an exception even if it's a warning. /// @@ -126,6 +129,9 @@ let Error ((n, text), m) = DiagnosticWithText(n, text, m) let ErrorWithSuggestions ((n, message), m, id, suggestions) = DiagnosticWithSuggestions(n, message, m, id, suggestions) +let ErrorEnabledWithLanguageFeature ((n, message), m, enabledByLangFeature) = + DiagnosticEnabledWithLanguageFeature (n, message, m, enabledByLangFeature) + let inline protectAssemblyExploration dflt f = try f () diff --git a/src/Compiler/Facilities/DiagnosticsLogger.fsi b/src/Compiler/Facilities/DiagnosticsLogger.fsi index 0ac4c90583..8357c00332 100644 --- a/src/Compiler/Facilities/DiagnosticsLogger.fsi +++ b/src/Compiler/Facilities/DiagnosticsLogger.fsi @@ -44,6 +44,13 @@ val StopProcessing<'T> : exn /// Represents a diagnostic exeption whose text comes via SR.* exception DiagnosticWithText of number: int * message: string * range: range +/// A diagnostic that is raised when enabled manually, or by default with a language feature +exception DiagnosticEnabledWithLanguageFeature of + number: int * + message: string * + range: range * + enabledByLangFeature: bool + /// Creates a diagnostic exeption whose text comes via SR.* val Error: (int * string) * range -> exn @@ -77,6 +84,9 @@ exception DiagnosticWithSuggestions of /// Creates a DiagnosticWithSuggestions whose text comes via SR.* val ErrorWithSuggestions: (int * string) * range * string * Suggestions -> exn +/// Creates a DiagnosticEnabledWithLanguageFeature whose text comes via SR.* +val ErrorEnabledWithLanguageFeature: (int * string) * range * bool -> exn + val inline protectAssemblyExploration: dflt: 'T -> f: (unit -> 'T) -> 'T val inline protectAssemblyExplorationF: dflt: (string * string -> 'T) -> f: (unit -> 'T) -> 'T diff --git a/src/Compiler/Facilities/LanguageFeatures.fs b/src/Compiler/Facilities/LanguageFeatures.fs index e7654bea42..424e949eed 100644 --- a/src/Compiler/Facilities/LanguageFeatures.fs +++ b/src/Compiler/Facilities/LanguageFeatures.fs @@ -61,6 +61,7 @@ type LanguageFeature = | EscapeDotnetFormattableStrings | ArithmeticInLiterals | ErrorReportingOnStaticClasses + | WarningWhenCopyAndUpdateRecordChangesAllFields /// LanguageVersion management type LanguageVersion(versionText) = @@ -138,6 +139,7 @@ type LanguageVersion(versionText) = LanguageFeature.EscapeDotnetFormattableStrings, previewVersion LanguageFeature.ArithmeticInLiterals, previewVersion LanguageFeature.ErrorReportingOnStaticClasses, previewVersion + LanguageFeature.WarningWhenCopyAndUpdateRecordChangesAllFields, previewVersion ] @@ -252,6 +254,7 @@ type LanguageVersion(versionText) = | LanguageFeature.EscapeDotnetFormattableStrings -> FSComp.SR.featureEscapeBracesInFormattableString () | LanguageFeature.ArithmeticInLiterals -> FSComp.SR.featureArithmeticInLiterals () | LanguageFeature.ErrorReportingOnStaticClasses -> FSComp.SR.featureErrorReportingOnStaticClasses () + | LanguageFeature.WarningWhenCopyAndUpdateRecordChangesAllFields -> FSComp.SR.featureWarningWhenCopyAndUpdateRecordChangesAllFields () /// 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 d070a8b4e3..714639147b 100644 --- a/src/Compiler/Facilities/LanguageFeatures.fsi +++ b/src/Compiler/Facilities/LanguageFeatures.fsi @@ -51,6 +51,7 @@ type LanguageFeature = | EscapeDotnetFormattableStrings | ArithmeticInLiterals | ErrorReportingOnStaticClasses + | WarningWhenCopyAndUpdateRecordChangesAllFields /// LanguageVersion management type LanguageVersion = diff --git a/src/Compiler/TypedTree/TypedTreeOps.fs b/src/Compiler/TypedTree/TypedTreeOps.fs index b87db718b3..17ce2d8e02 100644 --- a/src/Compiler/TypedTree/TypedTreeOps.fs +++ b/src/Compiler/TypedTree/TypedTreeOps.fs @@ -5983,14 +5983,14 @@ and remapUnionCases ctxt tmenv (x: TyconUnionData) = x.UnionCasesAsList |> List.map (remapUnionCase ctxt tmenv) |> Construct.MakeUnionCases and remapFsObjData ctxt tmenv x = - { x with - fsobjmodel_kind = - (match x.fsobjmodel_kind with - | TFSharpDelegate slotsig -> TFSharpDelegate (remapSlotSig (remapAttribs ctxt tmenv) tmenv slotsig) - | TFSharpClass | TFSharpInterface | TFSharpStruct | TFSharpEnum -> x.fsobjmodel_kind) - fsobjmodel_vslots = x.fsobjmodel_vslots |> List.map (remapValRef tmenv) - fsobjmodel_rfields = x.fsobjmodel_rfields |> remapRecdFields ctxt tmenv } - + { + fsobjmodel_kind = + match x.fsobjmodel_kind with + | TFSharpDelegate slotsig -> TFSharpDelegate (remapSlotSig (remapAttribs ctxt tmenv) tmenv slotsig) + | TFSharpClass | TFSharpInterface | TFSharpStruct | TFSharpEnum -> x.fsobjmodel_kind + fsobjmodel_vslots = x.fsobjmodel_vslots |> List.map (remapValRef tmenv) + fsobjmodel_rfields = x.fsobjmodel_rfields |> remapRecdFields ctxt tmenv + } and remapTyconRepr ctxt tmenv repr = match repr with diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf index 5b2ca185d7..c59befa7b1 100644 --- a/src/Compiler/xlf/FSComp.txt.cs.xlf +++ b/src/Compiler/xlf/FSComp.txt.cs.xlf @@ -382,6 +382,11 @@ reprezentace struktury aktivních vzorů + + Raises warnings when an copy-and-update record expression changes all fields of a record. + Raises warnings when an copy-and-update record expression changes all fields of a record. + + Raises warnings when 'let inline ... =' is used together with [<MethodImpl(MethodImplOptions.NoInlining)>] attribute. Function is not getting inlined. Vyvolá upozornění, když se použije „let inline ... =“ společně s atributem [<MethodImpl(MethodImplOptions.NoInlining)>]. Funkce není vkládána. @@ -872,6 +877,11 @@ Atributy nejde použít pro rozšíření typů. + + This copy-and-update record expression changes all fields of record type '{0}'. Consider using the record construction syntax instead. + This copy-and-update record expression changes all fields of record type '{0}'. Consider using the record construction syntax instead. + + The syntax 'expr1[expr2]' is used for indexing. Consider adding a type annotation to enable indexing, or if calling a function add a space, e.g. 'expr1 [expr2]'. Syntaxe expr1[expr2] se používá pro indexování. Pokud chcete povolit indexování, zvažte možnost přidat anotaci typu, nebo pokud voláte funkci, přidejte mezeru, třeba expr1 [expr2]. diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf index 7c92c3dd3f..c4bcef73d3 100644 --- a/src/Compiler/xlf/FSComp.txt.de.xlf +++ b/src/Compiler/xlf/FSComp.txt.de.xlf @@ -382,6 +382,11 @@ Strukturdarstellung für aktive Muster + + Raises warnings when an copy-and-update record expression changes all fields of a record. + Raises warnings when an copy-and-update record expression changes all fields of a record. + + Raises warnings when 'let inline ... =' is used together with [<MethodImpl(MethodImplOptions.NoInlining)>] attribute. Function is not getting inlined. Löst Warnungen aus, wenn „let inline ... =“ zusammen mit dem Attribut [<MethodImpl(MethodImplOptions.NoInlining)>] verwendet wird. Die Funktion wird nicht inline gesetzt. @@ -872,6 +877,11 @@ Attribute können nicht auf Typerweiterungen angewendet werden. + + This copy-and-update record expression changes all fields of record type '{0}'. Consider using the record construction syntax instead. + This copy-and-update record expression changes all fields of record type '{0}'. Consider using the record construction syntax instead. + + The syntax 'expr1[expr2]' is used for indexing. Consider adding a type annotation to enable indexing, or if calling a function add a space, e.g. 'expr1 [expr2]'. Die Syntax "expr1[expr2]" wird für die Indizierung verwendet. Fügen Sie ggf. eine Typanmerkung hinzu, um die Indizierung zu aktivieren, oder fügen Sie beim Aufrufen einer Funktion ein Leerzeichen hinzu, z. B. "expr1 [expr2]". diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf index d64f40279b..073ff01278 100644 --- a/src/Compiler/xlf/FSComp.txt.es.xlf +++ b/src/Compiler/xlf/FSComp.txt.es.xlf @@ -382,6 +382,11 @@ representación de struct para modelos activos + + Raises warnings when an copy-and-update record expression changes all fields of a record. + Raises warnings when an copy-and-update record expression changes all fields of a record. + + Raises warnings when 'let inline ... =' is used together with [<MethodImpl(MethodImplOptions.NoInlining)>] attribute. Function is not getting inlined. Genera advertencias cuando se usa "let inline ... =" junto con el atributo [<MethodImpl(MethodImplOptions.NoInlining)>]. La función no se está insertando. @@ -872,6 +877,11 @@ Los atributos no se pueden aplicar a las extensiones de tipo. + + This copy-and-update record expression changes all fields of record type '{0}'. Consider using the record construction syntax instead. + This copy-and-update record expression changes all fields of record type '{0}'. Consider using the record construction syntax instead. + + The syntax 'expr1[expr2]' is used for indexing. Consider adding a type annotation to enable indexing, or if calling a function add a space, e.g. 'expr1 [expr2]'. La sintaxis "expr1[expr2]" se usa para la indexación. Considere la posibilidad de agregar una anotación de tipo para habilitar la indexación, si se llama a una función, agregue un espacio, por ejemplo, "expr1 [expr2]". diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf index ffb0620e88..a6c5a50598 100644 --- a/src/Compiler/xlf/FSComp.txt.fr.xlf +++ b/src/Compiler/xlf/FSComp.txt.fr.xlf @@ -382,6 +382,11 @@ représentation de structure pour les modèles actifs + + Raises warnings when an copy-and-update record expression changes all fields of a record. + Raises warnings when an copy-and-update record expression changes all fields of a record. + + Raises warnings when 'let inline ... =' is used together with [<MethodImpl(MethodImplOptions.NoInlining)>] attribute. Function is not getting inlined. Génère des avertissements lorsque « let inline ... = » est utilisé avec l’attribut [<MethodImpl(MethodImplOptions.NoInlining)>]. La fonction n’est pas inlined. @@ -872,6 +877,11 @@ Impossible d'appliquer des attributs aux extensions de type. + + This copy-and-update record expression changes all fields of record type '{0}'. Consider using the record construction syntax instead. + This copy-and-update record expression changes all fields of record type '{0}'. Consider using the record construction syntax instead. + + The syntax 'expr1[expr2]' is used for indexing. Consider adding a type annotation to enable indexing, or if calling a function add a space, e.g. 'expr1 [expr2]'. La syntaxe « expr1[expr2] » est utilisée pour l’indexation. Envisagez d’ajouter une annotation de type pour activer l’indexation, ou si vous appelez une fonction, ajoutez un espace, par exemple « expr1 [expr2] ». diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf index 035dc847ee..36fe7ce6e9 100644 --- a/src/Compiler/xlf/FSComp.txt.it.xlf +++ b/src/Compiler/xlf/FSComp.txt.it.xlf @@ -382,6 +382,11 @@ rappresentazione struct per criteri attivi + + Raises warnings when an copy-and-update record expression changes all fields of a record. + Raises warnings when an copy-and-update record expression changes all fields of a record. + + Raises warnings when 'let inline ... =' is used together with [<MethodImpl(MethodImplOptions.NoInlining)>] attribute. Function is not getting inlined. Genera avvisi quando 'let inline ... =' viene usato insieme all'attributo [<MethodImpl(MethodImplOptions.NoInlining)>]. La funzione non viene resa inline. @@ -872,6 +877,11 @@ Gli attributi non possono essere applicati a estensioni di tipo. + + This copy-and-update record expression changes all fields of record type '{0}'. Consider using the record construction syntax instead. + This copy-and-update record expression changes all fields of record type '{0}'. Consider using the record construction syntax instead. + + The syntax 'expr1[expr2]' is used for indexing. Consider adding a type annotation to enable indexing, or if calling a function add a space, e.g. 'expr1 [expr2]'. La sintassi 'expr1[expr2]' viene usata per l'indicizzazione. Provare ad aggiungere un'annotazione di tipo per abilitare l'indicizzazione oppure se la chiamata a una funzione aggiunge uno spazio, ad esempio 'expr1 [expr2]'. diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf index dc36b5670a..fc8aeb1aa8 100644 --- a/src/Compiler/xlf/FSComp.txt.ja.xlf +++ b/src/Compiler/xlf/FSComp.txt.ja.xlf @@ -382,6 +382,11 @@ アクティブなパターンの構造体表現 + + Raises warnings when an copy-and-update record expression changes all fields of a record. + Raises warnings when an copy-and-update record expression changes all fields of a record. + + Raises warnings when 'let inline ... =' is used together with [<MethodImpl(MethodImplOptions.NoInlining)>] attribute. Function is not getting inlined. 'let inline ... =' が [<MethodImpl(MethodImplOptions.NoInlining)>] 属性と一緒に使用されるときに警告を生成します。関数はインライン化されていません。 @@ -872,6 +877,11 @@ 属性を型拡張に適用することはできません。 + + This copy-and-update record expression changes all fields of record type '{0}'. Consider using the record construction syntax instead. + This copy-and-update record expression changes all fields of record type '{0}'. Consider using the record construction syntax instead. + + The syntax 'expr1[expr2]' is used for indexing. Consider adding a type annotation to enable indexing, or if calling a function add a space, e.g. 'expr1 [expr2]'. 構文 'expr1[expr2]' はインデックス作成に使用されます。インデックスを有効にするために型の注釈を追加するか、関数を呼び出す場合には、'expr1 [expr2]' のようにスペースを入れます。 diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf index 01841f6fc2..b167a41d44 100644 --- a/src/Compiler/xlf/FSComp.txt.ko.xlf +++ b/src/Compiler/xlf/FSComp.txt.ko.xlf @@ -382,6 +382,11 @@ 활성 패턴에 대한 구조체 표현 + + Raises warnings when an copy-and-update record expression changes all fields of a record. + Raises warnings when an copy-and-update record expression changes all fields of a record. + + Raises warnings when 'let inline ... =' is used together with [<MethodImpl(MethodImplOptions.NoInlining)>] attribute. Function is not getting inlined. 'let inline ... ='을(를) [<MethodImpl(MethodImplOptions.NoInlining)>] 특성과 함께 사용하는 경우 경고를 발생합니다. 함수가 인라인되지 않습니다. @@ -872,6 +877,11 @@ 형식 확장에 특성을 적용할 수 없습니다. + + This copy-and-update record expression changes all fields of record type '{0}'. Consider using the record construction syntax instead. + This copy-and-update record expression changes all fields of record type '{0}'. Consider using the record construction syntax instead. + + The syntax 'expr1[expr2]' is used for indexing. Consider adding a type annotation to enable indexing, or if calling a function add a space, e.g. 'expr1 [expr2]'. 인덱싱에는 'expr1[expr2]' 구문이 사용됩니다. 인덱싱을 사용하도록 설정하기 위해 형식 주석을 추가하는 것을 고려하거나 함수를 호출하는 경우 공백을 추가하세요(예: 'expr1 [expr2]'). diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf index 13a6e4ef9b..7590c5fd9f 100644 --- a/src/Compiler/xlf/FSComp.txt.pl.xlf +++ b/src/Compiler/xlf/FSComp.txt.pl.xlf @@ -382,6 +382,11 @@ reprezentacja struktury aktywnych wzorców + + Raises warnings when an copy-and-update record expression changes all fields of a record. + Raises warnings when an copy-and-update record expression changes all fields of a record. + + Raises warnings when 'let inline ... =' is used together with [<MethodImpl(MethodImplOptions.NoInlining)>] attribute. Function is not getting inlined. Zgłasza ostrzeżenia, gdy element „let inline ... =” jest używany razem z atrybutem [<MethodImpl(MethodImplOptions.NoInlining)>]. Funkcja nie jest wstawiana. @@ -872,6 +877,11 @@ Atrybutów nie można stosować do rozszerzeń typu. + + This copy-and-update record expression changes all fields of record type '{0}'. Consider using the record construction syntax instead. + This copy-and-update record expression changes all fields of record type '{0}'. Consider using the record construction syntax instead. + + The syntax 'expr1[expr2]' is used for indexing. Consider adding a type annotation to enable indexing, or if calling a function add a space, e.g. 'expr1 [expr2]'. Do indeksowania używana jest składnia „expr1[expr2]”. Rozważ dodanie adnotacji typu, aby umożliwić indeksowanie, lub jeśli wywołujesz funkcję dodaj spację, np. „expr1 [expr2]”. diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf index 1a0bb4f0fb..620acbfb86 100644 --- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf +++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf @@ -382,6 +382,11 @@ representação estrutural para padrões ativos + + Raises warnings when an copy-and-update record expression changes all fields of a record. + Raises warnings when an copy-and-update record expression changes all fields of a record. + + Raises warnings when 'let inline ... =' is used together with [<MethodImpl(MethodImplOptions.NoInlining)>] attribute. Function is not getting inlined. Gera avisos quando 'let inline ... =' é usado junto com o atributo [<MethodImpl(MethodImplOptions.NoInlining)>]. A função não está sendo embutida. @@ -872,6 +877,11 @@ Os atributos não podem ser aplicados às extensões de tipo. + + This copy-and-update record expression changes all fields of record type '{0}'. Consider using the record construction syntax instead. + This copy-and-update record expression changes all fields of record type '{0}'. Consider using the record construction syntax instead. + + The syntax 'expr1[expr2]' is used for indexing. Consider adding a type annotation to enable indexing, or if calling a function add a space, e.g. 'expr1 [expr2]'. A sintaxe 'expr1[expr2]' é usada para indexação. Considere adicionar uma anotação de tipo para habilitar a indexação ou, se chamar uma função, adicione um espaço, por exemplo, 'expr1 [expr2]'. diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf index eaa6ee4ad8..604ba38207 100644 --- a/src/Compiler/xlf/FSComp.txt.ru.xlf +++ b/src/Compiler/xlf/FSComp.txt.ru.xlf @@ -382,6 +382,11 @@ представление структуры для активных шаблонов + + Raises warnings when an copy-and-update record expression changes all fields of a record. + Raises warnings when an copy-and-update record expression changes all fields of a record. + + Raises warnings when 'let inline ... =' is used together with [<MethodImpl(MethodImplOptions.NoInlining)>] attribute. Function is not getting inlined. Выдает предупреждения, когда используется параметр "let inline ... =" вместе с атрибутом [<MethodImpl(MethodImplOptions.NoInlining)>]. Функция не встраивается. @@ -872,6 +877,11 @@ Атрибуты не могут быть применены к расширениям типа. + + This copy-and-update record expression changes all fields of record type '{0}'. Consider using the record construction syntax instead. + This copy-and-update record expression changes all fields of record type '{0}'. Consider using the record construction syntax instead. + + The syntax 'expr1[expr2]' is used for indexing. Consider adding a type annotation to enable indexing, or if calling a function add a space, e.g. 'expr1 [expr2]'. Для индексирования используется синтаксис "expr1[expr2]". Рассмотрите возможность добавления аннотации типа для включения индексации или при вызове функции добавьте пробел, например "expr1 [expr2]". diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf index e1e62fd7d7..3d816c0993 100644 --- a/src/Compiler/xlf/FSComp.txt.tr.xlf +++ b/src/Compiler/xlf/FSComp.txt.tr.xlf @@ -382,6 +382,11 @@ etkin desenler için yapı gösterimi + + Raises warnings when an copy-and-update record expression changes all fields of a record. + Raises warnings when an copy-and-update record expression changes all fields of a record. + + Raises warnings when 'let inline ... =' is used together with [<MethodImpl(MethodImplOptions.NoInlining)>] attribute. Function is not getting inlined. [<MethodImpl(MethodImplOptions.NoInlining)>] özniteliği ile birlikte 'let inline ... =' kullanıldığında uyarı verir. İşlev satır içine alınmıyor. @@ -872,6 +877,11 @@ Öznitelikler tür uzantılarına uygulanamaz. + + This copy-and-update record expression changes all fields of record type '{0}'. Consider using the record construction syntax instead. + This copy-and-update record expression changes all fields of record type '{0}'. Consider using the record construction syntax instead. + + The syntax 'expr1[expr2]' is used for indexing. Consider adding a type annotation to enable indexing, or if calling a function add a space, e.g. 'expr1 [expr2]'. Söz dizimi “expr1[expr2]” dizin oluşturma için kullanılıyor. Dizin oluşturmayı etkinleştirmek için bir tür ek açıklama eklemeyi düşünün veya bir işlev çağırıyorsanız bir boşluk ekleyin, örn. “expr1 [expr2]”. diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf index 514a0ffe74..d729f95bd3 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf @@ -382,6 +382,11 @@ 活动模式的结构表示形式 + + Raises warnings when an copy-and-update record expression changes all fields of a record. + Raises warnings when an copy-and-update record expression changes all fields of a record. + + Raises warnings when 'let inline ... =' is used together with [<MethodImpl(MethodImplOptions.NoInlining)>] attribute. Function is not getting inlined. 当 "let inline ... =" 与 [<MethodImpl(MethodImplOptions.NoInlining)>] 属性一起使用时引发警告。函数未内联。 @@ -872,6 +877,11 @@ 属性不可应用于类型扩展。 + + This copy-and-update record expression changes all fields of record type '{0}'. Consider using the record construction syntax instead. + This copy-and-update record expression changes all fields of record type '{0}'. Consider using the record construction syntax instead. + + The syntax 'expr1[expr2]' is used for indexing. Consider adding a type annotation to enable indexing, or if calling a function add a space, e.g. 'expr1 [expr2]'. 语法“expr1[expr2]”用于索引。考虑添加类型批注来启用索引,或者在调用函数添加空格,例如“expr1 [expr2]”。 diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf index c724422d97..e0161fdf94 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf @@ -382,6 +382,11 @@ 現用模式的結構表示法 + + Raises warnings when an copy-and-update record expression changes all fields of a record. + Raises warnings when an copy-and-update record expression changes all fields of a record. + + Raises warnings when 'let inline ... =' is used together with [<MethodImpl(MethodImplOptions.NoInlining)>] attribute. Function is not getting inlined. 當 'let inline ... =' 與 [<MethodImpl(MethodImplOptions.NoInlining)>] 屬性一起使用時引發警告。函數未內嵌。 @@ -872,6 +877,11 @@ 屬性無法套用到類型延伸模組。 + + This copy-and-update record expression changes all fields of record type '{0}'. Consider using the record construction syntax instead. + This copy-and-update record expression changes all fields of record type '{0}'. Consider using the record construction syntax instead. + + The syntax 'expr1[expr2]' is used for indexing. Consider adding a type annotation to enable indexing, or if calling a function add a space, e.g. 'expr1 [expr2]'. 語法 'expr1[expr2]' 已用於編製索引。請考慮新增類型註釋來啟用編製索引,或是呼叫函式並新增空格,例如 'expr1 [expr2]'。 diff --git a/src/FSharp.Core/Linq.fs b/src/FSharp.Core/Linq.fs index 040ccebfa9..bdca8e9bab 100644 --- a/src/FSharp.Core/Linq.fs +++ b/src/FSharp.Core/Linq.fs @@ -725,7 +725,7 @@ module LeafExpressionConverter = | Patterns.NewDelegate(delegateTy, vs, b) -> let vsP = List.map ConvVarToLinq vs - let env = {env with varEnv = List.foldBack2 (fun (v:Var) vP -> Map.add v (vP |> asExpr)) vs vsP env.varEnv } + let env = { varEnv = List.foldBack2 (fun (v:Var) vP -> Map.add v (vP |> asExpr)) vs vsP env.varEnv } let bodyP = ConvExprToLinqInContext env b Expression.Lambda(delegateTy, bodyP, vsP) |> asExpr @@ -768,7 +768,7 @@ module LeafExpressionConverter = | Patterns.Let (v, e, b) -> let vP = ConvVarToLinq v - let envinner = { env with varEnv = Map.add v (vP |> asExpr) env.varEnv } + let envinner = { varEnv = Map.add v (vP |> asExpr) env.varEnv } let bodyP = ConvExprToLinqInContext envinner b let eP = ConvExprToLinqInContext env e let ty = Expression.GetFuncType [| v.Type; b.Type |] @@ -777,7 +777,7 @@ module LeafExpressionConverter = | Patterns.Lambda(v, body) -> let vP = ConvVarToLinq v - let env = { env with varEnv = Map.add v (vP |> asExpr) env.varEnv } + let env = { varEnv = Map.add v (vP |> asExpr) env.varEnv } let bodyP = ConvExprToLinqInContext env body let lambdaTy, tyargs = if bodyP.Type = typeof then diff --git a/src/FSharp.Core/async.fs b/src/FSharp.Core/async.fs index e907040c94..2cfed9bc67 100644 --- a/src/FSharp.Core/async.fs +++ b/src/FSharp.Core/async.fs @@ -316,7 +316,7 @@ type AsyncActivation<'T>(contents: AsyncActivationContents<'T>) = /// Produce a new execution context for a composite async member ctxt.WithContinuations(cont, econt, ccont) = AsyncActivation<'T> - { contents with + { cont = cont aux = { ctxt.aux with diff --git a/tests/FSharp.Compiler.ComponentTests/Diagnostics/Records.fs b/tests/FSharp.Compiler.ComponentTests/Diagnostics/Records.fs new file mode 100644 index 0000000000..e5640db0f0 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Diagnostics/Records.fs @@ -0,0 +1,68 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +module FSharp.Compiler.ComponentTests.Diagnostics.Records + +open Xunit +open FSharp.Test +open FSharp.Test.Compiler + +[] +let ``Warning emitted when record update syntax changes all fields in lang preview``() = + Fsx """ +module Records + +type R = { F1: int; F2: string } + +let updateOk r = { r with F1 = 1 } +let updateWarn r = { r with F1 = 1; F2 = "" } + """ + |> withLangVersionPreview + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Warning 3560, Line 7, Col 20, Line 7, Col 46, "This copy-and-update record expression changes all fields of record type 'Records.R'. Consider using the record construction syntax instead.") + ] + +[] +let ``Warning not emitted when record update syntax changes all fields in lang70``() = + Fsx """ +module Records + +type R = { F1: int; F2: string } + +let updateWarn r = { r with F1 = 1; F2 = "" } + """ + |> withLangVersion70 + |> typecheck + |> shouldSucceed + +[] +let ``Warning not emitted when record update syntax changes all fields when disabled manually in lang preview``() = + Fsx """ +module Records + +type R = { F1: int; F2: string } + +let updateWarn r = { r with F1 = 1; F2 = "" } + """ + |> withLangVersionPreview + |> withOptions ["--nowarn:3560"] + |> typecheck + |> shouldSucceed + +[] +let ``Warning emitted when record update syntax changes all fields when enabled manually in lang70``() = + Fsx """ +module Records + +type R = { F1: int; F2: string } + +let updateWarn r = { r with F1 = 1; F2 = "" } + """ + |> withLangVersion70 + |> withOptions ["--warnon:FS3560"] + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Warning 3560, Line 6, Col 20, Line 6, Col 46, "This copy-and-update record expression changes all fields of record type 'Records.R'. Consider using the record construction syntax instead.") + ] \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj index c244723eb7..f2e4de6576 100644 --- a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj +++ b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj @@ -205,6 +205,7 @@ + diff --git a/tests/FSharp.Test.Utilities/Compiler.fs b/tests/FSharp.Test.Utilities/Compiler.fs index 453d11f487..dee735dff4 100644 --- a/tests/FSharp.Test.Utilities/Compiler.fs +++ b/tests/FSharp.Test.Utilities/Compiler.fs @@ -244,7 +244,7 @@ module rec Compiler = let private getWarnings diagnostics = diagnostics |> List.filter (fun e -> match e.Error with Warning _ -> true | _ -> false) let private adjustRange (range: Range) (adjust: int) : Range = - { range with + { StartLine = range.StartLine - adjust StartColumn = range.StartColumn + 1 EndLine = range.EndLine - adjust diff --git a/tests/FSharp.Test.Utilities/ProjectGeneration.fs b/tests/FSharp.Test.Utilities/ProjectGeneration.fs index c9b21c4e4f..4e2e482390 100644 --- a/tests/FSharp.Test.Utilities/ProjectGeneration.fs +++ b/tests/FSharp.Test.Utilities/ProjectGeneration.fs @@ -141,7 +141,7 @@ type SyntheticProject = ) |> Async.RunSynchronously - { baseOptions with + { ProjectFileName = this.ProjectFileName ProjectId = None SourceFiles =