// REQUIRED_ARGS:

import core.stdc.stdio;

/*******************************************/

int bar(int a)
{
    int foo(int b) { return b + 1; }

    return foo(a);
}

void test1()
{
    assert(bar(3) == 4);
}

/*******************************************/

int bar2(int a)
{
    static int c = 4;

    int foo(int b) { return b + c + 1; }

    return foo(a);
}

void test2()
{
    assert(bar2(3) == 8);
}


/*******************************************/

int bar3(int a)
{
    static int foo(int b) { return b + 1; }

    return foo(a);
}

void test3()
{
    assert(bar3(3) == 4);
}

/*******************************************/

int bar4(int a)
{
    static int c = 4;

    static int foo(int b) { return b + c + 1; }

    return foo(a);
}

void test4()
{
    assert(bar4(3) == 8);
}


/*******************************************/

int bar5(int a)
{
    int c = 4;

    int foo(int b) { return b + c + 1; }

    return c + foo(a);
}

void test5()
{
    assert(bar5(3) == 12);
}


/*******************************************/

int bar6(int a)
{
    int c = 4;

    int foob(int b) { return b + c + 1; }
    int fooa(int b) { return foob(c + b) * 7; }

    return fooa(a);
}

void test6()
{
    assert(bar6(3) == 84);
}


/*******************************************/

int bar7(int a)
{
    static int c = 4;

    static int foob(int b) { return b + c + 1; }

    int function(int) fp = &foob;

    return fp(a);
}

void test7()
{
    assert(bar7(3) == 8);
}

/*******************************************/

int bar8(int a)
{
    int c = 4;

    int foob(int b) { return b + c + 1; }

    int delegate(int) fp = &foob;

    return fp(a);
}

void test8()
{
    assert(bar8(3) == 8);
}


/*******************************************/

struct Abc9
{
    int a;
    int b;
    int c = 7;

    int bar(int x)
    {
        Abc9 *foo() { return &this; }

        Abc9 *p = foo();
        assert(p == &this);
        return p.c + x;
    }
}

void test9()
{
    Abc9 x;

    assert(x.bar(3) == 10);
}

/*******************************************/

class Abc10
{
    int a;
    int b;
    int c = 7;

    int bar(int x)
    {
        Abc10 foo() { return this; }

        Abc10 p = foo();
        assert(p == this);
        return p.c + x;
    }

}

void test10()
{
    Abc10 x = new Abc10();

    assert(x.bar(3) == 10);
}


/*******************************************/

class Collection
{
    int[3] array;

    void opApply(void delegate(int) fp)
    {
        for (int i = 0; i < array.length; i++)
            fp(array[i]);
    }
}

int func11(Collection c)
{
    int max = int.min;

    void comp_max(int i)
    {
        if (i > max)
            max = i;
    }

    c.opApply(&comp_max);
    return max;
}

void test11()
{
    Collection c = new Collection();

    c.array[0] = 7;
    c.array[1] = 26;
    c.array[2] = 25;

    int m = func11(c);
    assert(m == 26);
}


/*******************************************/

void SimpleNestedFunction ()
{
    int nest () { return 432; }

    assert (nest () == 432);
    int delegate () func = &nest;
    assert (func () == 432);
}

void AccessParentScope ()
{
    int value = 9;

    int nest () { assert (value == 9); return 9; }

    assert (nest () == 9);
}

void CrossNestedScope ()
{
    int x = 45;

    void foo () { assert (x == 45); }
    void bar () { int z = 16; foo (); }
    bar ();
}

void BadMultipleNested ()
{
    int x;

    void foo ()
    {
       void bar ()
       {
           //erroneous x = 4; // Should fail.
       }
    }
}

/* This one kind of depends upon memory layout.  GlobalScopeSpoof should
be called with no "this" pointer; this is trying to ensure that
everything is working properly.  Of course, in the DMD calling
convention it'll fail if the caller passes too much/little data. */

void GlobalScopeSpoof (int x, int y)
{
    assert (x == y && y == 487);
}

void GlobalScope ()
{
    void bar () { GlobalScopeSpoof (487, 487); }
    bar ();
}

class TestClass
{
    int x = 6400;

    void foo ()
    {
       void bar () { assert (x == 6400); }
       bar ();
    }
}

void test12()
{
    SimpleNestedFunction ();
    AccessParentScope ();
    CrossNestedScope ();
    GlobalScope ();
    (new TestClass).foo ();
}


/*******************************************/

void test13()
{
    struct Abc
    {
        int x = 3;
        int y = 4;
    }

    Abc a;

    assert(a.x == 3 && a.y == 4);
}


/*******************************************/

void test14()
{
    struct Abc
    {
        int x = 3;
        int y = 4;

        int foo() { return y; }
    }

    Abc a;

    assert(a.foo() == 4);
}


/*******************************************/

void test15()
{
    static int z = 5;

    struct Abc
    {
        int x = 3;
        int y = 4;

        int foo() { return y + z; }
    }

    Abc a;

    assert(a.foo() == 9);
}


/*******************************************/

void test16()
{
    static int z = 5;

    static class Abc
    {
        int x = 3;
        int y = 4;

        int foo() { return y + z; }
    }

    Abc a = new Abc();

    assert(a.foo() == 9);
}


/*******************************************/

void test17()
{
    int function(int x) fp;

    fp = function int(int y) { return y + 3; };
    assert(fp(7) == 10);
}

/*******************************************/

void test18()
{
    static int a = 3;
    int function(int x) fp;

    fp = function int(int y) { return y + a; };
    assert(fp(7) == 10);
}

/*******************************************/

void test19()
{
    int a = 3;

    int delegate(int x) fp;

    fp = delegate int(int y) { return y + a; };
    assert(fp(7) == 10);
}


/*******************************************/

class Collection20
{
    int[3] array;

    void opApply(void delegate(int) fp)
    {
        for (int i = 0; i < array.length; i++)
            fp(array[i]);
    }
}

int func20(Collection20 c)
{
    int max = int.min;

    c.opApply(delegate(int i) { if (i > max) max = i; });
    return max;
}

void test20()
{
    Collection20 c = new Collection20();

    c.array[0] = 7;
    c.array[1] = 26;
    c.array[2] = 25;

    int m = func20(c);
    assert(m == 26);
}


/*******************************************/

