Skip to content

Commit 7764858

Browse files
committed
[ConstraintSystem] NFC: Move new diagnostics into separate files - Diagnostics.(h|cpp)
1 parent bda60b4 commit 7764858

File tree

6 files changed

+324
-265
lines changed

6 files changed

+324
-265
lines changed

lib/Sema/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ add_swift_library(swiftSema STATIC
1111
CSRanking.cpp
1212
CSSimplify.cpp
1313
CSSolver.cpp
14+
CSDiagnostics.cpp
1415
CalleeCandidateInfo.cpp
1516
CodeSynthesis.cpp
1617
Constraint.cpp

lib/Sema/CSApply.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
//===----------------------------------------------------------------------===//
1818

1919
#include "ConstraintSystem.h"
20+
#include "CSDiagnostics.h"
2021
#include "MiscDiagnostics.h"
2122
#include "TypeCheckProtocol.h"
2223
#include "swift/AST/ASTVisitor.h"

lib/Sema/CSDiag.cpp

Lines changed: 0 additions & 137 deletions
Original file line numberDiff line numberDiff line change
@@ -9156,140 +9156,3 @@ bool swift::diagnoseBaseUnwrapForMemberAccess(Expr *baseExpr, Type baseType,
91569156
}
91579157
return true;
91589158
}
9159-
9160-
FailureDiagnostic::~FailureDiagnostic() {}
9161-
9162-
Type FailureDiagnostic::getType(Expr *expr) const {
9163-
auto &cs = getConstraintSystem();
9164-
return solution.simplifyType(cs.getType(expr));
9165-
}
9166-
9167-
template <typename... ArgTypes>
9168-
InFlightDiagnostic
9169-
FailureDiagnostic::emitDiagnostic(ArgTypes &&... Args) const {
9170-
auto &cs = getConstraintSystem();
9171-
return cs.TC.diagnose(std::forward<ArgTypes>(Args)...);
9172-
}
9173-
9174-
Type RequirementFailure::getOwnerType() const {
9175-
return getType(getAnchor())->getRValueInstanceType();
9176-
}
9177-
9178-
const Requirement &RequirementFailure::getRequirement() {
9179-
auto *genericCtx = AffectedDecl->getAsGenericContext();
9180-
return genericCtx->getGenericRequirements()[getRequirementIndex()];
9181-
}
9182-
9183-
ValueDecl *RequirementFailure::getDeclRef() const {
9184-
auto &cs = getConstraintSystem();
9185-
9186-
auto *anchor = getAnchor();
9187-
auto *locator = cs.getConstraintLocator(anchor);
9188-
if (auto *AE = dyn_cast<CallExpr>(anchor)) {
9189-
assert(isa<TypeExpr>(AE->getFn()));
9190-
ConstraintLocatorBuilder ctor(locator);
9191-
locator = cs.getConstraintLocator(
9192-
ctor.withPathElement(PathEltKind::ApplyFunction)
9193-
.withPathElement(PathEltKind::ConstructorMember));
9194-
} else if (auto *UDE = dyn_cast<UnresolvedDotExpr>(anchor)) {
9195-
ConstraintLocatorBuilder member(locator);
9196-
locator =
9197-
cs.getConstraintLocator(member.withPathElement(PathEltKind::Member));
9198-
}
9199-
9200-
auto overload = getOverloadChoiceIfAvailable(locator);
9201-
if (overload)
9202-
return overload->choice.getDecl();
9203-
9204-
auto ownerType = getOwnerType();
9205-
if (auto *NA = dyn_cast<NameAliasType>(ownerType.getPointer()))
9206-
return NA->getDecl();
9207-
9208-
return ownerType->getAnyGeneric();
9209-
}
9210-
9211-
bool MissingConformanceFailure::diagnose() {
9212-
auto *anchor = getAnchor();
9213-
auto ownerType = getOwnerType();
9214-
auto type = getNonConformingType();
9215-
auto protocolType = getProtocolType();
9216-
9217-
// Find `ApplyExpr` based on a function expression attached to it.
9218-
auto findApplyExpr = [](Expr *parent, Expr *fnExpr) -> ApplyExpr * {
9219-
ApplyExpr *applyExpr = nullptr;
9220-
parent->forEachChildExpr([&applyExpr, &fnExpr](Expr *subExpr) -> Expr * {
9221-
auto *AE = dyn_cast<ApplyExpr>(subExpr);
9222-
if (!AE || AE->getFn() != fnExpr)
9223-
return subExpr;
9224-
9225-
applyExpr = AE;
9226-
return nullptr;
9227-
});
9228-
return applyExpr;
9229-
};
9230-
9231-
auto getArgumentAt = [](ApplyExpr *AE, unsigned index) -> Expr * {
9232-
assert(AE);
9233-
9234-
auto *arg = AE->getArg();
9235-
if (auto *TE = dyn_cast<TupleExpr>(arg))
9236-
return TE->getElement(index);
9237-
9238-
assert(index == 0);
9239-
if (auto *PE = dyn_cast<ParenExpr>(arg))
9240-
return PE->getSubExpr();
9241-
9242-
return arg;
9243-
};
9244-
9245-
auto *applyExpr = findApplyExpr(getParentExpr(), anchor);
9246-
9247-
Optional<unsigned> atParameterPos;
9248-
// Sometimes fix is recorded by type-checking sub-expression
9249-
// during normal diagnostics, in such case call expression
9250-
// is unavailable.
9251-
if (applyExpr) {
9252-
// If this is a static, initializer or operator call,
9253-
// let's not try to diagnose it here, but refer to expression
9254-
// diagnostics.
9255-
if (isa<BinaryExpr>(applyExpr) || isa<TypeExpr>(anchor))
9256-
return false;
9257-
9258-
if (auto *fnType = ownerType->getAs<AnyFunctionType>()) {
9259-
auto parameters = fnType->getParams();
9260-
for (auto index : indices(parameters)) {
9261-
if (parameters[index].getType()->isEqual(type)) {
9262-
atParameterPos = index;
9263-
break;
9264-
}
9265-
}
9266-
}
9267-
}
9268-
9269-
if (type->isExistentialType()) {
9270-
auto diagnostic = diag::protocol_does_not_conform_objc;
9271-
if (type->isObjCExistentialType())
9272-
diagnostic = diag::protocol_does_not_conform_static;
9273-
9274-
emitDiagnostic(anchor->getLoc(), diagnostic, type, protocolType);
9275-
} else if (atParameterPos) {
9276-
// Requirement comes from one of the parameter types,
9277-
// let's try to point diagnostic to the argument expression.
9278-
auto *argExpr = getArgumentAt(applyExpr, *atParameterPos);
9279-
emitDiagnostic(argExpr->getLoc(),
9280-
diag::cannot_convert_argument_value_protocol, type,
9281-
protocolType);
9282-
} else {
9283-
emitDiagnostic(anchor->getLoc(), diag::type_does_not_conform_owner,
9284-
ownerType, type, protocolType);
9285-
}
9286-
return true;
9287-
}
9288-
9289-
bool LabelingFailure::diagnose() {
9290-
auto &cs = getConstraintSystem();
9291-
auto *call = cast<CallExpr>(getAnchor());
9292-
return diagnoseArgumentLabelError(cs.getASTContext(), call->getArg(),
9293-
CorrectLabels,
9294-
isa<SubscriptExpr>(call->getFn()));
9295-
}

