Add a third branch to the constraint system for '&x' expressions that allows conversion from an lvalue to a type via an additional writeback step:
- Add an LValueConversionExpr node that converts from @lvalue T to @lvalue U, given a pair of functions that convert T -> U and U -> T, to represent the writeback temporary.
- Allow conversion in an inout expression from @lvalue T to a type U that has the following members:
static func __writeback_conversion(Builtin.RawPointer, T.Type) -> U
static func __writeback_conversion_get(T) -> V
static func __writeback_conversion_set(V) -> T
which builds a solution that produces an LValueConversion from the get/set pair before passing the pointer to the writeback temporary off to the conversion function.
Swift SVN r15764
Language features like erasing concrete metatype
values are also left for the future. Still, baby steps.
The singleton ordinary metatype for existential types
is still potentially useful; we allow it to be written
as P.Protocol.
I've been somewhat cavalier in making code accept
AnyMetatypeType instead of a more specific type, and
it's likely that a number of these places can and
should be more restrictive.
When T is an existential type, parse T.Type as an
ExistentialMetatypeType instead of a MetatypeType.
An existential metatype is the formal type
\exists t:P . (t.Type)
whereas the ordinary metatype is the formal type
(\exists t:P . t).Type
which is singleton. Our inability to express that
difference was leading to an ever-increasing cascade
of hacks where information is shadily passed behind
the scenes in order to make various operations with
static members of protocols work correctly.
This patch takes the first step towards fixing that
by splitting out existential metatypes and giving
them a pointer representation. Eventually, we will
need them to be able to carry protocol witness tables
Swift SVN r15716
permit the result to be *convertible* to the contextual
type and not merely *exactly equal*.
I don't have a use case for factory methods that return
subtypes, but factory methods that return @unchecked T?
are going to be pervasive, and it's not like the subtype
thing is unreasonable.
Swift SVN r15664
We'll need types to be convertible from multiple kinds of inouts, which currently can't be represented with protocol conformance since we only allow one protocol conformance per type per protocol. Instead just look for a magic "__inout_conversion" static method in the type; this is lame but easy, and inout conversions shouldn't be available outside of the stdlib anyway.
Swift SVN r15599
Add two new AST node types:
- InOutConversionExpr, which represents an '&x' expression that involves inout conversion. This will be a signal to SILGen not to introduce a writeback scope for the nested conversion call.
- LValueToPointerExpr, which represents the primitive '@lvalue T' to 'RawPointer' conversion that produces the argument to the inout conversion.
Build an InOutConversionExpr AST when an inout expression is resolved by a conversion to an BuiltinInOutAddressConvertible type.
Swift SVN r15594
Set up the disjunction system for '&x' expressions that allows them to type-check either as simple lvalue-to-inout conversions, as before, or as address conversions that go through one of the BuiltinInOut*Convertible protocols. The solution side is not yet implemented.
Swift SVN r15593
Resolve selector references using compound name lookup, pushing DeclNames a bit deeper through the type-checker and diagnostics as necessary.
Swift SVN r14791
Factor an IdentityExpr base class out of ParenExpr, and migrate most of the logic to see through ParenExprs to see through IdentityExprs instead. Add DotSelfExpr as a new subclass of IdentityExpr, produced by parsing 'x.self'.
Swift SVN r14381
Introduce a new expression kind, OpenExistentialExpr, that "opens" up
an existential value into a value of a fresh archetype type that
represents the dynamic type of the existential. That value can be
referenced (via an OpaqueValueExpr) within the within the
subexpression of OpenExistentialExpr. For example, a call to a
DynamicSelf method on an existential looks something like this:
(open_existential_expr implicit type='P'
(opaque_value_expr implicit type='opened P' @ 0x7fd95207c290
unique)
(load_expr implicit type='P'
(declref_expr type='@lvalue P' decl=t.(file).func
decl.p@t.swift:5:37 specialized=no))
(erasure_expr implicit type='P'
(call_expr type='opened P'
(archetype_member_ref_expr type='() -> opened P'
decl=t.(file).P.f@t.swift:2:8 [with Self=opened P]
(opaque_value_expr implicit type='opened P' @
0x7fd95207c290 unique))
(tuple_expr type='()')))))
Note that we're using archetype_member_ref_expr rather than
existential_member_ref_expr, because the call is operating on the
opaque_value_expr of archetype type. The outer erasure turns the
archetype value back into an existential value.
The SILGen side of this is somewhat incomplete; we're using
project_existential[_ref] to open the existential, which is almost
correct: it gives us access to the value as an archetype, but IRGen
doesn't know to treat the archetype type as a fresh archetype whose
conformances come from the existential. Additionally, the output of
the opened type is not properly parsable. I'll fix this in follow-on
commits.
Finally, the type checker very narrowly introduces support for
OpenExistentialExpr as it pertains to DynamicSelf. However, this can
generalize to support all accesses into existentials, eliminating the
need for ExistentialMemberRef and ExistentialSubscript in the AST and
protocol_method in SIL, as well as enabling more advanced existential
features should we want them later.
Swift SVN r13740
- purge @inout from comments in the compiler except for places talking about
the SIL argument convention.
- change diagnostics to not refer to @inout
- Change the astprinter to print InoutType without the @, so it doesn't show
up in diagnostics or in closure argument types in code completion.
- Implement type parsing support for the new inout syntax (before we just
handled patterns).
- Switch the last couple of uses in the stdlib (in types) to inout.
- Various testcase updates (more to come).
Swift SVN r13564
Introduce a new Pattern::forEachVariable that takes a lambda and iterates
over all the variables encompassed by the pattern (the ones found by
collectVariables) and runs the lambda on it.
Use this to implement collectVariables, so we only have one copy of the code.
Convert several places to use this, removing a bunch of duplicated code for
walking the pattern structure and extracting decls.
Convert a few uses of collectVariables to forEachVariable, leading to more
clear code without a temporary smallvector.
Remove simplifyPatternTypes in CSApply.cpp, which is dead.
Swift SVN r13545
This eliminates the duplication of type variables that represent the member types of existing type variables. I'm unable to trigger this with a test case at the moment, but it becomes important when we begin to substitute type variables through protocol conformances.
Swift SVN r12971
As with chaining initialization ('super.init' calls), wrapping the
delegating initialization in RebindSelfInConstructorExpr ensures that
'self' gets overwritten by the result of delegation.
Note that I'd much prefer that RebindSelfInConstructorExpr be
introduced by the type checker (not the parser). That cleanup will
follow.
Swift SVN r11932
is no longer an lvalue, since it doesn't make sense to assign to super.
This eliminates a bunch of special cases and simplifies things.
Swift SVN r11803
with qualifiers on it, we have two distinct types:
- LValueType(T) aka @lvalue T, which is used for mutable values on the LHS of an
assignment in the typechecker.
- InOutType(T) aka @inout T, which is used for @inout arguments, and the implicit
@inout self argument of mutable methods on value types. This type is also used
at the SIL level for address types.
While I detangled a number of cases that were checking for LValueType (without checking
qualifiers) and only meant @inout or @lvalue, there is more to be done here. Notably,
getRValueType() still strips @inout, which is totally and unbearably wrong.
Swift SVN r11727
- Switch all the 'self' mutable arguments to take self as @inout, since
binding methods to uncurried functions expose them as such.
- Eliminate the subtype relationship between @inout and @inout(implicit),
which means that we eliminate all sorts of weird cases where they get
dropped (see the updated testcases).
- Eliminate the logic in adjustLValueForReference that walks through functions
converting @inout to @inout(implicit) in strange cases.
- Introduce a new set of type checker constraints and conversion kinds to properly
handle assignment operators: when rebound or curried, their input/result argument
is exposed as @inout and requires an explicit &. When applied directly (e.g.
as ++i), they get an implicit AddressOfExpr to bind the mutated lvalue as an
@inout argument.
Overall, the short term effect of this is to fix a few old bugs handling lvalues.
The long term effect is to drive a larger wedge between implicit and explicit
lvalues.
Swift SVN r11708
- mark closure arguments (both explicit and $0's) as immutable
- Adjust the stdlib (one place) and some tests to cope with this.
- Remove some special case logic in sema for lvalue qualifying
anonymous closure exprs, which is now the wrong thing to do.
Swift SVN r11674
(various) FunctionType::get's, ArrayType::get,
ArraySliceType::get, OptionalType::get, and a few
other places.
There is more to be done here, but this is all I plan to do
for now.
Swift SVN r11497
Similar to r11235, but for 'is' expressions. QoI suffers somewhat here
because (1) we don't have an easy way to specialize the diagnostic,
and (2) we can't fix up the broken constraint system when we hit a
problem.
Swift SVN r11241