D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 9822 - Using module variable of templated type parametrized by lambda
Summary: Using module variable of templated type parametrized by lambda
Status: NEW
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: All All
: P2 critical
Assignee: No Owner
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2013-03-27 02:48 UTC by Dicebot
Modified: 2024-12-13 18:05 UTC (History)
4 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Dicebot 2013-03-27 02:48:49 UTC
Motivating code snippet:

-----
module test;    

import std.algorithm, std.traits, std.stdio;

enum r1 = [1, 2, 3];
auto product = cartesianProduct(r1, r1);

void main()
{
    writeln(product);	
}
-----
Segmentation fault
-----

What is expected: either working code, or compile-time error.
Comment 1 bearophile_hugs 2013-03-27 10:44:04 UTC
A reduction:


struct MapResult(alias fun) {
    int[] _input;

    @property bool empty() {
        return _input.length == 0;
    }

    void popFront() {
        _input = _input[1 .. $];
    }

    @property auto ref front() {
        return fun(1);
    }
}

auto map(alias fun)(int[] r) {
    return MapResult!(fun)(r);
}

auto foo(int[] r) {
    return map!(x => r)([1]);
}

enum r1 = [1];
auto result = foo(r1);

void main() {
    foreach (t; result) {}
}
Comment 2 hsteoh 2013-05-27 20:21:42 UTC
Huh, this is really strange. Moving the cartesianProduct line inside main() makes the problem go away. Why?
Comment 3 hsteoh 2013-05-27 21:19:14 UTC
Hmph. I think this is a compiler bug. Putting the code inside a unittest block makes the problem go away too.
Comment 4 hsteoh 2013-05-27 21:40:27 UTC
Retitled this bug based on bearophile's reduction, and comparison of the disassembly of buggy version (result assigned to module-global variable) vs. non-buggy version (result assigned to local variable); this looks like a wrong-code bug.
Comment 5 Maxim Fomin 2013-05-27 22:03:00 UTC
Simplified: 

struct MapResult(alias fun) {
    @property auto ref front() {
        return fun(1);
    }
}

auto map(alias fun)() {
    return MapResult!(fun)();
}

auto foo(int[] r) {
    return map!((int x) => r)();
}

auto result = foo([1]);

void main() {
    result.front();
}

There is wrong-code on accessing or passing module object. It has nothing to do with auto or ranges.
Comment 6 Vladimir Panteleev 2017-07-05 14:53:33 UTC
(In reply to Dicebot from comment #0)
> Motivating code snippet:

BTW, this example works since https://github.com/dlang/phobos/pull/2534. The reductions in comment 1 and comment 5 still produce a segfaulting program.
Comment 7 dlangBugzillaToGithub 2024-12-13 18:05:26 UTC
THIS ISSUE HAS BEEN MOVED TO GITHUB

https://github.com/dlang/dmd/issues/18549

DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB