From 988180d4b611ea061b38ef0b5d78096439251e21 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Thu, 20 Feb 2025 11:47:57 +0100 Subject: [PATCH 1/7] Warn when 'unit' is passed to an 'obj' argument --- src/Compiler/Checking/ConstraintSolver.fs | 7 +++++-- .../Checking/Expressions/CheckExpressions.fs | 2 ++ src/Compiler/FSComp.txt | 2 ++ src/Compiler/Facilities/LanguageFeatures.fs | 3 +++ src/Compiler/Facilities/LanguageFeatures.fsi | 1 + src/Compiler/xlf/FSComp.txt.cs.xlf | 10 ++++++++++ src/Compiler/xlf/FSComp.txt.de.xlf | 10 ++++++++++ src/Compiler/xlf/FSComp.txt.es.xlf | 10 ++++++++++ src/Compiler/xlf/FSComp.txt.fr.xlf | 10 ++++++++++ src/Compiler/xlf/FSComp.txt.it.xlf | 10 ++++++++++ src/Compiler/xlf/FSComp.txt.ja.xlf | 10 ++++++++++ src/Compiler/xlf/FSComp.txt.ko.xlf | 10 ++++++++++ src/Compiler/xlf/FSComp.txt.pl.xlf | 10 ++++++++++ src/Compiler/xlf/FSComp.txt.pt-BR.xlf | 10 ++++++++++ src/Compiler/xlf/FSComp.txt.ru.xlf | 10 ++++++++++ src/Compiler/xlf/FSComp.txt.tr.xlf | 10 ++++++++++ src/Compiler/xlf/FSComp.txt.zh-Hans.xlf | 10 ++++++++++ src/Compiler/xlf/FSComp.txt.zh-Hant.xlf | 10 ++++++++++ .../OptionalDefaultParamArgs.fs | 19 ++++++++++++++++--- .../W_WrongDefaultObj.fs | 13 +++++++++++++ .../W_WrongDefaultType.fs | 1 + 21 files changed, 173 insertions(+), 5 deletions(-) create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MemberDefinitions/OptionalDefaultParamArgs/W_WrongDefaultObj.fs diff --git a/src/Compiler/Checking/ConstraintSolver.fs b/src/Compiler/Checking/ConstraintSolver.fs index 50026fe382..efdf109355 100644 --- a/src/Compiler/Checking/ConstraintSolver.fs +++ b/src/Compiler/Checking/ConstraintSolver.fs @@ -3175,6 +3175,7 @@ and ArgsMustSubsumeOrConvert trackErrors { let g = csenv.g let m = callerArg.Range + let callerTy = callerArg.CallerArgumentType let calledArgTy, usesTDC, eqn = AdjustCalledArgType csenv.InfoReader ad isConstraint enforceNullableOptionalsKnownTypes calledArg callerArg match eqn with @@ -3186,8 +3187,10 @@ and ArgsMustSubsumeOrConvert match usesTDC with | TypeDirectedConversionUsed.Yes(warn, _, _) -> do! WarnD(warn csenv.DisplayEnv) | TypeDirectedConversionUsed.No -> () - do! SolveTypeSubsumesTypeWithReport csenv ndeep m trace cxsln (Some calledArg.CalledArgumentType) calledArgTy callerArg.CallerArgumentType - if calledArg.IsParamArray && isArray1DTy g calledArgTy && not (isArray1DTy g callerArg.CallerArgumentType) then + do! SolveTypeSubsumesTypeWithReport csenv ndeep m trace cxsln (Some calledArg.CalledArgumentType) calledArgTy callerTy + if g.langVersion.SupportsFeature(LanguageFeature.WarnWhenUnitPassedToObjArg) && isUnitTy g callerTy && isObjTyAnyNullness g calledArgTy then + do! WarnD(Error(FSComp.SR.tcUnitToObjSubsumption(), m)) + if calledArg.IsParamArray && isArray1DTy g calledArgTy && not (isArray1DTy g callerTy) then return! ErrorD(Error(FSComp.SR.csMethodExpectsParams(), m)) else return usesTDC diff --git a/src/Compiler/Checking/Expressions/CheckExpressions.fs b/src/Compiler/Checking/Expressions/CheckExpressions.fs index d80470b9e5..94e6a8c1c8 100644 --- a/src/Compiler/Checking/Expressions/CheckExpressions.fs +++ b/src/Compiler/Checking/Expressions/CheckExpressions.fs @@ -9787,6 +9787,8 @@ and GetNewInferenceTypeForMethodArg (cenv: cenv) x = | SynExpr.Quote (_, raw, a, _, _) -> if raw then cont (0, mkRawQuotedExprTy g) else loopExpr a (cont << fun struct (depth, ty) -> depth + 1, mkQuotedExprTy g ty) + | SynExpr.Const (SynConst.Unit, _) -> + cont (0, g.unit_ty) | _ -> cont (0, NewInferenceType g) let struct (_depth, ty) = loopExpr x id diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt index ad95dc6556..eedaecbb9b 100644 --- a/src/Compiler/FSComp.txt +++ b/src/Compiler/FSComp.txt @@ -1683,6 +1683,7 @@ forFormatInvalidForInterpolated4,"Interpolated strings used as type IFormattable 3394,parsNewExprMemberAccess,"This member access is ambiguous. Please use parentheses around the object creation, e.g. '(new SomeType(args)).MemberName'" 3395,tcImplicitConversionUsedForMethodArg,"This expression uses the implicit conversion '%s' to convert type '%s' to type '%s'." 3396,tcLiteralAttributeCannotUseActivePattern,"A [] declaration cannot use an active pattern for its identifier" +3397,tcUnitToObjSubsumption,"This expression uses 'unit' for an 'obj'-typed argument. This will lead to passing 'null' at runtime. This warning may be disabled using '#nowarn \"3397\"." 3401,ilxgenInvalidConstructInStateMachineDuringCodegen,"The resumable code construct '%s' may only be used in inlined code protected by 'if __useResumableCode then ...' and the overall composition must form valid resumable code." 3402,tcInvalidResumableConstruct,"The construct '%s' may only be used in valid resumable code." 3501,tcResumableCodeFunctionMustBeInline,"Invalid resumable code. Any method of function accepting or returning resumable code must be marked 'inline'" @@ -1794,3 +1795,4 @@ featureDontWarnOnUppercaseIdentifiersInBindingPatterns,"Don't warn on uppercase 3874,tcExpectedTypeParamMarkedWithUnitOfMeasureAttribute,"Expected unit-of-measure type parameter must be marked with the [] attribute." featureDeprecatePlacesWhereSeqCanBeOmitted,"Deprecate places where 'seq' can be omitted" featureSupportValueOptionsAsOptionalParameters,"Support ValueOption as valid type for optional member parameters" +featureSupportWarnWhenUnitPassedToObjArg,"Warn when unit is passed to a member accepting `obj` argument, e.g. `Method(o:obj)` will warn if called via `Method()`." diff --git a/src/Compiler/Facilities/LanguageFeatures.fs b/src/Compiler/Facilities/LanguageFeatures.fs index 5401ea26a1..867dfd40f7 100644 --- a/src/Compiler/Facilities/LanguageFeatures.fs +++ b/src/Compiler/Facilities/LanguageFeatures.fs @@ -98,6 +98,7 @@ type LanguageFeature = | UseTypeSubsumptionCache | DeprecatePlacesWhereSeqCanBeOmitted | SupportValueOptionsAsOptionalParameters + | WarnWhenUnitPassedToObjArg /// LanguageVersion management type LanguageVersion(versionText) = @@ -227,6 +228,7 @@ type LanguageVersion(versionText) = LanguageFeature.DontWarnOnUppercaseIdentifiersInBindingPatterns, previewVersion LanguageFeature.DeprecatePlacesWhereSeqCanBeOmitted, previewVersion LanguageFeature.SupportValueOptionsAsOptionalParameters, previewVersion + LanguageFeature.WarnWhenUnitPassedToObjArg, previewVersion ] static let defaultLanguageVersion = LanguageVersion("default") @@ -388,6 +390,7 @@ type LanguageVersion(versionText) = | LanguageFeature.UseTypeSubsumptionCache -> FSComp.SR.featureUseTypeSubsumptionCache () | LanguageFeature.DeprecatePlacesWhereSeqCanBeOmitted -> FSComp.SR.featureDeprecatePlacesWhereSeqCanBeOmitted () | LanguageFeature.SupportValueOptionsAsOptionalParameters -> FSComp.SR.featureSupportValueOptionsAsOptionalParameters () + | LanguageFeature.WarnWhenUnitPassedToObjArg -> FSComp.SR.featureSupportWarnWhenUnitPassedToObjArg () /// 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 9057288800..410a8b193c 100644 --- a/src/Compiler/Facilities/LanguageFeatures.fsi +++ b/src/Compiler/Facilities/LanguageFeatures.fsi @@ -89,6 +89,7 @@ type LanguageFeature = | UseTypeSubsumptionCache | DeprecatePlacesWhereSeqCanBeOmitted | SupportValueOptionsAsOptionalParameters + | WarnWhenUnitPassedToObjArg /// LanguageVersion management type LanguageVersion = diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf index 30a20d94b2..74894da5d0 100644 --- a/src/Compiler/xlf/FSComp.txt.cs.xlf +++ b/src/Compiler/xlf/FSComp.txt.cs.xlf @@ -627,6 +627,11 @@ Support ValueOption as valid type for optional member parameters + + Warn when unit is passed to a member accepting `obj` argument, e.g. `Method(o:obj)` will warn if called via `Method()`. + Warn when unit is passed to a member accepting `obj` argument, e.g. `Method(o:obj)` will warn if called via `Method()`. + + Union case test properties Vlastnosti testu případu sjednocení @@ -1712,6 +1717,11 @@ Neočekávaný typ funkce v definici pole případu sjednocení. Pokud chcete, aby pole bylo funkcí, zvažte zabalení signatury funkce závorkami, např. | Případ a -> b na | případ (a -> b). + + This expression uses 'unit' for an 'obj'-typed argument. This will lead to passing 'null' at runtime. This warning may be disabled using '#nowarn \"3397\". + This expression uses 'unit' for an 'obj'-typed argument. This will lead to passing 'null' at runtime. This warning may be disabled using '#nowarn \"3397\". + + '{0}' is normally used as a type constraint in generic code, e.g. \"'T when ISomeInterface<'T>\" or \"let f (x: #ISomeInterface<_>)\". See https://aka.ms/fsharp-iwsams for guidance. You can disable this warning by using '#nowarn \"3536\"' or '--nowarn:3536'. '{0}' se obvykle používá jako omezení typu v obecném kódu, například \"T when ISomeInterface<'T>\" nebo \"let f (x: #ISomeInterface<_>)\". Pokyny najdete v https://aka.ms/fsharp-iwsams. Toto upozornění můžete zakázat pomocí #nowarn \"3536\" nebo '--nowarn:3536'. diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf index 99eb6f814b..7740961586 100644 --- a/src/Compiler/xlf/FSComp.txt.de.xlf +++ b/src/Compiler/xlf/FSComp.txt.de.xlf @@ -627,6 +627,11 @@ Support ValueOption as valid type for optional member parameters + + Warn when unit is passed to a member accepting `obj` argument, e.g. `Method(o:obj)` will warn if called via `Method()`. + Warn when unit is passed to a member accepting `obj` argument, e.g. `Method(o:obj)` will warn if called via `Method()`. + + Union case test properties Eigenschaften von Union-Falltests @@ -1712,6 +1717,11 @@ Unerwarteter Funktionstyp in Felddefinition von Union-Fall (case). Wenn das Feld eine Funktion sein soll, sollten Sie die Funktionssignatur in Klammern einschließen, z. B. | Case of a -> b als | Case of (a -> b). + + This expression uses 'unit' for an 'obj'-typed argument. This will lead to passing 'null' at runtime. This warning may be disabled using '#nowarn \"3397\". + This expression uses 'unit' for an 'obj'-typed argument. This will lead to passing 'null' at runtime. This warning may be disabled using '#nowarn \"3397\". + + '{0}' is normally used as a type constraint in generic code, e.g. \"'T when ISomeInterface<'T>\" or \"let f (x: #ISomeInterface<_>)\". See https://aka.ms/fsharp-iwsams for guidance. You can disable this warning by using '#nowarn \"3536\"' or '--nowarn:3536'. „{0}“ wird normalerweise als Typeinschränkung im generischen Code verwendet, z. B. \"'T when ISomeInterface<'T>\" oder \"let f (x: #ISomeInterface<_>)\". Anleitungen finden Sie unter https://aka.ms/fsharp-iwsams. Sie können diese Warnung deaktivieren, indem Sie „#nowarn \"3536\"“ or „--nowarn:3536“ verwenden. diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf index 5a84160317..9f042384d3 100644 --- a/src/Compiler/xlf/FSComp.txt.es.xlf +++ b/src/Compiler/xlf/FSComp.txt.es.xlf @@ -627,6 +627,11 @@ Support ValueOption as valid type for optional member parameters + + Warn when unit is passed to a member accepting `obj` argument, e.g. `Method(o:obj)` will warn if called via `Method()`. + Warn when unit is passed to a member accepting `obj` argument, e.g. `Method(o:obj)` will warn if called via `Method()`. + + Union case test properties Propiedades de prueba de caso de unión @@ -1712,6 +1717,11 @@ Tipo de función inesperado en la definición de campo de caso de unión. Si pretende que el campo sea una función, considere la posibilidad de encapsular la firma de función con paréntesis, por ejemplo, Case of a -> b en | Case of (a -> b). + + This expression uses 'unit' for an 'obj'-typed argument. This will lead to passing 'null' at runtime. This warning may be disabled using '#nowarn \"3397\". + This expression uses 'unit' for an 'obj'-typed argument. This will lead to passing 'null' at runtime. This warning may be disabled using '#nowarn \"3397\". + + '{0}' is normally used as a type constraint in generic code, e.g. \"'T when ISomeInterface<'T>\" or \"let f (x: #ISomeInterface<_>)\". See https://aka.ms/fsharp-iwsams for guidance. You can disable this warning by using '#nowarn \"3536\"' or '--nowarn:3536'. '{0}' se usa normalmente como restricción de tipo en código genérico; por ejemplo, \"'T when ISomeInterface<'T>\" o \"let f (x: #ISomeInterface<_>)\". Consulte https://aka.ms/fsharp-iwsams para obtener instrucciones. Puede deshabilitar esta advertencia con "#nowarn \"3536\"" o "--nowarn:3536". diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf index 3e98a55816..621286a8e2 100644 --- a/src/Compiler/xlf/FSComp.txt.fr.xlf +++ b/src/Compiler/xlf/FSComp.txt.fr.xlf @@ -627,6 +627,11 @@ Support ValueOption as valid type for optional member parameters + + Warn when unit is passed to a member accepting `obj` argument, e.g. `Method(o:obj)` will warn if called via `Method()`. + Warn when unit is passed to a member accepting `obj` argument, e.g. `Method(o:obj)` will warn if called via `Method()`. + + Union case test properties Propriétés du test de cas d’union @@ -1712,6 +1717,11 @@ Type de fonction inattendu dans la définition du champ de cas d'union. Si vous souhaitez que le champ soit une fonction, envisagez d'envelopper la signature de la fonction avec des parenthèses, par exemple. | Cas de a -> b dans | Cas de (a -> b). + + This expression uses 'unit' for an 'obj'-typed argument. This will lead to passing 'null' at runtime. This warning may be disabled using '#nowarn \"3397\". + This expression uses 'unit' for an 'obj'-typed argument. This will lead to passing 'null' at runtime. This warning may be disabled using '#nowarn \"3397\". + + '{0}' is normally used as a type constraint in generic code, e.g. \"'T when ISomeInterface<'T>\" or \"let f (x: #ISomeInterface<_>)\". See https://aka.ms/fsharp-iwsams for guidance. You can disable this warning by using '#nowarn \"3536\"' or '--nowarn:3536'. '{0}' est généralement utilisée comme contrainte de type dans le code générique, par exemple \"'T when ISomeInterface<'T>\" or \"let f (x: #ISomeInterface<_>)\". Consultez https://aka.ms/fsharp-iwsams pour obtenir de l’aide. Vous pouvez désactiver cet avertissement à l’aide de '#nowarn \"3536\"' or '--nowarn:3536'. diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf index b982714a14..1d7bdf56aa 100644 --- a/src/Compiler/xlf/FSComp.txt.it.xlf +++ b/src/Compiler/xlf/FSComp.txt.it.xlf @@ -627,6 +627,11 @@ Support ValueOption as valid type for optional member parameters + + Warn when unit is passed to a member accepting `obj` argument, e.g. `Method(o:obj)` will warn if called via `Method()`. + Warn when unit is passed to a member accepting `obj` argument, e.g. `Method(o:obj)` will warn if called via `Method()`. + + Union case test properties Proprietà test case di unione @@ -1712,6 +1717,11 @@ Tipo di funzione imprevisto nella definizione del campo del caso di unione. Se desideri che il campo sia una funzione, considera di eseguire il wrapping della firma della funzione con le parentesi, ad esempio | Case of a -> b into | Case of (a -> b). + + This expression uses 'unit' for an 'obj'-typed argument. This will lead to passing 'null' at runtime. This warning may be disabled using '#nowarn \"3397\". + This expression uses 'unit' for an 'obj'-typed argument. This will lead to passing 'null' at runtime. This warning may be disabled using '#nowarn \"3397\". + + '{0}' is normally used as a type constraint in generic code, e.g. \"'T when ISomeInterface<'T>\" or \"let f (x: #ISomeInterface<_>)\". See https://aka.ms/fsharp-iwsams for guidance. You can disable this warning by using '#nowarn \"3536\"' or '--nowarn:3536'. '{0}' viene in genere usato come vincolo di tipo nel codice generico, ad esempio \"'T when ISomeInterface<'T>\" o \"let f (x: #ISomeInterface<_>)\". Per indicazioni, vedere https://aka.ms/fsharp-iwsams. È possibile disabilitare questo avviso usando '#nowarn \"3536\"' o '--nowarn:3536'. diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf index 3a23712a96..c928a51da3 100644 --- a/src/Compiler/xlf/FSComp.txt.ja.xlf +++ b/src/Compiler/xlf/FSComp.txt.ja.xlf @@ -627,6 +627,11 @@ Support ValueOption as valid type for optional member parameters + + Warn when unit is passed to a member accepting `obj` argument, e.g. `Method(o:obj)` will warn if called via `Method()`. + Warn when unit is passed to a member accepting `obj` argument, e.g. `Method(o:obj)` will warn if called via `Method()`. + + Union case test properties ユニオン ケースのテスト プロパティ @@ -1712,6 +1717,11 @@ 共用体ケースのフィールド定義で予期しない関数型が発生しました。フィールドを関数にする場合は、関数シグネチャを parens でラップすることを検討してください、例えば、 | Case of a -> b into | Case of (a -> b)。 + + This expression uses 'unit' for an 'obj'-typed argument. This will lead to passing 'null' at runtime. This warning may be disabled using '#nowarn \"3397\". + This expression uses 'unit' for an 'obj'-typed argument. This will lead to passing 'null' at runtime. This warning may be disabled using '#nowarn \"3397\". + + '{0}' is normally used as a type constraint in generic code, e.g. \"'T when ISomeInterface<'T>\" or \"let f (x: #ISomeInterface<_>)\". See https://aka.ms/fsharp-iwsams for guidance. You can disable this warning by using '#nowarn \"3536\"' or '--nowarn:3536'. '{0}' は通常、ジェネリック コードの型制約として使用されます (例: \"'T when ISomeInterface<'T>\" または \"let f (x: #ISomeInterface<_>)\")。ガイダンスについては https://aka.ms/fsharp-iwsams を参照してください。この警告は、'#nowarn \"3536\"' または '--nowarn:3536' を使用して無効にできます。 diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf index 41ad2ce40a..aaff373fcd 100644 --- a/src/Compiler/xlf/FSComp.txt.ko.xlf +++ b/src/Compiler/xlf/FSComp.txt.ko.xlf @@ -627,6 +627,11 @@ Support ValueOption as valid type for optional member parameters + + Warn when unit is passed to a member accepting `obj` argument, e.g. `Method(o:obj)` will warn if called via `Method()`. + Warn when unit is passed to a member accepting `obj` argument, e.g. `Method(o:obj)` will warn if called via `Method()`. + + Union case test properties 공용 구조체 사례 테스트 속성 @@ -1712,6 +1717,11 @@ 공용 구조체 사례 필드 정의에 예기치 않은 함수 형식이 있습니다. 필드가 함수가 되도록 하려면 함수 시그니처를 구문 분석으로 래핑하는 것이 좋습니다(예: | Case of a -> b into | Case of (a -> b)) + + This expression uses 'unit' for an 'obj'-typed argument. This will lead to passing 'null' at runtime. This warning may be disabled using '#nowarn \"3397\". + This expression uses 'unit' for an 'obj'-typed argument. This will lead to passing 'null' at runtime. This warning may be disabled using '#nowarn \"3397\". + + '{0}' is normally used as a type constraint in generic code, e.g. \"'T when ISomeInterface<'T>\" or \"let f (x: #ISomeInterface<_>)\". See https://aka.ms/fsharp-iwsams for guidance. You can disable this warning by using '#nowarn \"3536\"' or '--nowarn:3536'. '{0}'은(는) 일반적으로 제네릭 코드에서 형식 제약 조건으로 사용됩니다(예: \"'T when ISomeInterface<'T>\" 또는 \"let f (x: #ISomeInterface<_>)\"). 지침은 https://aka.ms/fsharp-iwsams를 참조하세요. '#nowarn \"3536\"' 또는 '--nowarn:3536'을 사용하여 이 경고를 비활성화할 수 있습니다. diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf index f7cf199c4f..f886e72e8f 100644 --- a/src/Compiler/xlf/FSComp.txt.pl.xlf +++ b/src/Compiler/xlf/FSComp.txt.pl.xlf @@ -627,6 +627,11 @@ Support ValueOption as valid type for optional member parameters + + Warn when unit is passed to a member accepting `obj` argument, e.g. `Method(o:obj)` will warn if called via `Method()`. + Warn when unit is passed to a member accepting `obj` argument, e.g. `Method(o:obj)` will warn if called via `Method()`. + + Union case test properties Właściwości testowe przypadku unii @@ -1712,6 +1717,11 @@ Nieoczekiwany typ funkcji w definicji pola przypadku unii. Jeśli zamierzasz, aby pole było funkcją, rozważ ujęcie podpisu funkcji w nawiasy, np. | Przypadek a -> b | Przypadek (a -> b). + + This expression uses 'unit' for an 'obj'-typed argument. This will lead to passing 'null' at runtime. This warning may be disabled using '#nowarn \"3397\". + This expression uses 'unit' for an 'obj'-typed argument. This will lead to passing 'null' at runtime. This warning may be disabled using '#nowarn \"3397\". + + '{0}' is normally used as a type constraint in generic code, e.g. \"'T when ISomeInterface<'T>\" or \"let f (x: #ISomeInterface<_>)\". See https://aka.ms/fsharp-iwsams for guidance. You can disable this warning by using '#nowarn \"3536\"' or '--nowarn:3536'. Element „{0}” jest zwykle używany jako ograniczenie typu w kodzie ogólnym, np. \"" T, gdy ISomeInterface<' T>\" lub \"let f (x: #ISomeInterface<_>)\". Aby uzyskać wskazówki, zobacz https://aka.ms/fsharp-iwsams. To ostrzeżenie można wyłączyć, używając polecenia „nowarn \"3536\"" lub "--nowarn:3536”. diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf index 4813c27846..6908257467 100644 --- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf +++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf @@ -627,6 +627,11 @@ Support ValueOption as valid type for optional member parameters + + Warn when unit is passed to a member accepting `obj` argument, e.g. `Method(o:obj)` will warn if called via `Method()`. + Warn when unit is passed to a member accepting `obj` argument, e.g. `Method(o:obj)` will warn if called via `Method()`. + + Union case test properties Propriedades de teste de caso de união @@ -1712,6 +1717,11 @@ Tipo de função inesperado na definição de campo de caso de união. Se você pretende que o campo seja uma função, considere encapsular a assinatura de função com parênteses, por exemplo, | Caso de a -> b em | Caso de (a -> b). + + This expression uses 'unit' for an 'obj'-typed argument. This will lead to passing 'null' at runtime. This warning may be disabled using '#nowarn \"3397\". + This expression uses 'unit' for an 'obj'-typed argument. This will lead to passing 'null' at runtime. This warning may be disabled using '#nowarn \"3397\". + + '{0}' is normally used as a type constraint in generic code, e.g. \"'T when ISomeInterface<'T>\" or \"let f (x: #ISomeInterface<_>)\". See https://aka.ms/fsharp-iwsams for guidance. You can disable this warning by using '#nowarn \"3536\"' or '--nowarn:3536'. '{0}' normalmente é usado como uma restrição de tipo em código genérico, por exemplo, \"'T when ISomeInterface<'T>\" ou \"let f (x: #ISomeInterface<_>)\". Confira https://aka.ms/fsharp-iwsams para obter as diretrizes. Você pode desabilitar este aviso usando '#nowarn \"3536\"' ou '--nowarn:3536'. diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf index b1aad1198d..df0d5f9770 100644 --- a/src/Compiler/xlf/FSComp.txt.ru.xlf +++ b/src/Compiler/xlf/FSComp.txt.ru.xlf @@ -627,6 +627,11 @@ Support ValueOption as valid type for optional member parameters + + Warn when unit is passed to a member accepting `obj` argument, e.g. `Method(o:obj)` will warn if called via `Method()`. + Warn when unit is passed to a member accepting `obj` argument, e.g. `Method(o:obj)` will warn if called via `Method()`. + + Union case test properties Свойства теста союзного случая @@ -1712,6 +1717,11 @@ Неожиданный тип функции в определении поля регистра объединения. Если предполагается, что поле будет представлять собой функцию, следует обернуть сигнатуру функции родительными падежами, например, | Case of a -> b в | Case of (a -> b). + + This expression uses 'unit' for an 'obj'-typed argument. This will lead to passing 'null' at runtime. This warning may be disabled using '#nowarn \"3397\". + This expression uses 'unit' for an 'obj'-typed argument. This will lead to passing 'null' at runtime. This warning may be disabled using '#nowarn \"3397\". + + '{0}' is normally used as a type constraint in generic code, e.g. \"'T when ISomeInterface<'T>\" or \"let f (x: #ISomeInterface<_>)\". See https://aka.ms/fsharp-iwsams for guidance. You can disable this warning by using '#nowarn \"3536\"' or '--nowarn:3536'. "{0}" обычно используется в качестве ограничения типа в универсальном коде, например \"'T when ISomeInterface<"T>\" или \"let f (x: #ISomeInterface<_>)\". См. руководство на https://aka.ms/fsharp-iwsams. Это предупреждение можно отключить с помощью "#nowarn \"3536\"" или "--nowarn:3536". diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf index 050ccf6ea9..7756859313 100644 --- a/src/Compiler/xlf/FSComp.txt.tr.xlf +++ b/src/Compiler/xlf/FSComp.txt.tr.xlf @@ -627,6 +627,11 @@ Support ValueOption as valid type for optional member parameters + + Warn when unit is passed to a member accepting `obj` argument, e.g. `Method(o:obj)` will warn if called via `Method()`. + Warn when unit is passed to a member accepting `obj` argument, e.g. `Method(o:obj)` will warn if called via `Method()`. + + Union case test properties Birleşim durumu test özellikleri @@ -1712,6 +1717,11 @@ Birleşim durumu alan tanımında beklenmeyen işlev türü. Alanın bir işlev olmasını amaçlıyorsanız işlev imzasını parens ile sarmalamayı göz önünde bulundurun. Ör. | (a -> b) durumunda | a -> b durumu. + + This expression uses 'unit' for an 'obj'-typed argument. This will lead to passing 'null' at runtime. This warning may be disabled using '#nowarn \"3397\". + This expression uses 'unit' for an 'obj'-typed argument. This will lead to passing 'null' at runtime. This warning may be disabled using '#nowarn \"3397\". + + '{0}' is normally used as a type constraint in generic code, e.g. \"'T when ISomeInterface<'T>\" or \"let f (x: #ISomeInterface<_>)\". See https://aka.ms/fsharp-iwsams for guidance. You can disable this warning by using '#nowarn \"3536\"' or '--nowarn:3536'. '{0}' normalde genel kodda tür kısıtlaması olarak kullanılır, ör. \"'T when ISomeInterface<'T>\" veya \"let f (x: #ISomeInterface<_>)\". Rehber için bkz. https://aka.ms/fsharp-iwsams. '#nowarn \"3536\"' veya '--nowarn:3536' kullanarak bu uyarıyı devre dışı bırakabilirsiniz. diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf index 085668fbc0..59532dc06d 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf @@ -627,6 +627,11 @@ Support ValueOption as valid type for optional member parameters + + Warn when unit is passed to a member accepting `obj` argument, e.g. `Method(o:obj)` will warn if called via `Method()`. + Warn when unit is passed to a member accepting `obj` argument, e.g. `Method(o:obj)` will warn if called via `Method()`. + + Union case test properties 联合用例测试属性 @@ -1712,6 +1717,11 @@ 联合用例字段定义中出现意外的函数类型。如果打算将字段作为函数,请考虑使用括号括起函数签名,例如 | Case of a -> b into | Case of (a -> b)。 + + This expression uses 'unit' for an 'obj'-typed argument. This will lead to passing 'null' at runtime. This warning may be disabled using '#nowarn \"3397\". + This expression uses 'unit' for an 'obj'-typed argument. This will lead to passing 'null' at runtime. This warning may be disabled using '#nowarn \"3397\". + + '{0}' is normally used as a type constraint in generic code, e.g. \"'T when ISomeInterface<'T>\" or \"let f (x: #ISomeInterface<_>)\". See https://aka.ms/fsharp-iwsams for guidance. You can disable this warning by using '#nowarn \"3536\"' or '--nowarn:3536'. "{0}" 通常用作泛型代码中的类型约束,例如 \"'T when ISomeInterface<'T>\" or \"let f (x: #ISomeInterface<_>)\"。有关指南,请参阅 https://aka.ms/fsharp-iwsams。可以使用 '#nowarn \"3536\"' 或 '--nowarn:3536' 禁用此警告。 diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf index 48f36e8611..2274eb373c 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf @@ -627,6 +627,11 @@ Support ValueOption as valid type for optional member parameters + + Warn when unit is passed to a member accepting `obj` argument, e.g. `Method(o:obj)` will warn if called via `Method()`. + Warn when unit is passed to a member accepting `obj` argument, e.g. `Method(o:obj)` will warn if called via `Method()`. + + Union case test properties 聯集案例測試屬性 @@ -1712,6 +1717,11 @@ 聯集案例欄位定義中有未預期的函式類型。如果您想要讓欄位成為函式,請考慮使用括弧括住函式簽章,例如將 | Case of a -> b 變更為 | Case of (a -> b)。 + + This expression uses 'unit' for an 'obj'-typed argument. This will lead to passing 'null' at runtime. This warning may be disabled using '#nowarn \"3397\". + This expression uses 'unit' for an 'obj'-typed argument. This will lead to passing 'null' at runtime. This warning may be disabled using '#nowarn \"3397\". + + '{0}' is normally used as a type constraint in generic code, e.g. \"'T when ISomeInterface<'T>\" or \"let f (x: #ISomeInterface<_>)\". See https://aka.ms/fsharp-iwsams for guidance. You can disable this warning by using '#nowarn \"3536\"' or '--nowarn:3536'. '{0}' 通常做為一般程式碼中的類型限制式,例如 \"'T when ISomeInterface<'T>\" 或 \"let f (x: #ISomeInterface<_>)\"。請參閱 https://aka.ms/fsharp-iwsams 以尋求指引。您可以使用 '#nowarn \"3536\"' 或 '--nowarn:3536' 來停用此警告。 diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MemberDefinitions/OptionalDefaultParamArgs/OptionalDefaultParamArgs.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MemberDefinitions/OptionalDefaultParamArgs/OptionalDefaultParamArgs.fs index ae25dc7219..22fb9ac122 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MemberDefinitions/OptionalDefaultParamArgs/OptionalDefaultParamArgs.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MemberDefinitions/OptionalDefaultParamArgs/OptionalDefaultParamArgs.fs @@ -73,12 +73,25 @@ module MemberDefinitions_OptionalDefaultParamArgs = [] let ``W_WrongDefaultType_fs`` compilation = compilation + |> withLangVersionPreview |> verifyCompile |> shouldFail |> withDiagnostics [ - (Warning 3211, Line 10, Col 62, Line 10, Col 63, "The default value does not have the same type as the argument. The DefaultParameterValue attribute and any Optional attribute will be ignored. Note: 'null' needs to be annotated with the correct type, e.g. 'DefaultParameterValue(null:obj)'.") - ] - + Warning 3211, Line 10, Col 62, Line 10, Col 63, "The default value does not have the same type as the argument. The DefaultParameterValue attribute and any Optional attribute will be ignored. Note: 'null' needs to be annotated with the correct type, e.g. 'DefaultParameterValue(null:obj)'." + Error 193, Line 13, Col 25, Line 13, Col 27, """Type constraint mismatch. The type +'unit' +is not compatible with type +'string' """ ] + + [] + let ``W_WrongDefaultObjType_fs`` compilation = + compilation + |> withLangVersionPreview + |> verifyCompile + |> shouldFail + |> withDiagnostics + [ Warning 3211, Line 10, Col 62, Line 10, Col 67, "The default value does not have the same type as the argument. The DefaultParameterValue attribute and any Optional attribute will be ignored. Note: 'null' needs to be annotated with the correct type, e.g. 'DefaultParameterValue(null:obj)'." + Warning 3397, Line 12, Col 19, Line 12, Col 21, """This expression uses 'unit' for an 'obj'-typed argument. This will lead to passing 'null' at runtime. This warning may be disabled using '#nowarn "3397"."""] diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MemberDefinitions/OptionalDefaultParamArgs/W_WrongDefaultObj.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MemberDefinitions/OptionalDefaultParamArgs/W_WrongDefaultObj.fs new file mode 100644 index 0000000000..b0e95c0974 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MemberDefinitions/OptionalDefaultParamArgs/W_WrongDefaultObj.fs @@ -0,0 +1,13 @@ +// #Conformance #DeclarationElements #MemberDefinitions #OptionalDefaultParameterValueArguments + + +//The DefaultParameterValue attribute and any Optional attribute will be ignored. +//Note: 'null' needs to be annotated with the correct type, e.g. 'DefaultParameterValue(null:obj)'. + +open System.Runtime.InteropServices + +type Class() = + static member WrongType([]b:obj) = printfn "%A" b + +do Class.WrongType() +do Class.WrongType("") \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MemberDefinitions/OptionalDefaultParamArgs/W_WrongDefaultType.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MemberDefinitions/OptionalDefaultParamArgs/W_WrongDefaultType.fs index 89b002a923..8844f1bc8b 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MemberDefinitions/OptionalDefaultParamArgs/W_WrongDefaultType.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MemberDefinitions/OptionalDefaultParamArgs/W_WrongDefaultType.fs @@ -10,5 +10,6 @@ type Class() = static member WrongType([]b:string) = b let r = Class.WrongType("123") +let r2 = Class.WrongType() do () \ No newline at end of file From d87e6e4bed2980c9da8b0ed85ee6f880900870ca Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Thu, 20 Feb 2025 11:52:11 +0100 Subject: [PATCH 2/7] fantomas of the opera --- src/Compiler/Facilities/LanguageFeatures.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Compiler/Facilities/LanguageFeatures.fs b/src/Compiler/Facilities/LanguageFeatures.fs index 867dfd40f7..9ee90f98bb 100644 --- a/src/Compiler/Facilities/LanguageFeatures.fs +++ b/src/Compiler/Facilities/LanguageFeatures.fs @@ -390,7 +390,7 @@ type LanguageVersion(versionText) = | LanguageFeature.UseTypeSubsumptionCache -> FSComp.SR.featureUseTypeSubsumptionCache () | LanguageFeature.DeprecatePlacesWhereSeqCanBeOmitted -> FSComp.SR.featureDeprecatePlacesWhereSeqCanBeOmitted () | LanguageFeature.SupportValueOptionsAsOptionalParameters -> FSComp.SR.featureSupportValueOptionsAsOptionalParameters () - | LanguageFeature.WarnWhenUnitPassedToObjArg -> FSComp.SR.featureSupportWarnWhenUnitPassedToObjArg () + | LanguageFeature.WarnWhenUnitPassedToObjArg -> FSComp.SR.featureSupportWarnWhenUnitPassedToObjArg () /// Get a version string associated with the given feature. static member GetFeatureVersionString feature = From feacfca2752ac659cbb02a557e49cca0778d73eb Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Fri, 21 Feb 2025 11:07:03 +0100 Subject: [PATCH 3/7] notes + fix build of tests --- docs/release-notes/.FSharp.Compiler.Service/9.0.300.md | 1 + docs/release-notes/.Language/preview.md | 1 + tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule1.fs | 3 +++ tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule2.fs | 2 ++ 4 files changed, 7 insertions(+) diff --git a/docs/release-notes/.FSharp.Compiler.Service/9.0.300.md b/docs/release-notes/.FSharp.Compiler.Service/9.0.300.md index f64f090744..089f522611 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/9.0.300.md +++ b/docs/release-notes/.FSharp.Compiler.Service/9.0.300.md @@ -24,6 +24,7 @@ * Update `Obsolete` attribute checking to account for `DiagnosticId` and `UrlFormat` properties. ([PR #18224](https://github.com/dotnet/fsharp/pull/18224)) * Remove `Cancellable.UsingToken` from tests ([PR #18276](https://github.com/dotnet/fsharp/pull/18276)) * Added nullability annotations to `.Using` builder method for `async`, `task` and compiler-internal builders ([PR #18292](https://github.com/dotnet/fsharp/pull/18292)) +* Warn when `unit` is passed to an `obj`-typed argument ([PR #18330](https://github.com/dotnet/fsharp/pull/18330)) ### Breaking Changes * Struct unions with overlapping fields now generate mappings needed for reading via reflection ([Issue #18121](https://github.com/dotnet/fsharp/issues/17797), [PR #18274](https://github.com/dotnet/fsharp/pull/17877)) diff --git a/docs/release-notes/.Language/preview.md b/docs/release-notes/.Language/preview.md index d6ef41c3d5..905e086a16 100644 --- a/docs/release-notes/.Language/preview.md +++ b/docs/release-notes/.Language/preview.md @@ -4,6 +4,7 @@ * Deprecate places where `seq` can be omitted. ([Language suggestion #1033](https://github.com/fsharp/fslang-suggestions/issues/1033), [PR #17772](https://github.com/dotnet/fsharp/pull/17772)) * Added type conversions cache, only enabled for compiler runs ([PR#17668](https://github.com/dotnet/fsharp/pull/17668)) * Support ValueOption + Struct attribute as optional parameter for methods ([Language suggestion #1136](https://github.com/fsharp/fslang-suggestions/issues/1136), [PR #18098](https://github.com/dotnet/fsharp/pull/18098)) +* Warn when `unit` is passed to an `obj`-typed argument ([PR #18330](https://github.com/dotnet/fsharp/pull/18330)) ### Fixed diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule1.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule1.fs index 727ed166b8..902d45bf0e 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule1.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule1.fs @@ -13,6 +13,9 @@ open System open FSharp.Core.UnitTests.LibraryTestFx open Xunit +#nowarn "3397" // This expression uses 'unit' for an 'obj'-typed argument. This will lead to passing 'null' at runtime. +// Why warned - the tests here are actually trying to test that when this happens (unit passed), in indeed results in a null + type OperatorsModule1() = [] diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule2.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule2.fs index f2dc93d9ee..b5d236cfb0 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule2.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule2.fs @@ -19,6 +19,8 @@ open FSharp.Core.UnitTests.LibraryTestFx open Xunit #nowarn "3370" +#nowarn "3397" // This expression uses 'unit' for an 'obj'-typed argument. This will lead to passing 'null' at runtime. +// Why warned - the tests here are actually trying to test that when this happens (unit passed), in indeed results in a null /// If this type compiles without error it is correct /// Wrong if you see: FS0670 This code is not sufficiently generic. The type variable ^T could not be generalized because it would escape its scope. From b1ab1c20492bf3af3f4fb594ee6ae4b3b428d94e Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Fri, 21 Feb 2025 11:43:45 +0100 Subject: [PATCH 4/7] Apply suggestions from code review Co-authored-by: Adam Boniecki <20281641+abonie@users.noreply.github.com> --- tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule1.fs | 2 +- tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule2.fs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule1.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule1.fs index 902d45bf0e..ec620ebc22 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule1.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule1.fs @@ -14,7 +14,7 @@ open FSharp.Core.UnitTests.LibraryTestFx open Xunit #nowarn "3397" // This expression uses 'unit' for an 'obj'-typed argument. This will lead to passing 'null' at runtime. -// Why warned - the tests here are actually trying to test that when this happens (unit passed), in indeed results in a null +// Why warned - the tests here are actually trying to test that when this happens (unit passed), it indeed results in a null type OperatorsModule1() = diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule2.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule2.fs index b5d236cfb0..3e0ea65274 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule2.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule2.fs @@ -20,7 +20,7 @@ open Xunit #nowarn "3370" #nowarn "3397" // This expression uses 'unit' for an 'obj'-typed argument. This will lead to passing 'null' at runtime. -// Why warned - the tests here are actually trying to test that when this happens (unit passed), in indeed results in a null +// Why warned - the tests here are actually trying to test that when this happens (unit passed), it indeed results in a null /// If this type compiles without error it is correct /// Wrong if you see: FS0670 This code is not sufficiently generic. The type variable ^T could not be generalized because it would escape its scope. From 49980ae963ba5fb9511f8c5161b378a6405e00ad Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Fri, 21 Feb 2025 15:15:04 +0100 Subject: [PATCH 5/7] Address test warnings --- .../FSharp.Core/Microsoft.FSharp.Control/AsyncModule.fs | 3 +++ .../FSharp.Core/Microsoft.FSharp.Control/LazyType.fs | 3 +++ .../Microsoft.FSharp.Reflection/FSharpReflection.fs | 3 +++ 3 files changed, 9 insertions(+) diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/AsyncModule.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/AsyncModule.fs index d5bf29374d..b4e54ab6f4 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/AsyncModule.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/AsyncModule.fs @@ -12,6 +12,9 @@ open FSharp.Core.UnitTests.LibraryTestFx open Xunit open FsCheck +#nowarn "3397" // This expression uses 'unit' for an 'obj'-typed argument. This will lead to passing 'null' at runtime. +// Why warned - the tests here are actually trying to assert that Async still works. + module Utils = let internal memoizeAsync f = let cache = System.Collections.Concurrent.ConcurrentDictionary<'a, System.Threading.Tasks.Task<'b>>() diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/LazyType.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/LazyType.fs index 30643db549..9bc8ec3e7d 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/LazyType.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/LazyType.fs @@ -8,6 +8,9 @@ open Xunit open Microsoft.FSharp.Collections open FSharp.Core.UnitTests.LibraryTestFx +#nowarn "3397" // This expression uses 'unit' for an 'obj'-typed argument. This will lead to passing 'null' at runtime. +// Why warned - the tests here are actually trying to test that when this happens (unit passed), it indeed results in a null + type LazyType() = [] diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Reflection/FSharpReflection.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Reflection/FSharpReflection.fs index 56fd8a0a1b..fabb893620 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Reflection/FSharpReflection.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Reflection/FSharpReflection.fs @@ -12,6 +12,9 @@ open Xunit open Microsoft.FSharp.Reflection +#nowarn "3397" // This expression uses 'unit' for an 'obj'-typed argument. This will lead to passing 'null' at runtime. +// Why warned - the tests here are testing also how APIs react to unit being passed to it. + (* [Test Strategy] Make sure each method works on: From d217778f385cbbeaaebed16fbac20411fcb5687b Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Mon, 24 Feb 2025 12:01:12 +0100 Subject: [PATCH 6/7] Fix tests --- .../CustomAttributes/Basic/Basic.fs | 8 ++++--- .../OptionalDefaultParamArgs.fs | 22 +++++++++++-------- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/Basic.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/Basic.fs index 1e3c99dc8a..edb58e75a1 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/Basic.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/Basic.fs @@ -106,9 +106,11 @@ module CustomAttributes_Basic = |> verifyCompile |> shouldFail |> withDiagnostics [ - (Error 1, Line 10, Col 3, Line 10, Col 59, "This expression was expected to have type\n 'int array' \nbut here has type\n 'unit' ") - (Error 267, Line 10, Col 3, Line 10, Col 59, "This is not a valid constant expression or custom attribute value") - (Error 850, Line 10, Col 3, Line 10, Col 59, "This attribute cannot be used in this version of F#") + (Error 193, Line 10, Col 3, Line 10, Col 59, """Type constraint mismatch. The type + 'unit' + is not compatible with type + 'int array' + """) (Error 850, Line 13, Col 3, Line 13, Col 101, "This attribute cannot be used in this version of F#") (Error 850, Line 16, Col 3, Line 16, Col 50, "This attribute cannot be used in this version of F#") ] diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MemberDefinitions/OptionalDefaultParamArgs/OptionalDefaultParamArgs.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MemberDefinitions/OptionalDefaultParamArgs/OptionalDefaultParamArgs.fs index 22fb9ac122..6ea21bf539 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MemberDefinitions/OptionalDefaultParamArgs/OptionalDefaultParamArgs.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MemberDefinitions/OptionalDefaultParamArgs/OptionalDefaultParamArgs.fs @@ -35,9 +35,12 @@ module MemberDefinitions_OptionalDefaultParamArgs = compilation |> verifyCompile |> shouldFail - |> withDiagnostics [ - (Error 1, Line 13, Col 18, Line 13, Col 20, "This expression was expected to have type\n 'int' \nbut here has type\n 'unit' ") - ] + |> withDiagnostics + [(Error 193, Line 13, Col 18, Line 13, Col 20, "Type constraint mismatch. The type + 'unit' + is not compatible with type + 'int' + ")] // SOURCE=InterfaceMethod.fs [] @@ -76,12 +79,13 @@ module MemberDefinitions_OptionalDefaultParamArgs = |> withLangVersionPreview |> verifyCompile |> shouldFail - |> withDiagnostics [ - Warning 3211, Line 10, Col 62, Line 10, Col 63, "The default value does not have the same type as the argument. The DefaultParameterValue attribute and any Optional attribute will be ignored. Note: 'null' needs to be annotated with the correct type, e.g. 'DefaultParameterValue(null:obj)'." - Error 193, Line 13, Col 25, Line 13, Col 27, """Type constraint mismatch. The type -'unit' -is not compatible with type -'string' """ ] + |> withDiagnostics + [(Warning 3211, Line 10, Col 62, Line 10, Col 63, "The default value does not have the same type as the argument. The DefaultParameterValue attribute and any Optional attribute will be ignored. Note: 'null' needs to be annotated with the correct type, e.g. 'DefaultParameterValue(null:obj)'."); + (Error 193, Line 13, Col 25, Line 13, Col 27, "Type constraint mismatch. The type + 'unit' + is not compatible with type + 'string' + ")] [] let ``W_WrongDefaultObjType_fs`` compilation = From a1a370b7105ab9e3366640da832920c061939a34 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Mon, 24 Feb 2025 13:26:20 +0100 Subject: [PATCH 7/7] revert to stable warning when arg is other than obj --- .../Checking/Expressions/CheckExpressions.fs | 2 -- .../CustomAttributes/Basic/Basic.fs | 8 +++----- .../OptionalDefaultParamArgs.fs | 20 ++++++++----------- 3 files changed, 11 insertions(+), 19 deletions(-) diff --git a/src/Compiler/Checking/Expressions/CheckExpressions.fs b/src/Compiler/Checking/Expressions/CheckExpressions.fs index 5d236c1a1c..df64c4da62 100644 --- a/src/Compiler/Checking/Expressions/CheckExpressions.fs +++ b/src/Compiler/Checking/Expressions/CheckExpressions.fs @@ -9787,8 +9787,6 @@ and GetNewInferenceTypeForMethodArg (cenv: cenv) x = | SynExpr.Quote (_, raw, a, _, _) -> if raw then cont (0, mkRawQuotedExprTy g) else loopExpr a (cont << fun struct (depth, ty) -> depth + 1, mkQuotedExprTy g ty) - | SynExpr.Const (SynConst.Unit, _) -> - cont (0, g.unit_ty) | _ -> cont (0, NewInferenceType g) let struct (_depth, ty) = loopExpr x id diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/Basic.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/Basic.fs index edb58e75a1..1e3c99dc8a 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/Basic.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/Basic.fs @@ -106,11 +106,9 @@ module CustomAttributes_Basic = |> verifyCompile |> shouldFail |> withDiagnostics [ - (Error 193, Line 10, Col 3, Line 10, Col 59, """Type constraint mismatch. The type - 'unit' - is not compatible with type - 'int array' - """) + (Error 1, Line 10, Col 3, Line 10, Col 59, "This expression was expected to have type\n 'int array' \nbut here has type\n 'unit' ") + (Error 267, Line 10, Col 3, Line 10, Col 59, "This is not a valid constant expression or custom attribute value") + (Error 850, Line 10, Col 3, Line 10, Col 59, "This attribute cannot be used in this version of F#") (Error 850, Line 13, Col 3, Line 13, Col 101, "This attribute cannot be used in this version of F#") (Error 850, Line 16, Col 3, Line 16, Col 50, "This attribute cannot be used in this version of F#") ] diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MemberDefinitions/OptionalDefaultParamArgs/OptionalDefaultParamArgs.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MemberDefinitions/OptionalDefaultParamArgs/OptionalDefaultParamArgs.fs index 6ea21bf539..8ba293dce2 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MemberDefinitions/OptionalDefaultParamArgs/OptionalDefaultParamArgs.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MemberDefinitions/OptionalDefaultParamArgs/OptionalDefaultParamArgs.fs @@ -35,12 +35,9 @@ module MemberDefinitions_OptionalDefaultParamArgs = compilation |> verifyCompile |> shouldFail - |> withDiagnostics - [(Error 193, Line 13, Col 18, Line 13, Col 20, "Type constraint mismatch. The type - 'unit' - is not compatible with type - 'int' - ")] + |> withDiagnostics [ + (Error 1, Line 13, Col 18, Line 13, Col 20, "This expression was expected to have type\n 'int' \nbut here has type\n 'unit' ") + ] // SOURCE=InterfaceMethod.fs [] @@ -80,12 +77,11 @@ module MemberDefinitions_OptionalDefaultParamArgs = |> verifyCompile |> shouldFail |> withDiagnostics - [(Warning 3211, Line 10, Col 62, Line 10, Col 63, "The default value does not have the same type as the argument. The DefaultParameterValue attribute and any Optional attribute will be ignored. Note: 'null' needs to be annotated with the correct type, e.g. 'DefaultParameterValue(null:obj)'."); - (Error 193, Line 13, Col 25, Line 13, Col 27, "Type constraint mismatch. The type - 'unit' - is not compatible with type - 'string' - ")] + [ Warning 3211, Line 10, Col 62, Line 10, Col 63, "The default value does not have the same type as the argument. The DefaultParameterValue attribute and any Optional attribute will be ignored. Note: 'null' needs to be annotated with the correct type, e.g. 'DefaultParameterValue(null:obj)'." + Error 1, Line 13, Col 25, Line 13, Col 27, "This expression was expected to have type + 'string' + but here has type + 'unit' "] [] let ``W_WrongDefaultObjType_fs`` compilation =