int bar21(int a)
{
    int c = 3;

    int foo(int b)
    {
        b += c;         // 4 is added to b
        c++;            // bar.c is now 5
        return b + c;   // 12 is returned
    }
    c = 4;
    int i = foo(a);     // i is set to 12
    return i + c;       // returns 17
}

void test21()
{
    int i = bar21(3);   // i is assigned 17
    assert(i == 17);
}

/*******************************************/

void foo22(void delegate() baz)
{
  baz();
}

void bar22(int i)
{
  int j = 14;
  printf("%d,%d\n",i,j);

  void fred()
  {
    printf("%d,%d\n",i,j);
    assert(i == 12 && j == 14);
  }

  fred();
  foo22(&fred);
}

void test22()
{
  bar22(12);
}


/*******************************************/

void frelled(void delegate() baz)
{
  baz();
}

class Foo23
{
  void bar(int i)
  {
    int j = 14;
    printf("%d,%d\n",i,j);

    void fred()
    {
        printf("%d,%d\n",i,j);
        assert(i == 12);
        assert(j == 14);
    }

    frelled(&fred);
  }
}

void test23()
{
    Foo23 f = new Foo23();

    f.bar(12);
}


/*******************************************/

void delegate () function (int x) store24;

void delegate () zoom24(int x)
{
   return delegate void () { };
}

void test24()
{
   store24 = &zoom24;
   store24 (1) ();
}


/*******************************************/

void test25()
{
    delegate() { printf("stop the insanity!\n"); }();
    delegate() { printf("stop the insanity! 2\n"); }();
}

/*******************************************/

alias bool delegate(int) callback26;


bool foo26(callback26 a)
{
    return a(12);
}

class Bar26
{
    int func(int v)
    {
        printf("func(v=%d)\n", v);
        foo26(delegate bool(int a)
        {
            printf("%d %d\n",a,v); return true;
            assert(a == 12);
            assert(v == 15);
            assert(0);
        } );
        return v;
    }
}


void test26()
{
    Bar26 b = new Bar26();

    b.func(15);
}


/*******************************************/

class A27
{
    uint myFunc()
    {
        uint myInt = 13;
        uint mySubFunc()
        {
            return myInt;
        }
        return mySubFunc();
    }
}

void test27()
{
    A27 myInstance = new A27;
    int i = myInstance.myFunc();
    printf("%d\n", i);
    assert(i == 13);
}


/*******************************************/

void Foo28(void delegate() call)
{
    call();
}

class Bar28
{
    int func()
    {
        int count = 0;

        Foo28(delegate void() { ++count; } );
        return count;
    }
}

void test28()
{
    Bar28 b = new Bar28();
    int i = b.func();
    assert(i == 1);
}


/*******************************************/

class Foo29
{
  void Func(void delegate() call)
  {
    for(int i = 0; i < 10; ++i)
      call();
  }
}

class Bar29
{
    int Func()
    {
        int count = 0;
        Foo29 ic = new Foo29();

        ic.Func(delegate void() { ++count; } );
        return count;
    }
}

void test29()
{
    Bar29 b = new Bar29();
    int i = b.Func();
    assert(i == 10);
}

/*******************************************/

struct Foo30
{
  int[] arr;
}

void Func30(Foo30 bar)
{
    void InnerFunc(int x, int y)
    {
        int a = bar.arr[y]; // Ok

        if(bar.arr[y]) // Access violation
        {
        }
    }

    InnerFunc(5,5);
}


void test30()
{
  Foo30 abc;

  abc.arr.length = 10;
  Func30(abc);
}


/*******************************************/

void call31(int d, void delegate(int d) f)
{
    assert(d == 100 || d == 200);
    printf("d = %d\n", d);
    f(d);
}

void test31()
{
    call31(100, delegate void(int d1)
    {
        printf("d1 = %d\n", d1);
        assert(d1 == 100);
        call31(200, delegate void(int d2)
        {
            printf("d1 = %d\n", d1);
            printf("d2 = %d\n", d2);
            assert(d1 == 100);
            assert(d2 == 200);
        });
    });
}


/*******************************************/

void call32(int d, void delegate(int d) f)
{
    assert(d == 100 || d == 200);
    printf("d = %d\n", d);
    f(d);
}

void test32()
{
    call32(100, delegate void(int d1)
    {
        int a = 3;
        int b = 4;
        printf("d1 = %d, a = %d, b = %d\n", d1, a, b);
        assert(a == 3);
        assert(b == 4);
        assert(d1 == 100);

        call32(200, delegate void(int d2)
        {
            printf("d1 = %d, a = %d\n", d1, a);
            printf("d2 = %d, b = %d\n", d2, b);
            assert(a == 3);
            assert(b == 4);
            assert(d1 == 100);
            assert(d2 == 200);
        });
    });
}


/*******************************************/

void test33()
{
    extern (C) int Foo1(int a, int b, int c)
    {
        assert(a == 1);
        assert(b == 2);
        assert(c == 3);
        return 1;
    }

    extern (D) int Foo2(int a, int b, int c)
    {
        assert(a == 1);
        assert(b == 2);
        assert(c == 3);
        return 2;
    }

    extern (Windows) int Foo3(int a, int b, int c)
    {
        assert(a == 1);
        assert(b == 2);
        assert(c == 3);
        return 3;
    }

    extern (Pascal) int Foo4(int a, int b, int c)
    {
        assert(a == 1);
        assert(b == 2);
        assert(c == 3);
        return 4;
    }

    assert(Foo1(1, 2, 3) == 1);
    assert(Foo2(1, 2, 3) == 2);
    assert(Foo3(1, 2, 3) == 3);
    assert(Foo4(1, 2, 3) == 4);

    printf("test33 success\n");
}

/*******************************************/

class Foo34
{
    int x;

    class Bar
    {
        int y;

        int delegate() getDelegate()
        {
            assert(y == 8);
            auto i = sayHello();
            assert(i == 23);
            return &sayHello;
        }
    }
    Bar bar;

    int sayHello()
    {
        printf("Hello\n");
        assert(x == 47);
        return 23;
    }

    this()
    {
        x = 47;
        bar = new Bar();
        bar.y = 8;
    }
}

void test34()
{
    Foo34 foo = new Foo34();
    int delegate() saydg = foo.bar.getDelegate();
    printf("This should print Hello:\n");
    auto i = saydg();
    assert(i == 23);
}

