Commit Graph

656 Commits

Author SHA1 Message Date
Slava Pestov
eed84abda9 Sema: Add TVO_CanBindToNoEscape
We have a systemic class of issues where noescape types end up bound to
type variables in places that should not. The existing diagnostic for
this is ad-hoc and duplicated in several places but it doesn't actually
address the root cause of the problem.

For now, I've changed all call sites of createTypeVariable() to set the
new flag. I plan on removing enough occurrences of the flag to replicate
the old diagnostics. Then we can continue to refine this over time.
2019-04-16 23:01:33 -04:00
Slava Pestov
a3c15f2f6b Sema: References to TypeDecls should always be TypeExpr
In a few corner cases we built DeclRefExpr and MemberRefExpr
for references to types. These should just be TypeExpr so that
SILGen doesn't have to deal with it.

This also fixes a bug where a protocol typealias with an
unbound generic type could not be accessed properly from
expression context, but that is just so incredibly obscure.
2019-04-14 23:28:13 -04:00
Slava Pestov
1889d5aa45 Sema: Correctly simplify member types with a DynamicSelfType base
Fixes <https://bugs.swift.org/browse/SR-10434>, <rdar://problem/49779783>.
2019-04-12 01:00:19 -04:00
Pavel Yaskevich
93f9cb1d2a [ConstraintLocator] Identify whether locator is a result of keypath dynamic member lookup or belongs to keypath subscript component 2019-04-10 13:51:19 -07:00
Pavel Yaskevich
3288299e1e [ConstraintSystem] Make sure that each index argument of keypath subscript is Hashable
Move checking for index Hashable conformance from CSApply (post-factum)
to the solver and use recorded conformance records complete subscript
components.
2019-04-10 13:50:34 -07:00
Pavel Yaskevich
16b65018b4 Merge pull request #23436 from xedin/keypath-dynamic-lookup
[SE-0252][TypeChecker] Keypath Dynamic Member Lookup
2019-04-05 00:10:53 -07:00
Pavel Yaskevich
e3ad92fbfb [ConstraintSystem] Allow to use keypath dynamic member lookup inside keypath expressions 2019-04-03 11:01:48 -07:00
Brent Royal-Gordon
67af97c4db [NFC] Correct constraint system assumption
We currently assume that, if a subscript is declared within a value type’s decl, it must need `self` to be passed inout. This isn’t true for static subscripts, because even though the DeclContext is a value type, the metatype is actually a reference type. Skip this check for non-instance members.

NFC until static subscripts are added.
2019-04-01 18:04:00 -07:00
Pavel Yaskevich
8f880545cd [TypeChecker] Add ReferenceWritableKeyPath support to keypath dynamic member lookup 2019-04-01 12:41:55 -07:00
Pavel Yaskevich
d4bbcc1953 [TypeChecker] Add subscript support keypath dynamic member lookup 2019-04-01 12:40:39 -07:00
Pavel Yaskevich
2c82882b8f [ConstraintSystem] Move unviable keypath dynamic member check into performMemberLookup 2019-04-01 12:40:39 -07:00
Pavel Yaskevich
9eed0135fa [CSSolver] Don't generate implicit argument for keypath dynamic lookup
Implicit argument expression was necessary to generate keypath
constraint which is used to validate a choice picked for the member.
But since read-only check has been factored out it's now possible
to validate choice directly in combination with new 'keypath dynamic lookup'
locator associated with member type variable which represents result
of the dynamic lookup.
2019-04-01 12:40:39 -07:00
Pavel Yaskevich
cde23eccc8 [ConstraintSystem] Implement keypath dynamic member lookup
Implement keypath based dynamic member lookup which augments
functionality of existing @dynamicMemberLookup attribute.

Two new subscript overloads are accepted:

```
subscript(dynamicMember member: KeyPath<T, ...>) -> ...
subscript(dynamicmember member: WritableKeyPath<T, ...>) -> ...
```

Example:

