Commit Graph

885 Commits

Author SHA1 Message Date
Slava Pestov
f19cbef54d Sema: Try harder not to perform lookups into tuple types 2017-01-03 23:00:07 -08:00
Slava Pestov
7258861d73 Merge pull request #6515 from xedin/crasher-28588
[QoI] While merging equivalence classes don't forget to merge fixed types (if any).
2017-01-03 19:35:47 -08:00
Slava Pestov
a8da5b8d80 Merge pull request #6514 from xedin/SR_3506
[Diagnostics] When checking AssignExpr properly diagnose destination
2017-01-03 19:24:52 -08:00
Slava Pestov
5da7e10434 Merge pull request #6481 from xedin/diagnose-closure-return
[Diagnostics] Type-check return of the multi-statement closure without applying solutions
2017-01-03 18:55:27 -08:00
Slava Pestov
f56f403f9a Merge pull request #6528 from CodaFi/minimum-escape-velocity
[DiagnosticsQoI][SR-2657] Look through argument tuples when diagnosing conversion failures
2017-01-03 18:48:46 -08:00
Slava Pestov
d1b1361321 Merge pull request #6504 from CodaFi/crash-AAAAAHHH
Resolve some compiler crashers
2017-01-03 18:37:53 -08:00
Pavel Yaskevich
fb3515382c [Diagnostics] When checking AssignExpr properly diagnose destination
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.
2017-01-03 18:22:33 -08:00
Robert Widmann
e36b52c25d Resolve some compiler crashers
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.
2017-01-03 18:53:06 -07:00
Brian Gesiak
4108e1d9af [Sema] Mark VarDecl in capture lists
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.
2017-01-01 12:41:06 -05:00
Robert Widmann
bde054aa75 [DiagnosticsQoI] Look through argument tuples when diagnosing conversion failures
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.
2016-12-31 20:32:41 -07:00
Pavel Yaskevich
fac59ce4ee [Diagnostics] Improve diagnostics of self assignment of the anonymous closure parameters 2016-12-31 19:00:30 -08:00
Pavel Yaskevich
b236244a4b [QoI] Don't try to type-check closure return statement if it involves unresolved parameters
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.
2016-12-28 02:15:11 -08:00
Pavel Yaskevich
951395c5c5 [Diagnostics] Explicitly disallow solutions with unresolved types when diagnosing single expression closure bodies
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.
2016-12-26 04:26:37 -08:00
Pavel Yaskevich
f42fa362d1 [Diagnostics] Type-check return of the multi-statement closure without apply solutions
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.
2016-12-23 00:02:09 -08:00
Slava Pestov
caa7045ae5 AST: Remove unnecessary ModuleDecl parameter from GenericSignature::getSubstitutions() 2016-12-22 14:33:00 -05:00
Doug Gregor
dcdef4f7f5 [Type checker] Improve "downcast only unwraps optionals" diagnostics.
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.
2016-12-21 13:47:19 -08:00
Doug Gregor
40140d6e8d [Type checker] Drop unused closure parameter in TypeChecker::typeCheckCheckedCast.
This closure parameter isn't ever actually used and isn't needed. NFC
2016-12-21 13:46:14 -08:00
Doug Gregor
e97ab635ea [Constraint solver] Separate bridging conversions from other conversions.
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.
2016-12-21 13:46:14 -08:00
Slava Pestov
c0d506c82c Sema: Fix CSDiag's save/restore logic for decls with no type 2016-12-21 14:20:27 -05:00
Slava Pestov
f97d830861 Sema: Fix nullptr dereference in noteArchetypeSource() 2016-12-21 14:20:25 -05:00
practicalswift
26044559e0 [gardening] Initialize contextualTypeNode to nullptr to avoid the possibility of calling dyn_cast<BinaryExpr>(…) with an unitialized argument. 2016-12-18 19:53:28 +01:00
swift-ci
268c2b668d Merge pull request #6325 from practicalswift/gardening-20161216 2016-12-17 09:19:24 -08:00
practicalswift
38be6125e5 [gardening] C++ gardening: Terminate namespaces, fix argument names, ...
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.
2016-12-17 00:32:42 +01:00
practicalswift
16d6dce62e [gardening] Fix recently introduced typos. 2016-12-16 21:42:09 +01:00
Slava Pestov
2c6b9f71b6 AST: Change TypeAliasDecls to store an interface type as their underlying type
- 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.
2016-12-15 22:46:15 -08:00
Slava Pestov
a384b2a677 Don't call VarDecl::getType() on deserialized VarDecls 2016-12-15 22:46:15 -08:00
Doug Gregor
f85818fc4b Merge pull request #6294 from DougGregor/constraint-solver-gather-all-constraints
[Constraint solver] After binding a type variable, activate affected constraints
2016-12-14 21:12:40 -08:00
Doug Gregor
f68f87a56a [Constraint solver] After binding a type variable, activate affected constraints
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.
2016-12-14 20:18:04 -08:00
Slava Pestov
dbb9d315e3 Sema: Fix a couple of crashes in tuple arguments tests
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.
2016-12-13 23:22:10 -08:00
Pavel Yaskevich
37c6bdd657 [Diagnostics] Improve diagnostics involving implicitly unwrapped optional functions
In FailureDiagnosis::visitApplyExpr and CalleeCandidateInfo try to look
through ImplicitlyUnwrappedOptional function type, which improves diagnostics
for calls with invalid arguments.