/*******************************************/

class Foo35
{
    int x = 42;
    void bar()
    {
        int y = 43;
        new class Object
        {
            this()
            {
                //writefln("x = %s", x);
                //writefln("y = %s", y);
                assert(x == 42);
                assert(y == 43);
              //static assert(is(typeof(this.outer) == void*)); // Bugzilla 14442
                static assert(is(typeof(this.outer) == Foo35)); // Bugzilla 15839
            }
        };
    }
}

void test35()
{
    Foo35 f = new Foo35();
    f.bar();
}

/*******************************************/

class Foo36
{
    int x = 42;
    this()
    {
        int y = 43;
        new class Object
        {
            this()
            {
                //writefln("x = %s", x);
                //writefln("y = %s", y);
                assert(x == 42);
                assert(y == 43);
            }
        };
    }
}

void test36()
{
    Foo36 f = new Foo36();
}

/*******************************************/

class Foo37
{
    int x = 42;
    void bar()
    {
        int y = 43;
        void abc()
        {
            new class Object
            {
                this()
                {
                    //writefln("x = %s", x);
                    //writefln("y = %s", y);
                    assert(x == 42);
                    assert(y == 43);
                }
            };
        }

        abc();
    }
}

void test37()
{
    Foo37 f = new Foo37();
    f.bar();
}

/*******************************************/

void test38()
{
    int status = 3;

    int delegate() foo()
    {
        class C
        {
            int dg()
            {
                return ++status;
            }
        }

        C c = new C();

        return &c.dg;
    }

    int delegate() bar = foo();

    if(status != 3)
    {
        assert(0);
    }

    if(bar() != 4)
    {
        assert(0);
    }

    if(status != 4)
    {
        assert(0);
    }
}

/*******************************************/

void test39()
{
    int status;

    int delegate() foo()
    {
        return &(new class
            {
                int dg()
                {
                    return ++status;
                }
            }
        ).dg;
    }

    int delegate() bar = foo();

    if(status != 0)
    {
        assert(0);
    }

    if(bar() != 1)
    {
        assert(0);
    }

    if(status != 1)
    {
        assert(0);
    }
}

/*******************************************/

interface I40
{
    void get( string s );
}

class C40
{
    int a = 4;

    void init()
    {
        I40 i = new class() I40
        {
            void get( string s )
            {
                func();
            }
        };
        i.get("hello");
    }
    void func( ){ assert(a == 4); }
}

void test40()
{
    C40 c = new C40();
    c.init();
}

/*******************************************/

class C41
{   int a = 3;

    void init()
    {
        class N
        {
            void get()
            {
                func();
            }
        }
        N n = new N();
        n.get();
    }
    void func()
    {
        assert(a == 3);
    }
}


void test41()
{
   C41 c = new C41();
   c.init();
}

/*******************************************/

class C42
{   int a = 3;

    void init()
    {
        class N
        {
            void init()
            {
                class M
                {
                    void get()
                    {
                        func();
                    }
                }
                M m = new M();
                m.get();
            }
        }
        N n = new N();
        n.init();
    }
    void func()
    {
        assert(a == 3);
    }
}

void test42()
{
   C42 c = new C42();
   c.init();
}


/*******************************************/

int foo43(alias X)() { return X; }

void test43()
{
    int x = 3;

    void bar()
    {
        int y = 4;
        assert(foo43!(x)() == 3);
        assert(foo43!(y)() == 4);
    }

    bar();

    assert(foo43!(x)() == 3);
}


/*******************************************/

class Comb
{
}

Comb Foo44(Comb delegate()[] c...)
{
    Comb ec = c[0]();
    printf("1ec = %p\n", ec);
    ec.toString();
    printf("2ec = %p\n", ec);
    return ec;
}

Comb c44;

static this()
{
    c44 = new Comb;
}

void test44()
{
    c44 = Foo44(Foo44(c44));
}

/*******************************************/

class Bar45
{
    void test()
    {
        a = 4;
        Inner i = new Inner;
        i.foo();
    }

    class Inner
    {
        void foo()
        {
            assert(a == 4);
            Inner i = new Inner;
            i.bar();
        }

        void bar()
        {
            assert(a == 4);
        }
    }
    int a;
}

void test45()
{
    Bar45 b = new Bar45;
    assert(b.a == 0);
    b.test();
}

/*******************************************/

class Adapter
{
    int a = 2;

    int func()
    {
        return 73;
    }
}

class Foo46
{
    int b = 7;

    class AnonAdapter : Adapter
    {
        int aa = 8;

        this()
        {
            assert(b == 7);
            assert(aa == 8);
        }
    }

    void func()
    {
        Adapter a = cast( Adapter )( new AnonAdapter() );
        assert(a.func() == 73);
        assert(a.a == 2);
    }
}

void test46()
{
    Foo46 f = new Foo46();
    f.func();
}


/*******************************************/

void test47()
{
    void delegate() test =
    {
        struct Foo {int x=3;}
        Foo f;
        assert(f.x == 3);
    };
    test();
}

/*******************************************/

struct Outer48
{
    class Inner
    {
        this(int i) { b = i; }
        int b;
    }

    int a = 6;

    void f()
    {
        int nested()
        {
            auto x = new Inner(a);
            return x.b + 1;
        }
        int i = nested();
        assert(i == 7);
    }
}


void test48()
{
    Outer48 s;
    s.f();
}

/*******************************************/

void test49()
{
    int j = 10;
    void mainlocal(int x)
    {
        printf("mainlocal: j = %d, x = %d\n", j, x);
        assert(j == 10);
        assert(x == 1);
    }

    void fun2()
    {
        int k = 20;
        void fun2local(int x)
        {
            printf("fun2local: k = %d, x = %d\n", k, x);
            assert(j == 10);
            assert(k == 20);
            assert(x == 2);
        }

        void fun1()
        {
            mainlocal(1);
            fun2local(2);
        }

        fun1();
    }

    fun2();
}

/*******************************************/

void funa50(alias pred1, alias pred2)()
{
    pred1(1);
    pred2(2);
}

void funb50(alias pred1)()
{   int k = 20;
    void funb50local(int x)
    {
        printf("funb50local: k = %d, x = %d\n", k, x);
        assert(k == 20);
        assert(x == 2);
    }
    funa50!(pred1, funb50local)();
}

