mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Sema: Use weighted reduction order for opaque return types
If the opaque generic signature has a same-type requirement between an outer type parameter and an opaque type parameter, the former should always precede the latter in the type parameter order, even if it is longer. Achieve this by giving the innermost generic parameters a non-zero weight in the opaque generic signature. Now, when we map a type parameter into an opaque generic environment, we correctly decide if it is represented by a type parameter of the outer generic signature, in which case we apply the outer substitution map instead of instantiating an archetype. The included test case demonstrates the issue; we declare an opaque return type `some P<T.A.A>`, so the opaque generic signature has a requirement `T.A.A == <<some P>>.A`. Previously, the reduced type of `<<some P>>.A` was `<<some P>>.A`, so it remained opaque; now we apply outer substitutions to `T.A.A`. - Fixes https://github.com/swiftlang/swift/issues/81036. - Fixes rdar://problem/149871931.
This commit is contained in:
@@ -142,7 +142,7 @@ OpaqueResultTypeRequest::evaluate(Evaluator &evaluator,
|
||||
for (unsigned i = 0; i < opaqueReprs.size(); ++i) {
|
||||
auto *currentRepr = opaqueReprs[i];
|
||||
|
||||
if( auto opaqueReturn = dyn_cast<OpaqueReturnTypeRepr>(currentRepr) ) {
|
||||
if (auto opaqueReturn = dyn_cast<OpaqueReturnTypeRepr>(currentRepr)) {
|
||||
// Usually, we resolve the opaque constraint and bail if it isn't a class
|
||||
// or existential type (see below). However, in this case we know we will
|
||||
// fail, so we can bail early and provide a better diagnostic.
|
||||
@@ -163,13 +163,13 @@ OpaqueResultTypeRequest::evaluate(Evaluator &evaluator,
|
||||
}
|
||||
}
|
||||
|
||||
auto *paramType = GenericTypeParamType::getType(opaqueSignatureDepth, i,
|
||||
ctx);
|
||||
auto *paramType = GenericTypeParamType::getOpaqueResultType(
|
||||
opaqueSignatureDepth, i, ctx);
|
||||
genericParamTypes.push_back(paramType);
|
||||
|
||||
TypeRepr *constraint = currentRepr;
|
||||
|
||||
if (auto opaqueReturn = dyn_cast<OpaqueReturnTypeRepr>(currentRepr)){
|
||||
if (auto opaqueReturn = dyn_cast<OpaqueReturnTypeRepr>(currentRepr)) {
|
||||
constraint = opaqueReturn->getConstraint();
|
||||
}
|
||||
// Try to resolve the constraint repr in the parent decl context. It
|
||||
|
||||
27
test/SILGen/opaque_result_type_reduction_order.swift
Normal file
27
test/SILGen/opaque_result_type_reduction_order.swift
Normal file
@@ -0,0 +1,27 @@
|
||||
// RUN: %target-swift-emit-silgen %s
|
||||
|
||||
protocol N {
|
||||
associatedtype A: N
|
||||
}
|
||||
|
||||
struct G<T>: N {
|
||||
typealias A = G<G<T>>
|
||||
}
|
||||
|
||||
protocol P<A> {
|
||||
associatedtype A
|
||||
}
|
||||
|
||||
struct GG<T>: P {
|
||||
typealias A = T
|
||||
}
|
||||
|
||||
func f<T: N>(_: T) -> some P<T.A.A> {
|
||||
return GG<T.A.A>()
|
||||
}
|
||||
|
||||
func g<T: P>(_: T) -> T.A { fatalError() }
|
||||
|
||||
func h(_: G<G<G<Int>>>) {}
|
||||
|
||||
h(g(f(G<Int>())))
|
||||
Reference in New Issue
Block a user