Commit Graph

289 Commits

Author SHA1 Message Date
Slava Pestov
50bd7d2c03 AST: Factor out GenericSignature::lookupNestedType() 2021-07-14 00:02:56 -04:00
Slava Pestov
9a0c87b196 RequirementMachine: Implement GenericSignature::getCanonicalTypeInContext() query
We compute the canonical type by first simplifying the type term, and
then checking if it is a concrete type. If there's no concrete type,
we convert the simplified term back to an interface type and return
that; otherwise, we canonicalize any structural sub-components of
the concrete type that contain interface types, and so on.

Due to a quirk of how the existing declaration checker works, we also
need to handle "purely concrete" member types, eg if I have a
signature `<T where T == Foo>`, and we're asked to canonicalize the
type `T.[P:A]` where Foo : A.

This comes up because we can derive the signature `<T where T == Foo>`
from a generic signature like `<T where T : P>`; adding the
concrete requirement 'T == Foo' renders 'T : P' redundant. We then
want to take interface types written against the original signature
and canonicalize them with respect to the derived signature.

The problem is that `T.[P:A]` is not a valid term in the rewrite system
for `<T where T == Foo>`, since we do not have the requirement T : P.

A more principled solution would build a substitution map when
building a derived generic signature that adds new requirements;
interface types would first be substituted before being canonicalized
in the new signature.

For now, we handle this with a two-step process; we split a term up
into a longest valid prefix, which must resolve to a concrete type,
and the remaining suffix, which we use to perform a concrete
substitution using subst().
2021-07-09 00:04:36 -04:00
Slava Pestov
05b3f79cec RequirementMachine: Implement GenericSignature::getRequiredProtocols() query 2021-06-30 01:34:20 -04:00
Slava Pestov
a37ad9fc89 RequirementMachine: Implement GenericSignature::areSameTypeParametersInContext() query 2021-06-30 01:34:20 -04:00
Slava Pestov
5d91b59e87 RequirementMachine: Implement GenericSignature::isConcreteType() query 2021-06-30 01:34:20 -04:00
Slava Pestov
62e0ad0f02 RequirementMachine: Add a dump() method 2021-06-30 01:34:20 -04:00
Slava Pestov
53d68144f8 RequirementMachine: Implement GenericSignature::getLayoutConstraint() query 2021-06-30 01:34:20 -04:00
Slava Pestov
8053b91c0e RequirementMachine: Implement GenericSignature::requiresProtocol() query 2021-06-30 01:34:20 -04:00
Slava Pestov
7df09f14ee RequirementMachine: Implement GenericSignature::requiresClass() query 2021-06-30 01:34:20 -04:00
Slava Pestov
6fa7a3fedb AST: Introduce GenericSignatureImpl::getRequirementMachine() 2021-06-30 01:34:20 -04:00
Slava Pestov
6cb64c4a8d AST: Refactor GenericSignature::isRequirementSatisfied() to use Requirement::isSatisfied()
This becomes a utility that maps the requirement's types into the
generic environment if needed before calling out to the new
Requirement::isSatisfied().
2021-05-17 16:34:17 -04:00
Slava Pestov
fe06df8288 AST: Move guts of checkGenericArguments() to a new Requirement::isSatisfied() method 2021-05-17 16:34:17 -04:00
Slava Pestov
e6ff771d59 GSB: Rewrite getConformanceAccessPath(), again
The new approach is to not look at RequirementSources at all. Instead,
we exhaustively enumerate all conformance access paths, beginning
from the root conformance requirements in the signature, then doing
all conformance requirements from those protocols' requirement
signatures, and so on.

We enumerate conformance access paths in breadth first order by
length until we find the one we want. The results are memoized.

This fixes a regression with another change I'm working on. The
test case does not fail with this PR alone, but I'm adding it now
anyway.
2021-05-06 17:55:43 -04:00
Slava Pestov
61f796da5a GSB: Remove unused parameter from lookupConformance() 2021-04-03 22:33:14 -04:00
Slava Pestov
568320c1d3 GSB: Move guts of getCanonicalTypeInContext() from GenericSignature to the GSB 2021-03-24 18:45:04 -04:00
Slava Pestov
6f4f9f8c0f Merge pull request #36411 from slavapestov/fix-gsb-verification
GSB: Move signature verification from CanGenericSignature::getCanonical() to computeGenericSignature()
2021-03-12 09:36:35 -05:00
Slava Pestov
91ebe4485c GSB: Move signature verification from CanGenericSignature::getCanonical() to computeGenericSignature()
Doing this when computing a canonical signature didn't really
make sense because canonical signatures are not canonicalized
any more strongly _with respect to the builder_; they just
canonicalize their requirement types.

