Commit Graph

730 Commits

Author SHA1 Message Date
Slava Pestov
24de1913ac GSB: Merge collectRequirements() with enumerateRequirements() 2021-02-25 17:19:23 -05:00
Slava Pestov
e0c7627598 GSB: getBestConstraintSource() never returns nullptr 2021-02-25 17:19:23 -05:00
Slava Pestov
b9f5267ac1 GSB: Stop printing enumerated requirements in dump()
The call to enumerateRequirements() here actually makes debugging
more difficult, since it has a lot of side effects, for example
calling maybeResolveEquivalenceClass() and removeSelfDerived().

Also, this is the only usage of enumerateRequirements() other than
collectRequirements(), which allows the two to be merged together
and simplified.
2021-02-25 17:19:23 -05:00
Slava Pestov
34d3236316 GSB: Avoid re-resolving FloatingRequirementSources 2021-02-24 16:33:38 -05:00
Slava Pestov
39397d76a1 GSB: Remove HadAnyRedundantConstraints
Redundant requirements no longer pose a problem for the new
getConformanceAccessPath() implementation.
2021-02-23 16:26:04 -05:00
Slava Pestov
d492a53bf1 GSB: Remove unused SourceLoc parameter from computeGenericSignature() 2021-02-22 23:06:27 -05:00
Slava Pestov
3d5ca29993 GSB: Dump conformance and same-type requirement sources in EquivalenceClass::dump() 2021-02-18 22:35:00 -05:00
Slava Pestov
44dac01d99 GSB: Fix getMinimalConformanceSource() for top-level requirements in a requirement signature
Consider the following program:

protocol P1 {
  associatedtype A : P2
}

protocol P2 {
  associatedtype A
}

func f<T>(_: T) where T : P2, T.A : P1, T.A.A == T {}

There are two proofs of T : P2:

- The explicit requirement in f()'s generic signature.

- Since T.A.A == T, we can also prove T : P2 via T.A.A : P2:
  - First, we prove that T.A : P1 via the explicit requirement
    in f()'s generic signature.
  - Second, we prove that T.A.A : P1 via Self.A : P2 in P1's
    requirement signature.

However, the second proof does not render the explicit requirement
T : P2 redundant, because it relies on the existence of the
nested type T.A, which only exists if T : P2.

This is captured in getMinimalConformanceSource(), which returns
nullptr for the requirement source corresponding to the second proof
above. It does this by looking at the root type of the requirement
source, T.A.

Now consider the analogous situation but with protocols -- let's
replace f() with a protocol P3:

protocol P3 : P2 where Self.A : P1, Self.A.A == Self {}

Here, we also have two proofs of Self : P2:

- The explicit requirement in P3's requirement signature.
  - First, we prove that Self.A : P1 via the explicit requirement
    in P3's requirement siganture.
  - Second, we prove that Self.A.A : P1 via Self.A : P2 in P1's
    requirement signature.

Once again, the second proof implicitly depends on the explicit
requirement, so we cannot use it to mark the explicit requirement
as redundant. However, since the requirement source root type here
is just 'Self', we were unable to recognize this, and we would
diagnose the requirement as redundant and drop it, resulting in
computing an invalid requirement signature for protocol P3.

To fix this, handle requirements at the top level of a protocol
requirement signature just like they are explicit requirements.

Fixes https://bugs.swift.org/browse/SR-13850 / rdar://problem/71377571.
2021-02-18 22:35:00 -05:00
Slava Pestov
034c2be004 GSB: An unresolved DependentMemberType might resolve to a concrete TypeAliasDecl with a dependent underlying type
Fixes https://bugs.swift.org/browse/SR-11639 / rdar://problem/56466696
2021-02-12 17:47:31 -05:00
Slava Pestov
8edf4264ae GSB: Better handling of unresolved DependentMemberTypes in maybeResolveEquivalenceClass()
A DependentMemberType can either have a bound AssociatedTypeDecl,
or it might be 'unresolved' and only store an identifier.

In maybeResolveEquivalenceClass(), we did not handle the unresolved
case when the base type of the DependentMemberType had itself been
resolved to a concrete type.

Fixes <rdar://problem/71162777>.
2021-02-11 16:33:35 -05:00
Richard Wei
18fe723543 Merge pull request #35811 from rxwei/69980056-differentiable-reverse
[AutoDiff] Add '@differentiable(reverse)'.
2021-02-08 04:32:27 -08:00
Richard Wei
af8942d940 [AutoDiff] Rename '@differentiable' to '@differentiable(reverse)'.
Compiler:
- Add `Forward` and `Reverse` to `DifferentiabilityKind`.
- Expand `DifferentiabilityMask` in `ExtInfo` to 3 bits so that it now holds all 4 cases of `DifferentiabilityKind`.
- Parse `@differentiable(reverse)` and `@differentiable(_forward)` declaration attributes and type attributes.
- Emit a warning for `@differentiable` without `reverse`.
- Emit an error for `@differentiable(_forward)`.
- Rename `@differentiable(linear)` to `@differentiable(_linear)`.
- Make `@differentiable(reverse)` type lowering go through today's `@differentiable` code path. We will specialize it to reverse-mode in a follow-up patch.

