mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Merge pull request #79592 from xedin/rdar-131819800
[CSFix] Fix a null pointer dereference in `getStructuralTypeContext`
This commit is contained in:
@@ -1797,19 +1797,33 @@ public:
|
||||
/// "resolved" concrete type.
|
||||
Type getResolvedType(ASTNode node) const;
|
||||
|
||||
Type getContextualType(ASTNode anchor) const {
|
||||
std::optional<ContextualTypeInfo>
|
||||
getContextualTypeInfo(ASTNode anchor) const {
|
||||
for (const auto &entry : contextualTypes) {
|
||||
if (entry.first == anchor) {
|
||||
// The contextual information record could contain the purpose
|
||||
// without a type i.e. when the context is an optional-some or
|
||||
// an invalid pattern binding.
|
||||
if (auto contextualTy = entry.second.getType())
|
||||
if (entry.first == anchor)
|
||||
return entry.second;
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
Type getContextualType(ASTNode anchor) const {
|
||||
if (auto info = getContextualTypeInfo(anchor)) {
|
||||
// The contextual information record could contain the purpose
|
||||
// without a type i.e. when the context is an optional-some or
|
||||
// an invalid pattern binding.
|
||||
if (auto contextualTy = info->getType())
|
||||
return simplifyType(contextualTy);
|
||||
}
|
||||
}
|
||||
return Type();
|
||||
}
|
||||
|
||||
ContextualTypePurpose getContextualTypePurpose(ASTNode anchor) const {
|
||||
if (auto info = getContextualTypeInfo(anchor)) {
|
||||
return info->purpose;
|
||||
}
|
||||
return CTP_Unused;
|
||||
}
|
||||
|
||||
/// Retrieve the generic environment for the opened element of a given pack
|
||||
/// expansion, or \c nullptr if no environment was recorded.
|
||||
GenericEnvironment *
|
||||
|
||||
@@ -592,12 +592,16 @@ getStructuralTypeContext(const Solution &solution, ConstraintLocator *locator) {
|
||||
assert(locator->isLastElement<LocatorPathElt::ContextualType>() ||
|
||||
locator->isLastElement<LocatorPathElt::FunctionArgument>());
|
||||
|
||||
auto &cs = solution.getConstraintSystem();
|
||||
auto anchor = locator->getAnchor();
|
||||
auto contextualType = cs.getContextualType(anchor, /*forConstraint=*/false);
|
||||
auto exprType = cs.getType(anchor);
|
||||
return std::make_tuple(contextualTypeElt->getPurpose(), exprType,
|
||||
contextualType);
|
||||
auto contextualInfo = solution.getContextualTypeInfo(anchor);
|
||||
// For some patterns the type could be empty and the entry is
|
||||
// there to indicate the purpose only.
|
||||
if (!contextualInfo || !contextualInfo->getType())
|
||||
return std::nullopt;
|
||||
|
||||
auto exprType = solution.getType(anchor);
|
||||
return std::make_tuple(contextualInfo->purpose, exprType,
|
||||
contextualInfo->getType());
|
||||
} else if (auto argApplyInfo = solution.getFunctionArgApplyInfo(locator)) {
|
||||
Type fromType = argApplyInfo->getArgType();
|
||||
Type toType = argApplyInfo->getParamType();
|
||||
@@ -607,9 +611,8 @@ getStructuralTypeContext(const Solution &solution, ConstraintLocator *locator) {
|
||||
auto fromFnType = fromType->getAs<FunctionType>();
|
||||
auto toFnType = toType->getAs<FunctionType>();
|
||||
if (fromFnType && toFnType) {
|
||||
auto &cs = solution.getConstraintSystem();
|
||||
return std::make_tuple(
|
||||
cs.getContextualTypePurpose(locator->getAnchor()),
|
||||
solution.getContextualTypePurpose(locator->getAnchor()),
|
||||
fromFnType->getResult(), toFnType->getResult());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -805,3 +805,18 @@ func testMatchingNonErrorConformingTypeInClosure(_ x: any Error) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// rdar://131819800 - crash in `transformWithPosition` while trying to emit diagnostics for `AllowFunctionTypeMismatch` fix
|
||||
do {
|
||||
enum E {
|
||||
case test(kind: Int, defaultsToEmpty: Bool = false)
|
||||
}
|
||||
|
||||
func test(e: E) {
|
||||
if case .test(kind: _, // expected-error {{tuple pattern has the wrong length for tuple type '(Int, Bool)'}}
|
||||
name: let name?,
|
||||
defaultsToEmpty: _,
|
||||
deprecateName: let deprecatedName?) = e {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user