void test50()
{
    int j = 10;
    void mainlocal(int x)
    {
        printf("mainlocal: j = %d, x = %d\n", j, x);
        assert(j == 10);
        assert(x == 1);
    }
    funb50!(mainlocal)();
}

/*******************************************/

void funa51(alias pred1, alias pred2)()
{
    pred1(2);
    pred2(1);
}

void funb51(alias pred1)()
{   int k = 20;
    void funb51local(int x)
    {
        printf("funb51local: k = %d, x = %d\n", k, x);
        assert(k == 20);
        assert(x == 2);
    }
    funa51!(funb51local, pred1)();
}

void test51()
{
    int j = 10;
    void mainlocal(int x)
    {
        printf("mainlocal: j = %d, x = %d\n", j, x);
        assert(j == 10);
        assert(x == 1);
    }
    funb51!(mainlocal)();
}

/*******************************************/

C52 c52;

class C52
{
    int index = 7;
    void test1(){
        printf( "this = %p, index = %d\n", this, index );
        assert(index == 7);
        assert(this == c52);
    }
    void test()
    {
        class N
        {
            void callI()
            {
                printf("test1\n");
                test1();
                printf("test2\n");
                if (index is -1)
                {   // Access to the outer-super-field triggers the bug
                    printf("test3\n");
                }
            }
        }
        auto i = new N();
        i.callI();
    }
}

void test52()
{
    auto c = new C52;
    printf("c = %p\n", c);
    c52 = c;
    c.test();
}

/*******************************************/

void foo53(int i)
{
    struct SS
    {
        int x,y;
        int bar() { return x + i + 1; }
    }
    SS s;
    s.x = 3;
    assert(s.bar() == 11);
}

void test53()
{
    foo53(7);
}

/*******************************************/

void test54()
{
    int x = 40;
    int fun(int i) { return x + i; }

    struct A
    {
        int bar(int i) { return fun(i); }
    }

    A makeA()
    {
        // A a; return a;
        return A();
    }

    A makeA2()
    {
         A a;   return a;
        //return A();
    }

    A a = makeA();
    assert(a.bar(2) == 42);

    A b = makeA2();
    assert(b.bar(3) == 43);

    auto c = new A;
    assert(c.bar(4) == 44);
}
/*******************************************/

void test55()
{
    int localvar = 7;

    int inner(int delegate(ref int) dg) {
        int k = localvar;
        return 0;
    }

    int a = localvar * localvar; // This modifies the EAX register

    foreach (entry; &inner)
    {
    }
}

/*******************************************/
// 4401

void test4401()
{
    auto foo() {
        return 3;
    }

    auto bar() nothrow pure {
        return 3;
    }

    auto baz() @property pure @safe {
        return 3;
    }

    auto zoo()() @property pure @safe nothrow {
        return 3;
    }
}

/*******************************************/

alias void delegate() dg_t;

void Y(dg_t delegate (dg_t) y)
{
    struct F { void delegate(F) f; };

  version (all)
  { // generates error
    (dg_t delegate(F) a){return a(F((F b){return y(a(b))();})); }
    ((F b){return (){return b.f(b);};});
  }
  else
  {
    auto abc(dg_t delegate(F) a)
    {
        return a(F((F b){return y(a(b))();}));
    }

    abc((F b){return (){return b.f(b);};});
  }
}


void test7428(){
    dg_t foo(dg_t self)
    {
        void bar() { self(); }
        return &bar;
    }

    Y(&foo);
}

/*******************************************/
// 4612

struct S4612a(alias x)
{
    void* func() { void* p = &x; return p; }
}

struct S4612b(alias x)
{
    int i;
    void* func() { void* p = &x; return p; }
}

void test4612()
{
    int a;

    auto sa = S4612a!a();
    assert(sa.func() == &a);

    auto sb = S4612b!(a)();
    assert(sb.func() == &a);
}

/*******************************************/

struct S4841(alias pred)
{
    void unused_func();
}

void abc4841() {
   int w;
   S4841!(w) m;
}

void test4841() {
   abc4841();
}

/*******************************************/


void index7199()
{
    void find()
    {
        bool hay()
        {
            return true;
        }
    }

    find();
}

void test7199()
{
    index7199();
}

/*******************************************/
// 7965

void test7965()
{
    int x;
    static int* px;
    px = &x;

    printf("&x = %p in main()\n", &x);
    struct S1
    {
        char y;
        void boom() {
            printf("&x = %p in S1.boom()\n", &x);
            assert(&x == px);
            //x = 42; // makes the struct nested
        }
    }
    S1 s1;
    s1.boom();

    struct S2
    {
        this(int n) {
            printf("&x = %p in S2.this()\n", &x);
            assert(&x == px);
        }
        char y;
    }
    S2 s2 = S2(10);
}

struct S7965
{
    string str;
    uint unused1, unused2 = 0;
}

auto f7965(alias fun)()
{
    struct Result
    {
        S7965 s;
        this(S7965 _s) { s = _s; }  // required for the problem
        void g() { assert(fun(s.str) == "xa"); }
    }

    return Result(S7965("a"));
}

void test7965a()
{
    string s = "x";
    f7965!(a => s ~= a)().g();
    assert(s == "xa");
}

/*******************************************/
// 8188

mixin template Print8188(b...)
{
    int doprint()
    {
        return b[0] * b[1];
    }
}

class A8188
{
    int x, y;
    mixin Print8188!(x, y);
}

void test8188()
{
    auto a = new A8188;
    a.x = 2;
    a.y = 5;
    assert(a.doprint() == 10);
}

/*******************************************/
// 5082

struct S5082 { float x; }

struct Map5082a(alias fun)
{
    typeof({ return fun(int.init); }()) cache;
}

struct Map5082b(alias fun)
{
    typeof({ return fun(int.init); }()) cache;

    S5082 front(int i) { return fun(i); }
}

void test5082()
{
    auto temp = S5082(1);
    auto func = (int v){ return temp; };
    auto map1 = Map5082a!func();
    auto map2 = Map5082b!func();
    assert(map2.front(1) == temp);
}


/*******************************************/
// 8194

void test8194()
{
    int foo;
    static void bar()
    {
        typeof(foo) baz;
        static assert(is(typeof(baz) == int));
    }
}

/*******************************************/
// 8339

