Skip to content

Commit a5c5a01

Browse files
committed
Sema: Don't look at SubstitutedType in CSDiag
The code here is unprincipled, and mixes archetypes from multiple sources: 1) The callee's generic environment 2) The caller's generic environment 3) Any random archetypes appearing in the original types of typealiases, which could come from any generic environment Initially, an UncurriedCandidate's type starts out as #1, and then we sometimes set it to type #2 if the candidate is a method on a base class. We get swiftlang#3 by virtue of walking the original types of SubstitutedTypes created as part of dependent member type substitution. However, it turns out the real reason the SubstitutedType walk existed was so that #2 archetypes that appear in the UncurriedCandidate's type map to themselves. This doesn't require looking at the original type of a SubstitutedType at all; instead we just walk the UncurriedCandidate's type normally, collecting archetypes. If we do this, the code doesn't (erroneously) pick up random archetypes from typealiases, and this changes the output in the RangeDiagnostics test. While we can debate if the new diagnostics are better or worse (I think it's either a wash, or slightly better) the reason they changed is because more in-depth diagnostic code is now executing, without breaking things randomly as before. I suspect this is a good thing.
1 parent a32e11a commit a5c5a01

File tree

2 files changed

+92
-77
lines changed

2 files changed

+92
-77
lines changed

lib/Sema/CSDiag.cpp

Lines changed: 48 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -792,14 +792,6 @@ static void gatherArgumentLabels(Type type,
792792
labels.push_back(Identifier());
793793
}
794794

