mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
AST: Handle missing cases in findGenericParameterReferencesRec()
This commit is contained in:
@@ -4904,7 +4904,7 @@ findGenericParameterReferencesRec(CanGenericSignature genericSig,
|
||||
TypePosition position,
|
||||
bool canBeCovariantResult) {
|
||||
// If there are no type parameters, we're done.
|
||||
if (!type->hasTypeParameter())
|
||||
if (!type->getCanonicalType()->hasTypeParameter())
|
||||
return GenericParameterReferenceInfo();
|
||||
|
||||
// Tuples preserve variance.
|
||||
@@ -4954,7 +4954,7 @@ findGenericParameterReferencesRec(CanGenericSignature genericSig,
|
||||
// Don't forget to look in the parent.
|
||||
if (const auto parent = nominal->getParent()) {
|
||||
info |= findGenericParameterReferencesRec(
|
||||
genericSig, genericParam, parent, position,
|
||||
genericSig, genericParam, parent, TypePosition::Invariant,
|
||||
/*canBeCovariantResult=*/false);
|
||||
}
|
||||
|
||||
@@ -5033,10 +5033,40 @@ findGenericParameterReferencesRec(CanGenericSignature genericSig,
|
||||
return info;
|
||||
}
|
||||
|
||||
if (!type->isTypeParameter()) {
|
||||
// Packs are invariant.
|
||||
if (auto *pack = type->getAs<PackType>()) {
|
||||
auto info = GenericParameterReferenceInfo();
|
||||
|
||||
for (auto arg : pack->getElementTypes()) {
|
||||
info |= findGenericParameterReferencesRec(
|
||||
genericSig, genericParam, arg,
|
||||
TypePosition::Invariant, /*canBeCovariantResult=*/false);
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
// Pack expansions are invariant.
|
||||
if (auto *expansion = type->getAs<PackExpansionType>()) {
|
||||
return findGenericParameterReferencesRec(
|
||||
genericSig, genericParam, expansion->getPatternType(),
|
||||
TypePosition::Invariant, /*canBeCovariantResult=*/false);
|
||||
}
|
||||
|
||||
// Specifically ignore parameterized protocols and existential
|
||||
// metatypes because we can erase them to the upper bound.
|
||||
if (type->is<ParameterizedProtocolType>() ||
|
||||
type->is<ExistentialMetatypeType>()) {
|
||||
return GenericParameterReferenceInfo();
|
||||
}
|
||||
|
||||
// Everything else should be a type parameter.
|
||||
if (!type->isTypeParameter()) {
|
||||
llvm::errs() << "Unhandled type:\n";
|
||||
type->dump(llvm::errs());
|
||||
abort();
|
||||
}
|
||||
|
||||
Type selfTy(genericParam);
|
||||
if (!type->getRootGenericParam()->isEqual(selfTy)) {
|
||||
return GenericParameterReferenceInfo();
|
||||
|
||||
@@ -1025,6 +1025,10 @@ do {
|
||||
let _: Dictionary<String, any Class2Base & CovariantAssocTypeErasureDerived> = exist.method12()
|
||||
}
|
||||
|
||||
///
|
||||
/// Interactions between opening and parameter packs
|
||||
///
|
||||
|
||||
// Same-shape requirements
|
||||
protocol HasSameShape {
|
||||
func foo<each T, each U>(t: repeat each T, u: repeat each U) -> (repeat (each T, each U))
|
||||
@@ -1033,3 +1037,29 @@ protocol HasSameShape {
|
||||
func bar(a: any HasSameShape) -> (Int, String) {
|
||||
a.foo(t: 1, u: "hi")
|
||||
}
|
||||
|
||||
// Make sure we look through a pack type when evaluating the variance of the result
|
||||
struct Variadic<each A> {}
|
||||
|
||||
protocol VariadicResult {
|
||||
associatedtype A
|
||||
func foo() -> Variadic<A>
|
||||
}
|
||||
|
||||
func variadicResult(a: any VariadicResult) {
|
||||
a.foo()
|
||||
// expected-error@-1 {{member 'foo' cannot be used on value of type 'any VariadicResult'; consider using a generic constraint instead}}
|
||||
}
|
||||
|
||||
// Pack expansions are invariant
|
||||
struct Pair<X, Y> {}
|
||||
|
||||
protocol PackExpansionResult {
|
||||
associatedtype A
|
||||
func foo<each T>(t: repeat each T) -> (repeat Pair<each T, A>)
|
||||
}
|
||||
|
||||
func packExpansionResult(p: any PackExpansionResult) {
|
||||
p.foo(t: 1, "hi")
|
||||
// expected-error@-1 {{member 'foo' cannot be used on value of type 'any PackExpansionResult'; consider using a generic constraint instead}}
|
||||
}
|
||||
Reference in New Issue
Block a user