We break name lookup circularities by special-casing validation of
type aliases, resolving the underlying type of the type alias before
building the generic environment of the protocol that contains the
type alias.
However doing this gives the type alias an underlying type written
in terms of unresolved DependentMemberTypes which do not map to
associated types.
Attempting to substitute such a type fails.
We worked around this by re-validating type alias members of
protocols when we finally got around to building the protocol's
generic environment. Force this to happen earlier in
substMemberTypeWithBase(), because we need the fully resolved
underlying type in order to perform the substitution.
Also, fix TypeAliasDecl::setUnderlyingType() to only create a new
NameAliasType the first time it is called. In this special case
where it can be called twice with a resolved underlying type the
second time, we should not be creating a new NameAliasType.
There are better fixes possible here, requiring various levels
of refactoring. I'll investigate this soon, but for now this narrow
fix should address the problem with minimal risk.
Fixes <rdar://problem/33189068>.
Also, begin to pass around base types instead of raw InOutType types. Ideally, only Sema needs to deal with them, but this means that a bunch of callers need to unwrap any inouts that might still be lying around before forming these types.
Multiple parts of the compiler were slicing, dicing, or just dropping these flags. Because I intend to use them for the new function type representation, I need them to be preserved all across the compiler. As a first pass, this stubs in what will eventually be structural rules as asserts and tracks down all callers of consequence to conform to the new invariants.
This is temporary.
Use ArchetypeResolutionKind::CompleteWellFormed whenever we need to
ask questions about the potential archetype, and
ArchetypeResolutionKind::WellFormed when we need only evaluate whether
there is a legitimate type with that name (and possibly get a handle
to it).
In anticipation of future attributes, and perhaps the ability to
declare lvalues with specifiers other than 'let' and 'var', expand
the "isLet" bit into a more general "specifier" field.
The outside representation already went to a flat set of requirements;
make the internal representation match so we aren't tempted to use the
requirement signature as inputs to a generic signature.
Rather than pretend that the requirement signature of a protocol is a
full, well-formed generic signature that one can meaningfully query,
treat it as a flat set of requirements. Nearly all clients already did
this, but make it official. NFC
Using the attribute in this position is a relic from the Swift 2
days, and fixing it required letting invalid code fall through to
Sema instead of being diagnosed in Parse proper. Treat 'var'
in this position like 'let' by simply offering to remove it
instead of extracting it into a separate variable.
- A mutating method or accessor always has 'inout self'.
- A nonmutating method or accessor never has 'inout self'.
- Only instance members can be mutating.
- Addressors are still addressors even when on static members.
Came up after reviewing another patch that confused the two as
possibly distinct concepts.
We allow protocols to inherit from protocol compositions
defined via a typealias, eg,
typealias PQ = P & Q
protocol R : PQ {}
Sometimes, ProtocolDecl::getInheritedProtocols() is called before
the protocol's requirement signature has been computed. In this
case, we walk the inheritance clause of the protocol directly.
This walk was only looking at ProtocolType members of the
inheritance clause, ignoring ProtocolCompositionTypes.
As a result, name lookup could fail with an assertion because of
not being able to "see" members inherited via the protocol
composition.
Fixes <rdar://problem/32595988>.
The -enable-testing flag makes ValueDecl::getEffectiveAccess()
say that internal declarations are public.
This would lead us to emit spurious diagnostics if a default
argument of an internal function referenced a private symbol,
for example, which is something we actually want to allow.
This is a second revision of the patch -- instead of changing
getEffectiveAccess() to take an extra parameter, this changes
getFormalAccessScope() instead.
Fixes <rdar://problem/32592973>.
The -enable-testing flag makes ValueDecl::getEffectiveAccess()
say that internal declarations are public.
This would lead us to emit spurious diagnostics if a default
argument of an internal function referenced a private symbol,
for example, which is something we actually want to allow.
Hack around this by adding a new 'forLinkage' parameter to
getEffectiveAccess(). When this is false, we ignore the
-enable-testing flag, and only look for the @_versioned
attribute.
I'm not very happy with the fix, because it only compliates
the subtle behaviors of getFormalAccess(), getEffectiveAccess()
and getFormalAccessScope() further. But refactoring this is
a bigger change than I'm willing to put into swift-4.0-branch.
Fixes <rdar://problem/32592973>.
This is accomplished by recognizing this specific situation and
replacing the 'objc' attribute with a hidden '_objcRuntimeName'
attribute. This /only/ applies to classes that are themselves
non-generic (including any enclosing generic context) but that have
generic ancestry, and thus cannot be exposed directly to Objective-C.
This commit also eliminates '@NSKeyedArchiverClassName'. It was
decided that the distinction between '@NSKeyedArchiverClassName' and
'@objc' was too subtle to be worth explaining to developers, and that
any case where you'd use '@NSKeyedArchiverClassName' was already a
place where the ObjC name wasn't visible at compile time.
This commit does not update diagnostics to reflect this change; we're
going to change them anyway.
rdar://problem/32414557
Potential archetypes can resolve to either an associated type or a
typealias. Generalize the latter to "any concrete type", both because
the current implementation is unnecessarily narrow (typealiases aren't
actually special in this regard) and to get us closer to handling
lookups via superclass constraints when resolving these types.
With the introduction of special decl names, `Identifier getName()` on
`ValueDecl` will be removed and pushed down to nominal declarations
whose name is guaranteed not to be special. Prepare for this by calling
to `DeclBaseName getBaseName()` instead where appropriate.
This changes `getBaseName()` on `DeclName` to return a `DeclBaseName`
instead of an `Identifier`. All places that will continue to be
expecting an `Identifier` are changed to call `getBaseIdentifier` which
will later assert that the `DeclName` is actually backed by an
identifier and not a special name.
For transitional purposes, a conversion operator from `DeclBaseName` to
`Identifier` has been added that will be removed again once migration
to DeclBaseName has been completed in other parts of the compiler.
Unify approach to printing declaration names
Printing a declaration's name using `<<` and `getBaseName()` is be
independent of the return type of `getBaseName()` which will change in
the future from `Identifier` to `DeclBaseName`