mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Merge remote-tracking branch 'origin/main' into rebranch
This commit is contained in:
@@ -2344,7 +2344,11 @@ public:
|
|||||||
|
|
||||||
/// Retrieve the substitution map applied to the declaration's underlying
|
/// Retrieve the substitution map applied to the declaration's underlying
|
||||||
/// to produce the described type.
|
/// 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
|
/// Get the direct generic arguments, which correspond to the generic
|
||||||
/// arguments that are directly applied to the typealias declaration
|
/// arguments that are directly applied to the typealias declaration
|
||||||
|
|||||||
@@ -2155,7 +2155,8 @@ GenericSignature TypeAliasType::getGenericSignature() const {
|
|||||||
return typealias->getGenericSignature();
|
return typealias->getGenericSignature();
|
||||||
}
|
}
|
||||||
|
|
||||||
SubstitutionMap TypeAliasType::getSubstitutionMap() const {
|
SubstitutionMap
|
||||||
|
TypeAliasType::getSubstitutionMap(bool wantContextualType) const {
|
||||||
auto genericSig = typealias->getGenericSignature();
|
auto genericSig = typealias->getGenericSignature();
|
||||||
if (!genericSig)
|
if (!genericSig)
|
||||||
return SubstitutionMap();
|
return SubstitutionMap();
|
||||||
@@ -2164,8 +2165,14 @@ SubstitutionMap TypeAliasType::getSubstitutionMap() const {
|
|||||||
DeclContext *dc = typealias->getDeclContext();
|
DeclContext *dc = typealias->getDeclContext();
|
||||||
|
|
||||||
if (dc->isLocalContext()) {
|
if (dc->isLocalContext()) {
|
||||||
if (auto parentSig = dc->getGenericSignatureOfContext())
|
if (auto parentSig = dc->getGenericSignatureOfContext()) {
|
||||||
|
if (wantContextualType) {
|
||||||
|
parentSubMap =
|
||||||
|
parentSig.getGenericEnvironment()->getForwardingSubstitutionMap();
|
||||||
|
} else {
|
||||||
parentSubMap = parentSig->getIdentitySubstitutionMap();
|
parentSubMap = parentSig->getIdentitySubstitutionMap();
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if (auto parent = getParent()) {
|
} else if (auto parent = getParent()) {
|
||||||
parentSubMap = parent->getContextSubstitutionMap(dc);
|
parentSubMap = parent->getContextSubstitutionMap(dc);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -261,16 +261,30 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
Type transformTypeAliasType(TypeAliasType *aliasTy) {
|
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;
|
SmallVector<Type, 4> genericArgs;
|
||||||
for (auto arg : aliasTy->getDirectGenericArgs())
|
for (auto arg : aliasTy->getDirectGenericArgs())
|
||||||
genericArgs.push_back(transform(arg));
|
genericArgs.push_back(transform(arg));
|
||||||
|
|
||||||
auto substTy = TypeAliasType::get(
|
auto parentTy = transform(aliasTy->getParent());
|
||||||
aliasTy->getDecl(), transform(aliasTy->getParent()), genericArgs,
|
auto subMap = TypeAliasType::get(TAD, parentTy, genericArgs,
|
||||||
transform(aliasTy->getSinglyDesugaredType()));
|
aliasTy->getSinglyDesugaredType())
|
||||||
openGenericTypeRequirements(substTy->getDecl(),
|
->getSubstitutionMap(/*wantContextualType*/ true);
|
||||||
substTy->getSubstitutionMap());
|
|
||||||
return substTy;
|
openGenericTypeRequirements(TAD, subMap);
|
||||||
|
return transform(TAD->getUnderlyingType().subst(subMap));
|
||||||
}
|
}
|
||||||
|
|
||||||
Type transformErrorType(ErrorType *errTy) {
|
Type transformErrorType(ErrorType *errTy) {
|
||||||
|
|||||||
24
test/Constraints/rdar160135085.swift
Normal file
24
test/Constraints/rdar160135085.swift
Normal 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)
|
||||||
@@ -1,23 +1,22 @@
|
|||||||
// RUN: %target-typecheck-verify-swift
|
// RUN: %target-typecheck-verify-swift
|
||||||
|
|
||||||
struct K<U> {} // expected-note 6{{'U' declared as parameter to type 'K'}}
|
struct K<U> {}
|
||||||
protocol Q {}
|
protocol Q {}
|
||||||
|
struct ConformingType: Q {}
|
||||||
|
|
||||||
struct S1<T: Q>: ExpressibleByArrayLiteral { // expected-note 2{{where 'T' = 'K<Int>'}}
|
struct S1<T: Q>: ExpressibleByArrayLiteral { // expected-note 2{{where 'T' = 'K<Int>'}}
|
||||||
init(_ x: T) {}
|
init(_ x: T) {}
|
||||||
init(arrayLiteral: 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>) {
|
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 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 _ = [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'}}
|
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 {{generic type alias 'R1' requires that 'K<Int>' conform to 'Q'}}
|
||||||
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}}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protocol P2 {
|
protocol P2 {
|
||||||
@@ -25,11 +24,11 @@ protocol P2 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct S2<A: Q>: P2 {} // expected-note 3{{where 'A' = 'K<Int>'}}
|
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.
|
// Same as S2, but without the Q requirement.
|
||||||
struct S3<A>: P2 {}
|
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 {}
|
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'}}
|
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 _ = 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'}}
|
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 {{generic type alias 'R2' requires that 'K<Int>' conform to 'Q'}}
|
||||||
let _: R2<K> = foo(K<Int>.self) // expected-error 2{{generic type alias 'R2' requires that 'K<U>' conform to 'Q'}}
|
let _: R3<K> = foo(K<Int>.self) // expected-error {{generic type alias 'R3' requires that 'K<Int>' 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}}
|
|
||||||
|
|
||||||
func foo<T: P2>(_ x: T.Type, _ y: T.A.Type) {}
|
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'}}
|
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'}}
|
_ = 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())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -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 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'}}
|
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}}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -21,5 +21,4 @@
|
|||||||
<FileRef location = "group:../../../../swift-system"></FileRef>
|
<FileRef location = "group:../../../../swift-system"></FileRef>
|
||||||
<FileRef location = "group:../../../../swift-tools-support-core"></FileRef>
|
<FileRef location = "group:../../../../swift-tools-support-core"></FileRef>
|
||||||
<FileRef location = "group:../../../../swiftpm"></FileRef>
|
<FileRef location = "group:../../../../swiftpm"></FileRef>
|
||||||
<FileRef location = "group:../../../../yams"></FileRef>
|
|
||||||
</Workspace>
|
</Workspace>
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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
|
||||||
Reference in New Issue
Block a user