lib/Sema/CSDiagnostics.cpp

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
//===--- CSDiagnostics.cpp - Constraint Diagnostics -----------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
// This file implements diagnostics for constraint system.
14+
//
15+
//===----------------------------------------------------------------------===//
16+
17+
#include "ConstraintSystem.h"
18+
#include "CSDiagnostics.h"
19+
#include "MiscDiagnostics.h"
20+
#include "swift/AST/Expr.h"
21+
#include "swift/AST/Types.h"
22+
#include "llvm/ADT/ArrayRef.h"
23+
24+
using namespace swift;
25+
using namespace constraints;
26+
27+
FailureDiagnostic::~FailureDiagnostic() {}
28+
29+
Type FailureDiagnostic::getType(Expr *expr) const {
30+
auto &cs = getConstraintSystem();
31+
return solution.simplifyType(cs.getType(expr));
32+
}
33+
34+
template <typename... ArgTypes>
35+
InFlightDiagnostic
36+
FailureDiagnostic::emitDiagnostic(ArgTypes &&... Args) const {
37+
auto &cs = getConstraintSystem();
38+
return cs.TC.diagnose(std::forward<ArgTypes>(Args)...);
39+
}
40+
41+
Type RequirementFailure::getOwnerType() const {
42+
return getType(getAnchor())->getRValueInstanceType();
43+
}
44+
45+
const Requirement &RequirementFailure::getRequirement() {
46+
auto *genericCtx = AffectedDecl->getAsGenericContext();
47+
return genericCtx->getGenericRequirements()[getRequirementIndex()];
48+
}
49+
50+
ValueDecl *RequirementFailure::getDeclRef() const {
51+
auto &cs = getConstraintSystem();
52+
53+
auto *anchor = getAnchor();
54+
auto *locator = cs.getConstraintLocator(anchor);
55+
if (auto *AE = dyn_cast<CallExpr>(anchor)) {
56+
assert(isa<TypeExpr>(AE->getFn()));
57+
ConstraintLocatorBuilder ctor(locator);
58+
locator = cs.getConstraintLocator(
59+
ctor.withPathElement(PathEltKind::ApplyFunction)
60+
.withPathElement(PathEltKind::ConstructorMember));
61+
} else if (auto *UDE = dyn_cast<UnresolvedDotExpr>(anchor)) {
62+
ConstraintLocatorBuilder member(locator);
63+
locator =
64+
cs.getConstraintLocator(member.withPathElement(PathEltKind::Member));
65+
}
66+
67+
auto overload = getOverloadChoiceIfAvailable(locator);
68+
if (overload)
69+
return overload->choice.getDecl();
70+
71+
auto ownerType = getOwnerType();
72+
if (auto *NA = dyn_cast<NameAliasType>(ownerType.getPointer()))
73+
return NA->getDecl();
74+
75+
return ownerType->getAnyGeneric();
76+
}
77+
78+
bool MissingConformanceFailure::diagnose() {
79+
auto *anchor = getAnchor();
80+
auto ownerType = getOwnerType();
81+
auto type = getNonConformingType();
82+
auto protocolType = getProtocolType();
83+
84+
// Find `ApplyExpr` based on a function expression attached to it.
85+
auto findApplyExpr = [](Expr *parent, Expr *fnExpr) -> ApplyExpr * {
86+
ApplyExpr *applyExpr = nullptr;
87+
parent->forEachChildExpr([&applyExpr, &fnExpr](Expr *subExpr) -> Expr * {
88+
auto *AE = dyn_cast<ApplyExpr>(subExpr);
89+
if (!AE || AE->getFn() != fnExpr)
90+
return subExpr;
91+
92+
applyExpr = AE;
93+
return nullptr;
94+
});
95+
return applyExpr;
96+
};
97+
98+
auto getArgumentAt = [](ApplyExpr *AE, unsigned index) -> Expr * {
99+
assert(AE);
100+
101+
auto *arg = AE->getArg();
102+
if (auto *TE = dyn_cast<TupleExpr>(arg))
103+
return TE->getElement(index);
104+
105+
assert(index == 0);
106+
if (auto *PE = dyn_cast<ParenExpr>(arg))
107+
return PE->getSubExpr();
108+
109+
return arg;
110+
};
111+
112+
auto *applyExpr = findApplyExpr(getParentExpr(), anchor);
113+
114+
Optional<unsigned> atParameterPos;
115+
// Sometimes fix is recorded by type-checking sub-expression
116+
// during normal diagnostics, in such case call expression
117+
// is unavailable.
118+
if (applyExpr) {
119+
// If this is a static, initializer or operator call,
120+
// let's not try to diagnose it here, but refer to expression
121+
// diagnostics.
122+
if (isa<BinaryExpr>(applyExpr) || isa<TypeExpr>(anchor))
123+
return false;
124+
125+
if (auto *fnType = ownerType->getAs<AnyFunctionType>()) {
126+
auto parameters = fnType->getParams();
127+
for (auto index : indices(parameters)) {
128+
if (parameters[index].getType()->isEqual(type)) {
129+
atParameterPos = index;
130+
break;
131+
}
132+
}
133+
}
134+
}
135+
136+
if (type->isExistentialType()) {
137+
auto diagnostic = diag::protocol_does_not_conform_objc;
138+
if (type->isObjCExistentialType())
139+
diagnostic = diag::protocol_does_not_conform_static;
140+
141+
emitDiagnostic(anchor->getLoc(), diagnostic, type, protocolType);
142+
} else if (atParameterPos) {
143+
// Requirement comes from one of the parameter types,
144+
// let's try to point diagnostic to the argument expression.
145+
auto *argExpr = getArgumentAt(applyExpr, *atParameterPos);
146+
emitDiagnostic(argExpr->getLoc(),
147+
diag::cannot_convert_argument_value_protocol, type,
148+
protocolType);
149+
} else {
150+
emitDiagnostic(anchor->getLoc(), diag::type_does_not_conform_owner,
151+
ownerType, type, protocolType);
152+
}
153+
return true;
154+
}
155+
156+
bool LabelingFailure::diagnose() {
157+
auto &cs = getConstraintSystem();
158+
auto *call = cast<CallExpr>(getAnchor());
159+
return diagnoseArgumentLabelError(cs.getASTContext(), call->getArg(),
160+
CorrectLabels,
161+
isa<SubscriptExpr>(call->getFn()));
162+
}

0 commit comments

Comments
 (0)