Commit Graph

313 Commits

Author SHA1 Message Date
Doug Gregor
e3a5318b97 [Type checker] Teach conformsToProtocol() to check conditional requirements.
conformsToProtocol() is the main way in which we check whether a given type
conforms to a given protocol. Extend it to check conditional requirements by
default, so that an unmodified caller will get the "does not conform" result
(with diagnostics when a location is present) rather than simply ignoring
the conditional requirements.

Some callers take responsibility for conditional requirements, e.g., to
push them into the constraint system. Allow those callers to opt out of
this checking, and do so wherever appropriate.

Fixes rdar://problem/35518088, where we were ignoring the conditional
requirements needed to verify that Equatable synthesis could be performed.
2017-11-21 21:02:00 -08:00
Doug Gregor
c5fe5c47c9 [AST] Verify canonicalization of generic signatures.
When we canonicalize a generic signature, ensure that the resulting
signature has canonical requirements in the appropriate order.
More validation for generic signature canonicalization as part of the
ABI, which is tracked by SR-3733 / rdar://problem/31412994.
2017-11-06 21:22:36 -08:00
Doug Gregor
e0aedef88a [AST] Handle superclass and concrete sources in conformance access paths.
If we encounter a superclass or concrete source within a conformance
access path, use the stored conformance to terminate the path. Fixes a
compiler crasher.
2017-10-27 23:41:08 -07:00
Doug Gregor
a510e9b56d [GSB] Eliminate most uses of PotentialArchetype::getBuilder().
The remaining two uses after this refactor are... stubborn.
2017-10-23 10:39:21 -07:00
Doug Gregor
aa9755d149 [GSB] Start moving RequirementSource off of potential archetypes.
Eliminate potential archetypes from most of the public interface of
RequirementSource.
2017-10-20 15:18:36 -07:00
Doug Gregor
3177edc911 [GSB] Eliminate an unnecessary archetype-anchor computation. 2017-10-17 21:00:24 -07:00
Doug Gregor
6db9cc8c54 [AST] Consolidate the generic signature "diff" algorithm used in two places.
Introduce GenericSignature::requirementsNotSatisfiedBy(otherSig) to
compute the set of requirements in a generic signature that aren't satisfied
by some other generic signature. This is used both for conditional
conformances (the conditional requirements) and for name mangling of
constrained extensions/protocol conformances.
2017-10-12 14:23:46 -07:00
Doug Gregor
e4ff3a5377 [Mangling] Mangle generic signature requirements not satisfied by parent context.
The mangler had some ad hoc logic for only mangling requirements in a
generic signature that are not requirements in the parent context's
generic signature. However, it was based on an heuristic that isn't
correct. Replace that logic with a check to determine whether
the requirement is satisfied by the parent generic signature, which is
far simpler.

Fixes rdar://problem/31889040 / SR-6107.
2017-10-11 08:46:01 -07:00
Huon Wilson
945f723d59 [AST] Compute conditional requirements in a conformance.
This allows determining which requirements make a conformance conditional; as
in, which requirements aren't known as part of the type itself.

Additionally, use this to assert that a few builtin protocols aren't
conditionally-conformed-to, something we won't support for now.
2017-10-10 20:17:39 -07:00
Doug Gregor
1f1b75a56d [AST] Eliminate ModuleDecl parameters from GenericSignature. 2017-10-10 10:01:39 -07:00
Doug Gregor
936a701b15 [AST] Stop uniquing canonical GSBs based on the module.
Now that the GenericSignatureBuilder is no longer sensitive to the input
module, stop uniquing the canonical GSBs based on that module. The main
win here is when deserializing a generic environment: we would end up 
creating a canonical GSB in the module we deserialized and another
canonical GSB in the module in which it is used.
2017-10-10 09:41:23 -07:00
Doug Gregor
6374a17df9 [GSB] Introduce EquivalenceClass::getAnchor().
The anchor of an equivalence class canonically represents that equivalence
class. Add API for computing the anchor directly, and switch a few more
clients off of `resolveArchetype()`.
2017-09-28 15:47:57 -07:00
Doug Gregor
684a484d81 SR-5753: Don't warn about constraints redundant with inferred constraints. 2017-09-26 17:22:43 -07:00
Doug Gregor
70d4e12285 [GSB] Introduce resolveEquivalenceClass() and start using it.
Queries through the GenericSignatureBuilder about a particular type
parameter only really need information about the equivalence class in which that type parameter resides. Introduce a new entry point
GenericSignatureBuilder::resolveEquivalenceClass() that only

