Commit Graph

43 Commits

Author SHA1 Message Date
Kavon Farvardin 21b2ebff12 Sema: infer inverses in opaque return types
Opaque return types are special type declarations that have it
own nested generic signature. Thus, given this:
```
  protocol P<A> { associatedtype A: ~Copyable }
  func f<T: ~Copyable>() -> some P<T> {}
```
The generic signature for f is <T where T Escapable>, and
for the opaque return type, its nested signature ends up as
```
  <X where X: P, X.A == T>
```
With SE-503, we will now also expand a default for the suppressed
primary associated type, so the signature after expansion becomes
```
  <X where X: P, X.A == T, X.A: Copyable>
```
It would be smarter to effectively have this rule
```
  X.A == T, T: ~Copyable
  ----------------------
     X.A: ~Copyable
```
where we infer the inverse on X.A to cancel-out the
expanded default X.A: Copyable. We already do this for
two in-scope type parameters, and it would be better if
we did it if one side was out-of-scope, but that would
be source-breaking to do in general.

In the case of opaque return types, the fact that
it has a nested generic signature seems more an
artifact of the implementation. There also is little
risk of source break, as the only kinds of same-type
requirements that can appear are from parameterized
protocol type.

The experimental suppressed associated types prior to
SE-503 wouldn't be broken by this change, as they do
not infer defaults that need suppression, and we only
filter-out requirements from defaults expansion, rather
than explicitly-written ones.

rdar://175500824
2026-05-04 14:49:34 -07:00
Kavon Farvardin 6651cb6389 NFC: refactor the applyInverses bool
There's a need for more control over how default requirements
for conformance to Copyable/Escapable are expanded, and
subsequently how inverses are applied or inferred to cancel-out
those defaults.

The pattern of `/*applyInverses*/BOOL` is insufficient, so this
is a refactoring to grow that into a proper type that carries
an option that can be used in some future scenario about inferring
inverses for opaque return types.
2026-04-29 16:56:00 -07:00
Slava Pestov ee440f3c91 AST: Remove MakeAbstractConformanceForGenericType
While the intent behind this functor was noble, it has grown in complexity
considerably over the years, and it seems to be nothing but a source of
crashes in practice. I don't want to deal with it anymore, so I've decided
to just subsume all usages with LookUpConformanceInModule instead.
2025-07-15 16:34:11 -04:00
Slava Pestov 7bde868468 AST: Simplify RequirementEnvironment construction a bit more 2025-07-11 13:31:50 -04:00
Slava Pestov 03de964154 AST: Change RequirementEnvironment::getRequirementToWitnessThunkSubs() to use contextual types
In the provided test case, the generic signature of the
protocol requirement is

    <Self, T where Self == T.A, T: P2>

The conformance requirement `Self: P1` is derived from `T: P2`
and `Self.A: P1` in P1. So given a substitution map
`{ Self := X, T := T }` that replaces T with a concrete type X
and T with a type parameter T, there are two ways to recover a
substituted conformance for `Self: P1`:

- We can apply the substitution map to Self to get X, and look
  up conformance of X to P1, to get a concrete conformance.

- We can evaluate the conformance path `(T: P2)(Self.A: P1)`,
  to get an abstract conformance.

Both answers are correct, but SILGenModule::emitProtocolWitness()
was assuming it would always get a concrete conformance back.

This was the case until e3c8f423bc,
but then we started returning an abstract conformance. SILGen
would then mangle the protocol witness thunk in a way that was
not sufficiently unique, and as a result, we could miscompile
a program where two witness tables both hit this same scenario.

By using contextual types in the getRequirementToWitnessThunkSubs()
substitution map, we ensure that evaluating the conformance path
against the substitution map produces the same result as performing
the global lookup.

Also, to prevent this from happening again, add a check to SILGen
to guard against emitting two protocol witness thunks with the
same mangled name.

Unfortunately, this is done intentionally as part of some
backward deployment logic for coroutine accessors. There is a
hack to allow duplicate thunks with the same name in this case,
but this should be revisited some day.

