diff --git a/src/expression.c b/src/expression.c index 0181f7e1b3e4..108f5b32cbc3 100644 --- a/src/expression.c +++ b/src/expression.c @@ -8161,25 +8161,6 @@ Expression *DotTemplateInstanceExp::semanticY(Scope *sc, int flag) Declaration *v = s->isDeclaration(); if (v && (v->isFuncDeclaration() || v->isVarDeclaration())) { - /* Fix for Bugzilla 4003 - * The problem is a class template member function v returning a reference to the same - * type as the enclosing template instantiation. This results in a nested instantiation, - * which of course gets short circuited. The return type then gets set to - * the template instance type before instantiation, rather than after. - * We can detect this by the deco not being set. If so, go ahead and retry - * the return type semantic. - * The offending code is the return type from std.typecons.Tuple.slice: - * ref Tuple!(Types[from .. to]) slice(uint from, uint to)() - * { - * return *cast(typeof(return) *) &(field[from]); - * } - * and this line from the following unittest: - * auto s = a.slice!(1, 3); - * where s's type wound up not having semantic() run on it. - */ - if (v->type && !v->type->deco) - v->type = v->type->semantic(v->loc, sc); - e = new DotVarExp(loc, eleft, v); e = e->semantic(sc); return e; diff --git a/test/compilable/imports/stdio4003.d b/test/compilable/imports/stdio4003.d new file mode 100644 index 000000000000..f37b70e4d78d --- /dev/null +++ b/test/compilable/imports/stdio4003.d @@ -0,0 +1,3 @@ +module imports.stdio4003; + +import imports.typecons4003; diff --git a/test/compilable/imports/test4003a.d b/test/compilable/imports/test4003a.d new file mode 100644 index 000000000000..a05a16d5b902 --- /dev/null +++ b/test/compilable/imports/test4003a.d @@ -0,0 +1,6 @@ +module imports.test4003a; + +import imports.typecons4003; + +Tuple!(string) t; + diff --git a/test/compilable/imports/test65a.d b/test/compilable/imports/test65a.d deleted file mode 100644 index 995c6fe7a3bc..000000000000 --- a/test/compilable/imports/test65a.d +++ /dev/null @@ -1,6 +0,0 @@ -module imports.test65a; - -import std.typecons; - -Tuple!(string) t; - diff --git a/test/compilable/imports/typecons4003.d b/test/compilable/imports/typecons4003.d new file mode 100644 index 000000000000..d1d2eff80adc --- /dev/null +++ b/test/compilable/imports/typecons4003.d @@ -0,0 +1,22 @@ +module imports.typecons4003; + +struct Tuple(T...) +{ + alias T Types; + Types field; + + ref Tuple!(Types[from .. to]) slice(uint from, uint to)() + { + return *cast(typeof(return) *) &(field[from]); + } + + void test() //unittest + { + .Tuple!(int, string, float, double) a; + a.field[1] = "abc"; + a.field[2] = 4.5; + auto s = a.slice!(1, 3); + static assert(is(typeof(s) == Tuple!(string, float))); + //assert(s.field[0] == "abc" && s.field[1] == 4.5); + } +} diff --git a/test/compilable/test4003.d b/test/compilable/test4003.d new file mode 100644 index 000000000000..8a401f219bd2 --- /dev/null +++ b/test/compilable/test4003.d @@ -0,0 +1,6 @@ +// EXTRA_SOURCES: imports/test4003a.d +// PERMUTE_ARGS: + +import imports.stdio4003; +void main(){} + diff --git a/test/compilable/test65.d b/test/compilable/test65.d deleted file mode 100644 index 8a4ff924aeea..000000000000 --- a/test/compilable/test65.d +++ /dev/null @@ -1,8 +0,0 @@ -// 4003 -// EXTRA_SOURCES: imports/test65a.d -// PERMUTE_ARGS: -// REQUIRED_ARGS: -unittest - -import std.stdio; -void main(){} - diff --git a/test/fail_compilation/ice10938.d b/test/fail_compilation/ice10938.d new file mode 100644 index 000000000000..2b3eab52ea3f --- /dev/null +++ b/test/fail_compilation/ice10938.d @@ -0,0 +1,23 @@ +/* +TEST_OUTPUT: +--- +fail_compilation/ice10938.d(12): Error: no property 'opts' for type 'ice10938.C' +--- +*/ + +class C +{ + this() + { + this.opts["opts"] = 1; + } + + auto opDispatch(string field : "opts")() + { + return this.opts; // ICE -> compile time error + } +} + +void main() +{ +}