```swift
struct Point {
  let x: Int
  var y: Int
}

@dynamicMemberLookup struct Lens<T> {
  var obj: T

  init(_ obj: T) {
    self.obj = obj
  }

  subscript<U>(dynamicMember member: KeyPath<T, U>) -> Lens<U> {
    get { return Lens<U>(obj[keyPath: member]) }
  }

  subscript<U>(dynamicMember member: WritableKeyPath<T, U>) -> Lens<U> {
    get { return Lens<U>(obj[keyPath: member]) }
    set { obj[keyPath: member] = newValue.obj }
  }
}

var lens = Lens(Point(x: 0, y: 0))

_ = lens.x // converted into `lens[dynamicMember: KeyPath<Point, Int>`
_ = lens.y = Lens(10) // converted into `lens[dynamicMember: WritableKeyPath<Point, Int>]`
```
2019-04-01 12:40:39 -07:00
Pavel Yaskevich
f95d9b092e [TypeChecker] Add new type of overload choice to support keypath dynamic lookup 2019-04-01 12:40:39 -07:00
Pavel Yaskevich
8e420496b2 [ConstraintSystem] Delay adding contextual requirements until parent type is opened
`openUnboundGenericType` eagerly tries to add conditional requirements
associated with chain of parents of the given type if type has been
declared inside of constrained extension. But one of the parent types
might be unbound e.g. `A.B` which means it has to be opened, which
by itself, would add such requirements.

Resolves: rdar://problem/49371608
2019-03-28 22:08:33 -07:00
Pavel Yaskevich
bdf21be00c [ConstraintSystem] NFC: Add hasFix() to DisjunctionChoice 2019-03-14 13:18:42 -07:00
Pavel Yaskevich
7633d012e5 [ConstraintSystem] Attach fixes to incorrectly referenced or unviable overloads
Instead of waiting until the overload is attempted, let's figure out
if there is anything wrong with it beforehand and attach a fix to the
"bind overload" constraint representing it.
2019-03-13 12:09:12 -07:00
Pavel Yaskevich
70c59afb40 [ConstraintSystem] Move "outer" candidates handling to simplifyMemberConstraint
Further simplify `addOverloadSet` and move "outer" candidate handling
to the only place where it comes up - `simplifyMemberConstraint`.
Also move constraint generation for choices into a separate method.

This is a stepping stone on the path to enable attaching fixes to
the overload choices.
2019-03-12 14:46:35 -07:00
Pavel Yaskevich
54290c7840 [ConstraintSystem] Prefer a single local choice over outer alternatives
This is a follow-up to https://github.com/apple/swift/pull/23194,
which broke a case were single local overload choice was preferred
over any number of outer alternatives.
2019-03-11 17:01:15 -07:00
Pavel Yaskevich
c2590c0dec [ConstraintSystem] Simplify addOverloadSet
- Remove whole disjunction favoring which has no effect;
- Avoid creating separate disjunction for "inner" choices,
  which is going to be flattened later anyway.
2019-03-08 18:25:32 -08:00
Doug Gregor
fd50d945ce [Constraint system] Move SIMD operator partitioning into disjunction partitioning
Continuing along my path to move application-independent partitioning
rules into the common disjunction partitioning code.
2019-03-05 15:01:46 -08:00
Doug Gregor
b993c6e076 [Constraint solver] Move tryOptimizeGenericDisjunction() into partitioning
This narrow favoring rule makes more sense as part of disjunction
partitioning, because it is not dependent on the use site at all and
should only kick in when other options fail.
2019-03-05 15:01:46 -08:00
Doug Gregor
d2c7c8d5ee [Constraint solver] Enable favoring of disjunction constraints during solving
Allow constraints to be favored during solving, and unwound after exiting
that particular solver scope. We're not using this yet.
2019-03-05 10:30:51 -08:00
Doug Gregor
c0917c90d2 [Constraint solver] Revert the "common type" optimization.
The "common type" optimization isn't really buying us anything at this
point, because we're not able to make much use of the common structure
often enough. Revert the "common type" optimization for now... I'll
bring it back when there's enough optimization infrastructure around
it to make it compelling.
2019-03-04 15:00:45 -08:00
Doug Gregor
e5613296fd [Constraint solver] Minor cleanup for @optional declarations. 2019-03-01 23:10:01 -08:00
Doug Gregor
6246e7e1db [Constraint solver] Fix effective-overload-type for constructors, dynamic Self
Implement support for querying the effective overload type for constructors
and fix a semi-related bug for methods returning dynamic Self, which I
had not accounted for.
2019-03-01 23:10:01 -08:00
Doug Gregor
233cf6ffa6 [Constraint solver] Address feedback from Pavel and Slava. 2019-03-01 20:54:48 -08:00
Doug Gregor
4097428df9 [Constraint solver] Declarations with IUOs don’t have effective overload types
A declaration with an implicitly-unwrapped optional essentially has two
effective overload types, because the result might be optional or it might
have been forced. Disable computation of the effective overload type in this
case.
2019-03-01 09:45:24 -08:00
Doug Gregor
bdc961d8c6 [Constraint solver] Do argument label matching during apply simplification.
When simplifying a function application constraint, check the argument
labels for that application against the disjunction containing the overload
set, disabling any overloads with mis-matching labels. This is staging for
several different directions:

* Eliminating the argument label matching from performMemberLookup, where it
does not belong
* More aggressively filtering the overload set when we have some concrete
information about argument types
* Identifying favored constraints when we have some concrete information
about argument types

At present, the only easily-visible effect of this change is that
we now properly handle argument label matching for non-member functions.
2019-02-28 23:53:08 -08:00
Doug Gregor
76c7b63fa4 [Constraint solver] Fix a typo in a comment (in both places it is used). 2019-02-28 09:03:19 -08:00
Doug Gregor
202d52135d [Constraint system] Generalize effective-overload-type computation.
Extend the computation of effective overload types, used in common result
type and common type computations, to also handle subscripts and variables.
This allows the optimization to also apply to subscripts, which did not
previously have a peephole in constraint generation.
2019-02-27 23:30:03 -08:00
Doug Gregor
5f99d91ea8 [Constraint solver] Compute common apply result type in the solver.
Constraint generation for function application expressions contains a simple
hack to try to find the common result type for an overload set containing
callable things. Instead, perform this “common result type” computation
when simplifying an applicable function constraint, so it is more
widely applicable.
2019-02-27 23:30:03 -08:00
Doug Gregor
86d14a8be8 Merge pull request #22858 from DougGregor/constraint-system-common-type-overloads
[Constraint system] Compute and use a common type among overloads.
2019-02-26 15:39:18 -08:00
Doug Gregor
7bc3dfb223 [Constraint solver] Ignore type declarations in "common type" computation.
Type declarations are handled somewhat specially by the constraint
solver when applied, so temporarily exclude them from the "common
type" computation.
2019-02-24 14:05:03 -10:00
Doug Gregor
1ab417cd8e [Constraint system] Compute and use a common type among overloads.
Given an overload set, attempt to compute a "common type" that
abstracts over all entries in the overload set, providing more
structure for the constraint solver.
2019-02-22 21:53:34 -10:00
Suyash Srijan
34f8670d2a [CS] Use fixes to diagnose instance member on type (or vice versa) access (#21830)
This PR migrates instance member on type and type member on instance diagnostics handling to use the new diagnostics framework (fixes) and create more reliable and accurate diagnostics in such scenarios.
2019-02-22 16:57:26 -08:00
Pavel Yaskevich
5f47862d7c [ConstraintLocator] Add generic signature to OpenedGeneric element
This information is useful for requirement diagnostics, because
generic signature represents the source of generic requirements.
2019-02-14 00:34:18 -08:00
Slava Pestov
e18a61c3b4 Sema: Remove unused parameter from getTypeOfReference() 2019-02-07 23:46:31 -05:00
Pavel Yaskevich
1d42e16ad2 [ConstraintSystem] Detect invalid implicit ref to initializer on non-const metatype
Situations like:

```swift
struct S {}
func foo(_ s: S.Type) {
  _ = s()
}
```

Used to be diagnosed in solution application phase, which means that
solver was allowed to formed an incorrect solution.
2019-02-07 00:17:07 -08:00
Pavel Yaskevich
1d8cee9cb4 [ConstraintSystem] Detect invalid initializer references early
Currently invalid initializer references are detected and
diagnosed in solution application phase, but that's too
late because solver wouldn't have required information while
attempting to determine the best solution, which might result
in viable solutions being ignored in favour of incorrect ones e.g.

```swift
protocol P {
  init(value: Int)
}

class C {
  init(value: Int, _: String = "") {}
}

func make<T: P & C>(type: T.Type) -> T {
  return T.init(value: 0)
}
```

In this example `init` on `C` would be preferred since it
comes from the concrete type, but reference itself is invalid
because it's an attempt to construct class object using
metatype value via non-required initalizer.

Situations like these should be recognized early and invalid
use like in case of `C.init` should be ranked lower or diagnosed
if that is the only possible solution.

Resolves: rdar://problem/47787705
2019-02-05 10:25:36 -08:00
Pavel Yaskevich
174fd14090 [CSDiagnostics] Diagnose invalid partial application of init delegation 2019-01-25 14:18:04 -08:00
Pavel Yaskevich
7d830cee8b [ConstraintSystem] Add a fix to detect invalid partial application
Currently supported only partial applications of instance methods
marked as `mutating`.
2019-01-25 13:29:11 -08:00
Pavel Yaskevich
fe9376dd78 Merge pull request #22082 from xedin/move-weights-to-cs
[ConstraintSystem] Track AST depth information directly
2019-01-24 11:53:17 -08:00
Pavel Yaskevich
e604261805 [ConstraintSystem] Track AST depth information directly
Instead of storing information about expression depths in the
solver state (which gets recomputed for salvage) let's track
it directly in constraint system, which also gives solver
access to it when needed e.g. for fixes.
2019-01-23 18:44:53 -08:00
Pavel Yaskevich
49c40d92f6 [AST] Augment getDepthMap with information about parent expressions
Which is very useful for the solver because otherwise it'd have to
compute and store this information twice.
2019-01-23 18:21:07 -08:00
David Ungar
584c157796 WIP move info to KnownProtocols.def, unformatted 2019-01-17 11:15:58 -08:00
Slava Pestov
6f15193ac3 Merge pull request #21846 from slavapestov/bind-constraint-more
Sema: Use ConstraintKind::Bind where possible instead of ::Equal
2019-01-14 17:56:14 -05:00
Pavel Yaskevich
69c622fc06 Merge pull request #21783 from xedin/rdar-30933988
[AST] `Decl::is*AccessibleFrom` methods should respect access control…
2019-01-14 14:06:44 -08:00
Slava Pestov
e99607c421 Sema: Use ConstraintKind::Bind where possible instead of ::Equal
Solving Bind is a little easier than Equal. The only remaining uses of Equal
are in the .member syntax and keypaths; if we can refactor those, we might be
able to simplify LValue handling in the type checker in general.
2019-01-14 14:55:16 -05:00
Slava Pestov
33871548b3 Clean up TypeVariableType::Implementation::mustBeMaterializable(), etc 2019-01-12 14:10:11 -05:00