template map8339a(fun...)
{
    auto map8339a(Range)(Range r) {
        struct Result {
            this(double[] input) {}
        }
        return Result(r);
    }
}
template map8339b(fun...)
{
    auto map8339b(Range)(Range r) {
        struct Result {
            this(double[] input) { fun[0](input.length); }
        }
        return Result(r);
    }
}
template map8339c(fun...)
{
    auto map8339c(Range)(Range r) {
        static struct Result {
            this(double[] input) {}
        }
        return Result(r);
    }
}
template map8339d(fun...)
{
    auto map8339d(Range)(Range r) {
        static struct Result {
            this(double[] input) { fun[0](input.length); }
        }
        return Result(r);
    }
}
void copy8339(T)(T x)
{
    T xSaved;
}
void test8339a()
{
    double[] x;
    int n;

    // Result has context pointer, so cannot copy
    static assert (!is(typeof({ copy8339(map8339a!(a=>a)(x)); })));
    static assert (!is(typeof({ copy8339(map8339a!(a=>n)(x)); })));

    // same as
    static assert (!is(typeof({ copy8339(map8339b!(a=>a)(x)); })));
    static assert (!is(typeof({ copy8339(map8339b!(a=>n)(x)); })));

    // fun is never instantiated
    copy8339(map8339c!(a=>a)(x));
    copy8339(map8339c!(a=>n)(x));

    // static nested struct doesn't have contest pointer
    copy8339(map8339d!(a=>a)(x));
  //copy8339(map8339d!(a=>n)(x));   // too strict case

}

template filter8339(alias pred)
{
    auto filter8339(R)(R r) {
        struct Result {
            R range;
            this(R r) { range = r; }
            auto front() { return pred(0); }
        }
        return Result(r);
    }
}
void test8339b()
{
    static makefilter() { int n; return filter8339!(a=>n)([]); }

    auto r1 = makefilter();
    filter8339!(a=>a)(r1);
}

void test8339c()
{
    class C(X) { X x; }
    class C1 { C!C1 x; }
    alias C!C1 C2;

    struct Pair { C1 t; C2 u; void func(){} }
    Pair pair;
}

/*******************************************/
// 8704

void check8704(T, int num)()
{
    static if (num == 1) T t0;
    static if (num == 2) T t1 = T();
    static if (num == 3) T t2 = T(1);
}

void test8704()
{
    struct S
    {
        int n;
        void foo(){}
    }

    static assert(!is(typeof(check8704!(S, 1)())));
    static assert(!is(typeof(check8704!(S, 2)())));
    static assert(!is(typeof(check8704!(S, 3)())));

    static assert(!__traits(compiles, check8704!(S, 1)()));
    static assert(!__traits(compiles, check8704!(S, 2)()));
    static assert(!__traits(compiles, check8704!(S, 3)()));
}

/*******************************************/
// 8923

void test8923a()
{
    int val;

    struct S  // is nested struct
    {
        void foo() { val = 1; }  // access to val through the hidden frame pointer
    }
    S    s1a;           s1a.foo();
    S    s1b = S();     s1b.foo();
    S[1] s2a;           s2a[0].foo();
    S[1] s2b = S();     s2b[0].foo();

    static struct U { S s; }
    U    u1a;           u1a.s.foo();
    U    u1b = U();     u1b.s.foo();
    U    u1c = U(s1a);  u1c.s.foo();
    U[1] u2a;           u2a[0].s.foo();
    U[1] u2b = U();     u2b[0].s.foo();
    U[1] u2c = U(s1a);  u2c[0].s.foo();
    static struct V { S[1] s; }
    V    v1a;           v1a.s[0].foo();
    V    v1b = V();     v1b.s[0].foo();
    V    v1c = V(s1a);  v1c.s[0].foo();
    V[1] v2a;           v2a[0].s[0].foo();
    V[1] v2b = V();     v2b[0].s[0].foo();
    V[1] v2c = V(s1a);  v2c[0].s[0].foo();

    static struct W { S s; this(S s){ this.s = s; } }
    W    w1a;           w1a.s.foo();
    W    w1b = W();     w1b.s.foo();
    W    w1c = W(s1a);  w1c.s.foo();
    W[1] w2a;           w2a[0].s.foo();
    W[1] w2b = W();     w2b[0].s.foo();
    W[1] w2c = W(s1a);  w2c[0].s.foo();
    static struct X { S[1] s; this(S s){ this.s[] = s; } }
    X    x1a;           x1a.s[0].foo();
    X    x1b = X();     x1b.s[0].foo();
    X    x1c = X(s1a);  x1c.s[0].foo();
    X[1] x2a;           x2a[0].s[0].foo();
    X[1] x2b = X();     x2b[0].s[0].foo();
    X[1] x2c = X(s1a);  x2c[0].s[0].foo();

    // Both declarations, Y and Z should raise errors,
    // because their ctors don't initialize their field 's'.
  static assert(!__traits(compiles, {
    static struct Y { S s; this(S){} }
  }));
/+  Y    y1a;         //y1a.s.foo();
    Y    y1b = Y();     y1b.s.foo();
    Y    y1c = Y(s1a);//y1c.s.foo();
    Y[1] y2a;         //y2a[0].s.foo();
    Y[1] y2b = Y();     y2b[0].s.foo();
    Y[1] y2c = Y(s1a);//y2c[0].s.foo();  +/
  static assert(!__traits(compiles, {
    static struct Z { S[1] s; this(S){} }
  }));
/+  Z    z1a;         //z1a.s[0].foo();
    Z    z1b = Z();     z1b.s[0].foo();
    Z    z1c = Z(s1a);//z1c.s[0].foo();
    Z[1] z2a;         //z1a.s[0].foo();
    Z[1] z2b = Z();     z1b.s[0].foo();
    Z[1] z2c = Z(s1a);//z1c.s[0].foo();  // +/
}

struct Tuple8923(int v, T...)
{
    T field;
    static if (v == 1) this(T args) { }    // should be an error
    static if (v == 2) this(T args) { field = args; }
    static if (v == 3) this(U...)(U args) { }    // should be an error
    static if (v == 4) this(U...)(U args) { field = args; }
    //alias field this;
}
void test8923b()
{
    int val;
    struct S { void foo() { val = 1; } }

  static assert(!__traits(compiles, Tuple8923!(1, S)(S()) ));
  static assert(!__traits(compiles, Tuple8923!(3, S)(S()) ));

    auto tup2 = Tuple8923!(2, S)(S());
    tup2.field[0].foo();    // correctly initialized

    auto tup4 = Tuple8923!(4, S)(S());
    tup4.field[0].foo();    // correctly initialized
}