Instead, let's do these checks after creating the signature in
computeGenericSignature().

The old behavior had another undesirable property; since the
canonicalization was done by registerGenericSignatureBuilder(),
we would always build a new GSB from scratch for every
signature we compute.

The new location also means we do these checks for protocol
requirement signatures as well. This flags an existing fixed
crasher where we still emit bogus same-type requirements in
the requirement signature, so I moved this test back into
an unfixed state.
2021-03-11 21:07:33 -05:00
Slava Pestov
fce1f2c7fe GSB: getConformanceAccessPath() doesn't need to use getMinimalConformanceSource()
Previously we would look for a derived source before an explicit one,
on account of the explicit one possibly being redundant. However, the
presence of 'self-derived' sources meant that we had to call
getMinimalConformanceSource() to ensure the derived sources
were actually usable and would not produce an infinite conformance
access path.

I'd like to remove getMinimalConformanceSource() now that we have
an alternate algorithm to identify redundant explicit requirements.

Instead, we can handle the explicit case first, by checking for a
conformance requirement in the generic signature -- its presence
means it was not redundant, by construction.

Then once we handle that case, we know we're going to use a derived
source, and finding the shortest one seems to be good enough.

This fixes the IRGen crash in https://bugs.swift.org/browse/SR-11153;
the requirement signatures in that test still have unnecessary
same-type requirements printed, so I added a separate RUN: line
for those, and it's marked as known-failing with 'not %FileCheck'.
2021-03-11 15:23:50 -05:00
Slava Pestov
53e06d69b5 AST: Factor out a new Requirement::getProtocolDecl() utility method 2021-02-25 17:21:18 -05:00
Slava Pestov
f3f9555c55 GSB: New implementation of getConformanceAccessPath()
A new implementation from "first principles". The idea is that
for a given conformance, we either have an explicit source
which forms the root of the requirement path, or a derived
source, which we 'factor' into a parent type/parent protocol
pair, and a requirement signature requirement.

We recursively compute the conformance access path of the
parent type and parent protocol, and append the path element
for the requirement.

This fixes a long-standing crasher, and eliminates two hacks,
the 'usesRequirementSource' flag in RequirementSource, and
the 'HadAnyRedundantConstraints' flag in GenericSignatureBuilder.

