Commit Graph

861 Commits

Author SHA1 Message Date
Holly Borla
fab5b7d364 [RequirementMachine] Add a generic signature query that returns the
reduced shape of a given type parameter pack.
2022-10-06 20:38:31 -07:00
Holly Borla
60f80006fc [RequirementMachine] Generalize connected components to process same
shape requirements.
2022-10-06 20:38:31 -07:00
Holly Borla
f4bfce6448 [RequirementMachine] Map same-shape requriements to rewrite rules.
A same-shape requirement 'length(T...) == length(U...)' becomes a rewrite
rule 'T.[shape] => U.[shape]'. Reduced shape rules will drop the [shape]
term from each side of the rule, and create a same-shape requirement
between the two type parameter packs.
2022-10-06 20:38:31 -07:00
Holly Borla
0f13eda26c [RequirementMachine] Add a new symbol kind for the shape of a parameter
pack.
2022-10-06 20:38:30 -07:00
Holly Borla
ae5ebba2c1 [RequirementMachine] Add same-length requirement inference for pack
expansion types.
2022-10-06 20:38:30 -07:00
Slava Pestov
658ba01741 RequirementMachine: Redo concrete contraction after splitting concrete equivalence classes
This fixes an edge case where we start with the following requirements:

    - U : P
    - T : P
    - T.[P]A == C
    - T == G<T.[P]A>
    - U.[P]A == T.[P]A

and end up with the following set of minimal rules (where the type
witness for [P]A in the conformance G<C> : P is C):

    - U.[P] => U
    - U.[P:A] => T.[P:A]
    - T.[concrete: G<C>] => T
    - T.[concrete: G<C> : P] => T

Since U.[P]A and T.[P]A are concrete, we split the abstract same-type
requirement into two requirements, and re-run minimization:

    - U : P
    - T.[P]A == C
    - U.[P]A == C
    - T == G<C>

The concrete conformance rule T.[concrete: G<C> : P] => T does not
correspond to a requirement, so it was simply dropped, and the above
rules violate post-contraction invariants; T.[P]A is not a valid
type parameter because there is no conformance requirement T : P in
the minimized signature.

We can fix this by re-running concrete contraction after splitting
concrete equivalence classes. After contraction, the above requirements
turn into

    - U : P
    - C == C
    - U.[P]A == C
    - T == G<C>

Which correctly minimizes to

    - U : P
    - U.[P]A == C
    - T == G<C>

Both concrete contraction and concrete equivalence classes are hacks,
and we should think of a way to directly express the transformations
they perform with the rewrite system.

Fixes https://github.com/apple/swift/issues/61192.
2022-09-19 23:50:21 -04:00
Slava Pestov
6bd817c507 RequirementMachine: Add -debug-requirement-machine=split-concrete-equiv-class flag 2022-09-19 23:50:21 -04:00
Slava Pestov
5c32f2136e AST: Introduce RequirementKind::SameCount 2022-08-23 11:12:00 -04:00
Slava Pestov
7d8f3e6b63 AST: Change return type of Requirement::subst() to Requirement
Instead of returning None, let callers check hasError() if they need to.

Fixes rdar://problem/98565072.
2022-08-12 14:03:57 -04:00
Slava Pestov
9339443e79 RequirementMachine: Diagnose recursive requirements
Note the test cases in abstract_type_witnesses used to pass but are now
rejected. This is fine, because doing anything more complicated used to
crash, and the GSB would crash or misbehave with these examples.
2022-08-11 14:12:06 -04:00
Slava Pestov
42407bba3b RequirementMachine: Convert recursive requirements into ErrorTypes 2022-08-11 14:10:01 -04:00
Slava Pestov
3432a1f20c RequirementMachine: Don't filter out ErrorType as aggressively 2022-08-11 14:10:01 -04:00
Slava Pestov
e3ab64afa7 RequirementMachine: Compute recursive rules 2022-08-11 14:10:01 -04:00
Slava Pestov
15b99ae416 RequirementMachine: Concrete contraction gives up on recursive same-type and superclass requirements
A requirement of the form T == G<T> is never valid, and T == G<T.A>
will leave behind a term T.[P:A] once the conformance T : P is
dropped in contraction. So just ignore recursive requirements
here, allowing them to be properly diagnosed later.
2022-08-11 14:10:01 -04:00
Slava Pestov
5a49a337d9 RequirementMachine: Fix some comments 2022-08-11 14:10:01 -04:00
Slava Pestov
7eeb56309b RequirementMachine: Small concrete contraction cleanup 2022-08-11 14:10:01 -04:00
Slava Pestov
58f03af32d RequirementMachine: Print variadic generic parameter symbols in debug output 2022-08-10 23:44:36 -04:00
Ben Barham
a59fa46813 Merge pull request #60426 from bnbarham/include-smallvec
[Basic] Include SmallVector.h for Clang <= 5
2022-08-10 15:54:48 -07:00
Slava Pestov
4a041c57d0 AST: Rename ConformanceAccessPath to ConformancePath 2022-08-09 13:34:27 -04:00
Slava Pestov
9d96ed940f AST: Rename 'canonical wrt. generic signature' to 'reduced'
We had two notions of canonical types, one is the structural property
where it doesn't contain sugared types, the other one where it does
not contain reducible type parameters with respect to a generic
signature.

