Comment #0 by bearophile_hugs — 2010-10-06T14:08:53Z
This D2 code compiles and runs with no errors with dmd 2.049, and it ignores the "pure" attribute:
int z = 1000;
int foo(int x) {
pure int bar(int y) {
z++;
return x + y + z;
}
return bar(x * x);
}
void main() {
assert(foo(10) == 1111);
}
I expect this code to not compile.
Is DMD missing unit tests for this?
Comment #1 by smjg — 2010-10-07T04:33:04Z
Please remember to assign keywords to bug reports. To everybody reading this: Please look through issues you've reported and check for missing keywords.
Comment #2 by bearophile_hugs — 2010-10-26T15:34:16Z
It seems currently (2.050alpha) nested functions can't be pure:
import std.traits: FunctionAttribute, functionAttributes;
void main() {
static pure int foo1(int x) { return x; }
pure int foo2(int x) { return x; }
static assert(functionAttributes!(foo1) & FunctionAttribute.PURE); // asserts
static assert(functionAttributes!(foo2) & FunctionAttribute.PURE); // asserts
}
void main() {}
This is a problem because I'd like many functions of std.algorithm to be weakly pure. Many high order functions take an optional delegate argument, so if there's no handy way to build a pure delegate, they become less useful.
Comment #3 by clugdbug — 2010-10-27T01:54:01Z
This is the same issue as bug 4640 (and I think I've seen it somewhere else as well). It's a parsing issue.
Placing the attribute after the parameter list works.
int bar(int y) pure { .... }
Comment #4 by lewis1711 — 2010-10-31T15:52:50Z
I can confirm this bug.
It especially annoying because if you copypasta the bit on pure functionns straight out of TDPL it *will compile*, when the comment says it shouldn't.
import std.stdio;
void main()
{
pure bool leapYear(uint y)
{
auto result = (y % 4) == 0 && (y % 100 || (y % 400) == 0);
if (result) writeln(y, " is a leap year!"); // Error!
// Cannot call impure function writeln from pure function!
return result;
}
leapYear(1);
}
Comment #5 by kennytm — 2011-02-21T11:41:26Z
Looks like this is fixed in v2.052 or earlier.
Now bearophile's 1st program gives:
x.d(4): Error: pure function 'bar' cannot access mutable static data 'z'
x.d(5): Error: pure nested function 'bar' cannot access mutable data 'x'
x.d(5): Error: pure function 'bar' cannot access mutable static data 'z'
and Lewis' program gives:
x.d(8): Error: pure function 'leapYear' cannot call impure function 'writeln'
as expected, although I think 'bar' should be able to access 'x' in bearophile's 1st program.
On the other hand, bearophile's 2nd program now result in ICE (at least on Mac OS X)
Internal error: ../ztc/machobj.c 1805
Comment #6 by kennytm — 2011-02-21T11:50:21Z
(In reply to comment #5)
>
> On the other hand, bearophile's 2nd program now result in ICE (at least on Mac
> OS X)
>
> Internal error: ../ztc/machobj.c 1805
Never mind, it ICE only because there are two 'main's (issue 5634). Removing the 2nd 'main' the program compiles correctly.