795-
static Type stripSubstitutedTypes(Type t) {
796-
return t.transform([](Type t) -> Type {
797-
while (auto *ST = dyn_cast<SubstitutedType>(t.getPointer()))
798-
t = ST->getReplacementType();
799-
return t;
800-
});
801-
}
802-
803795
namespace {
804796
/// Each match in an ApplyExpr is evaluated for how close of a match it is.
805797
/// The result is captured in this enum value, where the earlier entries are
@@ -839,8 +831,17 @@ namespace {
839831
unsigned level;
840832
Type entityType;
841833

834+
// If true, entityType is written in terms of caller archetypes,
835+
// with any unbound generic arguments remaining as interface
836+
// type parameters in terms of the callee generic signature.
837+
//
838+
// If false, entityType is written in terms of callee archetypes.
839+
//
840+
// FIXME: Clean this up.
841+
bool substituted;
842+
842843
UncurriedCandidate(ValueDecl *decl, unsigned level)
843-
: declOrExpr(decl), level(level) {
844+
: declOrExpr(decl), level(level), substituted(false) {
844845

845846
if (auto *PD = dyn_cast<ParamDecl>(decl))
846847
entityType = PD->getType();
@@ -851,11 +852,9 @@ namespace {
851852
auto *M = DC->getParentModule();
852853
auto subs = DC->getGenericEnvironmentOfContext()
853854
->getForwardingSubstitutions(M);
854-
entityType = stripSubstitutedTypes(GFT->substGenericArgs(subs));
855+
entityType = GFT->substGenericArgs(subs);
855856
} else {
856-
entityType = ArchetypeBuilder::mapTypeIntoContext(
857-
DC, entityType);
858-
entityType = stripSubstitutedTypes(entityType);
857+
entityType = DC->mapTypeIntoContext(entityType);
859858
}
860859
}
861860

@@ -869,7 +868,8 @@ namespace {
869868
}
870869
}
871870
UncurriedCandidate(Expr *expr)
872-
: declOrExpr(expr), level(0), entityType(expr->getType()) {
871+
: declOrExpr(expr), level(0), entityType(expr->getType()),
872+
substituted(true) {
873873
}
874874

875875
ValueDecl *getDecl() const {
@@ -1033,9 +1033,7 @@ namespace {
10331033
/// obviously mismatching candidates and compute a "closeness" for the
10341034
/// resultant set.
10351035
ClosenessResultTy
1036-
evaluateCloseness(DeclContext *dc, Type candArgListType,
1037-
ValueDecl *candidateDecl,
1038-
unsigned level,
1036+
evaluateCloseness(UncurriedCandidate candidate,
10391037
ArrayRef<CallArgParam> actualArgs);
10401038

10411039
void filterListArgs(ArrayRef<CallArgParam> actualArgs);
@@ -1202,9 +1200,11 @@ static bool findGenericSubstitutions(DeclContext *dc, Type paramType,
12021200

12031201
bool mismatch(SubstitutableType *paramType, TypeBase *argType) {
12041202
Type type = paramType;
1205-
if (dc && dc->isGenericContext() && type->isTypeParameter())
1206-
type = ArchetypeBuilder::mapTypeIntoContext(dc, paramType);
1207-
1203+
if (type->is<GenericTypeParamType>()) {
1204+
assert(dc);
1205+
type = dc->mapTypeIntoContext(paramType);
1206+
}
1207+
12081208
if (auto archetype = type->getAs<ArchetypeType>()) {
12091209
auto existing = archetypesMap[archetype];
12101210
if (existing)
@@ -1215,7 +1215,7 @@ static bool findGenericSubstitutions(DeclContext *dc, Type paramType,
12151215
return false;
12161216
}
12171217
};
1218-
1218+
12191219
GenericVisitor visitor(dc, archetypesMap);
12201220
return visitor.match(paramType, actualArgType);
12211221
}
@@ -1224,11 +1224,14 @@ static bool findGenericSubstitutions(DeclContext *dc, Type paramType,
12241224
/// list. If the closeness is a miss by a single argument, then this returns
12251225
/// information about that failure.
12261226
CalleeCandidateInfo::ClosenessResultTy
1227-
CalleeCandidateInfo::evaluateCloseness(DeclContext *dc, Type candArgListType,
1228-
ValueDecl *candidateDecl,
1229-
unsigned level,
1227+
CalleeCandidateInfo::evaluateCloseness(UncurriedCandidate candidate,
12301228
ArrayRef<CallArgParam> actualArgs) {
1231-
auto candArgs = decomposeParamType(candArgListType, candidateDecl, level);
1229+
auto *dc = candidate.getDecl()
1230+
? candidate.getDecl()->getInnermostDeclContext()
1231+
: nullptr;
1232+
auto candArgs = decomposeParamType(candidate.getArgumentType(),
1233+
candidate.getDecl(),
1234+
candidate.level);
12321235

12331236
struct OurListener : public MatchCallArgumentListener {
12341237
CandidateCloseness result = CC_ExactMatch;
@@ -1336,27 +1339,20 @@ CalleeCandidateInfo::evaluateCloseness(DeclContext *dc, Type candArgListType,
13361339
if (paramType->is<InOutType>() && argType->is<LValueType>())
13371340
matchType = matchType->getInOutObjectType();
13381341

1339-
matchType.findIf([&](Type type) -> bool {
1340-
if (auto substitution = dyn_cast<SubstitutedType>(type.getPointer())) {
1341-
Type original = substitution->getOriginal();
1342-
if (dc && dc->isGenericContext() && original->isTypeParameter())
1343-
original = ArchetypeBuilder::mapTypeIntoContext(dc, original);
1344-
1345-
Type replacement = substitution->getReplacementType();
1342+
if (candidate.substituted) {
1343+
matchType.findIf([&](Type type) -> bool {
13461344
// If the replacement is itself an archetype, then the constraint
13471345
// system was asserting equivalencies between different levels of
13481346
// generics, rather than binding a generic to a concrete type (and we
13491347
// don't/won't have a concrete type). In which case, it is the
13501348
// replacement we are interested in, since it is the one in our current
13511349
// context. That generic type should equal itself.
1352-
if (auto ourGeneric = replacement->getAs<ArchetypeType>())
1353-
archetypesMap[ourGeneric] = replacement;
1354-
else if (auto archetype = original->getAs<ArchetypeType>())
1355-
archetypesMap[archetype] = replacement;
1356-
}
1357-
return false;
1358-
});
1359-
1350+
if (auto archetype = type->getAs<ArchetypeType>()) {
1351+
archetypesMap[archetype] = archetype;
1352+
}
1353+
return false;
1354+
});
1355+
}
13601356
matched = findGenericSubstitutions(dc, matchType, rArgType,
13611357
archetypesMap);
13621358
}
@@ -1569,9 +1565,11 @@ void CalleeCandidateInfo::collectCalleeCandidates(Expr *fn,
15691565
C.level += 1;
15701566

15711567
// Compute a new substituted type if we have a base type to apply.
1572-
if (baseType && C.level == 1 && C.getDecl())
1568+
if (baseType && C.level == 1 && C.getDecl()) {
15731569
C.entityType = baseType->getTypeOfMember(CS->DC->getParentModule(),
15741570
C.getDecl(), nullptr);
1571+
C.substituted = true;
1572+
}
15751573
}
15761574

15771575
return;
@@ -1664,13 +1662,10 @@ void CalleeCandidateInfo::filterListArgs(ArrayRef<CallArgParam> actualArgs) {
16641662
// Now that we have the candidate list, figure out what the best matches from
16651663
// the candidate list are, and remove all the ones that aren't at that level.
16661664
filterList([&](UncurriedCandidate candidate) -> ClosenessResultTy {
1667-
auto inputType = candidate.getArgumentType();
16681665
// If this isn't a function or isn't valid at this uncurry level, treat it
16691666
// as a general mismatch.
1670-
if (!inputType) return { CC_GeneralMismatch, {}};
1671-
ValueDecl *decl = candidate.getDecl();
1672-
return evaluateCloseness(decl ? decl->getInnermostDeclContext() : nullptr,
1673-
inputType, decl, candidate.level, actualArgs);
1667+
if (!candidate.getArgumentType()) return { CC_GeneralMismatch, {}};
1668+
return evaluateCloseness(candidate, actualArgs);
16741669
});
16751670
}
16761671

@@ -1782,8 +1777,10 @@ CalleeCandidateInfo::CalleeCandidateInfo(Type baseType,
17821777
if (substType && selfAlreadyApplied)
17831778
substType = substType->getTypeOfMember(CS->DC->getParentModule(),
17841779
decl, nullptr);
1785-
if (substType)
1780+
if (substType) {
17861781
candidates.back().entityType = substType;
1782+
candidates.back().substituted = true;
1783+
}
17871784
}
17881785
}
17891786

@@ -5310,14 +5307,12 @@ bool FailureDiagnosis::visitSubscriptExpr(SubscriptExpr *SE) {
53105307
CalleeCandidateInfo::ClosenessResultTy
53115308
{
53125309
// Classify how close this match is. Non-subscript decls don't match.
5313-
auto *SD = dyn_cast_or_null<SubscriptDecl>(cand.getDecl());
5314-
if (!SD) return { CC_GeneralMismatch, {}};
5310+
if (!dyn_cast_or_null<SubscriptDecl>(cand.getDecl()))
5311+
return { CC_GeneralMismatch, {}};
53155312

53165313
// Check whether the self type matches.
53175314
auto selfConstraint = CC_ExactMatch;
5318-
if (calleeInfo.evaluateCloseness(SD->getInnermostDeclContext(),
5319-
cand.getArgumentType(), SD, cand.level,
5320-
decomposedBaseType)
5315+
if (calleeInfo.evaluateCloseness(cand, decomposedBaseType)
53215316
.first != CC_ExactMatch)
53225317
selfConstraint = CC_SelfMismatch;
53235318

@@ -5326,9 +5321,7 @@ bool FailureDiagnosis::visitSubscriptExpr(SubscriptExpr *SE) {
53265321

53275322
// Explode out multi-index subscripts to find the best match.
53285323
auto indexResult =
5329-
calleeInfo.evaluateCloseness(SD->getInnermostDeclContext(),
5330-
cand.getArgumentType(), SD, cand.level,
5331-
decomposedIndexType);
5324+
calleeInfo.evaluateCloseness(cand, decomposedIndexType);
53325325
if (selfConstraint > indexResult.first)
53335326
return {selfConstraint, {}};
53345327
return indexResult;

test/stdlib/RangeDiagnostics.swift

Lines changed: 44 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -192,27 +192,38 @@ func disallowSubscriptingOnIntegers() {
192192

193193
r0[0] // expected-error {{ambiguous use of 'subscript'}}
194194
r1[0] // expected-error {{ambiguous use of 'subscript'}}
195-
r2[0] // expected-error {{cannot convert value of type 'Int' to expected argument type 'Range<ClosedRangeIndex<_>>'}}
196-
r3[0] // expected-error {{cannot convert value of type 'Int' to expected argument type 'Range<ClosedRangeIndex<_>>'}}
195+
r2[0] // expected-error {{cannot subscript a value of type 'CountableClosedRange<Int>' with an index of type 'Int'}}
196+
// expected-note@-1 {{overloads for 'subscript'}}
197+
r3[0] // expected-error {{cannot subscript a value of type 'CountableClosedRange<UInt>' with an index of type 'Int'}}
198+
// expected-note@-1 {{overloads for 'subscript'}}
197199

198200
r0[UInt(0)] // expected-error {{ambiguous reference to member 'subscript'}}
199201
r1[UInt(0)] // expected-error {{ambiguous use of 'subscript'}}
200-
r2[UInt(0)] // expected-error {{cannot convert value of type 'UInt' to expected argument type 'Range<ClosedRangeIndex<_>>'}}
201-
r3[UInt(0)] // expected-error {{cannot convert value of type 'UInt' to expected argument type 'Range<ClosedRangeIndex<_>>'}}
202+
r2[UInt(0)] // expected-error {{cannot subscript a value of type 'CountableClosedRange<Int>' with an index of type 'UInt'}}
203+
// expected-note@-1 {{overloads for 'subscript' exist}}
204+
r3[UInt(0)] // expected-error {{cannot subscript a value of type 'CountableClosedRange<UInt>' with an index of type 'UInt'}}
205+
// expected-note@-1 {{overloads for 'subscript' exist}}
202206

203207
r0[0..<4] // expected-error {{ambiguous use of 'subscript'}}
204208
r1[0..<4] // expected-error {{ambiguous use of 'subscript'}}
205-
r2[0..<4] // expected-error {{cannot convert call result type 'CountableRange<_>' to expected type 'Range<ClosedRangeIndex<_>>'}}
206-
r3[0..<4] // expected-error {{cannot convert call result type 'CountableRange<_>' to expected type 'Range<ClosedRangeIndex<_>>'}}
209+
r2[0..<4] // expected-error {{cannot subscript a value of type 'CountableClosedRange<Int>' with an index of type 'CountableRange<Int>'}}
210+
// expected-note@-1 {{overloads for 'subscript' exist}}
211+
r3[0..<4] // expected-error {{cannot subscript a value of type 'CountableClosedRange<UInt>' with an index of type 'CountableRange<Int>'}}
212+
// expected-note@-1 {{overloads for 'subscript' exist}}
207213
(10..<100)[0] // expected-error {{ambiguous use of 'subscript'}}
208-
(UInt(10)...100)[0..<4] // expected-error {{cannot convert call result type 'CountableRange<_>' to expected type 'Range<ClosedRangeIndex<_>>'}}
214+
(UInt(10)...100)[0..<4] // expected-error {{cannot subscript a value of type 'CountableClosedRange<UInt>' with an index of type 'CountableRange<Int>'}}
215+
// expected-note@-1 {{overloads for 'subscript'}}
209216

210217
r0[0...4] // expected-error {{ambiguous use of 'subscript'}}
211218
r1[0...4] // expected-error {{ambiguous use of 'subscript'}}
212-
r2[0...4] // expected-error {{cannot convert call result type 'CountableClosedRange<_>' to expected type 'Range<ClosedRangeIndex<_>>'}}
213-
r3[0...4] // expected-error {{cannot convert call result type 'CountableClosedRange<_>' to expected type 'Range<ClosedRangeIndex<_>>'}}
214-
(10...100)[0...4] // expected-error {{cannot convert call result type 'CountableClosedRange<_>' to expected type 'Range<ClosedRangeIndex<_>>'}}
215-
(UInt(10)...100)[0...4] // expected-error {{cannot convert call result type 'CountableClosedRange<_>' to expected type 'Range<ClosedRangeIndex<_>>'}}
219+
r2[0...4] // expected-error {{cannot subscript a value of type 'CountableClosedRange<Int>' with an index of type 'CountableClosedRange<Int>'}}
220+
// expected-note@-1 {{overloads for 'subscript'}}
221+
r3[0...4] // expected-error {{cannot subscript a value of type 'CountableClosedRange<UInt>' with an index of type 'CountableClosedRange<Int>'}}
222+
// expected-note@-1 {{overloads for 'subscript'}}
223+
(10...100)[0...4] // expected-error {{cannot subscript a value of type 'CountableClosedRange<Int>' with an index of type 'CountableClosedRange<Int>'}}
224+
// expected-note@-1 {{overloads for 'subscript'}}
225+
(UInt(10)...100)[0...4] // expected-error {{cannot subscript a value of type 'CountableClosedRange<UInt>' with an index of type 'CountableClosedRange<Int>'}}
226+
// expected-note@-1 {{overloads for 'subscript'}}
216227

217228
r0[r0] // expected-error {{ambiguous use of 'subscript'}}
218229
r0[r1] // expected-error {{ambiguous reference to member 'subscript'}}
@@ -224,15 +235,23 @@ func disallowSubscriptingOnIntegers() {
224235
r1[r2] // expected-error {{ambiguous reference to member 'subscript'}}
225236
r1[r3] // expected-error {{ambiguous use of 'subscript'}}
226237

227-
r2[r0] // expected-error {{cannot convert value}}
228-
r2[r1] // expected-error {{cannot convert value}}
229-
r2[r2] // expected-error {{cannot convert value}}
230-
r2[r3] // expected-error {{cannot convert value}}
238+
r2[r0] // expected-error {{cannot subscript a value of type 'CountableClosedRange<Int>' with an index of type 'CountableRange<Int>'}}
239+
// expected-note@-1 {{overloads for 'subscript'}}
240+
r2[r1] // expected-error {{cannot subscript a value of type 'CountableClosedRange<Int>' with an index of type 'CountableRange<UInt>'}}
241+
// expected-note@-1 {{overloads for 'subscript'}}
242+
r2[r2] // expected-error {{cannot subscript a value of type 'CountableClosedRange<Int>' with an index of type 'CountableClosedRange<Int>'}}
243+
// expected-note@-1 {{overloads for 'subscript'}}
244+
r2[r3] // expected-error {{cannot subscript a value of type 'CountableClosedRange<Int>' with an index of type 'CountableClosedRange<UInt>'}}
245+
// expected-note@-1 {{overloads for 'subscript'}}
231246

232-
r3[r0] // expected-error {{cannot convert value}}
233-
r3[r1] // expected-error {{cannot convert value}}
234-
r3[r2] // expected-error {{cannot convert value}}
235-
r3[r3] // expected-error {{cannot convert value}}
247+
r3[r0] // expected-error {{cannot subscript a value of type 'CountableClosedRange<UInt>' with an index of type 'CountableRange<Int>'}}
248+
// expected-note@-1 {{overloads for 'subscript'}}
249+
r3[r1] // expected-error {{cannot subscript a value of type 'CountableClosedRange<UInt>' with an index of type 'CountableRange<UInt>'}}
250+
// expected-note@-1 {{overloads for 'subscript'}}
251+
r3[r2] // expected-error {{cannot subscript a value of type 'CountableClosedRange<UInt>' with an index of type 'CountableClosedRange<Int>'}}
252+
// expected-note@-1 {{overloads for 'subscript'}}
253+
r3[r3] // expected-error {{cannot subscript a value of type 'CountableClosedRange<UInt>' with an index of type 'CountableClosedRange<UInt>'}}
254+
// expected-note@-1 {{overloads for 'subscript'}}
236255
}
237256

238257
do {
@@ -255,14 +274,17 @@ func disallowSubscriptingOnIntegers() {
255274
r2[0..<4] // expected-error {{type 'ClosedRange<Int>' has no subscript members}}
256275
r3[0..<4] // expected-error {{type 'ClosedRange<UInt>' has no subscript members}}
257276
(10..<100)[0] // expected-error {{ambiguous use of 'subscript'}}
258-
(UInt(10)...100)[0..<4] // expected-error {{cannot convert call result type}}
277+
(UInt(10)...100)[0..<4] // expected-error {{cannot subscript a value of type 'CountableClosedRange<UInt>' with an index of type 'CountableRange<Int>'}}
278+
// expected-note@-1 {{overloads for 'subscript'}}
259279

260280
r0[0...4] // expected-error {{type 'Range<Int>' has no subscript members}}
261281
r1[0...4] // expected-error {{type 'Range<UInt>' has no subscript members}}
262282
r2[0...4] // expected-error {{type 'ClosedRange<Int>' has no subscript members}}
263283
r3[0...4] // expected-error {{type 'ClosedRange<UInt>' has no subscript members}}
264-
(10...100)[0...4] // expected-error {{cannot convert call result type 'CountableClosedRange<_>' to expected type 'Range<ClosedRangeIndex<_>>'}}
265-
(UInt(10)...100)[0...4] // expected-error {{cannot convert call result type}}
284+
(10...100)[0...4] // expected-error {{cannot subscript a value of type 'CountableClosedRange<Int>' with an index of type 'CountableClosedRange<Int>'}}
285+
// expected-note@-1 {{overloads for 'subscript'}}
286+
(UInt(10)...100)[0...4] // expected-error {{cannot subscript a value of type 'CountableClosedRange<UInt>' with an index of type 'CountableClosedRange<Int>'}}
287+
// expected-note@-1 {{overloads for 'subscript'}}
266288

267289
r0[r0] // expected-error {{type 'Range<Int>' has no subscript members}}
268290
r0[r1] // expected-error {{type 'Range<Int>' has no subscript members}}

0 commit comments

Comments
 (0)