From a3a203f31fbb44ceb346abeb06997237cbaae1a6 Mon Sep 17 00:00:00 2001 From: k-hara Date: Thu, 24 Apr 2014 00:59:52 +0900 Subject: [PATCH] fix Issue 12554 - [ICE](struct.c line 898) with failed delegate purity --- src/class.c | 4 +-- src/struct.c | 2 +- test/fail_compilation/ice12554.d | 55 ++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 3 deletions(-) create mode 100644 test/fail_compilation/ice12554.d diff --git a/src/class.c b/src/class.c index 06b38d559856..c343734e78d5 100644 --- a/src/class.c +++ b/src/class.c @@ -266,7 +266,7 @@ void ClassDeclaration::semantic(Scope *sc) if (type->ty == Tclass && ((TypeClass *)type)->sym != this) { TemplateInstance *ti = ((TypeClass *)type)->sym->isInstantiated(); - if (ti && ti->errors) + if (ti && isError(ti)) ((TypeClass *)type)->sym = this; } @@ -1268,7 +1268,7 @@ void InterfaceDeclaration::semantic(Scope *sc) if (type->ty == Tclass && ((TypeClass *)type)->sym != this) { TemplateInstance *ti = ((TypeClass *)type)->sym->isInstantiated(); - if (ti && ti->errors) + if (ti && isError(ti)) ((TypeClass *)type)->sym = this; } diff --git a/src/struct.c b/src/struct.c index acc68e9835fc..eecb1e5f3534 100644 --- a/src/struct.c +++ b/src/struct.c @@ -691,7 +691,7 @@ void StructDeclaration::semantic(Scope *sc) if (type->ty == Tstruct && ((TypeStruct *)type)->sym != this) { TemplateInstance *ti = ((TypeStruct *)type)->sym->isInstantiated(); - if (ti && ti->errors) + if (ti && isError(ti)) ((TypeStruct *)type)->sym = this; } diff --git a/test/fail_compilation/ice12554.d b/test/fail_compilation/ice12554.d new file mode 100644 index 000000000000..9f9471ce1afa --- /dev/null +++ b/test/fail_compilation/ice12554.d @@ -0,0 +1,55 @@ +/* +TEST_OUTPUT: +--- +fail_compilation/ice12554.d(18): Error: pure function 'D main' cannot call impure function 'ice12554.array!(MapResult!((y) => x)).array' +fail_compilation/ice12554.d(37): instantiated from here: MapResult!((x) => foo.map!(MapResultS, (y) => x).array) +fail_compilation/ice12554.d(18): instantiated from here: map!(int[]) +fail_compilation/ice12554.d(21): Error: pure function 'D main' cannot call impure function 'ice12554.array!(MapResult!((y) => x)).array' +fail_compilation/ice12554.d(37): instantiated from here: MapResult!((x) => foo.map!(MapResultC, (y) => x).array) +fail_compilation/ice12554.d(21): instantiated from here: map!(int[]) +--- +*/ + +void main() pure +{ + int[] foo; + + // if indirectly instantiated aggregate is struct (== MapResultS) + foo.map!(MapResultS, x => foo.map!(MapResultS, y => x).array); + + // if indirectly instantiated aggregate is class (== MapResultC) + foo.map!(MapResultC, x => foo.map!(MapResultC, y => x).array); +} + +T array(T)(T a) +{ + static int g; g = 1; // impure operation + return a; +} + +template map(alias MapResult, fun...) +{ + auto map(Range)(Range r) + { + alias AppliedReturnType(alias f) = typeof(f(r[0])); + static assert(!is(AppliedReturnType!fun == void)); + + return MapResult!(fun).init; + } +} + +struct MapResultS(alias fun) +{ + @property front() + { + return fun(1); + } +} + +class MapResultC(alias fun) +{ + @property front() + { + return fun(1); + } +}