We had two predicates that were used to determine whether the default
argument for a wrapped property in the memberwise initializer would be
of the wrapper type (e.g., Lazy<Int>) vs. the wrapped type
(Int). Those two predicates could disagree, causing a SILGen assertion
and crash. Collapse the two predicates into one correct one,
fixing rdar://problem/57545381.
Complete the refactoring by splitting the semantic callers for the original decl of a dynamically replaced declaration.
There's also a change to the way this attribute is validated and placed. The old model visited the attribute on any functions and variable declarations it encountered in the primary. Once there, it would strip the attribute off of variables and attach the corresponding attribute to each parsed accessor, then perform some additional ObjC-related validation.
The new approach instead leaves the attribute alone. The request exists specifically to perform the lookups and type matching required to find replaced decls, and the attribute visitor no longer needs to worry about revisiting decls it has just grafted attributes onto. This also means that a bunch of parts of IRGen and SILGen that needed to fan out to the accessors to ask for the @_dynamicReplacement attribute to undo the work the type checker had done can just look at the storage itself. Further, syntactic requests for the attribute will now consistently succeed, where before they would fail dependending on whether or not the type checker had run - which was generally not an issue by the time we hit SIL.
Add DynamicallyReplacedDeclRequest to ValueDecl and plumb the request through to TypeCheckAttr where it replaces TypeChecker::findReplacedDynamicFunction.
The computation for "is explicitly initialized" on a pattern binding
entry didn't account for explicit initialization via the property
wrapper (e.g. @Wrapper(closure: { ... })), which lead to a crash for
properties with optional type. Fixes rdar://problem/57411331.
When an original module name is specified via @_originalDefinedIn attribute, we need to
use the original module name for all related runtime symbol names instead of the current
module names.
rdar://55268186
This commit changes how we represent caller-side
default arguments within the AST. Instead of
directly inserting them into the call-site, use
a DefaultArgumentExpr to refer to them indirectly.
The main goal of this change is to make it such
that the expression type-checker no longer cares
about the difference between caller-side and
callee-side default arguments. In particular, it
no longer cares about whether a caller-side
default argument is well-formed when type-checking
an apply. This is important because any
conversions introduced by the default argument
shouldn't affect the score of the resulting
solution.
Instead, caller-side defaults are now lazily
type-checked when we want to emit them in SILGen.
This is done through introducing a request, and
adjusting the logic in SILGen to be more lenient
with ErrorExprs. Caller-side defaults in primary
files are still also currently checked as a part
of the declaration by `checkDefaultArguments`.
Resolves SR-11085.
Resolves rdar://problem/56144412.
This commit introduces a request to type-check a
default argument expression and splits
`getDefaultValue` into 2 accessors:
- `getStructuralDefaultExpr` which retrieves the
potentially un-type-checked default argument
expression.
- `getTypeCheckedDefaultExpr` which retrieves a
fully type-checked default argument expression.
In addition, this commit adds `hasDefaultExpr`,
which allows checking for a default expr without
kicking off a request.
This commit adds a request that computes
the initializer context for a parameter with a
default expr or stored property default.
This avoids having to compute them for synthesized
decls and is a step towards requestifying default
argument parsing.
When SE-110 was being implemented, we accidentally began to accept
closure parameter declarations that had no associated parameter names,
e.g.
foo { ([Int]) in /**/ }
This syntax has never been sanctioned by any version of Swift and should
be banned. However, the change was made long enough ago and there are
enough clients relying on this, that we cannot accept the source break
at the moment. For now, add a bit to ParamDecl that marks a parameter
as destructured, and back out setting the invalid bit on the type repr
for these kinds of declarations.
To prevent further spread of this syntax, stub in a warning that offers
to insert an anonymous parameter.
Resolves part of rdar://56673657 and improves QoI for errors like
rdar://56911630
This is just for prototyping purposes. I also had to loosen a small restriction
where semantics functions were not allowed in local contexts. There really is no
reason to enforce this and I think since it came in the first commit that
introduced semanitcs it was most likely NadavR just being conservative and
careful.
Witness matching is a source of a lot of ad-hoc cycles, and mixes the
logic that performs resolution, caching, validation, and cycle detection into one
place. To make matters worse, some checkers kick off other checks in
order to cache work for further declarations, and access an internal
cache on their subject conformance for many requirements at once, or
sometimes just one requirement.
None of this fits into the request evaluator's central view of the
caching. This is further evidenced by the fact that if you attempt to
move the caching step into the evaluator, it overcaches the same
witness and trips asserts.
As a start, define requests for the resolution steps, and flush some
hacks around forcing witness resolution. The caching logic is mostly
untouched (the requests don't actually cache anything), but some cycle
breaking is now handled in the evaluator itself. Once witness matching
has been refactored to cache with the evaluator, all of these hacks can
go away.
My urge to destroy the LazyResolver outweighs the compromises here.
Codable's deep magic currently forces conformance checks in the middle
of name lookup in order to inject CodingKeys into lookup results. This
is compounded by the fact that this lookup fixup is occuring
incrementally, meaning depending on order of requirements being looked
up, Decl::getMembers() will give you a different answer.
Compounding this, NameLookup relied on the LazyResolver to formalize
this layering violation, and relied on implicit laziness to guard
against re-entrancy.
The approach is multi-pronged:
1) Shift the layering violation into the request evaluator
2) Spell out the kinds of resolution we support explicitly (make them
easier to find and kill)
3) Remove the LazyResolver entrypoint this was relying on
4) Split off the property wrappers part into its own utility
These include memberwise initializers for pointer properties and enum
case constructors for pointer payloads. In both cases, the pointer is
being immediately escaped, so don't allow the user to pass a temporary
pointer value.
This non-user-facing attribute is used to denote pointer parameters
which do not accept pointers produced from temporary pointer conversions
such as array-to-pointer, string-to-pointer, and in some cases
inout-to-pointer.
By convention, most structs and classes in the Swift compiler include a `dump()` method which prints debugging information. This method is meant to be called only from the debugger, but this means they’re often unused and may be eliminated from optimized binaries. On the other hand, some parts of the compiler call `dump()` methods directly despite them being intended as a pure debugging aid. clang supports attributes which can be used to avoid these problems, but they’re used very inconsistently across the compiler.
This commit adds `SWIFT_DEBUG_DUMP` and `SWIFT_DEBUG_DUMPER(<name>(<params>))` macros to declare `dump()` methods with the appropriate set of attributes and adopts this macro throughout the frontend. It does not pervasively adopt this macro in SILGen, SILOptimizer, or IRGen; these components use `dump()` methods in a different way where they’re frequently called from debugging code. Nor does it adopt it in runtime components like swiftRuntime and swiftReflection, because I’m a bit worried about size.
Despite the large number of files and lines affected, this change is NFC.
* [Sema] Factor out shouldAttemptInitializerSynthesis
This makes sure we don't attempt to synthesize
a memberwise or default initializer for an invalid
decl, or one in a module interface.
* [Sema] Requesify inheritsSuperclassInitializers
This commit introduces a request for computing
whether a class inherits both designated and
convenience initializers from its superclass.
The shared logic of finding initializers which the
subclass hasn't overriden has been factored out
into `collectNonOveriddenSuperclassInits`.
* Cleanup addImplicitInheritedConstructorsToClass
This commit removes some code that's no longer
needed. In addition, now that we've requestified
`inheritsSuperclassInitializers`, we can directly
diagnose on non-inherited required convenience
inits within the loop.
* Inherited init synthesis no longer deals with clang decls
Now that the computation of
`inheritsSuperclassInitializers` has been split off
into a request, we can avoid calling
`addImplicitInheritedConstructorsToClass` for clang
decls.
* Address review feedback
Continue to cache the InheritsSuperclassInits bit
on the AST.
ProtocolConformanceRef already has an invalid state. Drop all of the
uses of Optional<ProtocolConformanceRef> and just use
ProtocolConformanceRef::forInvalid() to represent it. Mechanically
translate all of the callers and callsites to use this new
representation.
This commit adds two requests, one to compute
whether or not a decl should have a default
initializer, and another to synthesize it.
This then allows us to remove the default constructor
synthesis from addImplicitConstructorsToClass as
well as completely eliminate addImplicitConstructorsToStruct.
For now, we can just force the requests in
addImplicitConstructors.
Use the request evaluator to get the easier in-module precedence group cycles. Unfortunately, cross-module precedence group cycles are still a possibility, and do not actually cause cyclic request evaluation, so we cannot completely erase the old diagnostics machinery.
Move the machinery itself into the type checker and shift the request into that zone as well to appease the linker.
This will make it easier to prototype diagnostics on specifically marked nominal
types. My intended usage would be to have a way to emit diagnostics if specific
instances of the nominal type are ever not on the stack.
The moment you've all been waiting for...
Define InterfaceTypeRequest and use it to, well, compute the interface
type. This naturally widens the few cycles that we pick up with the
request evaluator.
There is still a lot of work to get done here, mostly around scaling
back all of the ad-hoc circularity checks around the interface type
computation. It would also be great to improve the circularity
diagnostics.
Switch most callers to explicit indices. The exceptions lie in things that needs to manipulate the parsed output directly including the Parser and components of the ASTScope. These are included as friend class exceptions.
Use it to provide an idealized API for the VarDecl case in validateDecl.
In reality, a lot of work is needed to rationalize the dependency
structure of this request. To start, the callers of
typeCheckPatternBinding must be eliminated piecemeal. Once that is
done, the AST should introduce pattern binding decls along all the
places where getParentStmt() used to apply.
Define a request that can be used to grab the fully validated and
type-checked form of a given pattern binding entry. Using this,
validation of pattern bindings is fully disconnected from validation of
bound variables, and cycles are now picked up by the request evaluator.
Using this, we can go clean up all the callers that are checking a bit
and calling back into typeCheckPatternBinding. It will also serve as
the basis for a request for the naming pattern for a VarDecl which will
clean that part of validateDecl.
When Decl::getLoc() is called upon a serialized AST and the
serialized source location is available, we lazily open the
external buffer and return a valid SourceLoc instance pointing
into the buffer.
Inline the interface type reset into its callers and make sure they're
also setting the invalid bit - which this was not doing before.
Unfortunately, this is not enough to be able to simplify any part of var
decl validation.
This is an amalgam of simplifications to the way VarDecls are checked
and assigned interface types.
First, remove TypeCheckPattern's ability to assign the interface and
contextual types for a given var decl. Instead, replace it with the
notion of a "naming pattern". This is the pattern that semantically
binds a given VarDecl into scope, and whose type will be used to compute
the interface type. Note that not all VarDecls have a naming pattern
because they may not be canonical.
Second, remove VarDecl's separate contextual type member, and force the
contextual type to be computed the way it always was: by mapping the
interface type into the parent decl context.
Third, introduce a catch-all diagnostic to properly handle the change in
the way that circularity checking occurs. This is also motivated by
TypeCheckPattern not being principled about which parts of the AST it
chooses to invalidate, especially the parent pattern and naming patterns
for a given VarDecl. Once VarDecls are invalidated along with their
parent patterns, a large amount of this diagnostic churn can disappear.
Unfortunately, if this isn't here, we will fail to catch a number of
obviously circular cases and fail to emit a diagnostic.
VarDecls inherit their TypeRepr from their enclosing pattern, if any.
To retrieve the TypeRepr attached to a VarDecl or a ParamDecl in
a uniform way, the getTypeReprOrParentPatternTypeRepr API has been
provided.