<div dir="ltr">Hi evolution community,<div><br></div><div>I would like to propose &quot;Scoped @available&quot; attribute.</div><div><br></div><div>What I want to achieve is to declare something that is publicly unavailable, but still usable from narrower scope. A concrete example is <font face="monospace, monospace">IndexableBase</font> in the standard library:</div><div><div><a href="https://github.com/apple/swift/blob/master/stdlib/public/core/Collection.swift#L18-L20" target="_blank">https://github.com/apple/<wbr>swift/blob/master/stdlib/<wbr>public/core/Collection.swift#<wbr>L18-L20</a><br></div><div>Workaround for this problem in stdlib is to use <font face="monospace, monospace">typealias</font> to underscored declaration. However, we can&#39;t use this technique in our module because underscored declarations are still visible and usable from outside.</div><div><br></div></div><div>As a solution, I propose to add <font face="monospace, monospace">&quot;access&quot;</font> parameter to <font face="monospace, monospace">@available</font> attribute, which limits the effect of <font face="monospace, monospace">@available</font> attribute to the specified value or outer.<br><br></div><div>---</div><div><font face="monospace, monospace">// Module: Library<br><br>/// This protocol is available for internal, but deprecated for public.<br>@available(*, deprecated, access: public, message: &quot;it will be </font><span style="font-family:monospace,monospace">removed</span><font face="monospace, monospace"> in future&quot;)<br>public protocol OldProtocol {<br>    /* ... */<br>}<br><br>public Foo: OldProtocol { // No diagnostics<br>}</font></div><div><font face="monospace, monospace"><br></font><div>---</div><font face="monospace, monospace">// Module: main</font></div><div><font face="monospace, monospace"><br>import Library<br><br>public Bar: OldProtocol { // warning: &#39;OldProtocol&#39; is deprecated: it will be removed in future<br>}</font></div><div><font face="monospace, monospace"><br></font></div><div><div>---</div></div><div><br></div><div>I think this is useful when you want to stop exposing declarations, but want to keep using them internally.</div><div><br></div><div>More examples:</div><div><br></div><div><font face="monospace, monospace">// is `open`, going to be `filerprivate`</font></div><div><font face="monospace, monospace">@available(*, deprecated, access: internal)</font></div><div><font face="monospace, monospace">open class Foo {}</font></div><div><font face="monospace, monospace"><br></font></div><div><div><font face="monospace, monospace">// was `internal`, now `private`</font></div><div><font face="monospace, monospace">@available(*, unavailable, access: fileprivate)</font></div><div><font face="monospace, monospace">var value: Int</font></div><div><font face="monospace, monospace"><br></font></div></div><div><font face="monospace, monospace">// No effect (invisible from public anyway): emit a warning</font></div><div><div><font face="monospace, monospace">@available(*, unavailable, access: public)</font></div><div><font face="monospace, monospace">internal struct Foo {}</font></div></div><div><br></div><div>What do you think?</div></div>