Commit Graph

127 Commits

Author SHA1 Message Date
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
0111618c50 RequirementMachine: Perform concrete contraction on protocol requirement signatures 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
Josh Soref
81d3ad76ac Spelling ast (#42463)
* spelling: accessor

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: accommodates

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: argument

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: associated

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: availability

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: available

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: belongs

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: bookkeeping

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: building

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: clazz

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: clonable

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: closure

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: concatenated

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: conformance

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: context

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: conversion

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: correspondence

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: declarations

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: declared

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: defining

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: delayed

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: dependency

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: deployed

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: descendants

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: diagnose

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: diagnostic

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: equitable

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: evaluation

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: exclusivity

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: existence

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: existential

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: explicit

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: expressed

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: for

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: foreign

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: function

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: identifier

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: implicit

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: indices

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: information

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: instance

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: interchangeable

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: interface

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: introduced

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: invalid

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: kind-in

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: least

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: library

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: location

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: namespace

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: necessary

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: nonexistent

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: not

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: number

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: obtains

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: occurs

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: opaque

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: overridden

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: parameter

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: precede

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: preceding

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: property

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: protocol

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: qualified

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: recognized

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: recursively

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: references

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: relaxing

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: represented

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: request

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: requirement

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: requirements

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: retrieve

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: returned

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: satisfied

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: satisfy

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: scanner

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: siblings

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: simplified

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: something

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: source

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: specializations

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: specially

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: statement

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: stripped

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: structure

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: substitution

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: the

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: transform

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: transformed

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: transitively

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: transparent

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: typecheck

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: unknown

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: unlabeled

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: unqualified

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: whether

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: with

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: scanner

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

Co-authored-by: Josh Soref <jsoref@users.noreply.github.com>
2022-04-21 12:57:16 -07:00
Holly Borla
de41a58051 Merge pull request #42257 from hborla/concrete-generic-params
[RequirementMachine] Diagnose type parameters that are made concrete by a same-type requirement.
2022-04-12 18:27:43 -07:00
Holly Borla
7f30f5b039 [RequirementMachine] Downgrade concrete type parameter diagnostics to a
warning.

These diagnostics are stricter in the RequirementMachine than in the GSB,
and there's code that relies on the more relaxed diagnostics in the source
compatibility suite. Downgrade these diagnostics to a warning using
warnUntilSwiftVersion(6).
2022-04-11 19:18:00 -07:00
Holly Borla
e26497a644 [RequirementMachine] Remove unnecessary conditions in concrete type parameter
diagnostics code.
2022-04-09 13:10:36 -07:00
Holly Borla
236e8e2b1d [RequirementMachine] Diagnose type parameters that are made concrete by a
same-type requirement.
2022-04-08 18:16:23 -07:00
Slava Pestov
bc43cdd104 RequirementMachine: Generalize hack that allows associated type inheritance clauses to reference protocol typealiases
We want to allow this for all conformance requirements written in protocols
or the `where` clause of protocol extensions.

Fixes rdar://problem/91304291.
2022-04-05 18:42:35 -04:00
Slava Pestov
d385b73cd6 RequirementMachine: Plumb source locations through concrete contraction 2022-04-01 22:33:03 -04:00
Slava Pestov
75161ce6b0 RequirementMachine: Tweak fixit that turns 'T : Int' into 'T == Int' slightly to match GSB 2022-04-01 01:05:54 -04:00
Holly Borla
deb62f7e3c [RequirementMachine] Add a helper method to RequirementMachine to compute
all requirement diagnostics from the minimal rewrite system.
2022-03-29 18:27:44 -07:00
Holly Borla
99f5e365cc [RequirementMachine] Compute and diagnose conflicting rules in the minimal
rewrite system of a generic/requirement signature.
2022-03-29 18:26:26 -07:00
Slava Pestov
a631d8aa3a RequirementMachine: Write some comments 2022-03-28 22:16:09 -04:00
Slava Pestov
4d097da73c RequirementMachine: Re-use requirement machines constructed by minimization for queries
Fixes rdar://problem/88135641.
2022-03-26 00:56:41 -04:00
Slava Pestov
af99ac55de RequirementMachine: Add -debug-requirement-machine=timers 2022-03-26 00:56:41 -04:00
Slava Pestov
3fe4aaae5a RequirementMachine: Fix subtle bug in isRecursivelyConstructingRequirementMachine()
I don't have a reduced test case. It was possible for computing the requirement
signatures of a connected component to have finished, and yet for the
ProtocolDecl::hasComputedRequirementSignature() method to return false, if
we had evaluated a RequirementSignatureRequestRQM but not the top-level
RequirementSignatureRequest.

Instead, track whether we've computed the signatures for a component directly.

I don't have a reduced test case. It would arise with associated type inference,
which uses this predicate to break nasty cycles.
2022-03-24 23:45:32 -04:00
Slava Pestov
441fa1679a RequirementMachine: Splitting concrete equivalence classes in protocol requirement signatures 2022-03-22 15:02:06 -04:00
Slava Pestov
ff40f109ca RequirementMachine: Allow RequirementMachine::isConcreteType() and ::getCanonicalTypeInContext() to be used with protocol connected components 2022-03-22 15:02:06 -04:00
Slava Pestov
4446f2afcf RequirementMachine: Move some code out of RuleBuilder and into RequirementSignatureRequest 2022-03-22 15:02:06 -04:00
Slava Pestov
466d6a9468 RequirementMachine: Refactor shouldSplitConcreteEquivalenceClasses() and splitConcreteEquivalenceClasses() a bit
Note that this changes the behavior of a test slightly when the
-disable-concrete-contraction flag is used. This is because we're
not using the Requirement Machine that minimized the signature
and not the Requirement Machine built from the minimized
signature; the former includes a concrete conformance rule.

The isConcreteType() query returns true on the former when
given the generic parameter τ_0_0.

Since -disable-concrete-contraction is only meant for debugging,
I'm just removing that line from the test.
2022-03-22 15:02:06 -04:00
Slava Pestov
11b45ca269 RequirementMachine: splitConcreteEquivalenceClass() uses getConcreteType() instead of getCanonicalTypeInContext() 2022-03-22 15:02:06 -04:00
Slava Pestov
24b6624275 RequirementMachine: Move some code around in RequirementMachineRequests.cpp 2022-03-22 15:02:06 -04:00
Slava Pestov
9ccdd15d58 RequirementMachine: Add upper bound on number of attempts at splitting concrete equivalence classes 2022-03-22 15:02:06 -04:00
Slava Pestov
4069434100 RequirementMachine: Preserve sugar when splitting concrete equivalence classes
Instead of kicking off an AbstractGenericSignatureRequest recursively,
handle the rebuilding in a loop in {Abstract,Inferred}GenericSignatureRequest.

This also avoids an unnecessary call to verify() when rebuilding.
2022-03-22 15:02:06 -04:00
Slava Pestov
2206b1c54d RequirementMachine: Split up equivalence classes with inferred concrete type
I'll clean this up, comment it and generalize it to work with protocol requirement
signatures soon. Landing this now to unblock the Linux corelibs-foundation build.

Fixes rdar://problem/89791117.
2022-03-18 01:29:22 -04:00
Slava Pestov
f3bcc52e6c RequirementMachine: Rename RequirementMachine::initWithProtocols() 2022-03-15 18:34:54 -04:00
Slava Pestov
2ee5aeefee RequirementMachine: InferredGenericSignatureRequest returns parent generic signature if completion fails 2022-03-14 12:33:18 -04:00
Slava Pestov
f5b3d19703 RequirementMachine: Replace hadError() with getErrors() returning an OptionSet
This gives us more fine-grained information which will be plumbed
through the various requests.
2022-03-14 12:33:18 -04:00
Slava Pestov
1578ab578a RequirementMachine: Refactor requests to not be downstream of the GenericSignatureBuilder
This will make it easier to remove the GenericSignatureBuilder (which
still won't happen for a little while).
2022-03-14 12:33:18 -04:00
Slava Pestov
05aeeff386 RequirementMachine: Reconstitute sugar in trivial cases
The Requirement Machine operates on canonical types internally and erases
sugared types appearing in generic requirements as a result.

For trivial cases like Array<T> vs [T], we can use the existing
TypeBase::reconstituteSugar() utility to produce a more aesthetically-pleasing
generic signature.
2022-03-14 12:33:18 -04:00
Slava Pestov
3576318fc7 RequirementMachine: Refactor construction of requirements from rules
The final step in minimization is building Requirements and
ProtocolTypeAliases from the minimal Rules in the RewriteSystem.

Move this to a new file and refactor it a bit to handle
Requirements and ProtocolTypeAliases more consistently.
2022-03-14 12:33:18 -04:00
Holly Borla
7ce6504b93 [RequirementMachine] Avoid passing the requirement error vector through
initialization of the rewrite system.

Instead, the rewrite system can determine trivially redundant requirements
by finding structural requirements with no associated rewrite rules.
2022-03-10 13:13:50 -08:00
Holly Borla
4b55c30fad [RequirementMachine] Instead of recording redundant requirements and other
diagnostics in the rewrite system, pass down the 'errors' vector from the
top-level requests.
2022-03-09 18:18:43 -08:00
Holly Borla
be30d76732 [RequirementMachine] Diagnose redundant requirements found during minimization
of the rewrite system.
2022-03-09 12:14:58 -08:00
Holly Borla
b18e815436 [RequirementMachine] Preserve structural requirements during rule construction,
and diagnose trivially redundant rules in the rewrite system.
2022-03-09 12:14:58 -08:00
Slava Pestov
9c2d540e69 RequirementMachine: Check invariants using GenericSignature::verify()
Previously only the GenericSignatureBuilder would call this; to ensure
we get the same test coverage when the Requirement Machine is 'on' as
'verify', also call this from the Requirement Machine.

For now, we can't call this from RequirementSignatureRequestRQM due
to circularity issues; that will have to wait until this request is
folded into RequirementSignatureRequest.
2022-03-03 14:05:02 -05:00
Slava Pestov
8e09ba8b45 RequirementMachine: Introduce 'concrete contraction' pre-processing pass before building rewrite system
See the comment at the top of ConcreteContraction.cpp for a detailed explanation.

This can be turned off with the -disable-requirement-machine-concrete-contraction
pass, mostly meant for testing. A few tests now run with this pass both enabled
and disabled, to exercise code paths which are otherwise trivially avoided by
concrete contraction.

Fixes rdar://problem/88135912.
2022-02-25 11:48:38 -05:00
Slava Pestov
ae1ef6d50d RequirementMachine: Eliminate RequirementMachine::initWithAbstractRequirements() 2022-02-23 00:20:57 -05:00
Holly Borla
1dddd9c047 [RequirementMachine] Move gating emitting diagnostics on the requirement
macine flags to callers.

Callers gate this decision on different flags; InferredGenericSignatureRequestRQM
needs RequirementMachineInferredSignatures to be enabled, and the other
callsites need RequirementMachineProtocolSignatures to be enabled.
2022-02-16 13:11:57 -08:00
Holly Borla
3837b4def4 [RequirementMachine] Diagnose early redundant requirements. 2022-02-16 13:11:57 -08:00
Holly Borla
3c2b588037 [RequirementMachine] Plumb the requirement errors vector through desugarRequirement. 2022-02-16 13:11:57 -08:00
Holly Borla
a74717ab69 [RequirementMachine] Diagnose non-protocol, non-class conformance/subtype
constraints in the requirement machine.
2022-02-16 13:11:56 -08:00
Slava Pestov
a1c03db381 AST: Generalize ProtocolDecl::getRequirementSignature() to a new RequirementSignature type
The RequirementSignature generalizes the old ArrayRef<Requirement>
which stores the minimal requirements that a conforming type's
witnesses must satisfy, to also record the protocol typealiases
defined in the protocol.
2022-02-13 00:24:23 -05:00
Slava Pestov
fa65fd0e05 RequirementMachine: Plumb protocol typealiases through minimization
Now that we can detect protocol typealias rules, collect and keep
track of them so that they can be recorded in protocol requirement
signatures.

For now, this is all NFC since nothing introduces such rules into
the rewrite system, except for invalid requirements which are
diagnosed anyway.
2022-02-13 00:24:23 -05:00
Slava Pestov
d4a4540494 RequirementMachine: Fix name lookups for the internal 'where' clause of a GenericParamList
These come up in SIL and in the experimental named opaque result types
implementation. Pass the correct DeclContext here, instead of using
the ModuleDecl.
2022-02-10 17:23:54 -05:00
Slava Pestov
2d066dd7ed RequirementMachine: Do a better job of filtering out invalid superclass and concrete type requirements
In the long run it doesn't really matter if we leave them in there, but for now
matching the GenericSignatureBuilder's behavior makes the tests pass with
-requirement-machine-inferred-signatures=verify.
2022-02-10 17:23:54 -05:00
Slava Pestov
50f84cb4bf RequirementMachine: Tweak debug output 2022-02-09 00:26:04 -05:00
Slava Pestov
37be2d5dd7 RequirementMachine: Emit a diagnostic note with the offending rewrite rule if completion failed
This surfaces an implementation detail, but it might be better
than nothing.
2022-02-07 08:20:59 -05:00
Slava Pestov
634ca55764 RequirementMachine: Rework completion limits a bit
- Rename StepLimit to MaxRuleCount, DepthLimit to MaxRuleLength
- Rename command line flags to -requirement-machine-max-rule-{count,length}=
- Check limits outside of PropertyMap::buildPropertyMap()
- Simplify the logic in RequirementMachine::computeCompletion()
2022-02-07 08:20:59 -05:00