Resolves: SR-3248.
2016-12-09 23:21:24 -08:00
Slava Pestov
e063e8297c Sema: Some fixes for the ITC
- 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.
2016-12-09 17:36:49 -08:00
Doug Gregor
38671e2771 [AST] Hide DeclContext::getAsGenericTypeOrGenericTypeExtensionContext().
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.
2016-12-05 22:42:03 -08:00
Slava Pestov
a5c5a0103a Sema: Don't look at SubstitutedType in CSDiag
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.
2016-12-05 13:22:23 -08:00
Slava Pestov
1a991da16d AST: Assign interface types to ParamDecls
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().
2016-12-04 00:02:21 -08:00
Slava Pestov
a17eec5211 Merge pull request #6018 from slavapestov/finish-removing-value-decl-get-type
Push ValueDecl::{has,get,set}Type() down to VarDecl
2016-12-01 20:02:27 -08:00
Slava Pestov
26c80420d1 Sema: Replace some getGenericParamsOfContext() calls with isGenericContext() 2016-12-01 19:28:13 -08:00
Slava Pestov
b4d11338ec AST: Push ValueDecl::{has,get,set}Type() down to VarDecl
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.
2016-12-01 19:28:13 -08:00
Pavel Yaskevich
f1905e8bd9 [QoI] Improve diagnostics for type member names shadowing top-level functions
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>.
2016-12-01 17:58:01 -08:00
Slava Pestov
2d83a79c2c AST: Remove TypeDecl::getDeclaredType()
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.
2016-12-01 13:00:18 -08:00
Slava Pestov
c71395a4c3 Sema: Small cleanup in CSDiag 2016-12-01 13:00:17 -08:00
Slava Pestov
044034cae5 Sema: hasType() => hasInterfaceType() 2016-11-29 03:05:31 -07:00
Slava Pestov
7c556712dd Sema: Fix CSDiag bug noticed by inspection
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.
2016-11-29 03:05:28 -07:00
Slava Pestov
492a8494ad Sema: CSDiag setType() => getInterfaceType()
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.
2016-11-29 03:05:28 -07:00
Slava Pestov
fa9d66c70f Sema: Small refactoring for findGenericSubstitutions()
When matching a potential callee type against the actual argument
types in a call expression, CSDiag would walk both types in parallel,
noting differences and recording archetype substitutions in a map.

We would also walk the callee type and attempt to recover substitutions
that came from a 'self.foo' method application where self is a generic
nominal type. This relied on the fact that Type::subst() leaves behind
the old types in the form of SubstitutedType sugar.

Only one of the two call sites of findGenericSubstitutions() used the
second feature, so move the SubstitutedType walk over to that call site
instead of doing it for both.

Unfortunately the SubstitutedType walk is somewhat fragile, because
multiple subst() calls with different generic contexts will leave behind
an unpredictable structure of SubstitutedTypes. The code in CSDiag has
some heuristics to bail out when things don't make sense, but I think it
would be simpler to just call getMemberSubstitutions() and pass around
the substitution map together with the substituted type and original decl.

Notably, the only other place we rely on SubstitutedType showing up in
the result of Type::subst() is accessibility and availability checking
for nested typealiases, like 'Foo<T>.Bar', so it might be wise to redo
these passes to operate on the types of decls before we apply generic
parameters. Then we could remove SubstitutedType altogether.
2016-11-29 03:05:27 -07:00
Slava Pestov
6cbb494ad2 AST: Give all ValueDecls an interface type
Previously, getInterfaceType() would return getType() if no
interface type was set. Instead, always set an interface type
explicitly.

Eventually we want to remove getType() altogether, and this
brings us one step closer to this goal.

Note that ParamDecls are excempt from this treatment, because
they don't have a proper interface type yet. Cleaning this up
requires more effort.
2016-11-29 03:05:25 -07:00
Slava Pestov
69e7cca64f AST: Remove ConstructorDecl::getResultType() 2016-11-29 03:05:22 -07:00
swift-ci
fe1cd74221 Merge pull request #5808 from xedin/r28051973 2016-11-28 17:01:38 -08:00
Pavel Yaskevich
2707a9c585 [Diagnostics] Improve diagnostics of overloaded mutating methods
Add special logic to FailureDiagnosis::visitApplyExpr to
handle situation like following:

struct S {
  mutating func f(_ i: Int) {}
  func f(_ f: Float) {}
}

Given struct has an overloaded method "f" with a single argument of
multiple different types, one of the overloads is marked as
"mutating", which means it can only be applied on LValue base type.
So when struct is used like this:

let answer: Int = 42
S().f(answer)

Constraint system generator is going to pick `f(_ f: Float)` as
only possible overload candidate because "base" of the call is immutable
and contextual information about argument type is not available yet.
Such leads to incorrect contextual conversion failure diagnostic because
type of the argument is going to resolved as (Int) no matter what.
To workaround that fact and improve diagnostic of such cases we are going
to try and collect all unviable candidates for a given call and check if
at least one of them matches established argument type before even trying
to re-check argument expression.

Resolves: <rdar://problem/28051973>.
2016-11-28 14:23:14 -08:00
Graydon Hoare
7c1dc18b64 Revert "Give all declarations an explicit interface type" 2016-11-24 09:55:27 -08:00
Slava Pestov
6db43138fa AST: Remove ConstructorDecl::getResultType() 2016-11-24 02:35:30 -05:00