Skip to content

Can't compile a module with a single import statement, while the imported module compiles fine #21098

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
kinke opened this issue Mar 27, 2025 · 3 comments
Labels
Severity:Industry Code that affects the industry Severity:rejects-valid Code that should compile but doesn't

Comments

@kinke
Copy link
Contributor

kinke commented Mar 27, 2025

This was dustmited from dlang/phobos#10715:

a.d:

import b;

b.d:

import phobos : Appender, Nullable;

struct Type {
    Nullable!(Type[]) templateArgs;
}

Type[] parseDeclarations() {
    Appender!(Type[]) members;
    return null;
}

enum ast = parseDeclarations();

phobos.d:

module phobos;



// module std.typecons;

struct Nullable(T)
{
    static struct DontCallDestructorT
    {
        T payload;
    }

    DontCallDestructorT _value;

    string toString() const
    {
        Appender!string app;
        formatValueImpl(app, _value);
        return null;
    }
}



// module std.array;

struct Appender(A)
{
    InPlaceAppender!A impl;
}

struct InPlaceAppender(T)
{
    static void toStringImpl(const T[] data)
    {
        string app;
        formatValue(app, data);
    }
}



// module std.format.internal.write;

void formatValueImpl(Writer, T)(Writer, const(T)) {}

void formatValueImpl(Writer, T)(Writer w, T obj)
if (is(T == U[], U))
{
    formatValue(w, obj[0]);
}

enum HasToStringResult
{
    none,
    bla
}

template hasToString(T)
{
    static if (is(typeof(
        (T val) {
            val.toString(s);
        })))
        enum hasToString = HasToStringResult.bla;
    else
        enum hasToString = HasToStringResult.none;
}

void formatValueImpl(Writer, T)(ref Writer w, T val)
if (is(T == struct) || is(T == union))
{
    static if (hasToString!T)
        int dummy;
    formatElement(w, val.tupleof);
}

void formatElement(Writer, T)(Writer w, T val)
{
    formatValueImpl(w, val);
}

void formatValue(Writer, T)(Writer w, T val)
{
    formatValueImpl(w, val);
}

Compiling b.d works fine with both DMD v2.110.0 and v2.111.0-rc.1:

$ dmd -o- b.d

But compiling a.d fails with both versions:

$ dmd -o- a.d
phobos.d(74): Error: expression `hasToString!(const(Nullable!(Type[])))` of type `void` does not have a boolean value
    static if (hasToString!T)
               ^
phobos.d(81): Error: template instance `phobos.formatValueImpl!(Appender!string, const(Nullable!(Type[])))` error instantiating
    formatValueImpl(w, val);
                   ^
phobos.d(76):        instantiated from here: `formatElement!(Appender!string, const(Nullable!(Type[])))`
    formatElement(w, val.tupleof);
                 ^
phobos.d(86):        instantiated from here: `formatValueImpl!(Appender!string, const(Type))`
    formatValueImpl(w, val);
                   ^
phobos.d(51):        instantiated from here: `formatValue!(Appender!string, const(Type))`
    formatValue(w, obj[0]);
               ^
phobos.d(81):        ... (2 instantiations, -v to show) ...
    formatValueImpl(w, val);
                   ^
phobos.d(19):        instantiated from here: `formatValueImpl!(Appender!string, const(DontCallDestructorT))`
        formatValueImpl(app, _value);
                       ^
b.d(4):        instantiated from here: `Nullable!(Type[])`
    Nullable!(Type[]) templateArgs;
    ^
phobos.d(74): Error: template instance `phobos.hasToString!(const(Nullable!(Type[])))` error instantiating
    static if (hasToString!T)
               ^
phobos.d(81):        instantiated from here: `formatValueImpl!(string, const(Nullable!(Type[])))`
    formatValueImpl(w, val);
                   ^
phobos.d(76):        instantiated from here: `formatElement!(string, const(Nullable!(Type[])))`
    formatElement(w, val.tupleof);
                 ^
phobos.d(86):        instantiated from here: `formatValueImpl!(string, const(Type))`
    formatValueImpl(w, val);
                   ^
phobos.d(51):        ... (5 instantiations, -v to show) ...
    formatValue(w, obj[0]);
               ^
phobos.d(30):        instantiated from here: `InPlaceAppender!(Type[])`
    InPlaceAppender!A impl;
    ^
b.d(8):        instantiated from here: `Appender!(Type[])`
    Appender!(Type[]) members;
    ^
phobos.d(76): Error: template instance `phobos.formatElement!(string, const(Type)[])` error instantiating
    formatElement(w, val.tupleof);
                 ^
phobos.d(81):        instantiated from here: `formatValueImpl!(string, const(DontCallDestructorT))`
    formatValueImpl(w, val);
                   ^
phobos.d(76):        instantiated from here: `formatElement!(string, const(DontCallDestructorT))`
    formatElement(w, val.tupleof);
                 ^
phobos.d(81):        instantiated from here: `formatValueImpl!(string, const(Nullable!(Type[])))`
    formatValueImpl(w, val);
                   ^
phobos.d(76):        ... (7 instantiations, -v to show) ...
    formatElement(w, val.tupleof);
                 ^
phobos.d(30):        instantiated from here: `InPlaceAppender!(Type[])`
    InPlaceAppender!A impl;
    ^
b.d(8):        instantiated from here: `Appender!(Type[])`
    Appender!(Type[]) members;
    ^

hasToString!T should obviously never yield void.

@kinke
Copy link
Contributor Author

kinke commented Apr 1, 2025

According to @ibuclaw, this is actually a regression and was introduced in #10718.

kinke added a commit to kinke/dmd that referenced this issue Apr 1, 2025
By reverting dlang#10718 - it seems superfluous nowadays?
kinke added a commit to kinke/dmd that referenced this issue Apr 1, 2025
By reverting dlang#10718 - it seems superfluous nowadays?
thewilsonator pushed a commit that referenced this issue Apr 1, 2025
By reverting #10718 - it seems superfluous nowadays?
@kinke
Copy link
Contributor Author

kinke commented Apr 2, 2025

Fixed by #21132.

@ibuclaw
Copy link
Member

ibuclaw commented Apr 2, 2025

According to @ibuclaw, this is actually a regression and was introduced in #10718.

For completeness sake, it was then fixed by #13374 (if you revert the change in 10718)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Severity:Industry Code that affects the industry Severity:rejects-valid Code that should compile but doesn't
Projects
None yet
Development

No branches or pull requests

2 participants