Skip to content

Commit a62d797

Browse files
committed
---
yaml --- r: 340783 b: refs/heads/rxwei-patch-1 c: a84cdbc h: refs/heads/master i: 340781: 7a3f350 340779: 59e7b6b 340775: de31a90 340767: ed21a6b
1 parent 20c07af commit a62d797

File tree

3 files changed

+190
-1
lines changed

3 files changed

+190
-1
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1015,7 +1015,7 @@ refs/tags/swift-DEVELOPMENT-SNAPSHOT-2018-08-18-a: b10b1fce14385faa6d44f6b933e95
10151015
refs/heads/rdar-43033749-fix-batch-mode-no-diags-swift-5.0-branch: a14e64eaad30de89f0f5f0b2a782eed7ecdcb255
10161016
refs/heads/revert-19006-error-bridging-integer-type: 8a9065a3696535305ea53fe9b71f91cbe6702019
10171017
refs/heads/revert-19050-revert-19006-error-bridging-integer-type: ecf752d54b05dd0a20f510f0bfa54a3fec3bcaca
1018-
refs/heads/rxwei-patch-1: 061ab18297b54c5133ccea268b86a2ddf7ad1330
1018+
refs/heads/rxwei-patch-1: a84cdbc31e5b45de174ec03818cb0e27abc20459
10191019
refs/heads/shahmishal-patch-1: e58ec0f7488258d42bef51bc3e6d7b3dc74d7b2a
10201020
refs/heads/typelist-existential: 4046359efd541fb5c72d69a92eefc0a784df8f5e
10211021
refs/tags/swift-4.2-DEVELOPMENT-SNAPSHOT-2018-08-20-a: 4319ba09e4fb8650ee86061075c74a016b6baab9

branches/rxwei-patch-1/lib/Sema/CSDiagnostics.cpp

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,95 @@ Type FailureDiagnostic::resolveInterfaceType(Type type,
143143
: resolvedType;
144144
}
145145

