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
|
||||
/// 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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
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
|
||||
|
||||
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())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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}}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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