ABI:
- Add `Forward` and `Reverse` to `FunctionMetadataDifferentiabilityKind`.
- Extend `TargetFunctionTypeFlags` by 1 bit to store the highest bit of differentiability kind (linear). Note that there is a 2-bit gap in `DifferentiabilityMask` which is reserved for `AsyncMask` and `ConcurrentMask`; `AsyncMask` is ABI-stable so we cannot change that.

_Differentiation module:
- Replace all occurrences of `@differentiable` with `@differentiable(reverse)`.
- Delete `_transpose(of:)`.

Resolves rdar://69980056.
2021-02-07 14:09:46 -08:00
Slava Pestov
fd809ca0c9 GSB: Instead of sorting connected components, sort the final requirements
There are fewer of them, since it is possible for the vast
majority of connected components to generate no requirements.
2021-02-07 01:14:52 -05:00
Slava Pestov
65620d75f3 GSB: FloatingRequirementSource::getSource() now takes a ResolvedType 2021-02-07 01:14:52 -05:00
Slava Pestov
df3c87911c GSB: PotentialArchetypes now store their canonical type
Instead of recomputing it on every call to getDependentType(),
we can just store it in there instead of the GenericParamKey
or AssociatedTypeDecl.

We still need to 're-sugar' user-visible dependent types to
get the right generic parameter name; a new getSugaredDependentType()
utility method is called in the right places for that.
2021-02-05 17:23:31 -05:00
Slava Pestov
143b3c18e9 GSB: Remove some dead code 2021-02-05 15:56:29 -05:00
Slava Pestov
5cec731355 GSB: DerivedSameTypeComponent can store a Type instead of a PotentialArchetype * 2021-02-05 15:56:29 -05:00
Anthony Latsis
afcb1665f8 GSB: Handle concrete ResolvedTypes in ArchetypeType::resolveNestedType()
A nested type of an archetype type might be concrete, for example, via a
same-type constraint:

extension SomeProtocol where SomeAssoc == Int {
  ... Self.SomeAssoc ...
}

This can happen in one of two ways; either the EquivalenceClass of the
nested type has a concrete type, or it is "fully concrete" because
there is no equivalence class and maybeResolveEquivalenceClass() returns
a ResolvedType storing the concrete type.

For some reason we didn't handle the second case here.

Fixes https://bugs.swift.org/browse/SR-13519 / rdar://problem/68531679
2021-01-12 23:52:44 -05:00
Slava Pestov
445d747622 AST: Move GenericParamList and friends to GenericParamList.{h,cpp} 2020-09-29 19:51:03 -04:00
Slava Pestov
ce550f2464 AST: Try harder to preserve type sugar in AbstractGenericSignatureRequest
AbstractGenericSignatureRequest tries to minimize the number of GSBs that we
spin up by only creating a GSB if the generic parameter and requirement types
are canonical. If they're not canonical, it first canonicalizes them, then
kicks off a request to compute the canonical signature, and finally, re-applies
type sugar.

We would do this by building a mapping for re-sugaring generic parameters,
however this mapping was only populated for the newly-added generic parameters.

If some of the newly-added generic requirements mention the base signature's
generic parameters, they would remain canonicalized.

Fixes <rdar://problem/67579220>.
2020-08-24 19:16:36 -04:00
Slava Pestov
92bc89b78f GSB: Add an inferred AnyObject constraint to @objc protocol requirement signatures
This simplifies GenericSignatureImpl::requiresClass(), which no longer
has to look through the conformances of the equivalence class.
2020-08-13 00:23:47 -04:00
Slava Pestov
34650e8f3a Merge pull request #32799 from AnthonyLatsis/sself-is-fixed
AssociatedTypeInference: Allow Self as a fixed type witness
2020-08-06 19:43:56 -04:00
Slava Pestov
94c6bff65d AST: Replace some calls to getDeclaredType() with getDeclaredInterfaceType() 2020-07-31 13:39:01 -04:00
Slava Pestov
c46eb22fcd AST: Don't attach trailing where clause requirements to the GenericParamList
Previously we had two representations for the 'where' clause of a
parsed declaration; if the declaration had generic parameters of
its own, we would store them in the GenericParamList, otherwise
we would store them separately in a TrailingWhereClause instance.

