Skip to content

Commit 382013f

Browse files
committed
[Diagnostics] Convert missing @escaping diagnostic to contextual failure
This gives diagnostic access to both sides of a conversion/binding which makes it easier to diagnose errors associated with generic parameters.
1 parent cc50b46 commit 382013f

File tree

2 files changed

+29
-34
lines changed

2 files changed

+29
-34
lines changed

lib/Sema/CSDiagnostics.cpp

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -897,27 +897,23 @@ bool NoEscapeFuncToTypeConversionFailure::diagnoseAsError() {
897897
if (diagnoseParameterUse())
898898
return true;
899899

900-
if (ConvertTo) {
901-
emitDiagnostic(anchor->getLoc(), diag::converting_noescape_to_type,
902-
ConvertTo);
903-
return true;
900+
if (auto *typeVar = getRawFromType()->getAs<TypeVariableType>()) {
901+
if (auto *GP = typeVar->getImpl().getGenericParameter()) {
902+
emitDiagnostic(anchor->getLoc(), diag::converting_noescape_to_type, GP);
903+
return true;
904+
}
904905
}
905906

906-
auto *loc = getLocator();
907-
if (auto gpElt = loc->getLastElementAs<LocatorPathElt::GenericParameter>()) {
908-
auto *paramTy = gpElt->getType();
909-
emitDiagnostic(anchor->getLoc(), diag::converting_noescape_to_type,
910-
paramTy);
911-
} else {
912-
emitDiagnostic(anchor->getLoc(), diag::unknown_escaping_use_of_noescape);
913-
}
907+
emitDiagnostic(anchor->getLoc(), diag::converting_noescape_to_type,
908+
getToType());
914909
return true;
915910
}
916911

917912
bool NoEscapeFuncToTypeConversionFailure::diagnoseParameterUse() const {
913+
auto convertTo = getToType();
918914
// If the other side is not a function, we have common case diagnostics
919915
// which handle function-to-type conversion diagnostics.
920-
if (!ConvertTo || !ConvertTo->is<FunctionType>())
916+
if (!convertTo->is<FunctionType>())
921917
return false;
922918

923919
auto *anchor = getAnchor();
@@ -943,7 +939,9 @@ bool NoEscapeFuncToTypeConversionFailure::diagnoseParameterUse() const {
943939
diag::converting_noespace_param_to_generic_type,
944940
PD->getName(), paramInterfaceTy);
945941

946-
emitDiagnostic(decl, diag::generic_parameters_always_escaping);
942+
auto declLoc = decl->getLoc();
943+
if (declLoc.isValid())
944+
emitDiagnostic(decl, diag::generic_parameters_always_escaping);
947945
};
948946

949947
// If this is a situation when non-escaping parameter is passed

lib/Sema/CSDiagnostics.h

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -585,26 +585,6 @@ class LabelingFailure final : public FailureDiagnostic {
585585
bool diagnoseAsNote() override;
586586
};
587587

588-
/// Diagnose errors related to converting function type which
589-
/// isn't explicitly '@escaping' to some other type.
590-
class NoEscapeFuncToTypeConversionFailure final : public FailureDiagnostic {
591-
Type ConvertTo;
592-
593-
public:
594-
NoEscapeFuncToTypeConversionFailure(ConstraintSystem &cs,
595-
ConstraintLocator *locator,
596-
Type toType = Type())
597-
: FailureDiagnostic(cs, locator), ConvertTo(toType) {}
598-
599-
bool diagnoseAsError() override;
600-
601-
private:
602-
/// Emit tailored diagnostics for no-escape parameter conversions e.g.
603-
/// passing such parameter as an @escaping argument, or trying to
604-
/// assign it to a variable which expects @escaping function.
605-
bool diagnoseParameterUse() const;
606-
};
607-
608588
/// Diagnose failures related to attempting member access on optional base
609589
/// type without optional chaining or force-unwrapping it first.
610590
class MemberAccessOnOptionalBaseFailure final : public FailureDiagnostic {
@@ -819,6 +799,23 @@ class ContextualFailure : public FailureDiagnostic {
819799
getDiagnosticFor(ContextualTypePurpose context, bool forProtocol);
820800
};
821801

802+
/// Diagnose errors related to converting function type which
803+
/// isn't explicitly '@escaping' to some other type.
804+
class NoEscapeFuncToTypeConversionFailure final : public ContextualFailure {
805+
public:
806+
NoEscapeFuncToTypeConversionFailure(ConstraintSystem &cs, Type fromType,
807+
Type toType, ConstraintLocator *locator)
808+
: ContextualFailure(cs, fromType, toType, locator) {}
809+
810+
bool diagnoseAsError() override;
811+
812+
private:
813+
/// Emit tailored diagnostics for no-escape parameter conversions e.g.
814+
/// passing such parameter as an @escaping argument, or trying to
815+
/// assign it to a variable which expects @escaping function.
816+
bool diagnoseParameterUse() const;
817+
};
818+
822819
/// Diagnose failures related to use of the unwrapped optional types,
823820
/// which require some type of force-unwrap e.g. "!" or "try!".
824821
class MissingOptionalUnwrapFailure final : public ContextualFailure {

0 commit comments

Comments
 (0)