Commit Graph

216 Commits

Author SHA1 Message Date
Slava Pestov
559eaf0208 AST: Fix combineSubstitutionMaps() for requirements placed on outer generic parameters
There's an evolution proposal going through that allows
for this in more places, so let's fix a known bug in this
area.

Fixes <https://bugs.swift.org/browse/SR-10073>,
<rdar://problem/48925725>.
2019-11-07 22:59:07 -05:00
Robert Widmann
4f84c2a628 Use the default constructor to clean up some APIs
Use ProtocolConformanceRef::forInvalid() in implementations only as a semantic signal.  In one place, use the default constructor to drop the final use of Optional<ProtocolConformanceRef>.
2019-10-29 16:56:22 -07: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
Slava Pestov
b3f43680d8 AST: Simplify SubstitutionMap::getProtocolSubstitutions() 2019-09-20 17:59:56 -04:00
Slava Pestov
8fab074bb5 AST: Fix regression from SubstFlags::UseErrorTypes removal
Note that while the original crasher in the radar is gone, my reduced test
case triggers an IRGen crash on both 5.1 and master because of an unrelated
bug that appears to be related to protocol requirement signatures and
declaration ordering.

Fixes <rdar://problem/54952911>.
2019-09-19 15:50:40 -04:00
Slava Pestov
2dbeeb0d3f AST: Make SubstFlags::UseErrorType the default behavior
We've fixed a number of bugs recently where callers did not expect
to get a null Type out of subst(). This occurs particularly often
in SourceKit, where the input AST is often invalid and the types
resulting from substitution are mostly used for display.

Let's fix all these potential problems in one fell swoop by changing
subst() to always return a Type, possibly one containing ErrorTypes.

Only a couple of places depended on the old behavior, and they were
easy enough to change from checking for a null Type to checking if
the result responds with true to hasError().

