You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Single tilde ~ in expressions compiles, but shouldn't #16135
Using the .NET 7 SDK and above, a single tilde ~ can be used in nearly any expression context and will compile (and can even make otherwise nonsensical syntax compile), but such an expression will fail or behave unintuitively at runtime.
Repro steps
Put a single tilde ~ in nearly any expression context: prefix, infix, postfix, circumfix...
The code compiles, but either:
a. Fails at runtime with a System.NullReferenceException.
b. Fails at runtime with Fatal error. Internal CLR error. (0x80131506), which crashes the runtime altogether. Exciting!
b. Generates a default value (0, null, etc.)—neat shorthand for Unchecked.defaultof<_>!
// These all compile...letf x = ~x
letg x y = x ~ y
leth x y =(x ~) y
letp x = x~
letq x = x ~
letx:int = ~
let_:int = ~ ~ ~ ~
let_= ~1let_=1~
let_= ~1~
let_=(~)1let_=(~)1111let_= ~ 1111let_=1111 ~
let_=11 ~ 11let_= ~ DDD ~
let_= ~ _._. ~
let_= ~ ``(👉゚ヮ゚)👉`` ~
let_= ~ <int> ~
let()= ignore ~
letzero= ~ + ~
Expected behavior
I don't believe that any code using a single ~ should compile (prefix operators involving ~ always have at least one other character).
Actual behavior
The code compiles—including outlandish code that would otherwise never compile—and strange things happen at runtime.
Known workarounds
Don't accidentally type ~ anywhere.
Related information
This behavior happens for me when compiling with the .NET 7 and 8 SDKs, but not with .NET 6, so it seems likely that it was introduced in 7.
Project had code like this (by accident, simplified):
letx=[1;2]|> List.minBy (~1)letf x =(~2) x
Taking the snippet of the OP, it compiles in my .NET 6 project. I also tested a NETStandard 2.1 project, where the same code "just compiles", but throws at runtime.
I'll try once the fix is public, if it fixes the bug in these projects as well.
I saw this happen in .NET 6 (in Visual Studio 17.8.0)
It's the tooling version (not the target framework) that matters for this. If you have the .NET 6 SDK installed, and specify that it be used in a global.json file, the examples above shouldn't compile (they don't for me).
Activity
T-Gro commentedon Oct 23, 2023
(to be bisected to find what has introduced it)
vzarytovskii commentedon Oct 23, 2023
I remember something was done around arithmetics in literals, wondering if it could've affected it.
But basically what's happening with it is
ldnull
ldc.i4.1
abonie commentedon Oct 27, 2023
Bisecting leads me to believe this was introduced by 7ea48f0
Although it isn't immediately obvious to me why
auduchinok commentedon Oct 27, 2023
@abonie Interesting, thanks for checking! I see why it could be related, but I'd expect an error there anyway. I'll take a look.
abelbraaksma commentedon Dec 23, 2023
I saw this happen in .NET 6 (in Visual Studio 17.8.3, Dec 5th, 2023):
Project had code like this (by accident, simplified):
Taking the snippet of the OP, it compiles in my .NET 6 project. I also tested a
NETStandard 2.1project, where the same code "just compiles", but throws at runtime.I'll try once the fix is public, if it fixes the bug in these projects as well.
brianrourkeboll commentedon Dec 23, 2023
It's the tooling version (not the target framework) that matters for this. If you have the .NET 6 SDK installed, and specify that it be used in a
global.jsonfile, the examples above shouldn't compile (they don't for me).