Commit Graph

88 Commits

Author SHA1 Message Date
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
Slava Pestov
b8fd9e7259 AST: Move the well-formedness check from mangling to GenericSignature constructor 2017-02-07 15:30:39 -08:00
Slava Pestov
79e86b66db AST: Remove Generic{Signature,Environment}::getSubstitutionMap() that update an existing map
These are no longer necessary now that we have combineSubstitutionMaps(),
and will not make sense once we switch to a more compact representation
for SubstitutionMap.
2017-02-06 22:39:27 -08:00
Slava Pestov
3519e0cd25 AST: Introduce new SubstitutionList type to replace ArrayRef<Substitution>
SubstitutionList is going to be a more compact representation of
a SubstitutionMap, suitable for inline allocation inside another
object.

For now, it's just a typedef for ArrayRef<Substitution>.
2017-02-06 21:36:33 -08:00
Slava Pestov
b22f9ea487 AST: Remove SubstitutionMap::getMap()
We don't want to expose the fact that SubstitutionMaps are
backed by a DenseMap, since that's going to change soon.
2017-02-06 19:43:33 -08:00
Slava Pestov
811e7eea55 Merge pull request #7251 from slavapestov/subst-map-impl-hiding
Start cleaning up SubstitutionMap construction
2017-02-06 17:05:54 -08:00
Slava Pestov
2f9bd597bb AST: Clean up duplicated code in GenericSignature.cpp 2017-02-06 16:14:07 -08:00
Doug Gregor
2b9260cdb5 [AST] Add GenericSignature::createGenericEnvironment().
This will eventually be the canonical way to create new generic environments. For now, it’s mainly aspirational.
2017-02-05 21:23:44 -08:00
Slava Pestov
cf4043b668 AST: Get rid of old form of Type::subst()
First, add some new utility methods to create SubstitutionMaps:

- GenericSignature::getSubstitutionMap() -- provides a new
  way to directly build a SubstitutionMap. It takes a
  TypeSubstitutionFn and LookupConformanceFn. This is
  equivalent to first calling getSubstitutions() with the two
  functions to create an ArrayRef<Substitution>, followed by
  the old form of getSubstitutionMap() on the result.

- TypeBase::getContextSubstitutionMap() -- replacement for
  getContextSubstitutions(), returning a SubstitutionMap.

- TypeBase::getMemberSubstitutionMap() -- replacement for
  getMemberSubstitutions(), returning a SubstitutionMap.

With these in place, almost all existing uses of subst() taking
a ModuleDecl can now use the new form taking a SubstitutionMap
instead. The few remaining cases are explicitly written to use a
TypeSubstitutionFn and LookupConformanceFn.
2017-02-03 19:55:40 -08:00
Slava Pestov
fc3244b2f2 Sema: Remove some redundant conformance lookup callbacks
Now we have LookUpConformanceInModule and
LookUpConformanceInSubstitutionMap.
2017-02-03 19:55:40 -08:00
Doug Gregor
ee00acf3d0 [AST] Remove GenericSignature::getRepresentative(). NFC
This entrypoint is unused and is a Bad Idea (TM). Remove it.
2017-02-02 21:25:29 -08:00
Doug Gregor
ded7e83aab [Archetype builder] Make canonicalization of dependent types deterministic.
The canonicalization of dependent member types had some
nondeterminism. The root of the problem was that we couldn't
round-trip dependent member types through the archetype
builder---resolving them to a potential archetype lost the specific
associated type that was recorded in the dependent member type, which
affected canonicalization. Maintain that information, make sure that
we always get the right archetype anchor, and tighten up the
canonicalization logic within a generic signature.

Fixes rdar://problem/30274260 and should unblock some other work
that depends on sanity from the archetype builder and generic
signature canonicalization.
2017-02-02 21:25:29 -08:00
Doug Gregor
f7f703ad04 [Archetype builder] Canonicalize and minimize same-type constraints.
Introduce an algorithm to canonicalize and minimize same-type
constraints. The algorithm itself computes the equivalence classes
that would exist if all explicitly-provided same-type constraints are
ignored, and then forms a minimal, canonical set of explicit same-type
constraints to reform the actual equivalence class known to the type
checker. This should eliminate a number of problems we've seen with
inconsistently-chosen same-type constraints affecting
canonicalization.
2017-02-01 10:51:02 -08:00
Doug Gregor
1f9406915b [Archetype builder] Make the "archetype anchor" use a total order.
Make the "archetype anchor" algorithm use the same total order used to
compare dependent types in a generic signature, so that it is a
dependable total order. Tighten up the compareDependentTypes() logic
(and checking of it) a bit now that it's being used more frequently.

The weird code around GenericSignature::isCanonicalTypeInContext() is
due to a longstanding issue where

  ArchetypeBuilder::resolveArchetype(t)->getDependentType()