For now, resolveEquivalanceClass() is a thin layer over
resolveArchetype().
2017-09-08 21:45:09 -07:00
Slava Pestov
9f8760b942 AST: Remove unused 'resolver' parameter from ModuleDecl::lookupConformance()
... as well as a bunch of downstream plumbing that is no
longer necessary.
2017-09-07 03:36:17 -07:00
Robert Widmann
6a47d02ca5 Don't add ErrorType-containing substitutions to the map
As a side-effect, resolves compiler crasher 28815
2017-07-13 13:22:23 -07:00
Doug Gregor
ae5091b09a [GSB] Clean up and audit uses of ArchetypeResolutionKind.
Use ArchetypeResolutionKind::CompleteWellFormed whenever we need to
ask questions about the potential archetype, and
ArchetypeResolutionKind::WellFormed when we need only evaluate whether
there is a legitimate type with that name (and possibly get a handle
to it).
2017-06-30 10:05:12 -07:00
Doug Gregor
d5a55d9676 [GSB] Eliminate "allow unresolved" from PotentialArchetype::getDependentType().
We don't need this now that there are no more unresolved types.
2017-06-30 09:05:27 -07:00
Doug Gregor
623d72db3c [AST] Make the "requirement signature" of a protocol a flat array.
Rather than pretend that the requirement signature of a protocol is a
full, well-formed generic signature that one can meaningfully query,
treat it as a flat set of requirements. Nearly all clients already did
this, but make it official. NFC
2017-06-29 14:01:49 -07:00
Doug Gregor
b3207c832a [Conformance access paths] Use protocol signature for building paths.
When a requirement signature could not be used to construct the
requirement sources in a conformance access path (due to recursive
protocols), we rebuild the path based on knowledge of the
protocol. Instead of using the requirement signature for this (which
depends on a canonicalized generic signature that breaks our intended
invariants w.r.t. unresolved nested types), use the protocol's generic
signature instead. This requires one small adjustment at the root of
the path, but is otherwise NFC.

Eliminates the penultimate use of AlwaysPartial.
2017-06-29 14:01:49 -07:00
Doug Gregor
791ac7fad4 [GSB] Clean up the meaning of ArchetypeResolutionKind::(Complete)WellFormed. 2017-06-23 17:23:07 -07:00
Doug Gregor
a9260f2d9a [GSB] Don't warn about redundancies due to inference from result types.
When we infer a requirement from the result type of a function, don't
warn if that requirement was also stated explicitly. This has been a
point of confusion since we introduced the redundancy warnings,
because users don't consider to result type to be an "input" to the
function in the way the compiler does. So, while technically it is
"correct" to warn, it's unintuitive---so stop.

Fixes SR-5072 / rdar://problem/31357967.
2017-06-16 13:45:07 -07:00
Doug Gregor
773e14422d Eliminate most uses of ArchetypeResolutionKind::AlwaysPartial.
When resolving archetypes using the "always partial" resolution kind,
we allow the system to form potential archetypes which might be
invalid. Start limiting the use of this "always partial" resolution
kind, so that it can eventually be removed entirely to simplify the
invariants of the GenericSignatureBuilder.

Each of the callers should either be working with complete,
well-formed archetypes or they should not force any resolution this
early.
2017-05-30 11:00:24 -07:00
Doug Gregor
329fd0c728 [AST] Pass GenericSignature through getOrCreateCanonicalGenericEnvironment().
Rather than having `ASTContext:: getOrCreateCanonicalGenericEnvironment()`
ask its `GenericSignatureBuilder` parameter recompute the generic signature
at nontrivial cost, just pass the known signature through.
2017-05-15 17:16:50 -07:00
Slava Pestov
504343c66e AST: Check invariants in GenericSignature::getSubstitutionMap(SubstitutionList) 2017-05-02 02:29:56 -07:00
Slava Pestov
3130c3cbd7 AST: Remove an overload of GenericSignature::getSubstitutions() 2017-04-28 13:26:02 -07:00
Slava Pestov
0290c2d5d8 AST: Make GenericSignature and GenericEnvironment SubstitutionMaps interchangable
SubstitutionMap::lookupConformance() would map archetypes out
of context to compute a conformance path. Do the same thing
in SubstitutionMap::lookupSubstitution().

The DenseMap of replacement types in a SubstitutionMap now
always has GenericTypeParamTypes as keys.

