- 
                Notifications
    You must be signed in to change notification settings 
- Fork 834
Description
Following #17519, we should see if it is possible for the F# compiler to emit a call to the System.Diagnostics.Debug.Assert overload that takes a message defaulting to CallerArgumentExpression for all usages of the assert keyword.
I.e., an expression like this
assert not truewould be translated to
System.Diagnostics.Debug.Assert (not true, "not true")Likewise:
assert (x = 3)→
System.Diagnostics.Debug.Assert ((x = 3), "(x = 3)")etc.
The C# compiler now does this for System.Diagnostics.Debug.Assert(booleanExpr) by means of the OverloadResolutionPriorityAttribute, which F# does not currently support: #16967 (comment)
dotnet/csharplang#7906: developers can add weight to which methods are better in overload resolution. This seems unlikely to impact F# as much.
Want to point out one place this will intersect with F#. Consider that very likely
Debugwill end up looking like the following:public static class Debug { [OverloadResolutionPriority(-1)] public static void Assert(bool condition) { ... } public static void Assert(bool condition, [CallerArgumentExpression] string? message = "") { ... } }Nothing will break for F# here when this happens, code will still compile as it used to. The experience for C# though will improve from a lot of
Debug.Assert failedmessages to the actual expression that passed into the assert. This is one part I thought might be interesting to F# .
See the BCL source:
[Conditional("DEBUG")]
[OverloadResolutionPriority(-1)] // lower priority than (bool, string) overload so that the compiler prefers using CallerArgumentExpression
public static void Assert([DoesNotReturnIf(false)] bool condition) =>
    Assert(condition, string.Empty, string.Empty);
[Conditional("DEBUG")]
public static void Assert([DoesNotReturnIf(false)] bool condition, [CallerArgumentExpression(nameof(condition))] string? message = null) =>
    Assert(condition, message, string.Empty);We could in theory do this in the F# compiler specifically for the assert keyword, without needing to support OverloadResolutionPriorityAttribute in general, by emitting a call to the new overload when it is available here:
fsharp/src/Compiler/Checking/Expressions/CheckExpressions.fs
Lines 7699 to 7706 in 69be2cd
| // Check an 'assert x' expression. | |
| and TcAssertExpr cenv overallTy env (m: range) tpenv x = | |
| let synm = m.MakeSynthetic() // Mark as synthetic so the language service won't pick it up. | |
| let callDiagnosticsExpr = SynExpr.App (ExprAtomicFlag.Atomic, false, mkSynLidGet synm ["System";"Diagnostics";"Debug"] "Assert", | |
| // wrap an extra parentheses so 'assert(x=1) isn't considered a named argument to a method call | |
| SynExpr.Paren (x, range0, None, synm), synm) | |
| TcExpr cenv overallTy env tpenv callDiagnosticsExpr | 
Metadata
Metadata
Assignees
Labels
Type
Projects
Status