Also while we're at it, simplify a few call sites of subst().
2019-08-22 01:07:50 -04:00
Jordan Rose
8157ccfce5 Teach SubstitutionMap::isIdentity about non-canonical generic params (#25767)
Do a weaker check here that only looks at the canonical generic params
and guarantees that *those* substitute to themselves. There may be
replacement types for other generic params too, to canonicalize them,
but that's not a problem.

This fixes a crash trying to mangle decls with opaque result types
that have generic signatures that canonicalize away a generic
parameter.

rdar://problem/51775857
2019-06-26 13:09:36 -07:00
Slava Pestov
18f216c581 Sema: Fix re-entrant call to ensureRequirementsAreSatisfied() when resolving associated conformances
ConformanceChecker::ensureRequirementsAreSatisfied() modifies the
conformance as it resolves each one of its associated conformances,
so a re-entrant call can end up corrupting state by adding too
many elements to the buffer, or adding elements at the wrong
offsets.

If TypeChecker::checkConformanceRequirements() was called before
ConformanceChecker::resolveTypeWitnesses(), we could re-entrantly call
ConformanceChecker::ensureRequirementsAreSatisfied():

TypeChecker::checkConformanceRequirements()
=> ConformanceChecker::ensureRequirementsAreSatisfied()
   => Type::subst(), etc
      => ConformanceChecker::resolveTypeWitnesses()
         => ConformanceChecker::ensureRequirementsAreSatisfied()

The code in SubstitutionMap::lookupConformance() worked around
this by checking the failure condition and calling
resolveTypeWitness() first, before calling getAssociatedConformance().

Instead, remove this and call resolveTypeWitness() from inside
NormalProtocolConformance::getAssociatedConformance().
2019-05-28 22:08:31 -04:00
Arnold Schwaighofer
60a93467f7 Perform substitution on conformances if we are supposed to substitute opaque archetypes
rdar://50413632
2019-05-02 15:36:37 -07:00
Arnold Schwaighofer
768d1c51a1 Address review feedback 2019-05-01 09:31:07 -07:00
Arnold Schwaighofer
a793dfb451 Respect resilience when specializing opaque type archetypes 2019-05-01 09:31:07 -07:00
Joe Groff
42e1824a30 Mangle opaque result types. 2019-04-17 14:43:32 -07:00
Joe Groff
e3bbd8ce9e Remove ResilienceExpansion from substOpaqueTypes for now.
It's currently meaningless, and it'll require thought to pass the correct value when it becomes
meaningful.
2019-04-17 14:43:32 -07:00
Joe Groff
a419754fe9 Support nested types on opaque archetypes (and maybe opened ones). 2019-04-17 14:43:32 -07:00
Joe Groff
c771a7e71b SILGen: Substitute away opaque types. 2019-04-17 14:43:32 -07:00
Slava Pestov
5062a81e3d AST: Start returning SelfProtocolConformances from ModuleDecl::lookupConformance()
Fixes <rdar://problem/49241923>, <https://bugs.swift.org/browse/SR-10015>.
2019-04-16 23:02:50 -04:00
Doug Gregor
4f5d2d3426 [Substitution map] When the superclass conforms to a protocol directly, use it.
When looking up a conformance in a substitution map, check whether
there is a superclass constraint that satisfies the conformance. If
so, use it directly rather than going through a slower path to find
it.

Addresses rdar://problem/46655186.
2018-12-21 15:29:09 -08:00
Joe Groff
89979137fc Push ArchetypeType's API down to subclasses.
And clean up code that conditionally works only with certain kinds of archetype along the way.
2018-12-12 19:45:40 -08:00
Slava Pestov
73f1990bc2 AST: Use getSelfInterfaceType() instead of getProtocolSelfType() where possible
The former appears in the code base a lot more frequently than the
latter, which returns a GenericTypeParamType *. Use it only in places
where the more specific type is intended.
2018-10-15 20:34:08 -07:00
Slava Pestov
a7e3513d8b AST: Use SubstitutionMap::getReplacementTypesBuffer() instead of getReplacementTypes() in a couple of places 2018-10-05 15:35:10 -04:00
Slava Pestov
ce770cdf4e AST: Introduce GenericSignature::forEachParam()
This replaces the inefficient pattern:

  for (auto param : sig->getGenericParams()) {
    if (sig->isCanonicalTypeInContext(param)) {
      ...
    } else {
      ...
    }
  }
2018-09-27 21:28:36 -07:00
Slava Pestov
c09f0578a6 AST: Fast path for SubstitutionMap::lookupConformance() 2018-09-27 21:21:59 -07:00
Doug Gregor
0972111c60 [Type checker] Start tracking overrides of protocol requirements.
When a protocol that inherits another protocol restates a requirement
from its inherited protocol, track that as an override in the AST.
2018-09-04 16:42:06 -07:00
Doug Gregor
c05415ce34 [Override checking] Switch name lookup over to normal qualified lookup.
We don’t need the extra capabilities of the TypeChecker’s name lookup,
so use Decl-based lookup.
2018-09-04 16:42:06 -07:00
Slava Pestov
c906c18db8 AST: More direct implementation of SubstitutionMap::subst()
Instead of using the callback form of SubstitutionMap::get(), let's
use the lower-level form that takes the replacement array and
conformances array directly, allowing us to bypass several
calls of subst() on 'this'.
2018-08-25 00:31:07 -07:00
Jordan Rose
537954fb93 [AST] Rename several DeclContext methods to be clearer and shorter (#18798)
- getAsDeclOrDeclExtensionContext -> getAsDecl

This is basically the same as a dyn_cast, so it should use a 'getAs'
name like TypeBase does.

- getAsNominalTypeOrNominalTypeExtensionContext -> getSelfNominalTypeDecl
- getAsClassOrClassExtensionContext -> getSelfClassDecl
- getAsEnumOrEnumExtensionContext -> getSelfEnumDecl
- getAsStructOrStructExtensionContext -> getSelfStructDecl
- getAsProtocolOrProtocolExtensionContext -> getSelfProtocolDecl
- getAsTypeOrTypeExtensionContext -> getSelfTypeDecl (private)

These do /not/ return some form of 'this'; instead, they get the
extended types when 'this' is an extension. They started off life with
'is' names, which makes sense, but changed to this at some point.  The
names I went with match up with getSelfInterfaceType and
getSelfTypeInContext, even though strictly speaking they're closer to
what getDeclaredInterfaceType does. But it didn't seem right to claim
that an extension "declares" the ClassDecl here.

- getAsProtocolExtensionContext -> getExtendedProtocolDecl

Like the above, this didn't return the ExtensionDecl; it returned its
extended type.

This entire commit is a mechanical change: find-and-replace, followed
by manual reformatted but no code changes.
2018-08-17 14:05:24 -07:00
Slava Pestov
fc80f75273 AST: Create new 'invalid' state for ProtocolConformanceRef 2018-07-16 16:44:27 -07:00
Slava Pestov
b288bea84b AST: Use llvm::dbgs instead of llvm::errs when printing SubstitutionMap verification errors 2018-06-15 13:15:16 -07:00
Slava Pestov
d8fc9decf9 AST: Remove GenericSignature::getSubstitutionMap() 2018-05-28 19:45:28 -07:00
Slava Pestov
d888df4e93 AST: Fix SubstitutionMap::verify()
Get the code compiling. It's not enabled yet because it causes
some problems still.
2018-05-28 19:07:56 -07:00
Doug Gregor
b0cc3ff6d3 [SubstitutionMap] Canonicalize non-substitutable replacement types.
When we compute a replacement type for a non-substitutable generic
parameter, canonicalize the type when our generic signature is
canonical. This ensures that the canonical substitution map will
have canonical types for all of the replacement types… including those
for non-substitutable generic parameters that aren’t part of the
FoldingSet profile.
2018-05-23 15:00:55 -07:00
Slava Pestov
bd6281c558 AST: Change SubstitutionMap conformance lookup callbacks to take ProtocolDecl and not ProtocolType 2018-05-19 01:09:17 -07:00
Slava Pestov
ebb1198d57 AST: There's no longer any reason to pass SubstitutionMap by const reference
SubstitutionMaps are now just a trivial pointer-sized value, so
pass them by value instead.

I did have to move a couple of functors from Type.h to SubstitutionMap.h
to resolve some issues with forward declarations.
2018-05-19 00:45:36 -07:00
Huon Wilson
51c14c8a1a Merge pull request #16622 from huonw/better-protocol-conformance-printing
Better protocol conformance and substitution map printing
2018-05-16 08:40:54 +10:00
Huon Wilson
dad4169333 [AST] Make dumping for SubstitutionMap lisp-formatted and indent-aware.
This is much easier to read when part of a larger dump, where it now occurs in
expressions and specialized conformances.

Part of rdar://problem/40074968.
2018-05-15 22:17:52 +10:00
Doug Gregor
140e5bfc84 [AST] Minor SubstitutionMap cleanups suggested by Slava. 2018-05-14 07:03:53 -07:00
Doug Gregor
f078fc8d18 [AST] Don't eagerly form replacements when building a SubstitutionMap.
When forming a substitution map from a type substitution function and
conformance lookup function, we were calling the type substitution function
for generic parameters that aren't canonical (e.g., because they are
same-typed to something else). The type substitution functions wouldn't
necessarily take the new generic signature into account, so we would get
incorrect replacement types.

Detect non-canonical generic parameters when forming substitution maps,
and leave those entries in the "replacements" array blank; we'll fill them
in later, properly, when needed.
2018-05-13 23:51:53 -07:00
Doug Gregor
8010939238 [AST] Eliminate several uses of enumeratePairedRequirements(). 2018-05-11 22:33:03 -07:00
Doug Gregor
ef020c74aa Eliminate all vestiges of Substitution and SubstitutionList.
Introduced during the bring-up of the generics system in July, 2012,
Substitution (and SubstitutionList) has been completely superseded by
SubstitutionMap. R.I.P.
2018-05-11 21:43:40 -07:00
Doug Gregor
38a189f650 [SubstitutionMap] Introduce hasAnySubstitutableParams().
Introduce an operation to check that a given substitution map is non-empty
(i.e., corresponds to a generic signature) and that the generic signature
has type parameters that aren’t bound to concrete types. This is the
appropriate predicate for SIL-and-later to determine whether there
will be any substitutions.
2018-05-11 13:18:06 -07:00
Doug Gregor
dc7a251d4c [SubstitutionMap] Handle substitution of non-canonical generic parameters.
SubstitutionMap::lookupSubstitution() assumed that any type parameter it was
given would already be canonical, and fail (return a null Type) when given
a type parameter that was equivalent to another type parameter but is
not itself canonical. Canonicalize, recursive, and record the replacement
type appropriately.
2018-05-11 13:18:06 -07:00
Doug Gregor
791df5ba55 [AST] Cache the computed SubstitutionList for a SubstitutionMap.
Every SubstitutionMap::toList() invocation would ASTContext-allocate
arrays for all of the conformances, then return a SmallVector of the
underlying substitutions, which both wastes memory *and* puts the onus
on the caller to allocate a copy of that outer SmallVector into the
ASTContext if it's going to be stored anywhere.

Stop the madness by caching an ASTContext-allocated SubstitutionList
within the storage for the SubstitutionMap. This both reduces repeated
allocations and eliminates the potential for errors.
2018-05-03 10:38:01 -07:00
Doug Gregor
4136a1897a [AST] Split SubstitutionMap::Storage into its own header.
Now that SubstitutionMap is used in so many places, reduce it's header
dependencies by moving SubstitutionMap::Storage into its own separate
implementation header. Use forward declarations of other entities
(GenericSignature, Substitution) instead.

Good for build times and general sanity.
2018-05-03 09:49:09 -07:00
Pavel Yaskevich
01312d9623 Merge pull request #16276 from xedin/add-implicit-inits-with-getparams
[Sema] Refactor member type matching from `checkOverrides` to make it reusable
2018-05-03 00:16:24 -07:00
Pavel Yaskevich
394ac6f4f1 [AST] lookupSubstition should produce nothing if there are not substitutions
If `SubstitutionMap` is empty there is nothing to replace so
we should always return empty substitution type and/or conformance ref.
2018-05-02 15:11:25 -07:00
Doug Gregor
bc5bbe8b64 [AST] Use SubstitutionMap, not SubstitutionList, in SILBoxType.
Eliminate the last place in the AST proper that stores
SubstitutionLists rather than SubstitutionMaps. Randomly fixes a
crasher, too.
2018-05-02 13:39:21 -07:00
Doug Gregor
3e2bed119b [AST] Switch SpecializedProtocolConformance over to SubstitutionMap.
Eliminate another common use of SubstitutionList from the AST.
2018-05-02 13:38:15 -07:00
Doug Gregor
192234415d [AST] Store SubstitutionMaps in ConcreteDeclRef and Witness data structures.
Replace two prominent uses of SubstitutionList, in ConcreteDeclRef and
Witness, with SubstitutionMap. Deal with the myriad places where we
now have substitution maps and need substitution lists (or vice versa)
caused by this change.

Overall, removes ~50 explicit uses of SubstitutionList (of ~400).
2018-05-02 13:38:14 -07:00