Fixes rdar://problem/155624135..
2025-07-11 13:31:35 -04:00
Slava Pestov 6ffa8fd489 AST: Change signature of LookupConformanceFn
Instead of passing in the substituted type, we pass in the
InFlightSubstitution. This allows the substituted type to be
recovered if needed, but we can now skip computing it for
the common case of LookUpConformanceInSubstitutionMap.
2025-04-30 13:42:20 -04:00
Slava Pestov 83d2060f32 AST: Replace a getSelfInterfaceType() with TheSelfType 2025-04-30 13:42:20 -04:00
Slava Pestov 6b4710ed22 Merge pull request #81142 from slavapestov/more-type-subst-cleanup
Clean up duplicated opened existential archetype handling in SIL and more
2025-04-30 02:42:57 -04:00
Slava Pestov 115ba5c54f AST: Factor out GenericTypeParamType::withDepth() 2025-04-29 13:55:29 -04:00
Slava Pestov cf1572c65b AST: Add ASTContext::TheSelfType for convenience 2025-04-28 11:49:50 -04:00
Slava Pestov a8bca07e54 AST: Fix handling of pack conformance requirements in RequirementEnvironment
If a generic signature states a requirement `each T: P`, we must wrap the
abstract conformance in a pack conformance first.

We let this slide before, but it's now flagged by SubstitutionMap::verify().
2024-11-15 17:26:35 -05:00
Slava Pestov 9d09f93a7f AST: Correctly use inherited conformances in RequirementEnvironment
When the conforming type is a class-constrained type parameter or
archetype, we must wrap the concrete superclass conformance in an
inherited conformance. This is now flagged by SubstitutionMap::verify().
2024-11-15 17:26:35 -05:00
Alejandro Alonso f4f60f4344 Remove Value requirement Add GenericTypeParamKind 2024-09-04 15:13:43 -07:00
Alejandro Alonso 75c2cbf593 Implement value generics
Some requirement machine work

Rename requirement to Value

Rename more things to Value

Fix integer checking for requirement

some docs and parser changes

Minor fixes
2024-09-04 15:13:25 -07:00
Slava Pestov fae01d9776 AST: Remove ModuleDecl parameter from more places 2024-07-06 12:05:46 -04:00
Tim Kientzle 1d961ba22d Add #include "swift/Basic/Assertions.h" to a lot of source files
Although I don't plan to bring over new assertions wholesale
into the current qualification branch, it's entirely possible
that various minor changes in main will use the new assertions;
having this basic support in the release branch will simplify that.
(This is why I'm adding the includes as a separate pass from
rewriting the individual assertions)
2024-06-05 19:37:30 -07:00
Slava Pestov 818f47918c AST: Use getNextDepth()/getMaxDepth() 2024-05-01 12:09:01 -04:00
Slava Pestov aa4a1b2b6e AST: The generic conformance of a specialized conformance is always normal 2024-03-07 12:22:33 -05:00
Slava Pestov af50d7e6b8 AST: Add allowInverses flag to AbstractGenericSignatureRequest 2024-02-05 18:43:06 -05:00
Slava Pestov 2146a5a8e7 AST: Remove some usages of SubstFlags::PreservePackExpansionLevel 2023-06-29 16:25:41 -04:00
Slava Pestov be218f5e16 AST: Use PackElementType to model references to pack elements of outer expansions 2023-06-06 14:18:37 -04:00
Slava Pestov fa1e17fab7 Sema: Protocol conformance checking fixes for variadic generics 2023-04-05 23:42:16 -04:00
Holly Borla c4b946195e [AST] Replace the "type sequence" terminology with "parameter pack". 2022-10-10 16:28:13 -07:00
Slava Pestov 7d8f3e6b63 AST: Change return type of Requirement::subst() to Requirement
Instead of returning None, let callers check hasError() if they need to.