This simplifies some code and brings us one step closer to
a more efficient representation of SubstitutionMaps.
2017-04-24 14:12:36 -07:00
practicalswift
797c2d8118 [gardening] Fix end of namespace comments 2017-04-20 22:01:01 +02:00
practicalswift
431e5a1440 [gardening] Use consistent end of namespace comments 2017-04-20 13:47:10 +02:00
Doug Gregor
98dbd23fe2 [GSB] Add RequirementSource::isProtocolRequirement() to check both protocol-requirement kinds.
It’s too easy to forget to check both ProtocolRequirement and InferredProtocolRequirement, so abstract the check into a method.
2017-04-18 15:47:40 -07:00
Doug Gregor
17846e2be1 [GSB] Cope with recursive requirements by delaying them.
Rather than detecting recursion and bailing early, delay requirements
that would form recursive types. Note that we aren't actually
processing them later.
2017-04-17 23:13:21 -07:00
Doug Gregor
8a4451dda9 [GSB] Infer requirements from concrete types in requirements.
When a requirement mentions a concrete type, that type might utter
other types (e.g., Set<T>) that infer requirements (here, T:
Hashable). Perform requirement inference for such types.

Part of rdar://problem/31520386.
2017-04-14 17:19:01 -07:00
Slava Pestov
256f34964d AST: Fix GenericSignature::requiresClass() for layout
We forgot to check for a layout constraint here.
2017-04-13 21:17:06 -07:00
Doug Gregor
97c6707910 [SubstitutionMap] Cope with missing conformances in lookupConformance().
When asking a substitution map for a conformance, it's okay if the
conformance isn't there---just detect this case and return None.

Also, collapse a redundant testcase Huon noted.
2017-04-04 10:58:01 -07:00
Doug Gregor
d0499a3613 [SubstitutionMap] Eliminate the parent map and handle archetype conformances.
When looking for a conformance for an archetype, map it out of context
to compute the conformance access path, then do the actual lookups
based on mapping the starting type back into the context. Eliminate
the parent map and "walk the conformances" functionality.
2017-04-04 10:58:01 -07:00
Doug Gregor
81c21b85f2 [AST] Track the generic signature/environment for a substitution map.
Substitution maps are effectively tied to a particular generic
signature or environment; keep track of that signature/environment so
that we can (eventually) use it to find conformances.
2017-04-04 10:58:01 -07:00
practicalswift
00ba5dc248 [gardening] Fix typos 2017-04-02 16:23:45 +02:00
Roman Levenstein
6f54798df8 Verify the construction of SubstitutionMaps
After substitution maps are constructed, check their invariants. It helps to catch very subtle bugs related to substitutions.
2017-03-20 15:30:12 -07:00
Doug Gregor
eaee4add8a [GSB] Track all conformance constraint sources.
Move the storage for the protocols to which a particular potential
archetype conforms into EquivalenceClass, so that it is more easily
shared. More importantly, keep track of *all* of the constraint
sources that produced a particular conformance requirement, so we can
revisit them later, which provides a number of improvements:

* We can drop self-derived requirements at the end, once we've
  established all of the equivalence classes
* We diagnose redundant conformance requirements, e.g., "T: Sequence"
  is redundant if "T: Collection" is already specified.
* We can choose the best path when forming the conformance access
  path.
2017-03-16 23:15:37 -10:00
Doug Gregor
a41e44fa27 [AST] Don't use a protocol's requirement signature to canonicalize types.
Requirement signatures are a bit brittle, because they (intentionally)
don't carry the "Self: Proto" requirement. Most of the compiler never
uses requirement signatures as a signature per se, which is good,
because they canonicalize poorly.

Teach the construction of conformance access paths to use the
protocol's generic signature for canonicalization, rather than the
requirement signature.

As a future step, we should present only the *requirements* from the
requirement signature to prevent its use as a full-fledged
GenericSignature.
2017-03-09 21:55:40 -08:00
Doug Gregor
1f8b0f9b85 Canonicalize conformance access paths for sources pre-requirement-signature.
When a requirement source involving a ProtocolRequirement element is
built prior to the requirement signature of the protocol it
references, we can end up with a requirement source whose steps don't
reflect was is actually available via the requirement signatures. When
building a conformance access path from such requirement sources,
canonicalize on-the-fly using the requirement signatures (which have
been/can be computed by this point) to produce a correct access path.
2017-03-08 16:14:55 -08:00
Slava Pestov
e62c238bc9 AST: Remove unused overload of GenericSignature::getSubstitutions() 2017-03-08 13:54:31 -08:00
Doug Gregor
202bc7eeea [AST] Introduce GenericSignature::getConformanceAccessPath().
Introduce an API that determines the "conformance access path" that
one would follow to find the conformance of a given type parameter
(e.g., T.Iterator.Element) to a given protocol (e.g., Equatable). A
conformance access path starts at one of the explicit requirements
of that generic signature and then proceeds through zero or more
protocol-supplied requirements. For example, given this function:

  func f<C: Collection>(_: C) { }

