`\.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
Now that function types cannot have a naked type variable as
their input type it's no longer possible to have an unsolved
ArgumentTupleConversion constraint, so we can bypass most of
the logic in matchTypes() and call matchCallArguments() instead.
Previously we would generate the following constraint here, where
'index' and 'output' are concrete types and $input is a type
variable:
- ValueMember(base, $input -> output)
- ArgumentTupleConversion(index, $input)
The problem is that we built a function type where the entire input
was a type variable, which would then bind to an argument list.
We could instead generate this constraint:
- ValueMember(base, $member)
- ApplicableFunction(index -> output, $member)
I also had to redo how keypaths map locators back to key path
components. Previously the ArgumentTupleConversion was created
with a locator ending in KeyPathComponent.
Now the ApplicableFunction is created with this locator, which means
the argument match is performed with a locator ending in
ApplyArgument.
A consequence of this is that the SubscriptIndex and SubscriptResult
locator path elements are no longer used, so remove them.
This requires various mechanical changes in places we look at
locators to handle this change. Should be NFC.
Previously we would generate the following constraint here, where
'base' was a concrete type and $arg and $result are type variables:
- ValueMember(base, $arg -> $result)
The problem is that we built a function type where the entire input
was a type variable, which would then bind to an argument list.
We could instead generate this constraint:
- ValueMember(base, $method)
That is not NFC though because we no longer have a type variable
bound to the argument list. Since $arg was created with
TVO_PreferSubtypeBinding, we would rank solutions by comparing
argument lists.
So we use the new FunctionInput constraint to extract the input
type of $method:
- ValueMember(base, $method)
- FunctionInput($method, $arg)
Once the ValueMember constraint is solved and $method has a fixed
type, $arg is bound to the function type's argument list, and
since it was created with TVO_PreferSubtypeBinding it participates
in ranking as before.
Amusingly enough, none of the tests in our suite exercised this
behavior, but the standard library would fail to build. So add a test.
These usages of getOld() always pass in a ParenType or TupleType
as the input type, so there's no conceptual difficulty with
using the new representation instead.
Note that eventually we want to remove decomposeInput() too.
However until ApplyExpr and friends are redesigned to directly
hold multiple arguments instead of a single argument
sub-expression that is a ParenExpr or TupleExpr, we don't
have a good way to avoid building a tuple type and decomposing
it in this one case.
Instead just inline what getOld() does so we can move forward.
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
Replace the GenericTypeResolver type hierarchy with TypeResolution,
which more simply encapsulates the information needed to resolve
dependent types and makes explicit those places where we are
using resolution to contextual types.
This makes it easier to grep for and eventually remove the
remaining usages.
It also allows you to write FunctionType::get({}, ...) to call the
ArrayRef overload empty parameter list, instead of picking the Type
overload and calling it with an empty Type() value.
While I"m at it, in a few places instead of renaming just clean up
usages where it was completely mechanical to do so.
- getAsDeclOrDeclExtensionContext -> getAsDecl
This is basically the same as a dyn_cast, so it should use a 'getAs'
name like TypeBase does.
- getAsNominalTypeOrNominalTypeExtensionContext -> getSelfNominalTypeDecl
- getAsClassOrClassExtensionContext -> getSelfClassDecl
- getAsEnumOrEnumExtensionContext -> getSelfEnumDecl
- getAsStructOrStructExtensionContext -> getSelfStructDecl
- getAsProtocolOrProtocolExtensionContext -> getSelfProtocolDecl
- getAsTypeOrTypeExtensionContext -> getSelfTypeDecl (private)
These do /not/ return some form of 'this'; instead, they get the
extended types when 'this' is an extension. They started off life with
'is' names, which makes sense, but changed to this at some point. The
names I went with match up with getSelfInterfaceType and
getSelfTypeInContext, even though strictly speaking they're closer to
what getDeclaredInterfaceType does. But it didn't seem right to claim
that an extension "declares" the ClassDecl here.
- getAsProtocolExtensionContext -> getExtendedProtocolDecl
Like the above, this didn't return the ExtensionDecl; it returned its
extended type.
This entire commit is a mechanical change: find-and-replace, followed
by manual reformatted but no code changes.
TypeResolutionFlags is overly complicated at the moment because the vast
majority of flag combinations are impossible and nonsensical. With this
patch, we create a new TypeResolverContext type that is a classic enum
and far easier to reason about. It also enables "exhaustive enum"
checking, unlike the "flags" based approach.
Existence of semantic expr (`getSemanticExpr()`) prevents ASTWalker
walking into the *original* sub expressions which may cause
re-typechecking failure. For example,
`ConstraintGenerator::visitArrayExpr()` assumes we already visited its
elements, but that's not the case if the semantic expr exists.
rdar://problem/42639255
Using dummy UnresolvedMemberExpr doesn't give us much benefit. Instead, use
CodeCompletionExpr which is type checked as type variable so can use
CodeCompletionTypeContextAnalyzer to infer context types.
This way, we can eliminate most of special logic for UnresolvedMember.
rdar://problem/39098974
* Restructure walkToExpr so we can handle nested implicit conversion
expressions. E.g
* Don't walk to children of 'CollectionUpcastConversionExpr'. Previously,
'walkIntoChildren' flag was ignored. Since this is also a
'ImplicitConversionExpr', just return 'subExpr()'.
(Fixes https://bugs.swift.org/browse/SR-8471 rdar://problem/43057058)
* Ignore OpaqueValueExpr in 'eraseOpenExistentialsOnly' mode. In this
mode, we allow waking into other implicit conversion expression
including 'MakeTemporarilyEscapableExpr'.
* Handle previously ignored expressions they are maked as
'llvm_unreachable' in 'ConstraintGenerator':
* Replace 'MakeTemporarilyEscapableExpr' with its original expression.
* Replace 'AutoClosureExpr' with its body.
This is helpful in experimenting with constraint solver changes that
might help us remove some of these unsound options. It's not ever mean
to be enabled, but if we're able to remove the things guarded by the
option we can eventually remove the option.
Literal initialization via coercion makes current incorrect logic
slightly more eager still, which leads to more chained arithmetic
operator expressions to be recognized as "symmetric" and their type
variables merged.
Although literal init via coercion does provide more type information,
let's treat it as regular initializer calls and don't record the types.
Resolves: rdar://problem/42750089
While inferring avoid associating type variables with closure
parameters, use cache instead and only set types when everything
is properly type-checked, this avoids multiple problems one of
them - leaking type variables outside of constraint system they
belong to.
This patch avoids merging type variables inside UnresolvedMemberExpr
and those outside, because they may not always be equivalent in CS.
Resolves: SR-8385.
Most of the use-cases of `gatherConstraints` require filtering
at least based on the constraint kind that caller is interested in,
so instead of returning unrelated results and asking caller to
filter separately, let's add that functionality directly to
`gatherConstraints`.
Since it's possible to find the same constraint through two different
but equivalent type variables, let's use a set to store constraints
instead of a vector to avoid processing the same constraint multiple
times.
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.
Any produced diagnostics are suppressed anyway by a special
diagnostic engine attached to the new type-checker, so there
no point of doing any of that work.
Resolves: rdar://problem/22996887