Merge remote-tracking branch 'origin/main' into rebranch

This commit is contained in:
swift-ci
2025-09-24 08:34:30 -07:00
9 changed files with 112 additions and 24 deletions

View File

@@ -2344,7 +2344,11 @@ public:
/// Retrieve the substitution map applied to the declaration's underlying
/// to produce the described type.
SubstitutionMap getSubstitutionMap() const;
///
/// \param wantContextualType If \c true, the substitution map will bind
/// outer local generic parameters to archetypes. Otherwise they will be left
/// unchanged.
SubstitutionMap getSubstitutionMap(bool wantContextualType = false) const;
/// Get the direct generic arguments, which correspond to the generic
/// arguments that are directly applied to the typealias declaration

View File

@@ -2155,7 +2155,8 @@ GenericSignature TypeAliasType::getGenericSignature() const {
return typealias->getGenericSignature();
}
SubstitutionMap TypeAliasType::getSubstitutionMap() const {
SubstitutionMap
TypeAliasType::getSubstitutionMap(bool wantContextualType) const {
auto genericSig = typealias->getGenericSignature();
if (!genericSig)
return SubstitutionMap();
@@ -2164,8 +2165,14 @@ SubstitutionMap TypeAliasType::getSubstitutionMap() const {
DeclContext *dc = typealias->getDeclContext();
if (dc->isLocalContext()) {
if (auto parentSig = dc->getGenericSignatureOfContext())
parentSubMap = parentSig->getIdentitySubstitutionMap();
if (auto parentSig = dc->getGenericSignatureOfContext()) {
if (wantContextualType) {
parentSubMap =
parentSig.getGenericEnvironment()->getForwardingSubstitutionMap();
} else {
parentSubMap = parentSig->getIdentitySubstitutionMap();
}
}
} else if (auto parent = getParent()) {
parentSubMap = parent->getContextSubstitutionMap(dc);
}

View File

@@ -261,16 +261,30 @@ public:
}
Type transformTypeAliasType(TypeAliasType *aliasTy) {
auto *TAD = aliasTy->getDecl();
// For a non-generic typealias, we can simply recurse into the underlying
// type. The constraint system doesn't properly handle opened types in
// the underlying type of a typealias (e.g TypeWalker won't visit them),
// so we don't preserve the sugar.
if (!TAD->getGenericSignature())
return transform(aliasTy->getSinglyDesugaredType());
// Otherwise we have a generic typealias, or typealias in a generic context,
// and need to open any requirements introduced. Then we need to
// re-substitute any opened types into the underlying type. Like the
// non-generic codepath we also don't want to preserve sugar.
SmallVector<Type, 4> genericArgs;
for (auto arg : aliasTy->getDirectGenericArgs())
genericArgs.push_back(transform(arg));
auto substTy = TypeAliasType::get(
aliasTy->getDecl(), transform(aliasTy->getParent()), genericArgs,
transform(aliasTy->getSinglyDesugaredType()));
openGenericTypeRequirements(substTy->getDecl(),
substTy->getSubstitutionMap());
return substTy;
auto parentTy = transform(aliasTy->getParent());
auto subMap = TypeAliasType::get(TAD, parentTy, genericArgs,
aliasTy->getSinglyDesugaredType())
->getSubstitutionMap(/*wantContextualType*/ true);
openGenericTypeRequirements(TAD, subMap);
return transform(TAD->getUnderlyingType().subst(subMap));
}
Type transformErrorType(ErrorType *errTy) {

View File

@@ -0,0 +1,24 @@
// RUN: %empty-directory(%t/modules)
// RUN: split-file %s %t
// RUN: %target-swift-frontend-emit-module -emit-module-path %t/modules/A.swiftmodule -module-name A %t/a.swift
// RUN: %target-swift-frontend-emit-module -emit-module-path %t/modules/B.swiftmodule -module-name B -I %t/modules %t/b.swift
// RUN: %target-swift-frontend -typecheck -I %t/modules %t/c.swift
//--- a.swift
public struct S<T> {
public init(_ x: T) {}
}
//--- b.swift
import A
public typealias S = A.S
//--- c.swift
import A
import B
_ = S(0)

View File

@@ -1,23 +1,22 @@
// RUN: %target-typecheck-verify-swift
struct K<U> {} // expected-note 6{{'U' declared as parameter to type 'K'}}
struct K<U> {}
protocol Q {}
struct ConformingType: Q {}
struct S1<T: Q>: ExpressibleByArrayLiteral { // expected-note 2{{where 'T' = 'K<Int>'}}
init(_ x: T) {}
init(arrayLiteral: T...) {}
}
typealias R1<T: Q> = S1<T> // expected-note {{where 'T' = 'K<Int>'}} expected-note 2{{where 'T' = 'K<U>'}}
typealias R1<T: Q> = S1<T> // expected-note 2{{where 'T' = 'K<Int>'}}
func foo(_ x: K<Int>) {
let _ = [x] as S1<K> // expected-error {{generic struct 'S1' requires that 'K<Int>' conform to 'Q'}}
let _ = [x] as R1<K> // expected-error {{generic type alias 'R1' requires that 'K<Int>' conform to 'Q'}}
let _: S1<K> = [x] // expected-error {{generic struct 'S1' requires that 'K<Int>' conform to 'Q'}}
// FIXME: We ought to be able to infer 'U' here.
let _: R1<K> = [x] // expected-error 2 {{generic type alias 'R1' requires that 'K<U>' conform to 'Q'}}
// expected-error@-1 2 {{generic parameter 'U' could not be inferred}}
let _: S1<K> = [x] // expected-error {{generic struct 'S1' requires that 'K<Int>' conform to 'Q'}}
let _: R1<K> = [x] // expected-error {{generic type alias 'R1' requires that 'K<Int>' conform to 'Q'}}
}
protocol P2 {
@@ -25,11 +24,11 @@ protocol P2 {
}
struct S2<A: Q>: P2 {} // expected-note 3{{where 'A' = 'K<Int>'}}
typealias R2<A: Q> = S2<A> // expected-note 2{{where 'A' = 'K<Int>'}} expected-note 2{{where 'A' = 'K<U>'}}
typealias R2<A: Q> = S2<A> // expected-note 3{{where 'A' = 'K<Int>'}}
// Same as S2, but without the Q requirement.
struct S3<A>: P2 {}
typealias R3<A: Q> = S3<A> // expected-note {{where 'A' = 'K<Int>'}} expected-note {{where 'A' = 'K<U>'}}
typealias R3<A: Q> = S3<A> // expected-note 2{{where 'A' = 'K<Int>'}}
func foo<T: P2>(_ y: T.A.Type) -> T {}
let _ = foo(K<Int>.self) as S2<K> // expected-error {{generic struct 'S2' requires that 'K<Int>' conform to 'Q'}}
@@ -37,11 +36,8 @@ let _ = foo(K<Int>.self) as R2<K> // expected-error {{generic type alias 'R2' re
let _ = foo(K<Int>.self) as R3<K> // expected-error {{generic type alias 'R3' requires that 'K<Int>' conform to 'Q'}}
let _: S2<K> = foo(K<Int>.self) // expected-error {{generic struct 'S2' requires that 'K<Int>' conform to 'Q'}}
// FIXME: We ought to be able to infer 'U' here.
let _: R2<K> = foo(K<Int>.self) // expected-error 2{{generic type alias 'R2' requires that 'K<U>' conform to 'Q'}}
// expected-error@-1 2 {{generic parameter 'U' could not be inferred}}
let _: R3<K> = foo(K<Int>.self) // expected-error {{generic type alias 'R3' requires that 'K<U>' conform to 'Q'}}
// expected-error@-1 2 {{generic parameter 'U' could not be inferred}}
let _: R2<K> = foo(K<Int>.self) // expected-error {{generic type alias 'R2' requires that 'K<Int>' conform to 'Q'}}
let _: R3<K> = foo(K<Int>.self) // expected-error {{generic type alias 'R3' requires that 'K<Int>' conform to 'Q'}}
func foo<T: P2>(_ x: T.Type, _ y: T.A.Type) {}
foo(S2<_>.self, K<Int>.self) // expected-error {{generic struct 'S2' requires that 'K<Int>' conform to 'Q'}}
@@ -52,3 +48,17 @@ struct S4<T: Q> { // expected-note {{where 'T' = 'Int'}}
}
_ = S4<_>(0) // expected-error {{generic struct 'S4' requires that 'Int' conform to 'Q'}}
func testLocalOuterGeneric<T>(_ x: T) {
typealias X<U: Q> = (T, U) // expected-note {{where 'U' = 'String'}}
let _: X<_> = (x, "") // expected-error {{generic type alias 'X' requires that 'String' conform to 'Q'}}
let _: X<_> = (x, ConformingType())
}
struct TestParentGeneric<T> {
typealias X<U: Q> = (T, U) // expected-note {{where 'U' = 'String'}}
func bar(_ x: T) {
let _: X<_> = (x, "") // expected-error {{generic type alias 'X' requires that 'String' conform to 'Q'}}
let _: X<_> = (x, ConformingType())
}
}

View File

@@ -465,3 +465,19 @@ func testSugar(_ gx: GX<Int>, _ gy: GX<Int>.GY<Double>, gz: GX<Int>.GY<Double>.E
let i2: Int = gy // expected-error{{cannot convert value of type 'GX<Int>.GY<Double>' (aka 'Array<Double>') to specified type 'Int'}}
let i3: Int = gz // expected-error{{cannot convert value of type 'GX<Int>.GY<Double>.Element' (aka 'Double') to specified type 'Int'}}
}
func testLocalRequirementInference<T>(_ x: T, y: Int, s: S) {
typealias X<U: P> = (T, U) where T == U.A
func foo<V>(_ x: X<V>) {} // expected-note {{where 'V' = 'Int'}} expected-note {{where 'T' = 'T', 'V.A' = 'S.A' (aka 'Float')}}
foo((x, y)) // expected-error {{local function 'foo' requires that 'Int' conform to 'P'}}
foo((x, s)) // expected-error {{local function 'foo' requires the types 'T' and 'S.A' (aka 'Float') be equivalent}}
}
struct TestNestedRequirementInference<T> {
typealias X<U: P> = (T, U) where T == U.A
func foo<V>(_ x: X<V>) {} // expected-note {{where 'V' = 'Int'}} expected-note {{where 'T' = 'T', 'V.A' = 'S.A' (aka 'Float')}}
func bar(_ x: T, y: Int, s: S) {
foo((x, y)) // expected-error {{instance method 'foo' requires that 'Int' conform to 'P'}}
foo((x, s)) // expected-error {{instance method 'foo' requires the types 'T' and 'S.A' (aka 'Float') be equivalent}}
}
}

View File

@@ -21,5 +21,4 @@
<FileRef location = "group:../../../../swift-system"></FileRef>
<FileRef location = "group:../../../../swift-tools-support-core"></FileRef>
<FileRef location = "group:../../../../swiftpm"></FileRef>
<FileRef location = "group:../../../../yams"></FileRef>
</Workspace>

View File

@@ -0,0 +1,6 @@
// {"kind":"typecheck","signature":"swift::constraints::ConstraintSystem::openGenericParameters(swift::DeclContext*, swift::GenericSignature, llvm::SmallVectorImpl<std::__1::pair<swift::GenericTypeParamType*, swift::TypeVariableType*>>&, swift::constraints::ConstraintLocatorBuilder, swift::constraints::PreparedOverloadBuilder*)","signatureAssert":"Assertion failed: (sig), function openGenericParameters"}
// RUN: not %target-swift-frontend -typecheck %s
class a<b
func c -> d
typealias c : a
c

View File

@@ -0,0 +1,8 @@
// {"kind":"typecheck","original":"0df5dc82","signature":"swift::constraints::ConstraintSystem::typeVarOccursInType(swift::TypeVariableType*, swift::Type, bool*)","signatureAssert":"Assertion failed: ((!typeVariables.empty() || hasError()) && \"Did not find type variables!\"), function getTypeVariables"}
// RUN: not %target-swift-frontend -typecheck %s
struct a<each b {
typealias d<c> = (
> func 1 {
typealias e = f
e
typealias e = d