The conformance access path for "C.Iterator: IteratorProtocol" is

  (C, Collection) -> (Self, Sequence) -> (Self.Iterator, IteratorProtocol)

because one starts with the explicit requirement "C: Collection", goes
to the inherited protocol requirement (the "Self" in Collection
conforms to Sequence) and then a requirement on the associated type
(Self.Iterator in Sequence conforms to IteratorProtocol).

This is all scaffolding now; it's intended to be used by IRGen (to
find the witness tables it needs) and SubstitutionMap (to dig out
conformances during substitution).
2017-03-07 09:25:43 -08:00
Slava Pestov
0f4a7d246f AST: Remove GenericSignature::getAllDependentTypes()
This was a remnant of the old generics implementation, where
all nested types were expanded into an AllArchetypes list.

For quite some time, this method no longer returned *all*
dependent types, only those with generic requirements on
them, and all if its remaining uses were a bit convoluted.

- In the generic specialization code, we used this to mangle
  substitutions for generic parameters that are not subject
  to a concrete same-type constraint.

  A new GenericSignature::getSubstitutableParams()
  function handles this use-case instead. It is similar
  to getGenericParams(), but only returns generic parameters
  which require substitution.

  In the future, SubstitutionLists will only store replacement
  types for these generic parameters, instead of the list of
  types that we used to produce from getAllDependentTypes().

- In specialization mangling and speculative devirtualization,
  we relied on SubstitutionLists having the same size and
  order as getAllDependentTypes(). It's better to turn the
  SubstitutionList into a SubstitutionMap instead, and do lookups
  into the map.

- In the SIL parser, we were making a pass over the generic
  requirements before looking at getAllDependentTypes();
  enumeratePairedRequirements() gives the correct information
  upfront.

- In SIL box serialization, we don't serialize the size of the
  substitution list, since it's available from the generic
  signature. Add a GenericSignature::getSubstitutionListSize()
  method, but that will go away soon once SubstitionList
  serialization only serializes replacement types for generic
  parameters.

- A few remaining uses now call enumeratePairedRequirements()
  directly.
2017-03-02 22:57:52 -08:00
Huon Wilson
c518f4bd0f [TypeCheck] Check all requirements of a protocol are satisfied by a conformance. 2017-02-24 19:40:45 -08:00
Doug Gregor
8e16f60aed [GenericSig] Properly drop *all* type parameters with concrete bindings.
When enumerating "paired" requirements, we were failing to drop some
generic type parameters that have concrete bindings. Drop all of them
consistently.
2017-02-23 10:43:00 -08:00
Slava Pestov
c5dfb5238a AST: Completely hide internal representation of SubstitutionMap
Make the addSubstitution() and addConformance() methods private,
and declare GenericEnvironment and GenericSignature as friends of
SubstitutionMap.

At some point in the future, we can switch to a more efficient
representation of SubstitutionMap, where instead of storing
multiple hashtables, we store arrays; the keys are pre-determined.
2017-02-12 01:42:36 -08:00
Slava Pestov
f1dcf5af1e AST: Write some more fake code for conformance lookup in signature
This just fixes the warning about 'Sig' being an unused
member of LookUpConformanceInSignature.
2017-02-12 00:51:27 -08:00
Doug Gregor
579af863c5 Rename ArchetypeBuilder -> GenericSignatureBuilder 2017-02-10 12:46:34 -08:00
Doug Gregor
c6cbd13d31 [ArchetypeBuilder] Eliminate expandGenericEnvironment().
Remove the pre-expansion of all of the archetypes in a generic
environment; they can be constructed lazily from interface types.

Note that this only concerns the construction of the archetypes
themselves. The archetype builder is still pre-expanding all
*potential* archetypes.

"Fixes" rdar://problem/30351514, in the sense that the eager code and
the assertion that was getting tripped up are being eliminated
completely.
2017-02-10 01:44:40 -08:00