Fixes rdar://problem/98565072.
2022-08-12 14:03:57 -04:00
Slava Pestov 63307760e4 AST: The underlying conformance of a specialized conformance is always a root conformance 2022-08-03 00:28:43 -04:00
Slava Pestov 03b3ec8718 AST: Rename 'synthetic' to 'witness thunk' in RequirementEnvironment and Witness 2022-07-20 11:52:07 -04:00
Slava Pestov 1687895d44 AST: Refactor RequirementEnvironment and Witness to store GenericSignature instead of GenericEnvironment 2022-07-20 11:52:07 -04:00
Robert Widmann 22405cefea Plumb the "Is Type Sequence" Bit Through the Surface AST 2021-11-08 13:48:30 -08:00
Slava Pestov f38f25a3de AST: Factor out AbstractGenericSignatureRequest into a new buildGenericSignature() function
This is slightly cleaner.
2021-10-30 00:35:59 -04:00
Robert Widmann 1329f3cfbd [NFC] Lift getGenericEnvironment() into GenericSignature 2021-07-22 23:33:02 -07:00
Robert Widmann d86551de67 Lift Requirement and Parameter Accessors up to GenericSignature
Start treating the null {Can}GenericSignature as a regular signature
with no requirements and no parameters. This not only makes for a much
safer abstraction, but allows us to simplify a lot of the clients of
GenericSignature that would previously have to check for null before
using the abstraction.
2021-07-22 23:27:05 -07:00
Anthony Latsis 9fd1aa5d59 [NFC] Pre- increment and decrement where possible 2020-06-01 15:39:29 +03: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
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 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 30d871b8c1 Switch requirement environment over to the abstract generic signature request 2019-08-26 09:54:20 -07:00
Slava Pestov d8fc9decf9 AST: Remove GenericSignature::getSubstitutionMap() 2018-05-28 19:45:28 -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 510f842488 AST: Workaround for same-type constraints getting dropped from requirement environment
The fix for <https://bugs.swift.org/browse/SR-617> introduced
a new kind of requirement environment where 'Self' remains a
generic parameter, but receives a class constraint, instead of
becoming fully concrete.

As before, we would form the synthetic signature by taking
the generic signature of the requirement, and substituting it
the new 'Self' type.

However, whereas previously the 'Self' type was always concrete
and any DependentMemberTypes in the requirement's signature
would become concrete type references, with a class-constrained
'Self' the DependentMemberTypes remain.

Apparently, the GSB cannot handle DependentMemberTypes where
the base is class-constrained.

Work around this by ensuring that we add a conformance constraint
for the 'Self' parameter to the protocol in question, which
allows the DependentMemberTypes to be correctly resolves once
the conformance is made concrete by a superclass constraint.

The FIXME comment being removed here references crashes which
no longer seem to reproduce, so I'm assuming some underlying
GSB issues got fixed and the FIXME is clearly no longer necessary.

However, I still consider this fix somewhat unsatisfying, because
it is not clear if there's some deeper flaw in how the GSB
models superclass constraints. It might resurface again in the
future.

Fixes <rdar://problem/39419121>, <https://bugs.swift.org/browse/SR-7428>.
2018-04-16 22:22:52 -07:00
Huon Wilson 63a50936e4 [AST] Keep generic type params generic in RequirementEnvironments.
Before this patch, the use of GenericSignature::getSubstitutionMap to
create a substitution map would result in some generic parameters being
completely elided (well, being mapped to concrete types causing a
->castTo<GenericTypeParamType>() to crash). This patch changes that to
just do the reindexing of the type parameters directly, without trying
to be smart with more contextual information (i.e. τ_0_0 -> τ_1_0, even
if there's a τ_0_0 == Int requirement).

Fixes rdar://problem/37291254 and SR-6990.
2018-02-13 22:58:14 +11:00
Doug Gregor beed602bdc [NFC] Fix new file headers 2017-12-11 17:03:07 -08:00
Doug Gregor 82dde17ef4 [Conformance checking] More refactoring of associated type inference.
Move the rest of associated type inference into the new source file,
and split RequirementEnvironment into its own AST-level header, because it
can be re-used and has no ties to the type checker.
2017-12-11 16:34:49 -08:00