Since the latter is more general and also used for protocols and
extensions, let's just use it for everything and simplify
GenericParamList in the process.
2020-07-28 02:07:16 -04:00
Robert Widmann
ec885b027b [NFC] const-qualify Inheritance-Clause-Bearing PointerUnion 2020-07-23 20:45:24 -07:00
Slava Pestov
7e5d566180 GSB: An anchor cannot have a concrete parent type
EquivalenceClass::getAnchor() always returns a canonical type and
the parent of a canonical type is itself be canonical.

This means that EquivalenceClass::getTypeInContext() can safely
assume that the parent type of a DependentMemberType maps to an
ArchetypeType in the GenericEnvironment.

Instead of trying to handle the case where the parent is concrete,
let's just crash by changing the conditional cast to an
unconditional one.
2020-07-21 21:29:12 -04:00
Slava Pestov
b76733b614 GSB: Simplify ResolvedType implementation
We don't need to store the EquivalenceClass anymore.
2020-07-16 23:31:34 -04:00
Slava Pestov
c0d981ad61 GSB: Simplify maybeResolveEquivalenceClass()
When passing in wantExactPotentialArchetype=false, we don't actually ever
call getDependentType() on the result. So the Type + EquivalenceClass form
of ResolvedType can be removed.
2020-07-16 23:31:34 -04:00
Anthony Latsis
28531141d2 AssociatedTypeInference: Self is a valid fixed type witness 2020-07-15 22:34:24 +03:00
Slava Pestov
71e267d5b1 GSB: Teach 'derived via concrete' computation about superclass constraints
Under certain circumstances, introducing a concrete same-type or
superclass constraint can re-introduce conformance constraints
which were previously redundant.

For example, consider this code, which we correctly support today:

protocol P {
  associatedtype T : Q
}

protocol Q {}

class SomeClass<U : Q> {}

struct Outer<T> where T : P {
  func inner<U>(_: U) where T == SomeClass<U>, U : Q {}
}

