The compiler may be treating AscW and ChrW as special cases. A search of the Roslyn source code for "AscW" turns up the following in OptimizeLibraryCall (lots of code snipped for clarity):
' AscW(char) / AscW(String)
' all values can be optimized as a literal, except an empty string that produces a diagnostic
If IsWellKnownTypeMember(WellKnownMember.Microsoft_VisualBasic_Strings__AscWCharInt32, method) OrElse
IsWellKnownTypeMember(WellKnownMember.Microsoft_VisualBasic_Strings__AscWStringInt32, method) Then
'[...]
Return ConstantValue.Create(AscW(argumentValue))
End If
' ChrW
' for -32768 < value or value > 65535 we show a diagnostic
If IsWellKnownTypeMember(WellKnownMember.Microsoft_VisualBasic_Strings__ChrWInt32Char, method) Then
'[...]
Return ConstantValue.Create(ChrW(argumentValue))
End If
'[...]
There's also a comment in EarlyWellKnownAttributeBinder.CanBeValidAttribute that specifically mentions AscW and ChrW in the types of compile-time constants that can be used for attribute values:
' 11.2 Constant Expressions
'
'A constant expression is an expression whose value can be fully evaluated at compile time.
' [...]
' The following run-time functions:
' Microsoft.VisualBasic.Strings.ChrW
' Microsoft.VisualBasic.Strings.Chr, if the constant value is between 0 and 128
' Microsoft.VisualBasic.Strings.AscW, if the constant string is not empty
' Microsoft.VisualBasic.Strings.Asc, if the constant string is not empty
The Mono vbnc compiler seems to have an IsConstantMethod helper method to support these functions (it specifically checks whether the method is AscW, Asc, ChrW, or Chr), along with a test case specifically to test whether const statements accept those functions, which suggests they are special cases.
If you look at your compiled assembly in ildasm, you'll see:
.field public static literal char Cr = char(0x000D)
You can see that the compiler is evaluating the function and emitting the result -- it's not embedding any sort of "constant function" call, and there's not any sort of attribute decoration on those functions in the reference source that marks them as a "constant function".
So to answer your questions, it looks like the compiler does this by treating those string functions as special hardcoded cases, and it doesn't look like there's any way to do so, short of modifying the compiler code.