Fixes https://bugs.swift.org/browse/SR-7371 / rdar://problem/39239511
2021-02-23 16:26:04 -05:00
Slava Pestov
b0208a134f AST: Move getSugaredType() from GenericEnvironment to GenericSignature
None of this actually involves archetypes, so it can just be an
operation on the GenericSignature itself.
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
844ab508e6 AST: Add more asserts for same-type constraints in generic signatures 2020-07-01 23:03:33 -04:00
Robert Widmann
9357c85209 Merge pull request #31838 from AnthonyLatsis/o-getinnermostgps
[NFC] AST: Optimize GenericSignatureImpl::getInnermostGenericParams
2020-06-04 10:46:02 -07:00
Anthony Latsis
9fd1aa5d59 [NFC] Pre- increment and decrement where possible 2020-06-01 15:39:29 +03:00
Anthony Latsis
b25c4665e4 GenericSignatureImpl, #31712: Plug remaining relevant methods with type param. assertions 2020-05-20 23:49:47 +03:00
Anthony Latsis
95c16fc9e1 [NFC] AST: Optimize GenericSignatureImpl::getInnermostGenericParams 2020-05-16 08:26:20 +03:00
Anthony Latsis
44a92a926c [NFC] GenericSignatureImpl: Spell conformsToProtocol & getConformsTo in terms of requirements 2020-05-14 22:51:44 +03:00
Anthony Latsis
df9103e9d7 [NFC] AST: Const-qualify GenericSignatureImpl 2020-05-13 01:03:08 +03:00
Anthony Latsis
3b73065b2b Merge pull request #31712 from AnthonyLatsis/assert-type-param-2
GenericSignatureImpl: Assert we were given type parameters in getSuperclassBound & conformsToProtocol
2020-05-12 08:12:53 +03:00
Anthony Latsis
534343875a GenericSignatureImpl: Assert we were given type parameters in getSuperclassBound & conformsToProtocol 2020-05-11 22:18:26 +03:00
Anthony Latsis
ab1ca1d6f7 AST: Assert we were given a type parameter in GenericSignatureImpl::requiresClass 2020-05-03 16:46:52 +03:00
Anthony Latsis
ba26d5701b AST: Make GenericSignatureImpl::requirementsNotSatisfiedBy const-correct 2020-04-23 03:18:43 +03:00
Anthony Latsis
b8341687fa AST: Fast path for matching can. signatures in requirementsNotSatisfiedBy 2020-04-23 03:18:37 +03: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
Dan Zheng
1486d6b346 NFC: Add GenericSignature::getCanonicalSignature. (#29105)
Motivation: `GenericSignatureImpl::getCanonicalSignature` crashes for
`GenericSignature` with underlying `nullptr`. This led to verbose workarounds
when computing `CanGenericSignature` from `GenericSignature`.

Solution: `GenericSignature::getCanonicalSignature` is a wrapper around
`GenericSignatureImpl::getCanonicalSignature` that returns the canonical
signature, or `nullptr` if the underlying pointer is `nullptr`.

Rewrite all verbose workarounds using `GenericSignature::getCanonicalSignature`.
2020-01-12 12:17:41 -08:00
Slava Pestov
21b5326e89 AST: Add an assertion 2019-11-07 22:59:07 -05:00
Robert Widmann
b849e51768 Use operator bool to claw back some readability 2019-10-29 16:56:21 -07:00
Robert Widmann
3e1a61f425 [NFC] Fold The Tri-State In Optional<ProtocolConformanceRef>
ProtocolConformanceRef already has an invalid state.  Drop all of the
uses of Optional<ProtocolConformanceRef> and just use
ProtocolConformanceRef::forInvalid() to represent it.  Mechanically
translate all of the callers and callsites to use this new
representation.
2019-10-29 16:55:56 -07:00
Robert Widmann
5a8d0744c3 [NFC] Adopt TypeBase-isms for GenericSignature
Structurally prevent a number of common anti-patterns involving generic
signatures by separating the interface into GenericSignature and the
implementation into GenericSignatureBase.  In particular, this allows
the comparison operators to be deleted which forces callers to
canonicalize the signature or ask to compare pointers explicitly.
2019-09-30 14:04:36 -07:00
Sasha Krassovsky
1e414f7fb6 Fix warnings in AST 2019-09-13 09:57:48 -07:00
Slava Pestov
600a6f37d8 IRGen: Remove CanGenericSignature::getGenericEnvironment() 2019-09-06 17:16:03 -04:00
Slava Pestov
1e94466bcc AST: Replace GenericSignature::createGenericEnvironment() with getGenericEnvironment()
This memoizes the result, which is fine for all callers; the only
exception is open existential types where each new open existential
now explicitly gets a unique generic environment, allocated by
calling GenericEnvironment::getIncomplete().
2019-09-06 17:16:03 -04:00
Doug Gregor
8ad76a1707 Canonicalize requests for the abstract generic signature.
When a request for an abstract generic signature contains noncanonical
types, first compute the abstract generic signature for the
canonicalized types, then map back to the provided generic
parameters. Clients of this request generally work in canonical types
already, but it's a small win.
2019-08-26 09:54:20 -07:00
Doug Gregor
a23a4353cb [Type checker] Requestify the formation of an abstract generic signature
Introduce a request to form an abstract generic signature given a
base signature, additional generic parameters, and additional
requirements. It is meant to provide a caching layer in front of the
generic signature builder.

Switch one direct client of the generic signature builder over to this
mechanism, the formation of a generic signature for an existential
type.
2019-08-26 09:54:19 -07:00
Alexis Laferrière
3dd54c24d1 Remove explicit calls to computeRequirementSignature
We can rely on lazy calls to getRequirementSignature instead.
2019-05-08 14:28:35 -07:00
Doug Gregor
24d24c0e63 [AST] Allocate GenericSignature(Builders) in the arena
Opaque result type archetypes can involve type variables, which
then get introduced into GenericSignatureBuilders and the
generated GenericSignatures. Allocate them in the proper arena
So we don’t end up with use-after-free errors.

Fixes rdar://problem/50309503.
2019-05-07 06:56:42 -07:00
Joe Groff
dd2b51d6dc Add an OpaqueTypeArchetypeType subclass. 2019-04-17 14:43:32 -07:00
Doug Gregor
3406307252 [GSB] Move local header inclusions to the top.
Thanks, Jordan. NFC
2018-12-17 10:24:18 -08:00
Doug Gregor
bbe3aa7e70 [AST] Improve canonicalization using dependent member types.
When substituting type parameters to compute a canonical type within a
given generic context, also handle the case where the type parameter is
directly known to be a concrete type. The type checker won’t do this, but 
SourceKit does. 

Fixes a regression in SourceKit/DocSupport/doc_stdlib.swift.
2018-12-17 10:01:03 -08:00