Repository navigation
Accept number, char, bool and %s holes in constant interpolated strings - #20754
xperiandri wants to merge 5 commits into
Conversation
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
❗ Release notes requiredYou can open this PR in browser to add release notes: open in github.dev Caution No release notes found for the changed paths (see table below). Please make sure to add an entry with an informative description of the change as well as link to this pull request, issue and language suggestion if applicable. Release notes for this repository are based on Keep A Changelog format. The following format is recommended for this repository: `* . (PR #XXXXX)`
If you believe that release notes are not necessary for this PR, please add NO_RELEASE_NOTES label to the pull request.
|
An interpolated string whose holes are non-null constant strings without alignment or format specifiers now folds to its text where F# requires a constant: [<Literal>] values (also in signatures), attribute arguments and type provider static arguments. It was rejected with FS0267, so a constant built from other constants needed '+'. The checker marks those three contexts in TcEnv and folds the string there. Everywhere else, quotations included, interpolated strings are still lowered to String.Concat. A hole that breaks a rule reports FS3925 at the hole; a hole that is not a constant reports FS0267 at the hole. Gated on the ConstantInterpolatedStrings preview feature. Language suggestion dotnet#1347 RFC FS-1352 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
RFC FS-1352 reports the rule error on the first hole that breaks a rule.
Later holes are still type-checked, but are no longer evaluated as
constants, so '$"{1}{2}"' gives FS3925 once instead of once per hole.
Reword FS3925 to the RFC's "must be a constant": the message is shown
when a hole keeps the string from being one.
Cover type provider static arguments, after 'const' and through a
literal, with a provider that returns its string static argument.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review follow-up. The hole text comes from a top-level tryConstantHoleText,
every hole is type-checked before the first one is evaluated (so a later
undefined name is still reported), and the constant path runs only when the
ConstantInterpolatedStrings feature is supported: before the preview language
version an interpolated string in a literal is checked as before, so a branch
that is never evaluated, such as false && ($"{1}" = "1"), stays valid.
The type provider test uses a small fixture that checks the argument it
receives: the helloWorld provider overflows the stack of the test host when it
is compiled in process. One language release note remains.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Unlike C#, F# formats integers, decimals, characters and Booleans in
interpolated strings with the invariant culture, so their text is known at
compile time. A constant interpolated string now also accepts such holes, and a
plain '%s' hole on a constant string, as asked in the RFC FS-1352 discussion:
the folded text is the text 'string' gives at run time ("True" for true,
"1.50" for 1.50m).
Float holes stay excluded: their text depends on the runtime the compiler runs
on (-0.0 is "0" on .NET Framework and "-0" on .NET). Enum holes stay excluded
too.
RFC FS-1352 amendment
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
1e9c891 to
280dd47
Compare
Stacked on #20753
A constant interpolated string also accepts integer,
decimal,charandboolholes and a plain%shole. F# formats these with the invariant culture, so the folded text is the run-time text:$"v{2}-{true}"is"v2-True". Float holes stay rejected, because their text depends on the runtime that runs the compiler (-0.0is0on .NET Framework and-0on .NET).Details