void test8923c()
{
    int val;

    struct S  // is nested struct
    {
        void foo() { val = 1; }  // access to val through the hidden frame pointer
    }
    S    s1a;           s1a.foo();
    S    s1b = S();     s1b.foo();
    S[1] s2a;           s2a[0].foo();
    S[1] s2b = S();     s2b[0].foo();

    // U,V,W,X are nested struct, but should work same as non-nested.
    // 1: bare struct object.  2: static array of structs.
    // a: default construction.
    // b: construction by literal syntax which has no argument.
    // c: construction by literal syntax which has one or more arguments.

    struct U
    {
        S s;
        void foo() { val = 2; }
    }
    U    u1a;           u1a.foo();      u1a.s.foo();
    U    u1b = U();     u1b.foo();      u1b.s.foo();
    U    u1c = U(s1a);  u1c.foo();      u1c.s.foo();
    U[1] u2a;           u2a[0].foo();   u2a[0].s.foo();
    U[1] u2b = U();     u2b[0].foo();   u2b[0].s.foo();
    U[1] u2c = U(s1a);  u2c[0].foo();   u2c[0].s.foo();

    struct V
    {
        S[1] s;
        void foo() { val = 2; }
    }
    V    v1a;           v1a.foo();      v1a.s[0].foo();
    V    v1b = V();     v1b.foo();      v1b.s[0].foo();
    V    v1c = V(s1a);  v1c.foo();      v1c.s[0].foo();
    V[1] v2a;           v2a[0].foo();   v2a[0].s[0].foo();
    V[1] v2b = V();     v2b[0].foo();   v2b[0].s[0].foo();
    V[1] v2c = V(s1a);  v2c[0].foo();   v2c[0].s[0].foo();

    struct W
    {
        S s;
        this(S s) { this.s = s; }
        void foo() { val = 2; }
    }
    W    w1a;           w1a.foo();      w1a.s.foo();
    W    w1b = W();     w1b.foo();      w1b.s.foo();
    W    w1c = W(s1a);  w1c.foo();      w1c.s.foo();
    W[1] w2a;           w2a[0].foo();   w2a[0].s.foo();
    W[1] w2b = W();     w2b[0].foo();   w2b[0].s.foo();
    W[1] w2c = W(s1a);  w2c[0].foo();   w2c[0].s.foo();

    struct X
    {
        S[1] s;
        this(S s) { this.s[] = s; }
        void foo() { val = 2; }
    }
    X    x1a;           x1a.foo();      x1a.s[0].foo();
    X    x1b = X();     x1b.foo();      x1b.s[0].foo();
    X    x1c = X(s1a);  x1c.foo();      x1c.s[0].foo();
    X[1] x2a;           x2a[0].foo();   x2a[0].s[0].foo();
    X[1] x2b = X();     x2b[0].foo();   x2b[0].s[0].foo();
    X[1] x2c = X(s1a);  x2c[0].foo();   x2c[0].s[0].foo();

    // Both declarations, Y and Z should raise errors,
    // because their ctors don't initialize their field 's'.
  static assert(!__traits(compiles, {
    struct Y1 { S s; this(S){} void foo() { val = 2; } }
  }));
  static assert(!__traits(compiles, {
    struct Y2 { S s; this(T)(S){} void foo() { val = 2; } }
    auto y2 = Y2!S(S());    // instantiate ctor
  }));

  static assert(!__traits(compiles, {
    struct Z1 { S[1] s; this(S){} void foo() { val = 2; } }
  }));
  static assert(!__traits(compiles, {
    struct Z2 { S[1] s; this(T)(S){} void foo() { val = 2; } }
    auto z2 = Z2!S(S());    // instantiate ctor
  }));
}

/*******************************************/
// 9003

void test9003()
{
    int i;
    struct NS {
        int n1;    // Comment to pass all asserts
        int n2;    // Uncomment to fail assert on line 19
        int f() { return i; }
    }

    static struct SS1 {
        NS ns;
    }
    SS1 ss1;
    assert(ss1.ns != NS.init);

    static struct SS2 {
        NS ns1, ns2;
    }
    SS2 ss2;
    assert(ss2.ns1 != NS.init); // line 19
    assert(ss2.ns2 != NS.init);

    static struct SS3 {
        int i;
        NS ns;
    }

    SS3 ss3;
    assert(ss3.ns != NS.init);

    static struct SS4 {
        int i;
        NS ns1, ns2;
    }

    SS4 ss4;
    assert(ss4.ns1 != NS.init); // fails
    assert(ss4.ns2 != NS.init); // fails
}

/*******************************************/
// 9006

void test9006()
{
    int i;
    struct NS
    {
        int n;
        int[3] a; // Uncomment to fail assert on line 20 and pass on line 23
        int f() { return i; }
    }
    NS ns;
    assert(ns != NS.init);
    ns = NS.init;
    assert(ns == NS.init);

    static struct SS { NS ns; }
version (LDC) {} else {
    // LDC_FIXME: Need to figure out to which extent we want to emulate this
    // behavior.
    assert(SS.init.ns == NS.init); // fails
    assert(SS.init.ns != NS());    // fails
}

    SS s;
    assert(s.ns != NS.init); // line 20
    assert(s != SS.init);    // fails
    s = SS.init;
    assert(s.ns == NS.init); // line 23, fails
    assert(s == SS.init);
}

/*******************************************/
// 9035

void test9035()
{
    static struct S {}

    void f(T)(auto ref T t)
    {
        static assert(!__traits(isRef, t));
    }

    f(S.init); // ok, rvalue
    f(S());    // ok, rvalue

    int i;
    struct Nested
    {
        int j = 0; void f() { ++i; }
    }

    f(Nested());    // ok, rvalue
    f(Nested.init); // fails, lvalue

    assert(Nested.init.j == 0);
    //(ref n) { n.j = 5; }(Nested.init);
    assert(Nested.init.j == 0); // fails, j is 5
}

