This is currently allowed and I don't understand why. Am I missing something? If one cannot refer to the type itself, then members cannot be accessed anyway - wouldn't it make sense to make this an error?
IIRC this is by design. I don't remember why, but I can guess that if you already providing an access modifier explicitly, it will behave as intended if you change the access level of the type to public for example.
From what I can remember, I think the design reasoning was that it helps a code author transition a type from private to internal to public. They can essentially write out what properties and methods are allowed to be public upfront before committing to actually making the type public.
If this wasn't allowed, the visibility of all the properties of a type would have to be changed as the visibility of the scope changes, causing quite a lot of code churn.
That seems like sacrificing clarity now for some potential benefit in the future. So far I've never wanted to do this and only encountered it in code review when a type was actually transitioning from public to internal.
This would also be a crucial feature for public subclasses with "hidden" ancestors.
We can't do that now, but especially since we also don't have abstract classes, I think this would be a valuable addition.
The more pragmatic reason that prompted this design in the first place is that, for a private type, it is impossible to spell the same level of access for its own members, because private inside a scope is less than private of the containing scope.
private /* == fileprivate */ struct A {
fileprivate let x: Int = 42
private /* < fileprivate */ struct B {
/* ??? */ let y: Int = 42
}
}