Skip to content

Commit 68dcbca

Browse files
Merge pull request #33581 from AnthonyLatsis/ripe-conformances/no-options
Sema: Pass substitution options to swift::checkTypeWitness
2 parents e3b7d5d + ec29edd commit 68dcbca

File tree

4 files changed

+48
-35
lines changed

4 files changed

+48
-35
lines changed

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3794,9 +3794,10 @@ ResolveWitnessResult ConformanceChecker::resolveWitnessViaDefault(
37943794

37953795
# pragma mark Type witness resolution
37963796

3797-
CheckTypeWitnessResult swift::checkTypeWitness(Type type,
3798-
AssociatedTypeDecl *assocType,
3799-
NormalProtocolConformance *Conf) {
3797+
CheckTypeWitnessResult
3798+
swift::checkTypeWitness(Type type, AssociatedTypeDecl *assocType,
3799+
const NormalProtocolConformance *Conf,
3800+
SubstOptions options) {
38003801
if (type->hasError())
38013802
return ErrorType::get(assocType->getASTContext());
38023803

@@ -3810,13 +3811,19 @@ CheckTypeWitnessResult swift::checkTypeWitness(Type type,
38103811
: type;
38113812

38123813
if (auto superclass = genericSig->getSuperclassBound(depTy)) {
3813-
// If the superclass has a type parameter, substitute in known type
3814-
// witnesses.
38153814
if (superclass->hasTypeParameter()) {
3816-
const auto subMap = SubstitutionMap::getProtocolSubstitutions(
3817-
proto, Conf->getType(), ProtocolConformanceRef(Conf));
3818-
3819-
superclass = superclass.subst(subMap);
3815+
// Replace type parameters with other known or tentative type witnesses.
3816+
superclass = superclass.subst(
3817+
[&](SubstitutableType *type) {
3818+
if (type->isEqual(proto->getSelfInterfaceType()))
3819+
return Conf->getType();
3820+
3821+
return Type();
3822+
},
3823+
LookUpConformanceInModule(dc->getParentModule()), options);
3824+
3825+
if (superclass->hasTypeParameter())
3826+
superclass = dc->mapTypeIntoContext(superclass);
38203827
}
38213828
if (!superclass->isExactSuperclassOf(contextType))
38223829
return superclass;

lib/Sema/TypeCheckProtocol.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,8 @@ class CheckTypeWitnessResult {
9696
/// \returns an empty result on success, or a description of the error.
9797
CheckTypeWitnessResult checkTypeWitness(Type type,
9898
AssociatedTypeDecl *assocType,
99-
NormalProtocolConformance *Conf);
99+
const NormalProtocolConformance *Conf,
100+
SubstOptions options = None);
100101

101102
/// Describes the means of inferring an abstract type witness.
102103
enum class AbstractTypeWitnessKind : uint8_t {

lib/Sema/TypeCheckProtocolInference.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1172,6 +1172,7 @@ AssociatedTypeDecl *AssociatedTypeInference::completeSolution(
11721172

11731173
// Check each abstract type witness we computed against the generic
11741174
// requirements on the corresponding associated type.
1175+
const auto substOptions = getSubstOptionsWithCurrentTypeWitnesses();
11751176
for (const auto &witness : abstractTypeWitnesses) {
11761177
Type type = witness.getType();
11771178
if (type->hasTypeParameter()) {
@@ -1184,8 +1185,7 @@ AssociatedTypeDecl *AssociatedTypeInference::completeSolution(
11841185

11851186
return Type();
11861187
},
1187-
LookUpConformanceInModule(dc->getParentModule()),
1188-
getSubstOptionsWithCurrentTypeWitnesses());
1188+
LookUpConformanceInModule(dc->getParentModule()), substOptions);
11891189

11901190
// If the substitution produced an error, we're done.
11911191
if (type->hasError())
@@ -1194,8 +1194,8 @@ AssociatedTypeDecl *AssociatedTypeInference::completeSolution(
11941194
type = dc->mapTypeIntoContext(type);
11951195
}
11961196

1197-
if (const auto &failed =
1198-
checkTypeWitness(type, witness.getAssocType(), conformance)) {
1197+
if (const auto &failed = checkTypeWitness(type, witness.getAssocType(),
1198+
conformance, substOptions)) {
11991199
// We failed to satisfy a requirement. If this is a default type
12001200
// witness failure and we haven't seen one already, write it down.
12011201
if (witness.getKind() == AbstractTypeWitnessKind::Default &&

test/decl/protocol/conforms/associated_type.swift

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -94,27 +94,8 @@ struct SR_12707_Conform_P2: SR_12707_P2 {
9494
typealias A = Never
9595
}
9696

97-
// Default type witness
98-
protocol SR_12707_P3 {
99-
associatedtype A
100-
associatedtype B: SR_12707_C<(A, Self)> = SR_12707_C<(A, Self)>
101-
}
102-
struct SR_12707_Conform_P3: SR_12707_P3 {
103-
typealias A = Never
104-
}
105-
106-
// FIXME: Type witness resolution success is order-dependent.
107-
protocol SR_12707_FIXME_P1 {
108-
associatedtype A
109-
}
110-
protocol SR_12707_FIXME_P2: SR_12707_FIXME_P1 {
111-
associatedtype B: SR_12707_C<(A, Self)> = SR_12707_C<(A, Self)> // expected-note {{default type 'associated_type.SR_12707_C<(associated_type.SR_12707_FIXME_Conform_P2.A, associated_type.SR_12707_FIXME_Conform_P2)>' (aka 'SR_12707_C<(Never, SR_12707_FIXME_Conform_P2)>') for associated type 'B' (from protocol 'SR_12707_FIXME_P2') does not inherit from 'associated_type.SR_12707_C<(associated_type.SR_12707_FIXME_Conform_P2.A, associated_type.SR_12707_FIXME_Conform_P2)>'}}
112-
}
113-
struct SR_12707_FIXME_Conform_P2: SR_12707_FIXME_P2 { // expected-error {{type 'SR_12707_FIXME_Conform_P2' does not conform to protocol 'SR_12707_FIXME_P2'}}
114-
typealias A = Never
115-
}
116-
117-
// FIXME: Type witness resolution success is order-dependent.
97+
// FIXME: resolveTypeWitnessViaLookup must not happen independently in the
98+
// general case.
11899
protocol SR_12707_FIXME_P3 {
119100
associatedtype A: SR_12707_C<B> // expected-note {{protocol requires nested type 'A'; do you want to add it?}}
120101
associatedtype B
@@ -123,3 +104,27 @@ struct SR_12707_FIXME_Conform_P3: SR_12707_FIXME_P3 { // expected-error {{type '
123104
typealias A = SR_12707_C<B> // expected-note {{possibly intended match 'SR_12707_FIXME_Conform_P3.A' (aka 'SR_12707_C<Never>') does not inherit from 'SR_12707_C<SR_12707_FIXME_Conform_P3.B>'}}
124105
typealias B = Never
125106
}
107+
108+
// FIXME: Associated type inference via value witnesses should consider
109+
// tentative witnesses when checking a candidate.
110+
protocol SR_12707_FIXME_P4 {
111+
associatedtype X = Never
112+
113+
associatedtype A: SR_12707_C<X> // expected-note {{unable to infer associated type 'A' for protocol 'SR_12707_FIXME_P4'}}
114+
func foo(arg: A)
115+
}
116+
struct SR_12707_FIXME_Conform_P4: SR_12707_FIXME_P4 { // expected-error {{type 'SR_12707_FIXME_Conform_P4' does not conform to protocol 'SR_12707_FIXME_P4'}}
117+
func foo(arg: SR_12707_C<Never>) {} // expected-note {{candidate would match and infer 'A' = 'SR_12707_C<Never>' if 'SR_12707_C<Never>' inherited from 'SR_12707_C<SR_12707_FIXME_Conform_P4.X>'}}
118+
}
119+
120+
// Abstract type witnesses.
121+
protocol SR_12707_P5a {
122+
associatedtype X = Never
123+
124+
associatedtype A: SR_12707_C<X>
125+
associatedtype B: SR_12707_C<X>
126+
}
127+
protocol SR_12707_P5b: SR_12707_P5a where B == SR_12707_C<X> {
128+
associatedtype C: SR_12707_C<Self> = SR_12707_C<Self>
129+
}
130+
struct SR_12707_Conform_P5<A: SR_12707_C<Never>>: SR_12707_P5b {}

0 commit comments

Comments
 (0)