Issue 18472 - [Reg 2.078] betterC: cannot use format at compile time.
Summary: [Reg 2.078] betterC: cannot use format at compile time.
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: x86 All
: P1 regression
Assignee: No Owner
URL:
Keywords: betterC, pull
Depends on:
Blocks:
 
Reported: 2018-02-20 06:51 UTC by Nicholas Wilson
Modified: 2023-03-01 02:32 UTC (History)
5 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Nicholas Wilson 2018-02-20 06:51:00 UTC
import std.format;
import std.stdio;
void main()
{
    enum s = "%1$s,%2$s".format("foo","bar");
    writeln(s);
}

fails with 

/dlang/dmd-nightly/linux/bin64/../../src/phobos/std/array.d(2889): Error: TypeInfo cannot be used with -betterC

due to the use of Appender

at line 2889 is 

`private struct Data`

This did use to work as I have always compiled Dcompute with -betterC, however upgrading to LDC 1.8.0b1 based on v2.078.2 (from LDC master in about December), I hit #18101, and trying run.dlang.io to see how soon it would get fixed and hit this.
Comment 1 Mike Franklin 2018-02-20 13:54:16 UTC
The test doesn't compile with 2.078.3. 2.078.3 does not include the TypeInfo check, so at most this is a diagnostic regression.  

https://run.dlang.io/is/fvj8jb

/dlang/dmd/linux/bin64/../../src/phobos/std/range/primitives.d(405): Error: static assert  "Cannot put a const(char)[] into a Appender!string."
/dlang/dmd/linux/bin64/../../src/phobos/std/format.d(1172):        instantiated from here: put!(Appender!string, const(char)[])
/dlang/dmd/linux/bin64/../../src/phobos/std/format.d(473):        instantiated from here: writeUpToNextSpec!(Appender!string)
/dlang/dmd/linux/bin64/../../src/phobos/std/format.d(5831):        instantiated from here: formattedWrite!(Appender!string, char, string, string)
onlineapp.d(5):        instantiated from here: format!(char, string, string)

Do you have a test that will demonstrate a successful build prior to the TypeInfo check introduced in 2.079?
Comment 2 Martin Nowak 2018-02-20 17:16:03 UTC
cat > bug.d << CODE
import std.format;
import std.stdio;
void main()
{
    enum s = "%1$s,%2$s".format("foo","bar");
    writeln(s);
}
CODE
dmd -c -betterC bug.d
----
/home/dawg/dlang/dmd-2.078.0/linux/bin64/../../src/phobos/std/range/primitives.d(405): Error: static assert  "Cannot put a const(char)[] into a Appender!string."
/home/dawg/dlang/dmd-2.078.0/linux/bin64/../../src/phobos/std/format.d(1172):        instantiated from here: put!(Appender!string, const(char)[])
/home/dawg/dlang/dmd-2.078.0/linux/bin64/../../src/phobos/std/format.d(473):        instantiated from here: writeUpToNextSpec!(Appender!string)
/home/dawg/dlang/dmd-2.078.0/linux/bin64/../../src/phobos/std/format.d(5831):        instantiated from here: formattedWrite!(Appender!string, char, string, string)
/home/dawg/Code/D/bug.d(5):        instantiated from here: format!(char, string, string)
----

Confirmed that this stopped to work with 2.078.0, the error looks rather weird, as betterC shouldn't change types.

Also indeed with 2.079.0-beta.1 the error message is now about using TypeInfo.
----
/home/dawg/dlang/dmd-2.079.0-beta.1/linux/bin64/../../src/phobos/std/array.d(2889): Error: TypeInfo cannot be used with -betterC
----