Rename the second one to a 'reduced type'.
2022-08-09 12:46:31 -04:00
Ben Barham
6de34f37e5 [NFC] Revert SmallVector<T> -> SmallVector<T, N> fixes
With the change to include `SmallVector.h` directly in `LLVM.h` rather
than forward declaring in the only case it matters (ie. Clang <= 5),
these fixes are no longer needed. Since defaulted version is preferred
when there's no better choice (which is presumably the case if that's
how they were originally added), use it instead. Some uses were instead
changed to add `llvm::` so remove that too.
2022-08-05 21:25:55 -07:00
Slava Pestov
25fb866239 RequirementMachine: Fix a request cycle
RequirementSignatureRequest
    => TypeAliasRequirementsRequest
       => isConstrainedExtension()
          => GenericSignatureRequest
             => RequirementSignatureRequest

Instead, use getTrailingWhereClause() as an approximation of
isConstrainedExtension().

Fixes rdar://problem/97236936.
2022-07-19 11:06:01 -04:00
Slava Pestov
901cdaf85e RequirementMachine: Relax assertions in verifyRewriteSystem()
We don't care as much about rules with weird shapes as long
as they're LHS- or RHS-simplified, since the new minimal conformances
algorithm no longer relies on certain invariants.

Fixes rdar://problem/94746399.
2022-07-06 14:34:26 -04:00
Slava Pestov
d3b7aab725 RequirementMachine: Remove completion procedure hacks for old minimal conformances algorithm 2022-07-06 11:57:21 -04:00
Slava Pestov
919101d4b3 RequirementMachine: Remove old minimal conformances algorithm 2022-07-06 11:57:21 -04:00
Slava Pestov
506cc356c1 RequirementMachine: New minimal conformances algorithm 2022-07-05 21:40:27 -04:00
Slava Pestov
93b94f9211 RequirementMachine: Relax an invariant in decomposeTermIntoConformanceRuleLeftHandSides() 2022-07-05 21:40:06 -04:00
Slava Pestov
e3488cecb2 RequirementMachine: Move decomposeTermIntoConformanceRuleLeftHandSides() to RewriteSystem 2022-07-05 21:40:06 -04:00
Slava Pestov
2caca13e41 RequirementMachine: Const correctness 2022-07-05 21:40:06 -04:00
Slava Pestov
cd118ea19b RequirementMachine: Don't filter out unavailable Sendable conformance if allowMissing=true
Fixes rdar://problem/94456989.
2022-06-22 00:48:59 -04:00
Slava Pestov
e805339de4 RequirementMachine: Relax assertion in verifyRewriteSystem()
We can end up with a rule that has a protocol symbol on the right hand side:

    X.Y.Z => X.W.[P]

This will occur if X.W.[P] was obtained by simplifying a term X.W.U.V via
a rule (U.V => [P]), and before completion discovers a rule
(X.W.[P] => X.W).

Fixes rdar://problem/94854326, rdar://problem/94980084.
2022-06-17 16:13:42 -04:00
Slava Pestov
bd46bdaaaa AST: Narrow the filtering of unavailable conformances to Sendable only
Remove the allowUnavailable parameter to lookupConformance(), and instead
explicitly check the result for hasUnavailableConformance() in the places
where we used to pass 'false'.

Also, narrow down this check in those places to the Sendable protocol
only, fixing a regression with Hashable conformance synthesis.

Fixes rdar://problem/94460143.
2022-06-14 21:24:08 -04:00
Slava Pestov
56f2f44592 Merge pull request #59369 from slavapestov/rqm-unavailable-conformance-fix
RequirementMachine: Fix handling of unavailable Sendable conformances in concretizeNestedTypesFromConcreteParent()
2022-06-10 21:41:10 -04:00
Slava Pestov
0254c0ee7c RequirementMachine: Fix handling of unavailable Sendable conformances in concretizeNestedTypesFromConcreteParent()
We can't just ignore unavailable conformances because the
generic signature we're computing might itself be attached
to an unavailable declaration.

Until we get a proper fix, only drop unavailable conformances
to Sendable here.

Fixes rdar://problem/94305457.
2022-06-10 17:46:40 -04:00
Slava Pestov
9695b1957a RequirementMachine: Concrete contraction needs to substitute the parent type of a subject type sometimes
If you have generic parameters <T, U> and requirements of the form:

- T : P
- T == ConcreteType<U>
- T.[P]U : SomeClass
- T.[P]U : SomeProto

And furthermore SomeClass does not conform to SomeProto, we can't leave
`T.[P]U : SomeClass` unsubstituted; we still have to replace `T` with
`ConcreteType<U>` to transform the latter two requirements into:

- U : SomeClass
- U : SomeProto

"Concrete contraction" is easily the hackiest part of the Requirement
Machine; I need to come up with a more principled solution for the
problem that it solves sooner or later.

