Bug 7554 – Immutable function pointer arguments too

Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
x86
OS
Windows
Creation time
2012-02-20T14:51:00Z
Last change time
2012-02-28T15:35:40Z
Keywords
pull, rejects-valid
Assigned to
nobody
Creator
bearophile_hugs

Comments

Comment #0 by bearophile_hugs — 2012-02-20T14:51:48Z
This problem may be correlated to Issue 7500 This code doesn't compile because 'foo' is mutable: T outer(T)(T function(in T) pure foo) pure { pure int inner() { return foo(5); } return inner(); } int sqr(in int x) pure { return x * x; } void main() { assert(outer(&sqr) == 25); } test.d(3): Error: pure nested function 'inner' cannot access mutable data 'foo' test.d(11): Error: template instance test.outer!(int) error instantiating But it doesn't work if you add an 'immutable': T outer(T)(immutable T function(in T) pure foo) pure { pure int inner() { return foo(5); } return inner(); } int sqr(in int x) pure { return x * x; } void main() { assert(outer(&sqr) == 25); } test.d(11): Error: template test.outer(T) cannot deduce template function from argument types !()(int function(const(int) x) pure) This compiles, but it's not nice: int sqr(in int x) pure { return x * x; } immutable sqrPtr =&sqr; auto outer(typeof(sqrPtr) foo) pure { pure int inner() { return foo(5); } return inner(); } void main() { assert(outer(sqrPtr) == 25); } A better workaround, found by Timon Gehr: T outer(T)(T function(in T) pure foo) pure { immutable fooTick = foo; pure int inner() { return fooTick(5); } return inner(); } int sqr(in int x) pure { return x * x; } void main() { assert(outer(&sqr) == 25); }
Comment #1 by k.hara.pg — 2012-02-26T08:23:38Z
I think making inner() pure isn't necessary. Following raises no error and works as expected. T outer(T)(T function(in T) pure foo) pure { int inner() { return foo(5); } return inner(); } int sqr(in int x) pure { return x * x; } void main() { assert(outer(&sqr) == 25); }
Comment #2 by bearophile_hugs — 2012-02-26T10:58:27Z
(In reply to comment #1) > I think making inner() pure isn't necessary. In this program I want inner() to be pure.
Comment #3 by bearophile_hugs — 2012-02-27T15:27:55Z
This code compiles, but I don't remember if this used to compile even before fixing bug 7500 : int outer(immutable int function(in int) pure foo) pure { pure int inner() { return foo(5); } return inner(); } int sqr(in int x) pure { return x * x; } void main() { assert(outer(&sqr) == 25); } This doesn't compile still: T outer(T)(immutable T function(T) pure foo) pure { pure int inner() { return foo(5); } return inner(); } int sqr(int x) pure { return x * x; } void main() { assert(outer(&sqr) == 25); }
Comment #4 by k.hara.pg — 2012-02-27T17:10:21Z
OK. Reduced test case. int sqr(int x) pure { return x * x; } void main() { immutable(int function(int) pure) ifp = &sqr; // Error: cannot implicitly convert expression (& sqr) of type int function(int x) pure to immutable(int function(int) pure) }
Comment #5 by k.hara.pg — 2012-02-27T18:58:37Z
Comment #6 by github-bugzilla — 2012-02-28T13:59:06Z
Commits pushed to master at https://github.com/D-Programming-Language/dmd https://github.com/D-Programming-Language/dmd/commit/c1906e09d7b773bc5ff0a2477b3139c98d8e60ea fix Issue 7554 - Immutable function pointer arguments too Protect function type from inappropriate modifier transition. https://github.com/D-Programming-Language/dmd/commit/461649be7975faf119188674f296a7fac7c38a96 Merge pull request #772 from 9rnsr/fix7554 Issue 7554 - Immutable function pointer arguments too