Commit Graph

2166 Commits

Author SHA1 Message Date
omochimetaru
484606dc3a [ConstraintSystem] Fix bug of argument reordering in matchCallArguments 2020-03-12 11:19:28 +09:00
Hamish Knight
b62c9b6b01 [CS] Use getParameterType for KeyPath as function
Previously we were using `getPlainType` to match
the parameter type against the key path's base
type. This gave us the external parameter type,
which would be the element type for a variadic
parameter.  However the code we generate expects
the internal parameter type, which is provided by
`getParameterType`.

Resolves rdar://problem/59445486.
2020-03-11 17:21:28 -07:00
Doug Gregor
a3979da1cd Merge pull request #30322 from DougGregor/function-builders-extras
[Function builders] Additional entry points
2020-03-11 16:17:27 -07:00
Doug Gregor
f0530d0a77 [Function builders] Support buildOptional(_:) in lieu of buildIf(_:).
Line up with the function builders pitch, which uses buildOptional(_:)
to build optional values.
2020-03-09 21:48:15 -07:00
Doug Gregor
ce97d22f21 [Function builders] Add support for buildFinalResult().
When present in a function builder, buildFinalResult() will be called on
the value of the outermost block to form the final result of the closure.
This allows one to collapse the full function builder computation into
a single result without having to do it in each buildBlock() call.
2020-03-09 00:10:07 -07:00
Pavel Yaskevich
135287871b [TypeChecker] NFC: Add a test-case for rdar://problem/60185506 2020-03-07 20:37:34 -08:00
Pavel Yaskevich
0ecedfa5ea Revert "[ConstraintSystem] Make it possible to infer subtype bindings through argument conversions"
Reverts apple/swift#30006. It caused a regression that we'd like to address before re-landing:

```swift
struct X {
  var cgf: CGFloat
}

func test(x: X?) {
  let _ = (x?.cgf ?? 0) <= 0.5
}
```

This reverts commit 0a6b444b49.
This reverts commit ed255596a6.
This reverts commit 3e01160a2f.
This reverts commit 96297b7e39.

Resolves: rdar://problem/60185506
2020-03-07 20:16:56 -08:00
Doug Gregor
1a981f917c [Constraint system] Clean up constraints associated with patterns.
Wherever we have constraints that involve pattern matching, use the
PatternMatch locator element. Additionally, don't use the TupleElement
locator element for tuple patterns, because it violates assumptions used
for diagnostics.

The new test was crashing; now it has a terrible diagnostic for which I
need to think harder about a fix.
2020-03-05 23:06:21 -08:00
Doug Gregor
6a5069d017 Merge pull request #30245 from xedin/rdar-60061646
[ConstraintSystem] Make sure pattern matching tuple destructuring works both ways
2020-03-05 21:48:30 -08:00
Holly Borla
f8de43b63b Merge pull request #30251 from hborla/invalid-optional-chaining
[ConstraintSystem] Don't assume the lhs type is for a generic parameter in simplifyConformsToConstraint.
2020-03-05 16:45:37 -08:00
Holly Borla
f77ea028b8 Merge pull request #30248 from hborla/unnamed-closure-param
[Parse] Mark closure parameters as definitively not destructured in parseClosureSignatureIfPresent.
2020-03-05 15:35:25 -08:00
Holly Borla
6898fbb0ef [ConstraintSystem] Don't assume the lhs type is for a
generic parameter in simplifyConformsToConstraint.
2020-03-05 14:39:30 -08:00
Pavel Yaskevich
1f222f307e [ConstraintSystem] Make sure pattern matching tuple destructuring works both ways
Consider following example:

```swift
enum E {
  case foo((x: Int, y: Int))
  case bar(x: Int, y: Int)
}

func test(e: E) {
  if case .foo(let x, let y) = e {}
  if case .bar(let tuple) = e {}
}
```

Both of `if case` expressions have to be supported:

1. `case .foo(let x, let y) = e` allows a single tuple
   parameter to be "destructured" into multiple arguments.

2. `case .bar(let tuple) = e` allows to match multiple
   parameters with a single tuple argument.

Resolves: rdar://problem/60061646
2020-03-05 14:05:35 -08:00
Holly Borla
3634b4366c [Parse] Mark closure parameters as definitively not destructured in
parseClosureSignatureIfPresent.