is not the identity function when the incoming type is a
DependentMemberType with known associated types. We want to establish
this behavior at some point going forward, in which case we can go
back to the prior implementation of
GenericSignature::isCanonicalTypeInContext().
2017-01-24 19:36:44 -08:00
Slava Pestov
f93c59fdcb AST: Don't canonicalize replacement type in substitutions
A change was recently made to canonicalize replacement types in
GenericSignature::getSubstitutions().

This resulted in ParenType being stripped off, which triggered
the 'tuple splat' diagnostic on code that was accepted in Swift 3.0.

I believe this canonicalization step is unnecessary; we
canonicalize using a brand-new ArchetypeBuilder that has no
generic signature added to it, so this is just equivalent to a
call to getCanonicalType().

Also adding the generic signature in question to the builder is
not the right answer either; the replacement types might be
written in terms of a different generic signature, or possibly
in terms of archetypes.

Taking this out seems to have no effect except changing a few
SIL dumps to contain sugared types, which should be harmless.

Part of fixing <rdar://problem/29739905>.
2017-01-19 20:07:05 -08:00
Doug Gregor
e305b2017b [AST] Allow computation of erroneous substitutions.
Be more tolerant of substitutions for erroneous types; the type
checker will diagnose these issues, but later code paths might still
form these substititions. Put in error types rather than crashing.
2017-01-19 10:43:24 -08:00
Doug Gregor
91af1d6af5 [AST] Use Type::transformRec() when getting a canonical type in context.
NFC cleanup
2017-01-19 10:35:07 -08:00
Slava Pestov
24b2531e5f AST: Have SubstitutionMaps manage the memory for the conformance array 2017-01-18 00:15:59 -08:00
Doug Gregor
a232b41f87 [Archetype builder] Use archetype anchors exclusively in requirements.
When enumerating requirements, always use the archetype anchors to
express requirements. Unlike "representatives", which are simply there
to maintain the union-find data structure used to track equivalence
classes of potential archetypes, archetype anchors are the
ABI-stable canonical types within a fully-formed generic signature.

The test case churn comes from two places. First, while
representatives are *often* the same as the archetype anchors, they
aren't *always* the same. Where they differ, we'll see a change in
both the printed generic signature and, therefore, it's
mangling.

Additionally, requirement inference now takes much greater
care to make sure that the first types in the requirement follow
archetype anchor ordering, so actual conformance requirements occur in
the requirement list at the archetype anchor---not at the first type
that is equivalent to the anchor---which permits the simplification in
IRGen's emission of polymorphic arguments.
2017-01-12 11:07:05 -08:00
swift-ci
808c48401f Merge pull request #6743 from swiftix/wip-partial-pre-specializations-wip-layout-constraints 2017-01-12 10:12:44 -08:00
Roman Levenstein
29180ca1a0 Add support for layout requirements with layout constraints.
This commit introduces new kind of requirements: layout requirements.

This kind of requirements allows to expose that a type should satisfy certain layout properties, e.g. it should be a trivial type, have a given size and alignment, etc.
2017-01-11 19:21:45 -08:00
Pavel Yaskevich
c158f49417 [Diagnostics] Improve diagnostics for generic types with unfulfilled requirements 2017-01-11 15:25:16 -08:00
Slava Pestov
7731d4c6cb Sema: Remove some unnecessary calls to getCanonicalType() 2017-01-08 21:01:13 -08:00
practicalswift
6d1ae2a39c [gardening] 2016 → 2017 2017-01-06 16:41:22 +01:00
Doug Gregor
16585992f6 [AST] Strengthen signature of SubstututionMap::addSubstitution().
It requires a CanSubstitutableType internally, so use that in the
signature and fix up all of the callers.
2017-01-05 16:04:19 -08:00
Slava Pestov
3cbc08cc4e AST/SIL: Fix problems if protocol requirement signature makes Self : P conformance implicit
Fixes assertion failures in SILGen and the optimizer with this
exotic setup:

protocol P {
  associatedtype T : Q
}

protocol Q {
  func requirement<U : P>(u: U) where U.T == Self
}

Here, we only have a U : P conformance, and not Self : Q,
because Self : Q is available as U.T : Q.

There were three problems here:

- The SIL verifier was too strict in verifying the generic signature.
  All that matters is we can get the Self parameter conformance, not
  that it's the first requirement, etc.

- GenericSignature::getSubstitutionMap() had a TODO concerning handling
  of same-type constraints -- this is the first test-case I've found
  that triggered the problem.

- GenericEnvironment::getSubstitutionMap() incorrectly ignored
  same-type constraints where one of the two types was a generic
  parameter.

Fixes <https://bugs.swift.org/browse/SR-3321>.
2017-01-04 02:28:55 -08:00