Fixes rdar://problem/94150249.
2022-06-08 00:40:30 -04:00
Slava Pestov
ea980d6fbd RequirementMachine: Dump rewrite system when minimal conformances detects an invariant violation 2022-06-08 00:34:55 -04:00
Doug Gregor
904a2ff64c Allow unavailable conformances to non-Sendaable protocols during contraction
Refusing to acknowledge unavailable conformances at this point in the
requirement machine doesn't allow us to make use of unavailable
conformances from unavailable contexts, something which code currently
depends on. Limit the new filtering behavior to `Sendable` conformances
where we need them, as a narrow fix for this regression. We'll revisit
the approach here later.

Fixes rdar://94154905.
2022-06-02 13:24:37 -07:00
Doug Gregor
c9c50b4ae0 [Requirement machine] Ignore unavailable conformances on superclass constraints.
When determining whether a superclass conforms to a particular protocol,
skip unavailable conformances. This way, we don't minimize away a
constraint that might only apply to subclasses of the specified
superclass.

Fixes rdar://91853658.
2022-05-27 13:09:15 -07:00
Slava Pestov
bfcaa39d37 Remove the GenericSignatureBuilder
Resolves rdar://problem/88136582.
2022-05-10 11:47:06 -04:00
Slava Pestov
f39372b33d RequirementMachine: Turn off redundant requirement warnings by default and add -warn-redundant-requirements frontend flag 2022-05-10 01:49:56 -04:00
Slava Pestov
f4cb13fa83 RequirementMachine: Pack the RequirementID field of Rule into a bitfield 2022-05-10 01:49:56 -04:00
Slava Pestov
77e2f4c002 RequirementMachine: getRequirementForDiagnostics() doesn't need to return an Optional 2022-05-10 01:49:56 -04:00
Slava Pestov
f901cc72b4 RequirementMachine: Move diagnostics code into a new Diagnostics.cpp 2022-05-10 01:49:56 -04:00
Slava Pestov
307aa46525 RequirementMachine: Fix a case where we diagnose requirements made redundant by an inferred requirement
We infer requirements from types appearing in parameter and result types,
like this:

    func foo<T>(_: Set<T>) // 'T : Hashable' inferred from 'Set<T>'

Normally we muffle the warning if the requirement is re-stated redundantly:

    func foo<T>(_: Set<T>) where T : Hashable // no warning

However, in some cases we failed to do this if the requirement was inferred
from a type appearing in a 'where' clause, like this:

    struct G<A, B> {}
    extension G where B : Hashable, A == Set<B> {}

This is because in this case the redundancy was detected by
RewriteSystem::addRule() returning false.

The simplest fix here is to change InferredGenericSignatureRequest
to re-order requirements so that inferred requirements appear last.
This way, if any are redundant, we won't diagnose them since it is
the inferred requirement that is redundant and not the user-written
one.

Fixes rdar://problem/92092635.
2022-05-10 01:49:56 -04:00
Slava Pestov
ae56af36d2 RequirementMachine: Workaround invariant violation when requirement signature completion fails
- If P is declared to inherit from Q and Q has an associated type named U, then
  isValidTypeInContext() returns true for a type 'T.U' where 'T' is a generic
  parameter conforming to P, and 'U' is the unresolved DependentMemberType, and
  the type 'T.U' will simplify to the term 'T.[P:U]'.

- However, if completion failed while building the rewrite system for P's
  requirement signature, then the requirement signature for P won't have a
  rule [P].[Q] => [P]. As a result, getTypeForTerm() will fail when given
  'T.[P:U]', because the property map entry for 'T' will not contain a
  conformance to Q.

Work around this by manually adding protocol inheritance rules when building
a signature from a protocol whose requirement signature failed to compute.

This was triggered by the test case I added in the previous commit to
test/Generics/non_confluent.swift.
2022-05-09 21:21:35 -04:00
Slava Pestov
0111618c50 RequirementMachine: Perform concrete contraction on protocol requirement signatures 2022-05-09 21:21:35 -04:00
Slava Pestov
75f6682969 RequirementMachine: Enable concrete contraction for nested type parameters
Fixes rdar://problem/91594361.
2022-05-09 21:21:35 -04:00
Slava Pestov
e5782a188d RequirementMachine: Refactor concrete contraction
Clean up the different cases by passing a 'Position' enum to
substTypeParameter().

Also generalize it to work with arbitrary type parameters instead
of generic parameters only, but leave this code path disabled
for now.
2022-05-09 21:21:35 -04:00
Robert Widmann
713b8b6843 Use Location of Inference Sources as a Fallback
It's possible for the requirement machine to fail to pick up a source location for its computed errors to attach to when
1) The declaration has no where clause
2) Nor does it have a generic parameter list

This is possible because of the magic of desugaring opaque types in input position to generic parameters a la

func foo(_ : some P<T, U>)

Try to use the first valid user-written inference source to derive a location.

rdar://92105516
2022-04-26 18:19:19 -07:00
Slava Pestov
f5078e2d2d Merge pull request #42538 from slavapestov/testcase-rdar92092635
Add test case for rdar://92092635
2022-04-21 21:33:07 -04:00