Once an accessor macro has produced accessors, parse them and wire them
into the AST so the rest of the compiler will see them. First
end-to-end test case!
Establish the relationship for generated sources, whether for macro
expansions or (via a small stretch) replacing function bodies with
other bodies, in the source manager itself. This makes the information
available for diagnostic rendering, and unifies a little bit of the
representation, although it isn't used for much yet.
`getValue` -> `value`
`getValueOr` -> `value_or`
`hasValue` -> `has_value`
`map` -> `transform`
The old API will be deprecated in the rebranch.
To avoid merge conflicts, use the new API already in the main branch.
rdar://102362022
getPotentiallyOpaqueGenericParams has a redundant call to check if
declarations contain any opaque type representations. We don't need
to check this here. Instead we can simply collect the result type
representaions without the additional checks.
Although the declaration of macros doesn't appear in Swift source code
that uses macros, they still operate as declarations within the
language. Rework `Macro` as `MacroDecl`, a generic value declaration,
which appropriate models its place in the language.
The vast majority of this change is in extending all of the various
switches on declaration kinds to account for macros.
Teach ASTScope how to reason about macro expansions. When we create an
ASTScope for a source file that represents a macro expansion, its
parent scope node is the macro expansion itself. When performing
unqualified lookup (of any form), find the starting source file based
on the location, not on the source file provided---this ensures that
we start lookups within the macro expansion (for example).
The effect of this is to enable macro expansions to work in nested
contexts, where they refer to names in the scope in which the macro is
expanded.
This is decidedly unhiegenic, but it fits with our syntactic model.
In the Swift grammar, the top-level of a source file is a mix of three
different kinds of "items": declarations, statements, and expressions.
However, the existing parser forces all of these into declarations at
parse time, wrapping statements and expressions in TopLevelCodeDecls,
so the primary API for getting the top-level entities in source files
is based on getting declarations.
Start generalizing the representation by storing ASTNode instances at
the top level, rather than declaration pointers, updating many (but
not all!) uses of this API. The walk over declarations is a (cached)
filter to pick out all of the declarations. Existing parsed files are
unaffected (the parser still creates top-level code declarations), but
the new "macro expansion" source file kind skips creating top-level
code declarations so we get the pure parse tree. Additionally, some
generalized clients (like ASTScope lookup) will now look at the list
of items, so they'll be able to walk into statements and expressions
without the intervening TopLevelCodeDecl.
Over time, I'd like to phase out `getTopLevelDecls()` entirely,
relying on the new `getTopLevelItems()` for parsed content. We can
introduce TopLevelCodeDecls more lazily for semantic walks.
Introduce `MacroExpansionExpr` and `MacroExpansionDecl` and plumb it through. Parse them in roughly the same way we parse `ObjectLiteralExpr`.
The syntax is gated under `-enable-experimental-feature Macros`.
Replace the use of bool and pointer returns for
`walkToXXXPre`/`walkToXXXPost`, and instead use
explicit actions such as `Action::Continue(E)`,
`Action::SkipChildren(E)`, and `Action::Stop()`.
There are also conditional variants, e.g
`Action::SkipChildrenIf`, `Action::VisitChildrenIf`,
and `Action::StopIf`.
There is still more work that can be done here, in
particular:
- SourceEntityWalker still needs to be migrated.
- Some uses of `return false` in pre-visitation
methods can likely now be replaced by
`Action::Stop`.
- We still use bool and pointer returns internally
within the ASTWalker traversal, which could likely
be improved.
But I'm leaving those as future work for now as
this patch is already large enough.
Introduce the compiler directive `#_hasSymbol` which will be used to detect whether weakly linked symbols are present at runtime. It is intended for use in combination with `@_weakLinked import` or `-weak-link-at-target`.
```
if #_hasSymbol(foo(_:)) {
foo(42)
}
```
Parsing only; SILGen is coming in a later commit.
Resolves rdar://99342017
Address small gaps in several places to make named opaque result types
partially work:
* Augment name lookup to look into the generic parameters when inside the
result type, which is used both to create structure and add requirements
via a `where` clause.
* Resolve opaque generic type parameter references to
OpaqueTypeArchetypeType instances, as we do for the "some" types
* Customize some opaque-type-specific diagnostics and type printing to
refer to the opaque generic parameter names specifically
* Fix some minor issues with the constraint system not finding
already-opened opaque generic type parameters and with the handling of
the opaque result type candidate set.
The major limitation on opaque types, where we cannot add requirements
that aren't strictly protocol or superclass requirements on the
generic parameters, remains. Until then, named opaque result types are
no more expressive than structural opaque result types.
Many, many, many types in the Swift compiler are intended to only be allocated in the ASTContext. We have previously implemented this by writing several `operator new` and `operator delete` implementations into these types. Factor those out into a new base class instead.
When LLDB wraps a user-defined expression in the REPL, it takes something like this
```
<expr>
```
and turns it into (very very abstractly)
```
var result
do {
result = <expr>
}
print(result)
```
In the process, it creates an implicit pattern binding and an implicit do block. Of these, only the implicit do is considered by ASTScope lookup to be relevant. This presents a problem when <expr> is or contains a closure, as the parameters of that closure are defined within a scope that will never be expanded. Thus,
```
> [42].map { x in x } // <- cannot find 'x' in scope
```
This patch provides the Swift half of the fix wherein we privilege pattern bindings created by the debugger and look through them to the underlying user expression when performing ASTScope expansion.
rdar://78256873
ASTScope only cares about attributes when lookup can be done inside of the
attribute, which isn't the case for implicit attributes because they're
typically built fully type-checked. This also avoids a crash when an
implicit attribute does not have a source range.
If a static variable can be evaluated at compile time, create an
accessor using that value. This means static variables will always be
inlined and removed.
Note: currently this only works with numeric types.
Combine the wasExpanded flag with the parent pointer, and remove
the haveAddedCleanup flag since it's no longer necessary now that
"re-expansion" is gone.
This doesn't really fit the request evaluator model since the
result of evaluating the request is the new insertion point,
but we don't have a way to get the insertion point of an
already-expanded scope.
Instead, let's change the callers of the now-removed
expandAndBeCurrentDetectingRecursion() to instead call
expandAndBeCurrent(), while checking first if the scope was
already expanded.
Also, set the expanded flag before calling expandSpecifically()
from inside expandAndBeCurrent(), to ensure that re-entrant
calls to expandAndBeCurrent() are flagged by the existing
assertion there.
Finally, replace a couple of existing counters, and the
now-gone request counter with a single ASTScopeExpansions
counter to track expansions.
We would get confused if we saw a PatternBindingDecl where
one entry introduced a binding, and the other did not.
Thanks to @DougGregor for the test case!
Scopes need to register cleanups for non-trivial ivars in the ASTContext.
Instead of doing that here, let's just change the SmallVectors into
ArrayRefs.
Fixes <rdar://problem/69908937>.
The top-level scope for a conditional clause with a pattern is now
ConditionalClausePatternUseScope, which introduces the pattern's
bindings.
Since the patterns are not visible in their own initializer, a new
ConditionalClauseInitializerScope is used for the initializer.
While it is nested inside of the ConditionalClausePatternUseScope,
it's lookup parent skips one level, giving us the desired behavior.
Today, the reported source range of a GuardStmtScope is just that of
the statement itself, ending after the 'else' block. Similarly, a
PatternEntryDeclScope ends immediately after the initializer
expression.
Since these scopes introduce names until the end of the parent
BraceStmt (meaning they change the insertion point), we were
relying on the addition of child scopes to extend the source
range.
While we still need the hack for extending source ranges to deal
with string interpolation, at least in the other cases we can
get rid of it.
Note that this fixes a bug where a GuardStmtScope would end
before an inactive '#if' block if the inactive '#if' block was
the last element of a BraceStmt.
The old behavior was that ASTScope would introduce all VarDecls
defined in a BraceStmt at the beginning of the BraceStmt.
I recently enabled the use of PatternEntryDeclScopes, which
introduce the binding at its actual source location instead of
at the beginning of the parent statement.
This patch now makes use of the new information by having
UnqualifiedLookupFlags::IncludeOuterResults toggle between
the two behaviors. When searching for outer results, we also
consider all VarDecls in a BraceStmt, not just those in scope.
This is implemented by giving AbstractASTScopeDeclConsumer a
new entry point, consumePossiblyNotInScope(). When looking up
into a BraceStmt, all VarDecls are passed in to this entry
point.
The default implementation does nothing, which means that
ASTScope::lookupSingleLocalDecl() now respects source locations
when searching for bindings, just like parse-time lookup.
However, Sema's preCheckExpression() pass, which sets
Flags::IgnoreOuterResults, will continue to find
forward-referenced VarDecls, just as it did with the old
context-based DeclContext lookup.
This gives us the desired behavior, where local bindings are in
scope after their definition.
Note that BraceStmt still introduces all bindings at the beginning,
but now we change BraceStmt to only introduce local functions and
types, allowing us to disable parse-time lookup.