Bug 4841 – -inline wrecks certain nested structs causing error "*** is a nested function and cannot be accessed from ***"

Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2010-09-08T04:08:00Z
Last change time
2013-10-10T04:59:50Z
Keywords
accepts-invalid, pull, rejects-valid
Assigned to
nobody
Creator
bearophile_hugs

Comments

Comment #0 by bearophile_hugs — 2010-09-08T04:08:00Z
This is a D2 program: import std.algorithm: map; import std.array: array; void main() { int c; array(map!((x){return c;})([1])); } It works if you compile it with dmd 2.048 with: dmd test.d But if use inlining: dmd -inline test.d It doesn't compile and dmd returns: test.d(5): Error: function D main is a nested function and cannot be accessed from array I think this is a compiler bug because inlining should not affect the compilability of a program.
Comment #1 by clugdbug — 2010-09-10T00:02:24Z
Original title: "An array()/map inlining problem" Here's a simpler case that gives the same error message, only with -inline: --- struct Struct4841(alias pred) { this(int k) { } } void bug4841a() { Struct4841!( (t) { any_old_garbage;} )( 1 ); } void bug4841b() { bug4841a(); } --- This is a problem with delegates and alias templates. It's not a regression. There also seems to be an accepts-invalid bug in this. You can put any old garbage inside the alias, which seems odd. And you cannot declare a variable of type Struct4841!( (t) { any_old_garbage;} ) --- it's rejected at the parsing stage.
Comment #2 by hoganmeier — 2012-01-16T12:41:31Z
I think the following test case also belongs to this issue: R1 find(alias pred = "a == b", R1, R2)(R1 haystack, R2 needle) { return simpleMindedFind!pred(haystack, needle); } R1 simpleMindedFind(alias pred, R1, R2)(R1 haystack, R2 needle) { bool haystackTooShort() { return true; } return haystack; } sizediff_t indexOf(Char1, Char2)(const(Char1)[] s, const(Char2)sub) { const(Char1)[] balance = find!({})(s, sub); return -1; } string extStr; void main() { extStr.indexOf("bla"); }
Comment #3 by dsimcha — 2012-01-24T13:41:43Z
*** Issue 4724 has been marked as a duplicate of this issue. ***
Comment #4 by clugdbug — 2012-01-27T00:35:53Z
Further reduced shows neither constructor nor delegate is required. struct Struct4841(alias pred) { void unused_func(); } void bug4841a() { int w; Struct4841!( w ) m; } void bug4841b() { bug4841a(); } ---------------- The unused function is required only because it makes Struct4841 into a nested struct. I think it is because moving a templated nested struct changes its type - the enclosing function is part of the mangled name, or something like that. It can't trivially be moved around.
Comment #5 by github-bugzilla — 2012-02-05T12:34:31Z
Commit pushed to master at https://github.com/D-Programming-Language/dmd https://github.com/D-Programming-Language/dmd/commit/7766bbd9857ab5ad5b1d5ff0444cb7088823a793 fix Issue 4841 - -inline wrecks nested struct with alias template parameter (An array()/map inlining problem)
Comment #6 by dsimcha — 2012-02-05T21:07:57Z
I just tested the fix that was merged recently. It only fixes some cases such as Don's and Tass3r's. Bearophile's case is still broken, as is the case I reported in Bug 4724.
Comment #7 by bugzilla — 2012-02-05T22:08:20Z
I believe this is the same as bug 5939.
Comment #8 by clugdbug — 2012-02-06T10:00:46Z
(In reply to comment #7) > I believe this is the same as bug 5939. I don't think bug 5939 involves -inline, but this one definitely does. Unless there are plans to make compiler changes are to fix bug 5939, the inliner shouldn't be making this transformation.
Comment #9 by bearophile_hugs — 2012-02-21T14:18:15Z
See also Issue 7559
Comment #10 by issues.dlang — 2013-02-16T15:54:35Z
Another example of this would be: import std.string; void main() { auto str = new char[](5); assert(sformat(str, "%s", 42) == "42"); } If you compile with -inline, it fails to compile with the latest master, giving /home/jmdavis/dmd2/linux/bin/../../src/phobos/std/string.d(2593): Error: function std.string.sformat!(char, int).sformat is a nested function and cannot be accessed from std.range.put!(Sink, const(char)).put /home/jmdavis/dmd2/linux/bin/../../src/phobos/std/string.d(2593): Error: function std.string.sformat!(char, int).sformat is a nested function and cannot be accessed from std.range.put!(Sink, const(char)).put /home/jmdavis/dmd2/linux/bin/../../src/phobos/std/string.d(2596): Error: function std.string.sformat!(char, int).sformat is a nested function and cannot be accessed from std.range.put!(Sink, const(char)).put /home/jmdavis/dmd2/linux/bin/../../src/phobos/std/string.d(2596): Error: function std.string.sformat!(char, int).sformat is a nested function and cannot be accessed from std.range.put!(Sink, const(char)).put /home/jmdavis/dmd2/linux/bin/../../src/phobos/std/string.d(2596): Error: function std.string.sformat!(char, int).sformat is a nested function and cannot be accessed from std.range.put!(Sink, const(char)).put /home/jmdavis/dmd2/linux/bin/../../src/phobos/std/string.d(2597): Error: function std.string.sformat!(char, int).sformat is a nested function and cannot be accessed from std.range.put!(Sink, const(char)).put /home/jmdavis/dmd2/linux/bin/../../src/phobos/std/string.d(2593): Error: function std.string.sformat!(char, int).sformat is a nested function and cannot be accessed from std.range.put!(Sink, char).put /home/jmdavis/dmd2/linux/bin/../../src/phobos/std/string.d(2593): Error: function std.string.sformat!(char, int).sformat is a nested function and cannot be accessed from std.range.put!(Sink, char).put /home/jmdavis/dmd2/linux/bin/../../src/phobos/std/string.d(2596): Error: function std.string.sformat!(char, int).sformat is a nested function and cannot be accessed from std.range.put!(Sink, char).put /home/jmdavis/dmd2/linux/bin/../../src/phobos/std/string.d(2596): Error: function std.string.sformat!(char, int).sformat is a nested function and cannot be accessed from std.range.put!(Sink, char).put /home/jmdavis/dmd2/linux/bin/../../src/phobos/std/string.d(2596): Error: function std.string.sformat!(char, int).sformat is a nested function and cannot be accessed from std.range.put!(Sink, char).put /home/jmdavis/dmd2/linux/bin/../../src/phobos/std/string.d(2597): Error: function std.string.sformat!(char, int).sformat is a nested function and cannot be accessed from std.range.put!(Sink, char).put /home/jmdavis/dmd2/linux/bin/../../src/phobos/std/string.d(2601): Error: function std.string.sformat!(char, int).sformat is a nested function and cannot be accessed from std.range.put!(Sink, char[]).put /home/jmdavis/dmd2/linux/bin/../../src/phobos/std/string.d(2601): Error: function std.string.sformat!(char, int).sformat is a nested function and cannot be accessed from std.range.put!(Sink, char[]).put /home/jmdavis/dmd2/linux/bin/../../src/phobos/std/string.d(2604): Error: function std.string.sformat!(char, int).sformat is a nested function and cannot be accessed from std.range.put!(Sink, char[]).put /home/jmdavis/dmd2/linux/bin/../../src/phobos/std/string.d(2604): Error: function std.string.sformat!(char, int).sformat is a nested function and cannot be accessed from std.range.put!(Sink, char[]).put /home/jmdavis/dmd2/linux/bin/../../src/phobos/std/string.d(2604): Error: function std.string.sformat!(char, int).sformat is a nested function and cannot be accessed from std.range.put!(Sink, char[]).put /home/jmdavis/dmd2/linux/bin/../../src/phobos/std/string.d(2605): Error: function std.string.sformat!(char, int).sformat is a nested function and cannot be accessed from std.range.put!(Sink, char[]).put /home/jmdavis/dmd2/linux/bin/../../src/phobos/std/string.d(2601): Error: function std.string.sformat!(char, int).sformat is a nested function and cannot be accessed from std.range.put!(Sink, const(char)[]).put /home/jmdavis/dmd2/linux/bin/../../src/phobos/std/string.d(2601): Error: function std.string.sformat!(char, int).sformat is a nested function and cannot be accessed from std.range.put!(Sink, const(char)[]).put /home/jmdavis/dmd2/linux/bin/../../src/phobos/std/string.d(2604): Error: function std.string.sformat!(char, int).sformat is a nested function and cannot be accessed from std.range.put!(Sink, const(char)[]).put
Comment #11 by bearophile_hugs — 2013-03-01T04:42:22Z
import std.array: array; import std.algorithm: map; void main() { int[] foo; auto r1 = map!(i => foo[0])([0]); auto r2 = array(r1); } Gives (dmd 2.063 alpha): temp.d(5): Error: function D main is a nested function and cannot be accessed from std.array.array!(MapResult!(__lambda2, int[])).array
Comment #12 by verylonglogin.reg — 2013-06-10T05:40:53Z
*** Issue 9187 has been marked as a duplicate of this issue. ***
Comment #13 by verylonglogin.reg — 2013-06-10T05:43:09Z
*** Issue 9996 has been marked as a duplicate of this issue. ***
Comment #14 by verylonglogin.reg — 2013-06-10T05:46:21Z
*** Issue 7129 has been marked as a duplicate of this issue. ***
Comment #15 by verylonglogin.reg — 2013-06-10T05:47:35Z
Currently failing tests: 1. From Description --- import std.algorithm: map; import std.array: array; void main() { int c; map!(x => c)([1]).array(); } --- 2. From Comment 10 --- import std.string; void main() { assert(new char[5].sformat("%s", 42) == "42"); } --- 3. From Issue 7129 Comment 4 --- auto fun() { int i; struct Result { this(int u) {} auto bar() { i = 42; } } return Result(); } void main() { auto t = fun(); t.bar(); } ---
Comment #16 by verylonglogin.reg — 2013-06-10T05:54:37Z
As mixing -inline/non-inline modules may result in a wrong code because of Issue 9193 one can use "-inline" only for toy D projects.
Comment #17 by bearophile_hugs — 2013-06-10T15:13:45Z
(In reply to comment #16) > As mixing -inline/non-inline modules may result in a wrong code because of > Issue 9193 one can use "-inline" only for toy D projects. If you believe that to be true, then I think you should raise the Importance of this issue to Major.
Comment #18 by k.hara.pg — 2013-07-09T20:27:33Z
Comment #19 by github-bugzilla — 2013-07-11T23:49:29Z
Commits pushed to master at https://github.com/D-Programming-Language/dmd https://github.com/D-Programming-Language/dmd/commit/1fbbe5966e372abb20e70c4ac69ecfaeaa6db952 fix Issue 4841 - -inline wrecks certain nested structs causing error "*** is a nested function and cannot be accessed from ***" https://github.com/D-Programming-Language/dmd/commit/c19b8a43f45da1347302d3b49a3d1b0b53997003 Merge pull request #2329 from 9rnsr/fix4841 Issue 4841 - -inline wrecks certain nested structs causing error "*** is a nested function and cannot be accessed from ***"
Comment #20 by k.hara.pg — 2013-10-10T04:59:50Z
*** Issue 11210 has been marked as a duplicate of this issue. ***