This change permits UnresolvedDotExpr to have both a name and a base that are implicit, but a valid DotLoc, and to treat that DotLoc as the node’s location. It then changes the generation of string interpolation code so that `$stringInterpolation.appendInterpolation` references have a DotLoc corresponding to the backslash in the string literal.
This makes it possible for `ExprContextAnalyzer` in IDE to correctly detect when you are code-completing in a string interpolation and treat it as an `appendInterpolation` call.
The initialization of an instance property that has an attached
property delegate involves the initial value written on the property
declaration, the implicit memberwise initializer, and the default
arguments to the implicit memberwise initializer. Implement SILGen
support for each of these cases.
There is a small semantic change to the creation of the implicit
memberwise initializer due to SE-0242 (default arguments for the
memberwise initializer). Specifically, the memberwise initializer will
use the original property type for the parameter to memberwise
initializer when either of the following is true:
- The corresponding property has an initial value specified with the
`=` syntax, e.g., `@Lazy var i = 17`, or
- The corresponding property has no initial value, but the property
delegate type has an `init(initialValue:)`.
The specific case that changed is when a property has an initial value
specified as a direct initialization of the delegate *and* the
property delegate type has an `init(initialValue:)`, e.g.,
```swift
struct X {
@Lazy(closure: { ... })
var i: Int
}
```
Previously, this would have synthesized an initializer:
```swift
init(i: Int = ???) { ... }
```
However, there is no way for the initialization specified within the
declaration of i to be expressed via the default argument. Now, it
synthesizes an initializer:
```swift
init(i: Lazy<Int> = Lazy(closure: { ... }))
```
ASTDumper doesn’t have any way to look up key path component types in the constraint solver, so they’re currently shown as null. This change adds a hook to look them up and looks in the key path component’s FunctionResult locator, which is where subscripts already keep their return type.
Instead of building ArgumentShuffleExprs, lets just build a TupleExpr,
with explicit representation of collected varargs and default
arguments.
This isn't quite as elegant as it should be, because when re-typechecking,
SanitizeExpr needs to restore the 'old' parameter list by stripping out
the nodes inserted by type checking. However that hackery is all isolated
in one place and will go away soon.
Note that there's a minor change the generated SIL. Caller default
arguments (#file, #line, etc) are no longer delayed and are instead
evaluated in their usual argument position. I don't believe this actually
results in an observable change in behavior, but if it turns out to be
a problem, we can pretty easily change it back to the old behavior with a
bit of extra work.
TupleShuffleExpr could not express the full range of tuple conversions that
were accepted by the constraint solver; in particular, while it could re-order
elements or introduce and eliminate labels, it could not convert the tuple
element types to their supertypes.
This was the source of the annoying "cannot express tuple conversion"
diagnostic.
Replace TupleShuffleExpr with DestructureTupleExpr, which evaluates a
source expression of tuple type and binds its elements to OpaqueValueExprs.
The DestructureTupleExpr's result expression can then produce an arbitrary
value written in terms of these OpaqueValueExprs, as long as each
OpaqueValueExpr is used exactly once.
This is sufficient to express conversions such as (Int, Float) => (Int?, Any),
as well as the various cases that were already supported, such as
(x: Int, y: Float) => (y: Float, x: Int).
https://bugs.swift.org/browse/SR-2672, rdar://problem/12340004
Before extending TupleShuffleExpr to represent all tuple
conversions allowed by the constraint solver, remove the
parts of TupleShuffleExpr that are no longer needed; this is
support for default arguments, varargs, and scalar-to-tuple and
tuple-to-scalar conversions.
Right now we use TupleShuffleExpr for two completely different things:
- Tuple conversions, where elements can be re-ordered and labels can be
introduced/eliminated
- Complex argument lists, involving default arguments or varargs
The first case does not allow default arguments or varargs, and the
second case does not allow re-ordering or introduction/elimination
of labels. Furthermore, the first case has a representation limitation
that prevents us from expressing tuple conversions that change the
type of tuple elements.
For all these reasons, it is better if we use two separate Expr kinds
for these purposes. For now, just make an identical copy of
TupleShuffleExpr and call it ArgumentShuffleExpr. In CSApply, use
ArgumentShuffleExpr when forming the arguments to a call, and keep
using TupleShuffleExpr for tuple conversions. Each usage of
TupleShuffleExpr has been audited to see if it should instead look at
ArgumentShuffleExpr.
In sequent commits I plan on redesigning TupleShuffleExpr to correctly
represent all tuple conversions without any unnecessary baggage.
Longer term, we actually want to change the representation of CallExpr
to directly store an argument list; then instead of a single child
expression that must be a ParenExpr, TupleExpr or ArgumentShuffleExpr,
all CallExprs will have a uniform representation and ArgumentShuffleExpr
will go away altogether. This should reduce memory usage and radically
simplify parts of SILGen.
For context, String, Nil, Bool, and Int already behave this way.
Note: Swift can compile against 80 or 64 bit floats as the builtin
literal type. Thus, it was necessary to capture this bit somehow in the
FloatLiteralExpr. This was done as another Type field capturing this
info.
For context, String, Nil, and Bool already behave this way.
Note: Before it used to construct (call, ... (integer_literal)), and the
call would be made explicit / implicit based on if you did eg: Int(3) or
just 3. This however did not translate to the new world so this PR adds
a IsExplicitConversion bit to NumberLiteralExpr. Some side results of
all this are that some warnings changed a little and some instructions are
emitted in a different order.
Currently invalid initializer references are detected and
diagnosed in solution application phase, but that's too
late because solver wouldn't have required information while
attempting to determine the best solution, which might result
in viable solutions being ignored in favour of incorrect ones e.g.
```swift
protocol P {
init(value: Int)
}
class C {
init(value: Int, _: String = "") {}
}
func make<T: P & C>(type: T.Type) -> T {
return T.init(value: 0)
}
```
In this example `init` on `C` would be preferred since it
comes from the concrete type, but reference itself is invalid
because it's an attempt to construct class object using
metatype value via non-required initalizer.
Situations like these should be recognized early and invalid
use like in case of `C.init` should be ranked lower or diagnosed
if that is the only possible solution.
Resolves: rdar://problem/47787705
Instead of constructing calls to ExpressibleByBooleanLiteral.init(booleanLiteral: ...) in CSApply.cpp, just
annotate BooleanLiteralExpr with the selected constructor and do the actual construction during SILGen.
For context, StringLiteralExpr and NilLiteralExpr already behave this way.
Instead of constructing calls to
ExpressibleByNilLiteral.init(nilLiteral: ()) in CSApply.cpp, just
annotate NilLiteralExpr with the selected construtor and do the actual
construction during SILGen.
For context, StringLiteralExpr already behaves this way.
We've been running doxygen with the autobrief option for a couple of
years now. This makes the \brief markers into our comments
redundant. Since they are a visual distraction and we don't want to
encourage more \brief markers in new code either, this patch removes
them all.
Patch produced by
for i in $(git grep -l '\\brief'); do perl -pi -e 's/\\brief //g' $i & done
The `Stmt` and `Expr` classes had both `dump` and `print` methods that behaved similarly, making it unclear what each method was for. Following a conversation in https://forums.swift.org/t/unifying-printing-logic-in-astdumper/15995/6 the `dump` methods will be used to print the S-Expression-like ASTs, and the `print` methods will be used to print the more textual ASTPrinter-based representations. The `Stmt` and `Expr` classes seem to be where this distinction was more ambiguous. These changes should fix that ambiguity.
A few other classes also have `print` methods used to print straightforward representations that are neither the S-Expressions nor ASTPrinters. These were left as they are, as they don't cause the same ambiguity.
It should be noted that the ASTPrinter implementations themselves haven't yet been finished and aren't a part of these changes.
There’s a few places where size_t is used for a field/parameter when constructing an array for types. Unfortunately, the Bitfields that were backing the inputs to these at some point after 4.1 grew past 32 bits and are now backed by a uint64_t. Even though the slice of the bitfield is small enough for 32-bit, clang sees these slices as 64-bit and complains if there isn’t a cast involved.
`\.self` is the final chosen syntax. Implement support for this syntax, and remove the stopgap builtin and `WritableKeyPath._identity` property that were in place before.
This silences the instances of the warning from Visual Studio about not all
codepaths returning a value. This makes the output more readable and less
likely to lose useful warnings. NFC.
We previously allowed these closures to default to (), but be inferred
as other types as well, which means that we will find some expressions
to be ambiguous because we end up finding multiple viable solutions
where there is really only one reasonable solution.
Fixes: rdar://problem/42337247
I needed this for materializeForSet remission, but it makes inherited
variadic initializers work, too.
I tried to make this a reasonable starting point for a real language
feature. Here's what's still missing:
- syntax
- semantic restrictions to ensure that the expression isn't written in
invalid places or arbitrarily converted
- SILGen support for expansions that aren't the only variadic argument
rdar://16331406
Now, an AbstractFunctionDecl always stores a single parameter list.
Furthermore, ConstructorDecl and DestructorDecl always store a
ParamDecl for 'self'.
FuncDecl only has a 'self' if it is a member of a nominal type or
extension, so we tail-allocate the storage for it.