146+
Optional<FunctionArgApplyInfo>
147+
FailureDiagnostic::getFunctionArgApplyInfo(ConstraintLocator *locator) const {
148+
auto &cs = getConstraintSystem();
149+
auto *anchor = locator->getAnchor();
150+
auto path = locator->getPath();
151+
152+
// Look for the apply-arg-to-param element in the locator's path. We may
153+
// have to look through other elements that are generated from an argument
154+
// conversion such as GenericArgument for an optional-to-optional conversion,
155+
// and OptionalPayload for a value-to-optional conversion.
156+
auto applyArgElt =
157+
std::find_if(path.rbegin(), path.rend(), [](LocatorPathElt elt) {
158+
return elt.getKind() == ConstraintLocator::ApplyArgToParam;
159+
});
160+
161+
if (applyArgElt == path.rend())
162+
return None;
163+
164+
assert(std::find_if(applyArgElt + 1, path.rend(), [](LocatorPathElt elt) {
165+
return elt.getKind() == ConstraintLocator::ApplyArgToParam;
166+
}) == path.rend() && "Multiple ApplyArgToParam components?");
167+
168+
// Form a new locator that ends at the apply-arg-to-param element, and
169+
// simplify it to get the full argument expression.
170+
auto argPath = path.drop_back(applyArgElt - path.rbegin());
171+
auto *argLocator = cs.getConstraintLocator(
172+
anchor, argPath, ConstraintLocator::getSummaryFlagsForPath(argPath));
173+
174+
auto *argExpr = simplifyLocatorToAnchor(cs, argLocator);
175+
176+
// If we were unable to simplify down to the argument expression, we don't
177+
// know what this is.
178+
if (!argExpr)
179+
return None;
180+
181+
ValueDecl *callee = nullptr;
182+
Type rawFnType;
183+
if (auto overload = getChoiceFor(anchor)) {
184+
// If we have resolved an overload for the callee, then use that to get the
185+
// function type and callee.
186+
if (auto *decl = overload->choice.getDeclOrNull())
187+
callee = decl;
188+
189+
rawFnType = overload->openedType;
190+
} else {
191+
// If we didn't resolve an overload for the callee, we must be dealing with
192+
// an apply of an arbitrary function expr.
193+
auto *fnExpr = cast<CallExpr>(anchor)->getFn();
194+
rawFnType = cs.getType(fnExpr)->getRValueType();
195+
}
196+
197+
auto *fnType = resolveType(rawFnType)->getAs<FunctionType>();
198+
if (!fnType)
199+
return None;
200+
201+
// Resolve the interface type for the function. Note that this may not be a
202+
// function type, for example it could be a generic parameter.
203+
Type fnInterfaceType;
204+
if (callee && callee->hasInterfaceType()) {
205+
// If we have a callee with an interface type, we can use it. This is
206+
// preferable to resolveInterfaceType, as this will allow us to get a
207+
// GenericFunctionType for generic decls.
208+
//
209+
// Note that it's possible to find a callee without an interface type. This
210+
// can happen for example with closure parameters, where the interface type
211+
// isn't set until the solution is applied. In that case, use
212+
// resolveInterfaceType.
213+
fnInterfaceType = callee->getInterfaceType();
214+
215+
// Strip off the curried self parameter if necessary.
216+
if (callee->hasCurriedSelf())
217+
fnInterfaceType = fnInterfaceType->castTo<AnyFunctionType>()->getResult();
218+
219+
if (auto *fn = fnInterfaceType->getAs<AnyFunctionType>()) {
220+
assert(fn->getNumParams() == fnType->getNumParams() &&
221+
"Parameter mismatch?");
222+
(void)fn;
223+
}
224+
} else {
225+
fnInterfaceType = resolveInterfaceType(rawFnType);
226+
}
227+
228+
auto argIdx = applyArgElt->getValue();
229+
auto paramIdx = applyArgElt->getValue2();
230+
231+
return FunctionArgApplyInfo(argExpr, argIdx, getType(argExpr), paramIdx,
232+
fnInterfaceType, fnType, callee);
233+
}
234+
146235
Type RequirementFailure::getOwnerType() const {
147236
auto *anchor = getRawAnchor();
148237

branches/rxwei-patch-1/lib/Sema/CSDiagnostics.h

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
namespace swift {
3333
namespace constraints {
3434

35+
class FunctionArgApplyInfo;
36+
3537
/// Base class for all of the possible diagnostics,
3638
/// provides most basic information such as location of
3739
/// the problem, parent expression and some utility methods.
@@ -162,6 +164,13 @@ class FailureDiagnostic {
162164

163165
Optional<SelectedOverload> getChoiceFor(Expr *) const;
164166

167+
/// For a given locator describing a function argument conversion, or a
168+
/// constraint within an argument conversion, returns information about the
169+
/// application of the argument to its parameter. If the locator is not
170+
/// for an argument conversion, returns \c None.
171+
Optional<FunctionArgApplyInfo>
172+
getFunctionArgApplyInfo(ConstraintLocator *locator) const;
173+
165174
private:
166175
/// Compute anchor expression associated with current diagnostic.
167176
std::pair<Expr *, bool> computeAnchor() const;
@@ -1336,6 +1345,97 @@ class SkipUnhandledConstructInFunctionBuilderFailure final
13361345
bool diagnoseAsNote() override;
13371346
};
13381347

1348+
/// Provides information about the application of a function argument to a
1349+
/// parameter.
1350+
class FunctionArgApplyInfo {
1351+
Expr *ArgExpr;
1352+
unsigned ArgIdx;
1353+
Type ArgType;
1354+
1355+
unsigned ParamIdx;
1356+
1357+
Type FnInterfaceType;
1358+
FunctionType *FnType;
1359+
const ValueDecl *Callee;
1360+
1361+
public:
1362+
FunctionArgApplyInfo(Expr *argExpr, unsigned argIdx, Type argType,
1363+
unsigned paramIdx, Type fnInterfaceType,
1364+
FunctionType *fnType, const ValueDecl *callee)
1365+
: ArgExpr(argExpr), ArgIdx(argIdx), ArgType(argType), ParamIdx(paramIdx),
1366+
FnInterfaceType(fnInterfaceType), FnType(fnType), Callee(callee) {}
1367+
1368+
/// \returns The argument being applied.
1369+
Expr *getArgExpr() const { return ArgExpr; }
1370+
1371+
/// \returns The position of the argument, starting at 1.
1372+
unsigned getArgPosition() const { return ArgIdx + 1; }
1373+
1374+
/// \returns The position of the parameter, starting at 1.
1375+
unsigned getParamPosition() const { return ParamIdx + 1; }
1376+
1377+
/// \returns The type of the argument being applied, including any generic
1378+
/// substitutions.
1379+
///
1380+
/// \param withSpecifier Whether to keep the inout or @lvalue specifier of
1381+
/// the argument, if any.
1382+
Type getArgType(bool withSpecifier = false) const {
1383+
return withSpecifier ? ArgType : ArgType->getWithoutSpecifierType();
1384+
}
1385+
1386+
/// \returns The interface type for the function being applied. Note that this
1387+
/// may not a function type, for example it could be a generic parameter.
1388+
Type getFnInterfaceType() const { return FnInterfaceType; }
1389+
1390+
/// \returns The function type being applied, including any generic
1391+
/// substitutions.
1392+
FunctionType *getFnType() const { return FnType; }
1393+
1394+
/// \returns The callee for the application.
1395+
const ValueDecl *getCallee() const { return Callee; }
1396+
1397+
private:
1398+
Type getParamTypeImpl(AnyFunctionType *fnTy,
1399+
bool lookThroughAutoclosure) const {
1400+
auto param = fnTy->getParams()[ParamIdx];
1401+
auto paramTy = param.getPlainType();
1402+
if (lookThroughAutoclosure && param.isAutoClosure())
1403+
paramTy = paramTy->castTo<FunctionType>()->getResult();
1404+
return paramTy;
1405+
}
1406+
1407+
public:
1408+
/// \returns The type of the parameter which the argument is being applied to,
1409+
/// including any generic substitutions.
1410+
///
1411+
/// \param lookThroughAutoclosure Whether an @autoclosure () -> T parameter
1412+
/// should be treated as being of type T.
1413+
Type getParamType(bool lookThroughAutoclosure = true) const {
1414+
return getParamTypeImpl(FnType, lookThroughAutoclosure);
1415+
}
1416+
1417+
/// \returns The interface type of the parameter which the argument is being
1418+
/// applied to.
1419+
///
1420+
/// \param lookThroughAutoclosure Whether an @autoclosure () -> T parameter
1421+
/// should be treated as being of type T.
1422+
Type getParamInterfaceType(bool lookThroughAutoclosure = true) const {
1423+
auto interfaceFnTy = FnInterfaceType->getAs<AnyFunctionType>();
1424+
if (!interfaceFnTy) {
1425+
// If the interface type isn't a function, then just return the resolved
1426+
// parameter type.
1427+
return getParamType(lookThroughAutoclosure)->mapTypeOutOfContext();
1428+
}
1429+
return getParamTypeImpl(interfaceFnTy, lookThroughAutoclosure);
1430+
}
1431+
1432+
/// \returns The flags of the parameter which the argument is being applied
1433+
/// to.
1434+
ParameterTypeFlags getParameterFlags() const {
1435+
return FnType->getParams()[ParamIdx].getParameterFlags();
1436+
}
1437+
};
1438+
13391439
} // end namespace constraints
13401440
} // end namespace swift
13411441

0 commit comments

Comments
 (0)