Commit Graph

93 Commits

Author SHA1 Message Date
Slava Pestov
e9c255bfca Sema: Better fix for banning the '() -> T' => '() -> ()?' implicit conversion
Previously we would check TMF_UnwrappingOptional flag, which does not
stick with the constraint, so it would not always persist. Now, add a
new OptionalPayload locator element, which is more correct.

Fixes <rdar://problem/30429709>.
2017-02-13 16:59:09 -08:00
Jacob Bandes-Storch
c98e515734 [QoI] Improvements to function call & closure diagnostics (#7224) 2017-02-07 17:36:11 -08:00
Jacob Bandes-Storch
3e7e923e6d [Parse] Reject trailing closures on literals (#7202)
`1 { }` was parsed as a call expression with a trailing closure. This made the diagnostics for `var x = 1 { get { ... } }` extremely bad. Resolves SR-3671.
2017-02-02 10:32:47 -08:00
Jordan Rose
eed34d15e7 Sema: Explicitly allow Optional-to-IUO when converting functions. (#7153)
We limit Optional-to-IUO as an implicit conversion to avoid making
common expressions ambiguous. However, this runs into trouble with
function-to-function conversions, which always look for a "Subtype"
relationship for their inputs and outputs. This is a conservative way
for Sema to avoid emitting conversions that SILGen cannot handle.

The problem case here is converting a closure with type '(Any!) ->
Void' to a value of type '(Any?) -> Void':

    let f: ((Any?) -> Void) = { (arg: Any!) in }

This is clearly a safe conversion, since 'Any!' and 'Any?' have the
same representation at run time, but historically we've disallowed it
because of the above rules. However, in Swift 3.0 this particular case
was permitted, with the type checker deciding that the 'Any?' argument
to 'f' could first itself be put into an 'Any', then /that/ value
could go through a value-to-optional conversion to make 'Any!'.
Fortunately the emitted code didn't follow this incorrect conversion
path.

This patch doesn't even try to emulate the old behavior. Instead, it
just weakens the restriction on Optional-to-IUO via a new type
matching flag that only applies within the context of matching
function types.

We can consider opening up function conversions in Swift 4 to anything
that supports conversion---not just subtyping---now that SILGen knows
how to automatically reabstract most such things. But whether we do or
not, Optional/IUO is a special case.

https://bugs.swift.org/browse/SR-3758
2017-01-31 13:42:09 -08:00
Pavel Yaskevich
0f716e643b [QoI] Fix inference of inout closure parameters in generic contexts
Convert subtype constraints with inout on one side and type variable
on the other into fixed binding. Constriants like `inout T0 subtype T1`
where (T0 must be materializable) are created when closures are part
of the generic function parameters e.g. `func foo<T>(_ t: T, (inout T) -> Void) {}`
so when such function gets called e.g.
```
  var x = 42
  foo(x) { $0 = 0 }
```
it's going to try and map closure parameters type (inout T0) - where
is opened generic parameter T - to argument type (T1), which can
be 'inout' but it's uncertain at this stage, but since closure
'declaration' `{ $0 = 0 }` is wrapped inside of a function call,
it has to 'map' parameters to arguments instead of converting them,
see `ConstraintSystem::matchFunctionTypes`.

Resolves: SR-3520, SR-1976, SR-3073, SR-3479.
2017-01-09 00:23:00 -08:00
Pavel Yaskevich
dd7360e821 [Diagnostics] Improve diagnostics for closures with erroneous implicit return types 2017-01-07 22:07:15 -08:00
Slava Pestov
fdaace5af5 Sema: Fix terrible bug with the '() -> T' => '() -> ()' implicit conversion
We have an implicit conversion where a closure with a non-Void
result type can be passed as a function value with a Void
result; this makes single-expression closures more usable in
the case where you want the single expression to be a
statement -- discarding it's result.

Unfortunately we were checking if the locator contains a
ClosureResult component *anywhere* in the path. This is too
permissive. The correct check is that the *last* path component
is a ClosureResult.

Otherwise, we happily convert anything to () *anywhere*
in a closure result, which crashes immediately in SILGen.

Fixes <https://bugs.swift.org/browse/SR-403>.
2017-01-03 20:13:44 -08:00
Pavel Yaskevich
fac59ce4ee [Diagnostics] Improve diagnostics of self assignment of the anonymous closure parameters 2016-12-31 19:00:30 -08:00
Slava Pestov
30c4235193 Sema: Horrific simulation of Swift 3 bug with argument labels for Swift 3 mode
In Swift 3.0.1, argument labels are ignored when calling a function
having a single parameter of 'Any' type. That is, if we have:

func foo(_: Any) {}

Both of the following were accepted in a no-assert build (an assert
build would crash, but the GM builds of Xcode ship with asserts off):

foo(123)
foo(data: 123)

This behavior was fixed by 578e36a7e1,
but unfortunately we have to revert to the old behavior *and* defeat
the assertion when in Swift 3 mode.

Swift 4 mode still has the correct behavior, where the second call
'foo(data: 123)' produces a diagnostic.

Now, I have to pour myself a strong drink to forget this ever happened.

Fixes <rdar://problem/28952837>.
2016-12-14 01:45:14 -08:00
Slava Pestov
321edbfca4 Revert "[Sema] Implement SE-0110"
This reverts commit e172383e2f.

There were two problems with this commit:
- This was a source-breaking change and should have been feature-gated.
- It only addressed one narrow case of SE-0110.

Fixes <rdar://problem/28621719>.
2016-12-13 22:11:51 -08:00
Slava Pestov
ed75fdacab Sema: Fix for accidental desugaring in simplifyType()
When called with a ParenType wrapping a DependentMemberType,
we would drop the ParenType because we used type->getAs<ParenType>()
rather than dyn_cast<ParenType>(type.getPointer()).

This fixes an existing QoI issue with closure argument tuples,
and prevents another regression once SubstitutedType is removed.
2016-12-07 14:16:43 -08:00
Pavel Yaskevich
d111e9b4be [Diagnostics] When building a subscript don't assume that overload is always present
This handles situation when overload for the subscript hasn't been resolved
by constraint solver, such might happen, for example, if solver was allowed to
produce solutions with free or unresolved type variables (e.g. when running diagnostics).

Resolves: <rdar://problem/27329076>, <rdar://problem/28619118>, <rdar://problem/2778734>.
2016-11-28 19:18:44 -08:00
David Farler
b7d17b25ba Rename -parse flag to -typecheck
A parse-only option is needed for parse performance tracking and the
current option also includes semantic analysis.
2016-11-28 10:50:55 -08:00
Pavel Yaskevich
28777a3c7e [Diagnostics] Coerce closure arguments to contextual type only if it is valid
Modify TypeChecker::coerceParameterListToType to always validate and consider only
valid contextual types (contains: no undefined, error, or type variables etc.) for
argument type coercion, such logic prevents erasure of important explicitly specified
type information attached to parameters of the closure expressions being diagnosed.

Resolves: SR-2994.
2016-11-11 10:31:30 -08:00
Doug Gregor
fbd5369fc9 Revert "Temporarily disable this test"
This reverts commit e3428bae13.
2016-11-06 22:30:19 -08:00
Doug Gregor
e3428bae13 Temporarily disable this test 2016-11-06 22:16:08 -08:00
Doug Gregor
f168e7270c [Type checker] Use DependentMemberType instead of type variables for nested types.
In the constraint solver, we've traditionally modeled nested type via
a "type member" constraint of the form

  $T1 = $T0.NameOfTypeMember

and treated $T1 as a type variable. While the solver did generally try
to avoid attempting bindings for $T1 (it would wait until $T0 was
bound, which solves the constraint), on occasion we would get weird
behavior because the solver did try to bind the type
variable.

With this commit, model nested types via DependentMemberType, the same
way we handle (e.g.) the nested type of a generic type parameter. This
solution maintains more information (e.g., we know specifically which
associated type we're referring to), fits in better with the type
system (we know how to deal with dependent members throughout the type
checker, AST, and so on), and is easier to reason able.

This change is a performance optimization for the type checker for a
few reasons. First, it reduces the number of type variables we need to
deal with significantly (we create half as many type variables while
type checking the standard library), and the solver scales poorly with
the number of type variables because it visits all of the
as-yet-unbound type variables at each solving step. Second, it
eliminates a number of redundant by-name lookups in cases where we
already know which associated type we want.

Overall, this change provides a 25% speedup when type-checking the
standard library.
2016-11-05 23:20:28 -07:00
Pavel Yaskevich
02cae22541 [Diagnostics] Extend contextual failure checking to all apply expressions
As an extension of SR-2208 apply contextual conversion failure checking
to all of the expressions diagnosed via FailureDiagnosis::visitApplyExpr.

Resolves <rdar://problem/28909024>.
2016-10-30 22:28:26 -07:00
practicalswift
265a4605a0 [gardening] Fix typos. 2016-10-16 12:53:49 +02:00
Pavel Yaskevich
578e36a7e1 [Type Checker] SR-2505: Fix "Call arguments did not match up" assertion
Always check arguments of the tuple type against corresponding parameters,
otherwise for a single argument functions e.g. foo(_ a: Any) after SE-0046
type checker is going to produce incorrect solution.
2016-10-14 13:27:33 -07:00
practicalswift
fa7fbdb8b0 [gardening] Remove redundant nil-initialization of optional variable
From the Swift documentation:

"If you define an optional variable without providing a default value,
 the variable is automatically set to nil for you."
2016-09-18 07:40:07 +02:00
Slava Pestov
79a1512576 Sema: Three fixes for the new @escaping attribute
- If a parameter type is a sugared function type, mark the type
  as non-escaping by default. Previously, we were only doing this
  if the parameter type was written as a function type, with no
  additional sugar.

  This means in the following cases, the function parameter type
  is now non-escaping:

  func foo(f: ((Int) -> Void))

  typealias Fn = (Int) -> Void
  func foo(f: Fn)

- Also, allow @escaping to be used in the above cases:

  func foo(f: @escaping ((Int) -> Void))

  typealias Fn = (Int) -> Void
  func foo(f: @escaping Fn)

- Diagnose usages of @escaping in inappropriate locations, instead
  of just ignoring them.

It is unfortunate that sometimes we end up desugaring the typealias,
but currently there are other cases where this occurs too, such as
qualified lookpu of protocol typealiases with a concrete base
type, and generic type aliases. A more general representation for
sugared types (such as an AttributedType sugared type) would allow
us to solve this in a more satisfactory manner in the future.

However at the very least this patch factors out the common code
paths and adds comments, so it shouldn't be too bad going forward.

Note that this is a source-breaking change, both because @escaping
might need to be added to parameters with a sugared function type,
and @escaping might be removed if it appears somewhere where we
do not mark function types as non-escaping by default.
2016-08-17 19:37:23 -07:00
Paul Meng
e172383e2f [Sema] Implement SE-0110
This commit built upon the work of Pull Request 3895. Apart from the
work to make the following work

```swift
let f: (Int, Int) -> Void = { x in  } // this is now an error
```

This patch also implement the part 2 mentioned in the #3895

```swift
let g: ((Int, Int)) -> Void = { y in  } // y should have type (Int, Int)
```
2016-08-14 12:02:27 +08:00
Michael Ilseman
f48471ebd4 [noescape by default] purge tests of needless @noescape 2016-08-04 16:14:27 -07:00
Jordan Rose
f42158b12e Revert "[Sema] ban multi-arguments to tuple coercion" (#3922)
It breaks cases where there really is a single unlabeled argument of tuple type, like this:

  let pairs = [(1, "A"), (2, "B")]
  print(pairs.map { $0.0 })
2016-08-01 19:22:19 -07:00
Daniel Duan
c9b73dacc2 [Sema] ban multi-arguments to tuple coercion
Implements part of SE-0110. Single argument in closures will not be accepted if
there exists explicit type with a number of arguments that's not 1.

```swift
let f: (Int, Int) -> Void = { x in } // this is now an error
```

Note there's a second part of SE-0110 which could be considered additive,
which says one must add an extra pair of parens to specify a single arugment
type that is a tuple:

```swift
let g ((Int, Int)) -> Void = { y in } // y should have type (Int, Int)
```

This patch does not implement that part.
2016-07-31 16:22:57 -07:00
Chris Lattner
807345a909 When we get an abiguity problem with a multi-statement closure return type, it is
almost always the case that the user didn't know what the rules are between
single expression and multistatement closures, and they often don't know how to
fix the problem.

Address this by doing some heroics when we detect this situation.  We now go dive
into the closure body, type check the explicit returns within it, and can usually
divine the right answer.  When we do that, generate a fixit hint that generates a
modification to the existing signature, or synthesizes the entire signature from
scratch.  This addresses:
<rdar://problem/22123191> QoI: multi-line closure with failure to infer result type should add a fixit
2016-07-30 14:36:47 -07:00
Chris Lattner
5a2406bf0a Move some closure related testcases out to Constraints/closures.swift,
since Constraints/diagnostics.swift is already so huge.  NFC.
2016-07-29 21:24:42 -07:00
Chris Lattner
84d27f8528 fix <rdar://problem/21675896> QoI: [Closure return type inference] Swift cannot find members for the result of inlined lambdas with branches
We previously produced the unhelpful error message:

x.swift:11:7: error: type of expression is ambiguous without more context

we now produce:

error: unable to infer closure return type in current context

which is going in the right direction.
2016-07-29 21:22:01 -07:00
Chris Lattner
764d0fc371 improve the diagnostics for when a multi-statement closure has no inferred result type.
Previously:

error: generic parameter 'T' could not be inferred
now:
error: unable to infer closure return type in current context

There is still more to do, but this fixes:
<rdar://problem/23570873> QoI: Poor error calling map without being able to infer "U" (closure result inference)
2016-07-29 17:49:23 -07:00
Michael Ilseman
c37751ae96 [noescape by defaul] make noescape the default
This flips the switch to have @noescape be the default semantics for
function types in argument positions, for everything except property
setters. Property setters are naturally escaping, so they keep their
escaping-by-default behavior.

Adds contentual printing, and updates the test cases.

There is some further (non-source-breaking) work to be done for
SE-0103:

- We need the withoutActuallyEscaping function
- Improve diagnostics and QoI to at least @noescape's standards
- Deprecate / drop @noescape, right now we allow it
- Update internal code completion printing to be contextual
- Add more tests to explore tricky corner cases
- Small regressions in fixits in attr/attr_availability.swift
2016-07-29 13:49:08 -07:00
Michael Ilseman
2bb3347b65 [noescape by default] Improve and introduce diagnostics
Changes diangostic messages from referring specifically to @noescape,
which is going away, to 'non-escaping'. Introduces better diagnostics
and fixits for adding @escaping to closures that escape.
2016-07-29 13:48:07 -07:00
David Farler
7bfaeb57f1 [SE-0081] Warn on deprecated where clause inside angle brackets
and provide a fix-it to move it to the new location as referenced
in SE-0081.

Fix up a few stray places in the standard library that is still using
the old syntax.

Update any ./test files that aren't expecting the new warning/fix-it
in -verify mode.

While investigating what I thought was a new crash due to this new
diagnostic, I discovered two sources of quite a few compiler crashers
related to unterminated generic parameter lists, where the right
angle bracket source location was getting unconditionally set to
the current token, even though it wasn't actually a '>'.
2016-07-26 01:41:10 -07:00
Andrew Trick
72b8813a64 Restore operator '+' family for UnsafePointer. (#3719)
The reverts part of my previous patch. Removing the operators is too much of a
performance penalty to take. The difference is that the Strideable operators are
not transparent.

I still need to remove the UnsafeRawPointer operators, so -Onone performance
will be bad in some cases until this is fixed:
<rdar://problem/27513184> [perf] Strideable operators are not transparent. This is a huge -Onone performance penalty.
2016-07-23 18:58:55 -07:00
Andrew Trick
198173b17b Remove the global operator '+' family from UnsafePointer and UnsafeRawPointer.
Generic versions of these functions are provided by Strideable.

This is required for SE-0107: UnsafeRawPointer. Otherwise, the presence
of non-generic operator overloads will conflict with existing operators
on String.
2016-07-22 22:14:19 -07:00
Andrew Trick
a41484ea2b Add UnsafeRawPointer type and API. (#3677)
* Add UnsafeRawPointer type and API.

As proposed in SE-0107:   UnsafeRawPointer.
https://github.com/apple/swift-evolution/blob/master/proposals/0107-unsaferawpointer.md

The fundamental difference between Unsafe[Mutable]RawPointer and
Unsafe[Mutable]Pointer<Pointee> is simply that the former is used for "untyped"
memory access, and the later is used for "typed" memory access. Let's refer to
these as "raw pointers" and "typed pointers". Because operations on raw pointers
access untyped memory, the compiler cannot make assumptions about the underlying
type of memory and must be conservative. With operations on typed pointers, the
compiler may make strict assumptions about the type of the underlying memory,
which allows more aggressive optimization.

Memory can only be accessed by a typed pointer when it is currently
bound to the Pointee type. Memory can be bound to type `T` via:
- `UnsafePointer<T>.allocate(capacity: n)`
- `UnsafePointer<Pointee>.withMemoryRebound(to: T.self, capacity: n) {...}`
- `UnsafeMutableRawPointer.initializeMemory(as: T.self, at: i, count: n, to: x)`
- `UnsafeMutableRawPointer.initializeMemory(as: T.self, from: p, count: n)`
- `UnsafeMutableRawPointer.moveInitializeMemory(as: T.self, from: p, count: n)`
- `UnsafeMutableRawPointer.bindMemory(to: T.self, capacity: n)`

Mangle UnsafeRawPointer as predefined substitution 'Sv' for Swift void
pointer ([urp] are taken).

* UnsafeRawPointer minor improvements.

Incorporate Dmitri's feedback.

Properly use a _memmove helper.

Add load/storeBytes alignment precondition checks.

Reword comments.

Demangler tests.

* Fix name mangling test cases.

* Fix bind_memory specialization.
2016-07-22 13:32:08 -07:00
Chris Lattner
e0fcec578d When evaluating candidates for closeness, make sure to consider UnresolvedType to be
a match, since it *could* be, and typically conforms to whatever the expression is.

Fixing this improves the diagnostic in Constraints/closures.swift significantly, and
fixes these bugs:
<rdar://problem/21718970> QoI: [uninferred generic param] cannot invoke 'foo' with an argument list of type '(Int)'
<rdar://problem/21718955> Swift useless error: cannot invoke 'foo' with no arguments

where before we produced:
error: cannot invoke 'foo' with an argument list of type '(Int)'

and now produce:

x.swift:5:10: error: generic parameter 'A' could not be inferred
Whatever.foo(a: 23)
         ^
x.swift:1:7: note: 'A' declared as parameter to type 'Whatever'
class Whatever<A: IntegerArithmetic, B: IntegerArithmetic> {
      ^
2016-07-03 15:18:58 -07:00
Doug Gregor
423c1f09da [Type checker] Use call argument matching even with type variables on the left-hand side.
Rather than using a specialized matching rule in the type checker that
depends on having default arguments in types, use call argument
matching consistently.

Note #1: This (correctly) breaks some existing code that depends on
inferring a parameter type of () for a single-argument parameter from
a no-argument function type().

Note #2: This pessimizes a code completion test, where the code
completion engine seems to depend on some quirks of argument
matching. The "type relationship" matching needs non-trivial work.
2016-06-29 20:43:42 -07:00
Trent Nadeau
0cc851568a Updated tests to use @discardableResult and _ = . 2016-05-11 22:53:38 -04:00
Chris Lattner
2c81c8a114 add some parens to the testsuite, NFC. 2016-05-05 23:19:08 -07:00
Chris Lattner
8746676616 Move @noescape and @autoclosure to their new places in various tests, NFC. 2016-04-15 16:05:35 -07:00
Manav Gabhawala
7928140f79 [SE-0046] Implements consistent function parameter labels by discarding extraneous parameter names and adding _ where necessary 2016-04-06 20:21:58 -04:00
Chris Lattner
514ec31114 Progress towards SR-1069:
- Fix ExprTypeSaverAndEraser to save & restore the invalid bit on closure parameter decls.
 - Teach CalleeCandidateInfo::evaluateCloseness to not try to find generic subs on types that
   contain a unresolved type within them.

With these changes, the compiler doesn't segfault on the testcase when assertions are
enabled.  It still doesn't produce a great diagnostic though.
2016-03-29 22:33:07 -07:00
Max Moiseev
859db53d87 Merge remote-tracking branch 'origin/master' into swift-3-api-guidelines 2016-03-01 12:56:26 -08:00
gregomni
545a3f913d [SR-832][Sema] Fix for function type args passed to @autoclosure params
Passing a function type to an @autoclosure param would always fail to
type check because of the attempt to decompose the parallel structure
of the two (both being functions). In this case, though, we don’t want
to do any such thing, we want to allow the ExprRewriter to explicitly
insert an AutoClosureExpr in coerceToType, as it would do with any
other non-function arg type.
2016-02-29 23:43:37 -08:00
Max Moiseev
a49dab6bf8 Merge remote-tracking branch 'origin/master' into swift-3-api-guidelines 2016-02-29 12:08:52 -08:00
Daniel Duan
780b58a9a5 [Parser] update tests for 'inout' syntax adjustment 2016-02-26 01:33:22 -08:00
Doug Gregor
7d70b704e4 Merge commit '5e11e3f7287427d386636a169c4065c0373931a8' into swift-3-api-guidelines 2016-01-19 23:18:20 -08:00
Chris Lattner
a5a988e726 Fix rdar://22509125 QoI: Error when unable to infer generic archetype lacks greatness
Rearrange diagnoseGeneralConversionFailure to diagnose structural problems
even if we have some UnresolvedTypes floating around, then reject constraint
failures with UnresolvedTypes in them even harder.  This keeps us giving
good errors about failures where we have a structural problem (with buried
irrelevant details) while not complaining about cases that are actually
ambiguous.

The end result of this is that we produce a lot better error messages in the
case of failed archetype inference.  This also highlights the poor job we do
handling multi-stmt closureexprs...
2016-01-11 20:45:11 -08:00
Max Moiseev
f51e708a8f Merge remote-tracking branch 'origin/master' into swift-3-api-guidelines 2016-01-04 12:25:25 -08:00