The constraint 'T == SomeClass<U>' makes the outer constraint
`T : P' redundant, because SomeClass already conforms to P.
It also introduces an implied same-type constraint 'U == T.T'.

However, whereas 'T : P' together with 'U == T.T' make 'U : Q'
redundant, the introduction of the constraint 'T == SomeClass<U>'
removes 'T : P', so we re-introduce an explicit constraint 'U : Q'
in order to get a valid generic signature.

This code path did the right thing for constraints derived via
concrete same-type constraints, but it did not handle superclass
constraints.

As a result, this case was broken:

struct Outer<T> where T : P {
  func inner<U>(_: U) where T : SomeClass<U>, U : Q {}
}

This is the same example as above, except T is related via a
superclass constraint to SomeClass<U>, instead of via a concrete
same-type constraint.

The subtlety here is that we must check if the superclass type
actually conforms to the requirement source's protocol, because it
is possible to have a superclass-constrained generic parameter
where some conformances are abstract. Eg, if SomeClass did not
conform to another protocol P2, we could write

func foo<T, U>(_: T, _: U) where T : SomeClass<U>, T : P2 {}

In this case, 'T : P2' is an abstract conformance on the type 'T'.

The common case where this would come up in real code is when you
have a class that conforms to a protocol with an associated type,
and one of the protocol requirements was fulfilled by a default in
a protocol extension, eg:

protocol P {
  associatedtype T : Q

  func foo()
}

extension P {
  func foo() {}
}

class ConformsWithDefault<T : Q> : P {}

The above used to crash; now it will type-check correctly.

Fixes <rdar://problem/44736411>, <https://bugs.swift.org/browse/SR-8814>..
2020-06-21 23:42:10 -04:00
Anthony Latsis
267e32dcd8 Merge pull request #32118 from AnthonyLatsis/post-increment-cleanup
[NFC] Pre- increment and decrement where possible
2020-06-02 20:10:29 +03:00
Anthony Latsis
9fd1aa5d59 [NFC] Pre- increment and decrement where possible 2020-06-01 15:39:29 +03:00
Varun Gandhi
c14e934563 [NFC] Remove redundant includes for llvm/ADT/SmallSet.h. 2020-05-31 13:07:45 -07:00
Owen Voorhees
45bc578ae5 [SourceManager] Rename line and column APIs for clarity 2020-05-21 12:54:07 -05:00
Slava Pestov
653fa07260 GSB: Fix maybeResolveEquivalenceClass() with member type of superclass-constrained type
Name lookup might find an associated type whose protocol is not in our
conforms-to list, if we have a superclass constraint and the superclass
conforms to the associated type's protocol.

We used to return an unresolved type in this case, which would result in
the constraint getting delayed forever and dropped.

While playing wack-a-mole with regressing crashers, I had to do some
refactoring to get all the tests to pass. Unfortuanately these refactorings
don't lend themselves well to being peeled off into their own commits:

- maybeAddSameTypeRequirementForNestedType() was almost identical to
  concretizeNestedTypeFromConcreteParent(), except for superclasses
  instead of concrete same-type constraints. I merged them together.

- We used to drop same-type constraints where the subject type was an
  ErrorType, because maybeResolveEquivalenceClass() would return an
  unresolved type in this case.

  This violated some invariants around nested types of ArchetypeTypes,
  because now it was possible for a nested type of a concrete type to
  be non-concrete, if the type witness in the conformance was missing
  due to an error.

  Fix this by removing the ErrorType hack, and adjusting a couple of
  other places to handle ErrorTypes in order to avoid regressing with
  invalid code.

Fixes <rdar://problem/45216921>, <https://bugs.swift.org/browse/SR-8945>,
<https://bugs.swift.org/browse/SR-12744>.
2020-05-19 20:28:51 -04:00
Slava Pestov
514a0423b6 GSB: Concretize nested types when adding a superclass constraint
When adding a superclass constraint, we need to find any nested
types belonging to protocols that the superclass conforms to,
and introduce implicit same-type constraints between each nested
type and the corresponding type witness in the superclass's
conformance to that protocol.

Fixes <rdar://problem/39481178>, <https://bugs.swift.org/browse/SR-11232>.
2020-05-15 21:58:58 -04:00
Arnold Schwaighofer
5c4bbf3de9 Merge pull request #31736 from aschwaighofer/fix_protocol_conformance_subst
Existentials don't always conform to a protocol via an abstract confo…
2020-05-13 11:27:25 -07:00
Anthony Latsis
df9103e9d7 [NFC] AST: Const-qualify GenericSignatureImpl 2020-05-13 01:03:08 +03:00
Arnold Schwaighofer
b40b1be41d Existentials don't always conform to a protocol via an abstract conformance
So it is not always correct to use the current conformance when substituting.

rdar://62894495
2020-05-12 12:20:01 -07:00
Anthony Latsis
724c76041d Merge pull request #31555 from AnthonyLatsis/arch-resolution-kind
GSB: Propagate ArchetypeResolutionKind to resolveDependentMemberTypes
2020-05-07 04:24:24 +03:00
Anthony Latsis
dfcc656501 GSB: Propagate ArchetypeResolutionKind to resolveDependentMemberTypes when resolving equivalence classes 2020-05-06 23:43:53 +03:00
Anthony Latsis
bc49a8e232 [Diags] NFC: Audit diags using DeclName for names of nominals and vars 2020-05-02 16:08:24 +03:00
Varun Gandhi
65577940d0 [NFC] Get rid of -Wrange-loop-analysis warnings. (#31324) 2020-04-27 09:47:52 -07:00
Anthony Latsis
74252028ca AST: Rename getFullName -> getName on ValueDecl & MissingMemberDecl 2020-04-23 05:16:55 +03:00
Slava Pestov
8d2a4105b4 GenericSignatureBuilder: Improved counters 2020-04-21 23:27:05 -04:00
Slava Pestov
b3aea6ee38 GenericSignatureBuilder: Simplify RequirementRHS type 2020-04-21 23:26:39 -04:00
Michael Forster
fae87c96d7 Move interleave(...) to the llvm namespace
This simplifies fixing the master-next build. Upstream LLVM already
has a copy of this function, so on master-next we only need to delete
the Swift copy, reducing the potential for merge conflicts.
2020-04-17 11:20:50 +02:00
swift-ci
9a0efcac2a Merge pull request #30548 from AnthonyLatsis/sr-7855 2020-04-13 13:20:27 -07:00
Robert Widmann
1f904ca86d Merge pull request #30669 from CodaFi/consteval
[NFC] A Handful of Sweeping Evaluator Cleanups
2020-03-27 09:43:28 -07:00
marcrasi
eae4c5eece [AutoDiff upstream] @differentiable function type sema (#30648)
Add type checking for `@differentiable` function types:
- Check that parameters and results conform to `Differentiable`.
- Implicitly conform parameters and results whose types are generic parameters
  to `Differentiable`.
- Upstream most of the differentiable_func_type_type_checking.swift test from
  `tensorflow` branch. A few function conversion tests have not been added
   because they depend on the `@differentiable` function conversion pipeline.

Diagnose gracefully when the `Differentiable` protocol is unavailable because
`_Differentiation` has not been imported.

Resolves TF-823 and TF-1219.
2020-03-26 23:28:02 -07:00