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

D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 4841 - -inline wrecks certain nested structs causing error "*** is a nested function and cannot be accessed from ***"
Summary: -inline wrecks certain nested structs causing error "*** is a nested function...
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: All All
: P2 normal
Assignee: No Owner
URL:
Keywords: accepts-invalid, pull, rejects-valid
: 4724 7129 9187 9996 11210 (view as issue list)
Depends on:
Blocks:
Reported: 2010年09月08日 04:08 UTC by bearophile_hugs
Modified: 2013年10月10日 04:59 UTC (History)
10 users (show)

See Also:


Attachments
Add an attachment (proposed patch, testcase, etc.)

Note You need to log in before you can comment on or make changes to this issue.
Description bearophile_hugs 2010年09月08日 04:08:00 UTC
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 Don 2010年09月10日 00:02:24 UTC
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 Trass3r 2012年01月16日 12:41:31 UTC
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 David Simcha 2012年01月24日 13:41:43 UTC
*** Issue 4724 has been marked as a duplicate of this issue. ***
Comment 4 Don 2012年01月27日 00:35:53 UTC
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 github-bugzilla 2012年02月05日 12:34:31 UTC
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 David Simcha 2012年02月05日 21:07:57 UTC
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 Walter Bright 2012年02月05日 22:08:20 UTC
I believe this is the same as bug 5939.
Comment 8 Don 2012年02月06日 10:00:46 UTC
(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 bearophile_hugs 2012年02月21日 14:18:15 UTC
See also Issue 7559 
Comment 10 Jonathan M Davis 2013年02月16日 15:54:35 UTC
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 bearophile_hugs 2013年03月01日 04:42:22 UTC
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 Denis Shelomovskii 2013年06月10日 05:40:53 UTC
*** Issue 9187 has been marked as a duplicate of this issue. ***
Comment 13 Denis Shelomovskii 2013年06月10日 05:43:09 UTC
*** Issue 9996 has been marked as a duplicate of this issue. ***
Comment 14 Denis Shelomovskii 2013年06月10日 05:46:21 UTC
*** Issue 7129 has been marked as a duplicate of this issue. ***
Comment 15 Denis Shelomovskii 2013年06月10日 05:47:35 UTC
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 Denis Shelomovskii 2013年06月10日 05:54:37 UTC
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 bearophile_hugs 2013年06月10日 15:13:45 UTC
(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 Kenji Hara 2013年07月09日 20:27:33 UTC
https://github.com/D-Programming-Language/dmd/pull/2329 
Comment 19 github-bugzilla 2013年07月11日 23:49:29 UTC
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 Kenji Hara 2013年10月10日 04:59:50 UTC
*** Issue 11210 has been marked as a duplicate of this issue. ***


AltStyle によって変換されたページ (->オリジナル) /