Otherwise, closure parameters that were parsed as "potentially destructured"
will fail constraint generation, even after the parser has decided
they are not destructured.
2020-03-05 13:45:37 -08:00
Pavel Yaskevich
8b6f66b245 Merge pull request #30223 from xedin/rdar-60048356
[ConstraintSystem] Preserve label matching rules in pattern matching …
2020-03-05 09:23:45 -08:00
Pavel Yaskevich
8ce5c7794b Merge pull request #30232 from xedin/rdar-60047439
[ConstraintSystem] Check availability as part of resolving overload c…
2020-03-05 09:23:04 -08:00
Pavel Yaskevich
4c600843d6 [ConstraintSystem] Check availability as part of resolving overload choice
This is a follow up to changes related to contextual availability
(https://github.com/apple/swift/pull/29921) which increased score
for unavailable declarations only if they were overloaded but
overlooked a case of a single unavailable choice.

Resolve: rdar://problem/60047439
2020-03-05 00:35:47 -08:00
Pavel Yaskevich
87878a65eb [ConstraintSystem] Preserve label matching rules in pattern matching context
Since constraint system now handles pattern matching it has
to preverse label matching semantics which existed in original
code: if pattern element has a label it has to match the one
in the tuple type it's matched against.

Resolves: rdar://problem/60048356
2020-03-04 23:09:31 -08:00
Doug Gregor
c0cf407565 [Constraint solver] Check case variable mutability consistency. 2020-03-04 22:46:36 -08:00
Doug Gregor
3887498e55 [Constraint system] Diagnose @unknown cases in function builders. 2020-03-04 22:46:36 -08:00
Doug Gregor
c962e48b35 [Function builders] Test with an lvalue subject 2020-03-04 22:46:36 -08:00
Holly Borla
516b3e43cd Merge pull request #30195 from hborla/function-builder-crash
[ConstraintSystem] Bail out of applyFunctionBuilderBodyTransform if there is a failure in constraint generation.
2020-03-04 06:52:18 -08:00
Holly Borla
24d8aa148f Merge pull request #30185 from hborla/dependent-type-requirement-failure
[ConstraintSystem] Replace dependent member types with holes when the…
2020-03-03 19:55:07 -08:00
Holly Borla
e3239ba5fc [ConstraintSystem] Bail out of applyFunctionBuilderBodyTransform if
there is a failure in constraint generation.
2020-03-03 19:32:06 -08:00
Doug Gregor
12f8b51921 Merge pull request #30189 from DougGregor/function-builders-switch-exhaustive
[Constraint solver] Check switch exhaustiveness in function builders
2020-03-03 18:48:39 -08:00
Holly Borla
fce8738ea8 [ConstraintSystem] Replace dependent member types with holes when the base type
doesn't conform to the associatedtype's protocol (only in diagnostic mode).

This allows the solver to find solutions for more cases involving requirement
failures for dependent member types without special cases across the solver
that check for dependent member types with no type variables.
2020-03-03 15:45:24 -08:00
Doug Gregor
7ee33a920d [Constraint solver] Check switch exhaustiveness in function builders 2020-03-03 13:44:36 -08:00
Doug Gregor
8191aa4924 Merge pull request #30174 from DougGregor/function-builder-switch
[Constraint system] Implement switch support for function builders.
2020-03-03 12:34:08 -08:00
Doug Gregor
ea8d143f64 [Constraint system] Introduce a one-way constraint for a switch subject.
The normal type checking of switch statements checks the switch subject
first, without context, then evaluates the cases. Introduce a one-way
constraint into the type checking of switch statements within function
builders to provide this same behavior. The difference can be observed
in code such as:

    enum E {
      case a
      case b(Int, String?)
    }

    enum E2 {
      case b(Int, String?)
    }

    func getSomeEnumOverloaded(_: Double) -> E { return .a }
    func getSomeEnumOverloaded(_: Int) -> E2 { return .b(0, nil) }

    func f() {
      switch getSomeEnumOverloaded(17) {
      case .a:  // error: no member named "a" in E2
        print("a")
      default:
        print("default")
      }
    }

When the subject expression `getSomeEnumOverloaded(17)` is resolved
without consider cases, it will select the second
`getSomeEnumOverloaded(_:)`, because the literal 17 prefers to be
an `Int`. The type checking of the first case would then fail because E2
does not contain a member named "a".

Prior to this change, the same expression within a function
builder would succeed in type checking, because the lack of case named
"a" within "E2" would make the second getSomeEnumOverloaded() unusable.

Making this code work by considering the cases along with the subject
expression is not unreasonable, and may be the right long term
direction for the language. However, it's a feature that should be
discussed separately, and the semantics should agree between function
builders and normal statements.

Big thanks to John McCall for noting the missing one-way constraint!
2020-03-03 08:51:26 -08:00
Pavel Yaskevich
f7b264583d [Diagnostic] Don't fix partial mismatch for sub-types associated with optional conversion
If mismatch detected by `repairFailures` is related to a complex
wrapped value of optional type formed from optional-to-optional
or value-to-optional conversion let's not try to fix it directly
but let `simplifyRestrictedConstraintImpl` record a top-level fix
for more context.

Resolves: rdar://problem/59703585
2020-03-03 00:24:34 -08:00
Doug Gregor
4b43573693 [Constraint system] Implement switch support for function builders.
Implement support for switch statements within function builders. Cases can
perform arbitrary pattern matches, e.g.,

    tuplify(true) { c in
      "testSwitchCombined"
      switch e {
      case .a:
        "a"
      case .b(let i, _?), .b(let i, nil):
        i + 17
      }
    }

subject to the normal rules of switch statements. Cases within function
builders cannot, however, include “fallthrough” statements, because those
(like “break” and “continue”) are control flow.

The translation of performed for `switch` statements is similar to that of
`if` statements, using `buildEither(first:)` and `buildEither(second:)` on
the function builder type.

This is the bulk of switch support, tracked by rdar://problem/50426203.
2020-03-02 17:25:25 -08:00
Pavel Yaskevich
0cd44a83a7 [ConstraintSystem] Don't record general contextual mismatch if there are restrictions present
If there are any conversion restrictions present while trying to repair
failures related to contextual type, let's give `simplifyRestrictedConstraintImpl`
a chance to run and fix the problem.

Resolves: rdar://problem/59773317
2020-03-02 11:07:31 -08:00
Pavel Yaskevich
c0b9394c42 Merge pull request #30113 from xedin/rdar-54580247
[CSBindings] Open collection before binding parameter only if origina…
2020-02-28 00:01:27 -08:00
Pavel Yaskevich
20fc51d4f4 [CSBindings] Open collection before binding parameter only if original argument type failed
Instead of always opening argument type represented by a collection
without type variables (to support subtyping when element is a labeled tuple),
let's try original type first and if that fails use a slower path with
indirection which attempts `array upcast`. Doing it this way helps to
propagate contextual information faster which fixes a performance regression.

Resolves: rdar://problem/54580247
2020-02-27 16:26:13 -08:00
Slava Pestov
019452f9af Sema: Diagnose unbound method references on 'super.'
This is something I noticed by inspection while working on
<https://bugs.swift.org/browse/SR-75>.

Inside a static method, 'self' is a metatype value, so
'self.instanceMethod' produces an unbound reference of type
(Self) -> (Args...) -> Results.

You might guess that 'super.instanceMethod' can similarly
be used to produce an unbound method reference that calls
the superclass method given any 'self' value, but unfortunately
it doesn't work.

Instead, 'super.instanceMethod' would produce the same
result as 'self.instanceMethod'. Maybe we can implement this
later, but for now, let's just diagnose the problem.

Note that partially-applied method references with 'super.'
-- namely, 'self.staticMethod' inside a static context, or
'self.instanceMethod' inside an instance context, continue
to work as before.

They have the type (Args...) -> Result; since the self value
has already been applied we don't hit the representational
issue.
2020-02-27 17:28:23 -05:00
Pavel Yaskevich
65ab041805 Merge pull request #29868 from omochi/fix-claimNextNamed
[ConstraintSystem] remove unused computation in claimNextNamed
2020-02-26 22:07:42 -08:00
omochimetaru
79a8a596e4 [ConstraintSystem] remove unused computation in claimNextNamed 2020-02-27 10:49:42 +09:00
Doug Gregor
031f5a4888 Merge pull request #30065 from DougGregor/function-builders-if-case-fixes
[Constraint system] Cleanups for function builders support for if let/if case let
2020-02-26 10:38:15 -08:00
Pavel Yaskevich
0e88bd6890 [ConstraintSystem] Don't attempt bindings for closure parameters/result until body is opened
Let's delay attempting any bindings for type variables representing
parameters or result type of the closure until the body is "opened"
because it's impossible to infer a full set of bindings until all
constraints related to a closure have been generated.

Resolves: rdar://problem/59741308
2020-02-25 17:42:37 -08:00
Pavel Yaskevich
9ae68133ff Merge pull request #30040 from xedin/sr-11743
[ConstraintSystem] Look through l-value while checking whether dynami…
2020-02-25 17:09:45 -08:00
Doug Gregor
8482516412 [Constraint system] Properly deal with "as" patterns.
Teach pattern matching involving "as" patterns to work properly in
function builders. The code almost handled this, but prematurely
prechecking expressions in patterns broke it.
2020-02-25 16:29:07 -08:00
Doug Gregor
cc8db01ba9 Merge pull request #30045 from DougGregor/function-builders-if-let
[Constraint system] Support if let / if case in function builders.
2020-02-25 16:24:09 -08:00
Doug Gregor
4830c48960 [Constraint system] Support if let / if case in function builders.
Use the generalized constraint generation and binding for patterns to
introduce support for if-let and if-case in function builders, handling
arbitrary patterns.

Part of function builder generalization, rdar://problem/50426203.
2020-02-25 09:44:06 -08:00
Pavel Yaskevich
7d4db41180 [TypeChecker] NFC: Add one more test-case for SR-11743 2020-02-25 08:55:00 -08:00
Doug Gregor
fe5c068ffb Merge pull request #29879 from DougGregor/constraint-system-patterns
[Constraint system] Generate constraints from patterns
2020-02-24 20:41:14 -08:00
Pavel Yaskevich
2cdd78501c [ConstraintSystem] Look through l-value while checking whether dynamic key path is recursive
Fix a crash in dynamic member lookup attempting to recursively
lookup a member on the same base type.

The problem is related to `isSelfRecursiveKeyPathDynamicMemberLookup`
which failed to look through l-value wrapping base type on each side of
the comparison, that's important because it's possible to have l-value
mismatch due to the fact that implicit call always gets l-value base
type but actual subscript which triggered dynamic lookup might be r-value.

Resolves: [SR-11743](https://bugs.swift.org/browse/SR-11743)
Resolves: rdar://problem/57091169
2020-02-24 19:38:20 -08:00
Pavel Yaskevich
b926250c70 Merge pull request #30006 from xedin/rdar-56212087
[ConstraintSystem] Make it possible to infer subtype bindings through argument conversions
2020-02-24 14:18:35 -08:00
Doug Gregor
dcf7ddeb3a [Constraint system] Generate constraints for EnumElement patterns.
Generate a complete set of constraints for EnumElement patterns, e.g.,

    case let .something(x, y)

Most of the complication here comes from the implicit injection of optionals,
e.g., this case can be matched to an optional of the enum type of which
`something` is a member. To effect this change, introduce a locator for
pattern matching and use it to permit implicit unwrapping during member
lookup without triggering an error.

Note also labels are dropped completely when performing the match,
because labels can be added or removed when pattern matching. Label
conflict are currently diagnosed as part of coercePatternToType, which
suffices so long as overloading cases based on argument labels is not
permitted.

The primary observable change from this commit is in diagnostics: rather
than diagnostics being triggered by `TypeChecker::coercePatternToType`,
diagnostics for matching failures here go through the diagnostics machinery
of the constraint solver. This is currently a regression, because
there are no custom diagnostics for pattern match failures within the
constraint system. This regression will be addressed in a subsequent
commit; for now, leave those tests failing.
2020-02-24 00:48:15 -08:00
Nate Cook
c6183ee71b Add RangeSet and discontiguous collection operations (#28161)
This adds the RangeSet and DiscontiguousSlice types, as well as collection
operations for working with discontiguous ranges of elements. This also adds
a COWLoggingArray type to the test suite to verify that mutable collection
algorithms don't perform unexpected copy-on-write operations when mutating
slices mid-operation.
2020-02-22 15:33:03 -06:00
Pavel Yaskevich
96297b7e39 [CSStep] Always attempt literal bindings in diagnostic mode
In case of contextual failures such bindings could produce
better solutions with fewer fixes.
2020-02-21 17:47:39 -08:00