void test9035a()
{
    int x;
    struct S {
        // no field
        void foo() { x = 1; }
    }
    S s1;
    S s2 = S();
    assert(s1  != S.init);  // OK
    assert(s2  != S.init);  // OK
    assert(S() != S.init);  // NG -> OK
}

/*******************************************/
// 9036

void test9036()
{
    static int i;
    static struct S
    {
        this(this) { ++i; }
    }

    S s = S.init;
    assert(i == 0); // postblit not called
    s = S.init;
    assert(i == 0); // postblit not called

    int k;
    static int j = 0;
    struct N
    {
        this(this)
        {
            ++j;
            assert(this.tupleof[$-1] != null); // fails
        }
        void f() { ++k; }
    }

    N n = N.init;
    assert(j == 0); // fails, j = 1, postblit called
    n = N.init;
    assert(j == 0); // fails, j = 2, postblit called
}

/*******************************************/

/+
auto fun8863(T)(T* ret) { *ret = T(); }

void test8863()
{
    int x = 1;
    struct A
    {
        auto f()
        {
            assert(x == 1);
        }
    }

    A a;
    a.f();
    fun8863!A(&a);
    a.f();
}
+/

/*******************************************/
// 8774

void popFront8774()
{
    int[20] abc;    // smash stack
}

struct MapResult8774(alias fun)
{
    void delegate() front()
    {
        return fun(1);
    }
}

void test8774() {

    int sliceSize = 100;

    void delegate() foo( int i )
    {
        void delegate() closedPartialSum()
        {
            int ii = i ;
            void bar()
            {
                printf("%d\n", sliceSize);
                assert(sliceSize == 100);
            }
            return &bar;
        }
        return closedPartialSum();
    }

    auto threads = MapResult8774!foo();

    auto dg = threads.front();
    popFront8774();

    printf("calling dg()\n");
    dg();
}

/*******************************************/

int Bug8832(alias X)()
{
    return X();
}

int delegate() foo8832()
{
  int stack;
  int heap = 3;

  int nested_func()
  {
    ++heap;
    return heap;
  }
  return delegate int() { return Bug8832!(nested_func); };
}

void test8832()
{
  auto z = foo8832();
  auto p = foo8832();
  assert(z() == 4);
  p();
  assert(z() == 5);
}

/*******************************************/
// 9315

auto test9315()
{
    struct S
    {
        int i;
        void bar() {}
    }
    pragma(msg, S.init.tupleof[$-1]);
}

/*******************************************/
// 9244

void test9244()
{
    union U {
        int i;
        @safe int x() { return i; }
    }
}

/*******************************************/
// 10495

struct X10495
{
    @disable this();
}

struct Y10495(alias f)
{
    void g() {}
}

class C10495
{
    X10495 s = X10495.init;

    void h()
    {
        Y10495!(a => a) st;
    }
}

/*******************************************/
// 11385

auto map11385(alias fun, R)(R range)
{
    return MapResult11385!(fun, R)(range);
}
struct MapResult11385(alias fun, R)
{
    R range;
    auto front() { return fun(range[0]); }
}
void test11385()
{
    //import std.algorithm;
    static auto fun1(T)(T a) { return a * 2; }
           auto fun2(T)(T a) { return a * 2; }
    [1].map11385!(a=>fun1(a));   // OK
    [1].map11385!(a=>fun2(a));   // NG:XXX is a nested function and cannot be accessed from XXX
}

/*******************************************/

void xmap(alias g)(int t)
{
    g(t);
}

enum foo11297 = function (int x)
   {
        //int bar(int y) { return x; } xmap!bar(7);
        xmap!(y => x)(7);
   };

void xreduce(alias f)()
{
    f(4);
}

void test11297()
{
    xreduce!foo11297();
}

/*******************************************/
// 11886

struct Lambda11886(alias fun)
{
    auto opCall(A...)(A args) { return fun(args); }
}
void test11886()
{
    int n = 10;
    Lambda11886!(x => x + n) f;
    assert(f(1) == 11); // Line 9

    struct NS
    {
        auto foo(T)(T t) { return t * n; }
    }
    static assert(NS.tupleof.length == 1);
    static assert(NS.sizeof == (void*).sizeof);
    NS ns;
    assert(ns.foo(2) == 20);
}

/*******************************************/
// 12234

void test12234()
{
    class B
    {
        int a;
        this(int aa) { a = aa; }
    }
    auto foo = {
        return new B(1);
    };
    static assert(is(typeof(foo) == delegate));

    auto b = foo();
    assert(b.a == 1);
}

/*******************************************/
// 12981

template Mix12981(T)
{
    class A
    {
        alias typeof(this.outer) x;
    }
}

class B12981
{
    mixin Mix12981!(int);

    static assert(is(A.x == B12981));
}

/*******************************************/
// 13861

struct Foo13861(alias f)
{
    struct Bar
    {
        Bar func()
        {
            return Bar();   // OK <- Segfault
        }
    }
}

void test13861()
{
    Foo13861!(n => n) a;
}

/*******************************************/
// 14398

void test14398()
{
    int outer;

    struct Inner
    {
        this(this)
        {
            outer += 42;
        }
    }

    struct Outer
    {
        Inner inner;

        this(int dummy)
        {
            inner = Inner();

            // hidden fields correctly set
            assert(this.tupleof[$-1] !is null);
            assert(inner.tupleof[$-1] !is null);
        }
    }

    Outer[1] arr1 = [Outer(0)];
    assert(outer == 0);     // no postblit called on arr1 construction
    auto arr2 = arr1;
    assert(outer == 42);    // inner is copied successfully
}

/*******************************************/
// 14846

void foo14846(Dg)(scope Dg code)
{
    static assert(is(Dg == delegate));
    code();
}

void test14846()
{
    int x;

    struct S
    {
        this(int n) { x = n; }
        ~this() { x = 99; }
    }

    foo14846({ S s; });
    foo14846({ S s = S(); });
    foo14846({ S s = S(1); });
    foo14846({ S[3] s; });

    foo14846({ S* p = new S(); });
    foo14846({ S* p = new S(1); });
    foo14846({ S[] a = [S()]; });
    foo14846({ S[] a = [S(1)]; });
}

/*******************************************/
// 15422

class App15422(T)
{
    this() {}