The test case compiles fine with 2.077.1.
Comment 3 Nicholas Wilson 2018-02-21 00:04:46 UTC
(In reply to Martin Nowak from comment #2)
> cat > bug.d << CODE
> import std.format;
> import std.stdio;
> void main()
> {
>     enum s = "%1$s,%2$s".format("foo","bar");
>     writeln(s);
> }
> CODE
> dmd -c -betterC bug.d
> ----
> /home/dawg/dlang/dmd-2.078.0/linux/bin64/../../src/phobos/std/range/
> primitives.d(405): Error: static assert  "Cannot put a const(char)[] into a
> Appender!string."
> /home/dawg/dlang/dmd-2.078.0/linux/bin64/../../src/phobos/std/format.d(1172):
> instantiated from here: put!(Appender!string, const(char)[])
> /home/dawg/dlang/dmd-2.078.0/linux/bin64/../../src/phobos/std/format.d(473):
> instantiated from here: writeUpToNextSpec!(Appender!string)
> /home/dawg/dlang/dmd-2.078.0/linux/bin64/../../src/phobos/std/format.d(5831):
> instantiated from here: formattedWrite!(Appender!string, char, string,
> string)
> /home/dawg/Code/D/bug.d(5):        instantiated from here: format!(char,
> string, string)
> ----
> 
> Confirmed that this stopped to work with 2.078.0, the error looks rather
> weird, as betterC shouldn't change types.
> 

Indeed that is issue 18101 which was fixed to check typeinfo, but now also fails at compile time.

> Also indeed with 2.079.0-beta.1 the error message is now about using
> TypeInfo.
> ----
> /home/dawg/dlang/dmd-2.079.0-beta.1/linux/bin64/../../src/phobos/std/array.
> d(2889): Error: TypeInfo cannot be used with -betterC
> ----
> 
> The test case compiles fine with 2.077.1.

That sounds about the right timeframe.
Comment 4 Mike Franklin 2018-02-21 01:15:05 UTC
Isn't this then a duplicate of Issue 18101?  In other words, if Issue 18101 were solved, there wouldn't be a need for TypeInfo, and therefore the TypeInfo error would not be triggered?
Comment 5 Rainer Schuetze 2018-04-15 13:41:42 UTC
Here's a simpler test case:

module betterc;
enum b = typeid(size_t) is typeid(uint);

>dmd -betterC -c betterc.d
betterc.d(2): Error: TypeInfo cannot be used with -betterC
Comment 6 Mike Franklin 2018-04-15 23:26:14 UTC
(In reply to Rainer Schuetze from comment #5)
> Here's a simpler test case:
> 
> module betterc;
> enum b = typeid(size_t) is typeid(uint);

At https://dlang.org/spec/betterc.html under the "Not Available" section:

> 2. TypeInfo and ModuleInfo

So, it is by design that any call to `typeid` is going to fail when compiled with `-betterC`.

This specific issue is about not being able to use `format` in `-betterC`.  Perhaps the reason for that is because `format` relies on runtime type information (i.e. TypeInfo).  So the solution, specific to this issue, would not be allow uses of `typeid` in `-betterC`, but rather to remove the dependency of `format` on runtime type information (if that's even possible).  

D has excellent facilities for doing introspection at compile-time, so it may be possible to look to those facilities in concert with templates to find a solution that does not rely on runtime type information.

It would likely also help to begin replacing compiler-generated calls to runtime hooks that depend on `TypeInfo` with templates.  

See also https://forum.dlang.org/post/mr7a65$2hc$1@digitalmars.com
Comment 7 Rainer Schuetze 2018-04-16 05:40:42 UTC
I think the main issue is that the compiler does not distinguish between information needed at compile time and what's necessary inside the object file.
Comment 8 Mike Franklin 2018-04-16 08:17:14 UTC
(In reply to Rainer Schuetze from comment #7)
> I think the main issue is that the compiler does not distinguish between
> information needed at compile time and what's necessary inside the object
> file.

Ok, I understand now:  `enum b = typeid(size_t) is typeid(uint);` should be evaluated at compile time, and I the -betterC limitations should only apply at runtime.
Comment 9 Mike Franklin 2018-04-16 08:50:18 UTC
Working on a fix at https://github.com/dlang/dmd/pull/8173
Comment 10 Mike Franklin 2018-04-16 10:47:49 UTC
PR 8173 seems to take care of the case...

module betterc;
enum b = typeid(size_t) is typeid(uint)

... but still fails for ...

import std.format;
import std.stdio;
void main()
{
    enum s = "%1$s,%2$s".format("foo","bar");
    writeln(s);
}

... with the same TypeInfo error.

However, if I comment out the TypeInfo check altogether, the `format` test case fails with...

phobos/std/range/primitives.d(405): Error: static assert:  "Cannot put a const(char)[] into a Appender!string."
phobos/std/format.d(1184):        instantiated from here: put!(Appender!string, const(char)[])
/phobos/std/format.d(473):        instantiated from here: writeUpToNextSpec!(Appender!string)
phobos/std/format.d(6168):        instantiated from here: formattedWrite!(Appender!string, char, string, string)
main.d(5):        instantiated from here: format!(char, string, string)

I'm wondering if there was another change to Phobos around the same time frame was the TypeInfo change that prevents the `format` expression from evaluating at compile-time.
Comment 11 github-bugzilla 2018-05-02 08:24:27 UTC
Commits pushed to master at https://github.com/dlang/dmd

https://github.com/dlang/dmd/commit/cb2b0b848a1c6a2b208ba12257f6204c725744e4
Partial fix for Issue 18472 - permit using typeid at compile-time in betterC

https://github.com/dlang/dmd/commit/a402a791694df063d8bd7a5b9d2f6651e9185cee
Merge pull request #8173 from JinShil/fix_18472

 Partial fix for Issue 18472 - permit using typeid at compile-time in betterC
merged-on-behalf-of: Jacob Carlborg <jacob-carlborg@users.noreply.github.com>
Comment 12 Mike Franklin 2018-08-02 18:13:26 UTC
This appears to work now in nightly:

import std.format;
import std.stdio;
void main()
{
    enum s = "%1$s,%2$s".format("foo","bar");
    writeln(s);
}

https://run.dlang.io/is/BDyoHF

It may have been fixed inadvertently by https://github.com/dlang/dmd/pull/8523
Comment 13 Mike Franklin 2018-08-02 18:15:05 UTC
(In reply to Mike Franklin from comment #12)
> This appears to work now in nightly:
> 
> import std.format;
> import std.stdio;
> void main()
> {
>     enum s = "%1$s,%2$s".format("foo","bar");
>     writeln(s);
> }
> 
> https://run.dlang.io/is/BDyoHF
> 
> It may have been fixed inadvertently by
> https://github.com/dlang/dmd/pull/8523

Gah, scratch that. Forgot to add the -betterC flag. :-(
Comment 14 Mike Parker 2019-10-17 09:43:53 UTC
A bounty has been set on this issue:

https://www.flipcause.com/secure/cause_pdetails/NjU3MTQ=
Comment 15 Dlang Bot 2022-12-09 01:17:37 UTC
@etcimon updated dlang/dmd pull request #14676 "Fix 18472: betterC cannot use format at compile time." fixing this issue:

- Fix 18472: betterC cannot use format at compile time.

https://github.com/dlang/dmd/pull/14676
Comment 16 Dlang Bot 2023-02-28 04:43:47 UTC
@WalterBright created dlang/dmd pull request #14930 "fix Issue 18472: betterC cannot use format at compile time" fixing this issue:

- fix Issue 18472: betterC cannot use format at compile time

https://github.com/dlang/dmd/pull/14930
Comment 17 Dlang Bot 2023-02-28 09:28:35 UTC
dlang/dmd pull request #14930 "fix Issue 18472: betterC cannot use format at compile time" was merged into master:

- 116d35134cc17fc06fc4b3ad1ed9af65b44e7d39 by Walter Bright:
  fix Issue 18472: betterC cannot use format at compile time

https://github.com/dlang/dmd/pull/14930
Comment 18 Walter Bright 2023-03-01 02:32:47 UTC
Continued with https://issues.dlang.org/show_bug.cgi?id=23754 as a Phobos bug.