June 16, 2023

I'm not sure if this behavior is desired and have any use-cases (should I report it as a bug?), but, for example, C# doesn't allow this.

import std.conv;

class Outer {
    private static class Inner {
        private int field = 30;
        override string toString() => to!string(field);
    }
    static Inner getInner() {
        return new Inner();
    }
}
import std.stdio: writeln;
import classes; // the file above

void main() {
    // Here I have an object of "some" type (B class cannot be
    // accessed) and can even do something with it!
    auto b = Outer.getInner();
    writeln(b); // 30
}

Same program in C# (private members are accessible only within their class):

using System;

public class Program {
    class Outer {
        private class Inner {
            private int field = 30;
            public override string ToString() => field.ToString();
        }
        // Error: Inconsistent accessibility: return type 'Program.Outer.Inner'
        // is less accessible than method 'Program.Outer.getInner()'
        public static Inner getInner() {
            return new Inner();
        }
    }
	
    public static void Main() {
        var b = Outer.getInner();
        Console.WriteLine(b);
    }
}