    auto test1(T val)
    in {} body      // necessary to reproduce the crash
    {
        struct Foo
        {
            this(int k) {}
            T a;
        }

        Foo foo;
        foo.a = val;

        // Frame of test2 function, allocated on heap.
        assert(foo.tupleof[$-1] !is null);

        //printf("&foo = %p\n", &foo);                  // stack
        //printf("&this = %p\n", &this);                // stack?
        //printf("foo.vthis = %p\n", foo.tupleof[$-1]); // stack...!?
        //assert(cast(void*)&this !is *cast(void**)&foo.tupleof[$-1], "bad");
        // BUG: currently foo.vthis set to the address of 'this' variable on the stack.
        // It's should be stomped to null, because Foo.vthis is never be used.

        int[Foo] map;
        map[foo] = 1;   // OK <- crash

        return foo;
    }

    auto test2(T val)
    //in {} body
    {
        int closVar;
        struct Foo
        {
            this(int k) { closVar = k; }
            // Make val a closure variable.

            T a;
        }

        Foo foo;
        foo.a = val;

        // Frame of test2 function, allocated on heap.
        assert(foo.tupleof[$-1] !is null);

        return foo;
    }
}

void test15422a()
{
    alias App = App15422!int;
    App app1 = new App;
    {
        auto x = app1.test1(1);
        auto y = app1.test1(1);
        static assert(is(typeof(x) == typeof(y)));

        // int (bitwise comparison)
        assert(x.a == y.a);

        assert(*cast(void**)&x.tupleof[$-1] is *cast(void**)&y.tupleof[$-1]);

        // bitwise equality (needOpEquals() and needToHash() returns false)
        assert(x == y);

        // BUG
        //assert(*cast(void**)&x.tupleof[$-1] is null);
        //assert(*cast(void**)&y.tupleof[$-1] is null);
        auto getZ() { auto z = app1.test1(1); return z; }
        auto z = getZ();
        assert(x.a == z.a);
        //assert(x.tupleof[$-1] is z.tupleof[$-1]);   // should pass
        //assert(x == z);                             // should pass

        x = y;  // OK, x.tupleof[$-1] = y.tupleof[$-1] is a blit copy.
    }
    App app2 = new App;
    {
        auto x = app1.test2(1);
        auto y = app2.test2(1);
        static assert(is(typeof(x) == typeof(y)));

        // int (bitwise comparison)
        assert(x.a == y.a);

        // closure envirionments
        assert(*cast(void**)&x.tupleof[$-1] !is *cast(void**)&y.tupleof[$-1]);

        // Changed to bitwise equality (needOpEquals() and needToHash() returns false)
        assert(x != y);         // OK <- crash

        x = y;  // OK, x.tupleof[$-1] = y.tupleof[$-1] is a blit copy.
    }
}

void test15422b()
{
    alias App = App15422!string;
    App app1 = new App;
    {
        auto x = app1.test1("a".idup);
        auto y = app1.test1("a".idup);
        static assert(is(typeof(x) == typeof(y)));

        // string (element-wise comparison)
        assert(x.a == y.a);

        assert(*cast(void**)&x.tupleof[$-1] is *cast(void**)&y.tupleof[$-1]);

        // memberwise equality (needToHash() returns true)
        assert(x == y);
        // Lowered to: x.a == y.a && x.tupleof[$-1] is y.tupleof[$-1]

        // BUG
        //assert(*cast(void**)&x.tupleof[$-1] is null);
        //assert(*cast(void**)&y.tupleof[$-1] is null);
        auto getZ() { auto z = app1.test1("a".idup); return z; }
        auto z = getZ();
        assert(x.a == z.a);
        //assert(x.tupleof[$-1] is z.tupleof[$-1]);   // should pass
        //assert(x == z);                             // should pass

        x = y;  // OK, x.tupleof[$-1] = y.tupleof[$-1] is a blit copy.
    }
    App app2 = new App;
    {
        auto x = app1.test2("a".idup);
        auto y = app2.test2("a".idup);
        static assert(is(typeof(x) == typeof(y)));

        // string (element-wise comparison)
        assert(x.a == y.a);

        // closure envirionments
        assert(*cast(void**)&x.tupleof[$-1] !is *cast(void**)&y.tupleof[$-1]);

        // Changed to memberwise equality (needToHash() returns true)
        // Lowered to: x.a == y.a && x.tupleof[$-1] is y.tupleof[$-1]
        assert(x != y);         // OK <- crash

        x = y;  // OK, x.tupleof[$-1] = y.tupleof[$-1] is a blit copy.
    }
}

/***************************************************/
// 15757

template map15757(fun...)
{
    auto map15757(R)(R r)
    {
        return MapResult15757!(fun, R)(r);
    }
}

struct MapResult15757(alias fun, R)
{
    R _input;

    this(R input)
    {
        _input = input;
    }
}

void wrap15757(R)(R r)
{
    struct M(R)
    {
        this(R r)
        {
            payload = r;
        }
        R payload;
    }

    M!R m = M!R(r);
}

void test15757() @safe
{
    [1,2,3].map15757!(x => x*x).wrap15757;
}

/***************************************************/

int main()
{
    test1();
    test2();
    test3();
    test4();
    test5();
    test6();
    test7();
    test8();
    test9();
    test10();
    test11();
    test12();
    test13();
    test14();
    test15();
    test16();
    test17();
    test18();
    test19();
    test20();
    test21();
    test22();
    test23();
    test24();
    test25();
    test26();
    test27();
    test28();
    test29();
    test30();
    test31();
    test32();
    test33();
    test34();
    test35();
    test36();
    test37();
    test38();
    test39();
    test40();
    test41();
    test42();
    test43();
    test44();
    test45();
    test46();
    test47();
    test48();
    test49();
    test50();
    test51();
    test52();
    test53();
    test54();
    test55();
    test4401();
    test7428();
    test4612();
    test4841();
    test7199();
    test7965();
    test7965a();
    test8188();

    test5082();
    test8194();
    test8339a();
    test8339b();
    test8339c();
    test8923a();
    test8923b();
    test8923c();
    test9003();
    test9006();
    test9035();
    test9035a();
    test9036();
//    test8863();
    test8774();
    test8832();
    test9315();
    test9244();
    test11385();
    test11297();
    test11886();
    test12234();
    test13861();
    test14398();
    test14846();
    test15422a();
    test15422b();
    test15757();

    printf("Success\n");
    return 0;
}
