Previously all of the following would strip off varying amounts of
MetatypeType, LValueType, InOutType, DynamicSelfType, etc:
- ConstraintSystem::performMemberLookup()
- ConstraintSystem::lookupMember()
- TypeChecker::lookupMember()
- DeclContext::lookupQualified()
- Type::getContextSubstitutions()
The problem is that the higher level methods that took a lookup type
would call the lower level methods, and post-process the result using
the given lookup type. Since different levels of sugar were stripped,
it made the code hard to reason about and opened up edge cases, eg
if a DynamicSelfType or InOutType appears where we didn't expect it.
Since filtering out static/instance and mutating/nonmutating members
is done at higher levels, there's no reason for these name lookup
operations to accept anything other than nominal types, existentials
and archetypes.
Make this so with assertions, and deal with the fallout.
- TypeMatchVisitor doesn't like seeing ErrorTypes -- stop if we have one.
- Common logic for replacing type parameters and variables with
UnresolvedType.
- Fix crash in coerceToType() if one of the two types has an UnresolvedType
in it, but not at the top level.
Fixes one compiler_crasher and some regressions with upcoming patches.
Not sure why but this was another "toxic utility method".
Most of the usages fell into one of three categories:
- The base value was always non-null, so we could just call
getCanonicalType() instead, making intent more explicit
- The result was being compared for equality, so we could
skip canonicalization and call isEqual() instead, removing
some boilerplate
- Utterly insane code that made no sense
There were only a couple of legitimate uses, and even there
open-coding the conditional null check made the code clearer.
Also while I'm at it, make the SIL open archetypes tracker
more typesafe by passing around ArchetypeType * instead of
Type and CanType.
Currently if destination is unresolved instead of trying to re-typecheck
it again and diagnose structural problems which led to such outcome, it
gets completely ignored in favor of trying to type-check source without
contextual type. That leads to missed diagnostic opportunities, which
results in problems on AST verification and SIL generation stages, and
generally missleading errors e.g. `.x = 0`.
Resolves: SR-3506.
Crashers fixed are minor logic errors:
Patterns: Crash occurred when requesting the range of a created
Pattern. Validity of the range should be checked before returning it
to keep the entire range valid or invalid but never both.
ParseExpr/ParsePattern: The same fixes as the ones provided in #6319
CSDiag: The generic visitor needn’t look through TypeVarTypes either.
Fixes SR-2757.
Variables in capture lists are treated as 'let' constants, which can
result in misleading, incorrect diagnostics. Mark them as such in order
to produce better diagnostics, by adding an extra parameter to the
VarDecl initializer.
Alternatively, these variables could be marked as implicit, but that
results in other diagnostic problems: capture list variables that are
never used produce warnings, but these warnings aren't normally emitted for
implicit variables. Other assertions in the compiler also misfire when
these variables are treated as implicit.
Another alternative would be to walk up the AST and determine whether
the `VarDecl`, but there doesn't appear to be a way to do so.
This gives us much better diagnostics around things like
escaping-mismatched function parameters which would previously skip
this and produce bogus invalid conversion errors between “identical”
types.
If return expression uses closure parameters, which have/are
type variables, such means that we won't be be able to
type-check result correctly and, unfornutately,
we are going to leak type variables from the parent
constraint system through declaration types.
When running diagnostics for single expression closures,
explicitly disallow to produce solutions with unresolved type variables,
because there is no auxiliary logic which would handle that and it's
better to allow failure diagnosis to run directly on the closure body.
Obtain type of the result expression without applying solutions,
because otherwise this might result in leaking of type variables,
since we are not reseting result statement and if expression is
sucessfully type-checked its type cleanup is going to be disabled
(we are allowing unresolved types), and as a side-effect it might
also be transformed e.g. OverloadedDeclRefExpr -> DeclRefExpr.
Specialize and improve the "downcast only unwraps optionals"
diagnostic to provide specific diagnostics + Fix-Its for the various
casts of forced cast, conditional cast, and "isa" check. Specifically:
* With a forced cast, customize the diagnostic. We still insert the
appropriate number of !'s, but now we remove the 'as! T' (if an
implicit conversion would suffice) or replace the 'as!' with 'as'
(if we still need a bridge)
* With a conditional cast, only emit a diagnostic if we're removing
just one level of optional. In such cases, we either have a no-op
(an implicit conversion would do) or we could just use 'as' to the
optional type, so emit a customized warning to do that. If we are
removing more than one level of optional, don't complain:
conditional casts can remove optionals. Add the appropriate Fix-Its
here.
* With an 'is' expression, only emit a diagnostic if we're removing
just one level of optional. In this case, the 'is' check is
equivalent to '!= nil'. Add a Fix-It for that.
Across the board, reduce the error to a warning. These are
semantically-well-formed casts, it's just that they could be written
better.
Fixes rdar://problem/28856049 and rdar://problem/22275685.
Previously, bridging conversions were handled as a form of "explicit
conversion" that was treated along the same path as normal
conversions in matchTypes(). Historically, this made some
sense---bridging was just another form of conversion---however, Swift
now separates out bridging into a different kind of conversion that is
available only via an explicit "as". This change accomplishes a few
things:
* Improves type inference around "as" coercions. We were incorrectly
inferring type variables of the "x" in "x as T" in cases where a
bridging conversion was expected, which cause some type inference
failures (e.g., the SR-3319 regression).
* Detangles checking for bridging conversions from other conversions,
so it's easier to isolate when we're applying a bridging
conversion.
* Explicitly handle optionals when dealing with bridging conversions,
addressing a number of problems with incorrect diagnostics, e.g.,
complains about "unrelated type" cast failures that would succeed at
runtime.
Addresses rdar://problem/29496775 / SR-3319 / SR-2365.
Changes:
* Terminate all namespaces with the correct closing comment.
* Make sure argument names in comments match the corresponding parameter name.
* Remove redundant get() calls on smart pointers.
* Prefer using "override" or "final" instead of "virtual". Remove "virtual" where appropriate.
- TypeAliasDecl::getAliasType() is gone. Now, getDeclaredInterfaceType()
always returns the NameAliasType.
- NameAliasTypes now always desugar to the underlying type as an
interface type.
- The NameAliasType of a generic type alias no longer desugars to an
UnboundGenericType; call TypeAliasDecl::getUnboundGenericType() if you
want that.
- The "lazy mapTypeOutOfContext()" hack for deserialized TypeAliasDecls
is gone.
- The process of constructing a synthesized TypeAliasDecl is much simpler
now; instead of calling computeType(), setInterfaceType() and then
setting the recursive properties in the right order, just call
setUnderlyingType(), passing it either an interface type or a
contextual type.
In particular, many places weren't setting the recursive properties,
such as the ClangImporter and deserialization. This meant that queries
such as hasArchetype() or hasTypeParameter() would return incorrect
results on NameAliasTypes, which caused various subtle problems.
- Finally, add some more tests for generic typealiases, most of which
fail because they're still pretty broken.
Once we've bound a type variable, we find those inactive constraints
that mention the type variable and make them active, so they'll be
simplified again. However, we weren't finding *all* constraints that
could be affected---in particular, we weren't searching everything
related to the type variables in the equivalence class, which meant
that some constraints would not get visited... and we would to
type-check simply because we didn't look at a constraint again when we
should have.
Fixes rdar://problem/29633747.
There's a general problem where a SubscriptExpr has an argument
that's a LoadExpr loading a tuple from an lvalue. For some reason
we don't construct the ParenExpr in this case, which confused
CSDiag.
Also, in Swift 3 mode, add a total hack to fudge things in
matchCallArguments() in the case where we erroneously lost
ParenType sugar.
In FailureDiagnosis::visitApplyExpr and CalleeCandidateInfo try to look
through ImplicitlyUnwrappedOptional function type, which improves diagnostics
for calls with invalid arguments.
Resolves: SR-3248.
- In functions called from resolveType(), consistently
use a Type() return value to indicate 'unsatisfied
dependency', and ErrorType to indicate failure.
- Plumb the unsatisfiedDependency callback through the
resolution of the arguments of BoundGenericTypes, and
also pass down the options.
- Before doing a conformance check on the argument of a
BoundGenericType, kick off a TypeCheckSuperclass request
if the type in question is a class. This ensures we don't
recurse through NominalTypeDecl::prepareConformanceTable(),
which wants to see a class with a valid superclass.
- The ResolveTypeOfDecl request was assuming that
the request was satisfied after calling validateDecl().
This is not the case when the ITC is invoked from a
recursive call to validateDecl(), hack this up by returning
*true* from isResolveTypeDeclSatisfied(); otherwise we
assert in satisfy(), and we can't make forward progress
in this case anyway.
- Fix a bug in cycle breaking; it seems if we don't invoke
the cycle break callback on all pending requests, we end
up looping forever in an outer call to satisfy().
- Remove unused TR_GlobalTypeAlias option.
This method gets the GenericTypeDecl for a typealias, nominal type, or
extension thereof. While the result is typed as GenericTypeDecl, it's
not always generic, so rename it accordingly.
An audit of the callers illustrated that they should be using
different entrypoints anyway, so fix all of the callers and make this
function private.
The code here is unprincipled, and mixes archetypes from
multiple sources:
1) The callee's generic environment
2) The caller's generic environment
3) Any random archetypes appearing in the original types of
typealiases, which could come from any generic environment
Initially, an UncurriedCandidate's type starts out as #1,
and then we sometimes set it to type #2 if the candidate is
a method on a base class.
We get #3 by virtue of walking the original types of
SubstitutedTypes created as part of dependent member type
substitution.
However, it turns out the real reason the SubstitutedType
walk existed was so that #2 archetypes that appear in the
UncurriedCandidate's type map to themselves. This doesn't
require looking at the original type of a SubstitutedType
at all; instead we just walk the UncurriedCandidate's type
normally, collecting archetypes.
If we do this, the code doesn't (erroneously) pick up random
archetypes from typealiases, and this changes the output in
the RangeDiagnostics test. While we can debate if the new
diagnostics are better or worse (I think it's either a wash,
or slightly better) the reason they changed is because more
in-depth diagnostic code is now executing, without breaking
things randomly as before. I suspect this is a good thing.
First, ensure all ParamDecls that are synthesized from scratch are given
both a contextual type and an interface type.
For ParamDecls written in source, add a new recordParamType() method to
GenericTypeResolver. This calls setType() or setInterfaceType() as
appropriate.
Interestingly enough a handful of diagnostics in the test suite have
improved. I'm not sure why, but I'll take it.
The ParamDecl::createUnboundSelf() method is now only used in the parser,
and no longer sets the type of the self parameter to the unbound generic
type. This was wrong anyway, since the type was always being overwritten.
This allows us to remove DeclContext::getSelfTypeOfContext().
Also, ensure that FuncDecl::getBodyResultTypeLoc() always has an interface
type for synthesized declarations, eliminating a mapTypeOutOfContext()
call when computing the function interface type in configureInterfaceType().
Finally, clean up the logic for resolving the DynamicSelfType. We now
get the interface or contextual type of 'Self' via the resolver, instead
of always getting the contextual type and patching it up inside
configureInterfaceType().
After recent changes, this asserts on all decls that are not VarDecls,
so we can just enforce that statically now. Interestingly, this turns
up some dead code which would have asserted immediately if called.
Also, replace AnyFunctionRef::getType() with
AnyFunctionRef::getInterfaceType(), since the old
AnyFunctionRef::getType() would just assert when called on
a Decl.
Consider expression with an implicit 'self.' reference:
extension Sequence {
func test() -> Int {
return max(1, 2)
}
}
We currently shadow names that appear in nested scopes, so the
top-level two-argument min()/max() functions are shadowed by the
versions of min()/max() in Sequence (which don’t take the same
number of arguments). This patch aims to improve situation on this
front and produce better diagnostics when that happens, hinting
the user about what went wrong and where matching function is
declared.
Resolves <rdar://problem/25341015>.
A pointless use of polymorphism -- the result values are not
interchangeable in any practical sense:
- For GenericTypeParamDecls, this returned getDeclaredInterfaceType(),
which is an interface type.
- For AssociatedTypeDecls, this returned the sugared AssociatedTypeType,
which desugars to an archetype.
- For TypeAliasDecls, this returned TypeAliasDecl::getAliasType(),
which desugars to a type containing archetypes.
- For NominalTypeDecls, this returned NominalTypeDecl::getDeclaredType(),
which is the unbound generic type, a special case used for inferring
generic arguments when they're not written in source.
This triggered with an existing test that was run against
some other changes I was working on, but the current code
does not demonstrate the problem.
However, it's "obviously" more "correct", so here we go.
When collecting callee candidates, get the interface type and map it
into context, rather than calling getType() directly.
This produces almost the same result as getType(), except for two
differences:
1) where getType() would return a PolymorphicFunctionType with
a reference to the original generic parameters, now CSDiag just
sees a simple FunctionType appears with discombobulated archetypes.
This is fine since CSDiag does not do anything specific with
PolymorphicFunctionTypes.
2) substGenericArgs() calls Type::subst(), which produces
SubstitutedType sugar. This would confuse CSDiag, which was not
prepared to see SubstitutedTypes that arise from this particular
call of Type::subst().
As mentioned in a previous commit message, CSDiag should be
refactored to get substitutions via a call to getMemberSubstitutions(),
instead of 'recovering' them from result of getTypeOfMember().
Until this can be fixed, I'm just manually stripping off any
SubstitutedTypes that appear from the call to substGenericArgs().
A better approach here would be to redo the callee diagnostics
stuff to look at interface types, plumbing through the correct
generic signatures. Then questions like 'what protocols does this
generic parameter conform to' can be asked of the signature and
interface type, instead of looking at archetypes.