Skip to content

Commit c19dfb5

Browse files
authored
Merge pull request #22219 from xedin/rdar-38885760-5.0
[5.0][TypeChecker] Always emit a fallback error if type-check failed witho
2 parents 26492b2 + 376e19e commit c19dfb5

File tree

13 files changed

+215
-20
lines changed

13 files changed

+215
-20
lines changed

include/swift/AST/ASTContext.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -765,6 +765,10 @@ class ASTContext final {
765765
bool IsError;
766766
};
767767

768+
/// Check whether current context has any errors associated with
769+
/// ill-formed protocol conformances which haven't been produced yet.
770+
bool hasDelayedConformanceErrors() const;
771+
768772
/// Add a delayed diagnostic produced while type-checking a
769773
/// particular protocol conformance.
770774
void addDelayedConformanceDiag(NormalProtocolConformance *conformance,

include/swift/AST/Builtins.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -580,6 +580,7 @@ BUILTIN_SANITIZER_OPERATION(TSanInoutAccess, "tsanInoutAccess", "")
580580
BUILTIN_TYPE_CHECKER_OPERATION(TypeJoin, type_join)
581581
BUILTIN_TYPE_CHECKER_OPERATION(TypeJoinInout, type_join_inout)
582582
BUILTIN_TYPE_CHECKER_OPERATION(TypeJoinMeta, type_join_meta)
583+
BUILTIN_TYPE_CHECKER_OPERATION(TriggerFallbackDiagnostic, trigger_fallback_diagnostic)
583584

584585
#undef BUILTIN_TYPE_CHECKER_OPERATION
585586

include/swift/AST/DiagnosticsSema.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2822,6 +2822,10 @@ ERROR(type_of_expression_is_ambiguous,none,
28222822
ERROR(specific_type_of_expression_is_ambiguous,none,
28232823
"expression type %0 is ambiguous without more context", (Type))
28242824

2825+
ERROR(failed_to_produce_diagnostic,Fatal,
2826+
"failed to produce diagnostic for expression; "
2827+
"please file a bug report with your project", ())
2828+
28252829

28262830
ERROR(missing_protocol,none,
28272831
"missing protocol %0", (Identifier))

lib/AST/ASTContext.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2047,6 +2047,19 @@ LazyGenericContextData *ASTContext::getOrCreateLazyGenericContextData(
20472047
lazyLoader);
20482048
}
20492049

2050+
bool ASTContext::hasDelayedConformanceErrors() const {
2051+
for (const auto &entry : getImpl().DelayedConformanceDiags) {
2052+
auto &diagnostics = entry.getSecond();
2053+
if (std::any_of(diagnostics.begin(), diagnostics.end(),
2054+
[](const ASTContext::DelayedConformanceDiag &diag) {
2055+
return diag.IsError;
2056+
}))
2057+
return true;
2058+
}
2059+
2060+
return false;
2061+
}
2062+
20502063
void ASTContext::addDelayedConformanceDiag(
20512064
NormalProtocolConformance *conformance,
20522065
DelayedConformanceDiag fn) {

lib/AST/Builtins.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1010,6 +1010,12 @@ static ValueDecl *getTypeJoinMetaOperation(ASTContext &Context, Identifier Id) {
10101010
return builder.build(Id);
10111011
}
10121012

1013+
static ValueDecl *getTriggerFallbackDiagnosticOperation(ASTContext &Context,
1014+
Identifier Id) {
1015+
// () -> Void
1016+
return getBuiltinFunction(Id, {}, Context.TheEmptyTupleType);
1017+
}
1018+
10131019
static ValueDecl *getCanBeObjCClassOperation(ASTContext &Context,
10141020
Identifier Id) {
10151021
// <T> T.Type -> Builtin.Int8
@@ -1899,7 +1905,10 @@ ValueDecl *swift::getBuiltinValueDecl(ASTContext &Context, Identifier Id) {
18991905
return getTypeJoinInoutOperation(Context, Id);
19001906

19011907
case BuiltinValueKind::TypeJoinMeta:
1902-
return getTypeJoinMetaOperation(Context, Id);
1908+
return getTypeJoinMetaOperation(Context, Id);
1909+
1910+
case BuiltinValueKind::TriggerFallbackDiagnostic:
1911+
return getTriggerFallbackDiagnosticOperation(Context, Id);
19031912
}
19041913

19051914
llvm_unreachable("bad builtin value!");

lib/Sema/CSApply.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3912,8 +3912,9 @@ namespace {
39123912
}
39133913

39143914
Expr *visitLazyInitializerExpr(LazyInitializerExpr *expr) {
3915-
simplifyExprType(expr);
3916-
assert(expr->getType()->isEqual(expr->getSubExpr()->getType()));
3915+
// Since `LazyInitializerExpr` should always have a type set,
3916+
// there is no need to do anything here.
3917+
assert(cs.getType(expr)->isEqual(expr->getSubExpr()->getType()));
39173918
return expr;
39183919
}
39193920

lib/Sema/CSDiag.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1893,6 +1893,10 @@ Expr *FailureDiagnosis::typeCheckChildIndependently(
18931893
// the context is missing).
18941894
TypeCheckExprOptions TCEOptions = TypeCheckExprFlags::DisableStructuralChecks;
18951895

1896+
// Make sure that typechecker knows that this is an attempt
1897+
// to diagnose a problem.
1898+
TCEOptions |= TypeCheckExprFlags::SubExpressionDiagnostics;
1899+
18961900
// Don't walk into non-single expression closure bodies, because
18971901
// ExprTypeSaver and TypeNullifier skip them too.
18981902
TCEOptions |= TypeCheckExprFlags::SkipMultiStmtClosures;

lib/Sema/CSGen.cpp

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1579,6 +1579,11 @@ namespace {
15791579
if (typeOperation != TypeOperation::None)
15801580
return CS.getASTContext().TheAnyType;
15811581

1582+
// If this is `Builtin.trigger_fallback_diagnostic()`, fail
1583+
// without producing any diagnostics, in order to test fallback error.
1584+
if (isTriggerFallbackDiagnosticBuiltin(expr, CS.getASTContext()))
1585+
return Type();
1586+
15821587
// Open a member constraint for constructor delegations on the
15831588
// subexpr type.
15841589
if (CS.TC.getSelfForInitDelegationInConstructor(CS.DC, expr)) {
@@ -2919,7 +2924,9 @@ namespace {
29192924
}
29202925

29212926
Type visitLazyInitializerExpr(LazyInitializerExpr *expr) {
2922-
return expr->getType();
2927+
auto type = expr->getType();
2928+
assert(type && "LazyInitializerExpr should always have type set");
2929+
return type;
29232930
}
29242931

29252932
Type visitEditorPlaceholderExpr(EditorPlaceholderExpr *E) {
@@ -3128,6 +3135,19 @@ namespace {
31283135
return tv;
31293136
}
31303137

3138+
static bool isTriggerFallbackDiagnosticBuiltin(UnresolvedDotExpr *UDE,
3139+
ASTContext &Context) {
3140+
auto *DRE = dyn_cast<DeclRefExpr>(UDE->getBase());
3141+
if (!DRE)
3142+
return false;
3143+
3144+
if (DRE->getDecl() != Context.TheBuiltinModule)
3145+
return false;
3146+
3147+
auto member = UDE->getName().getBaseName().userFacingName();
3148+
return member.equals("trigger_fallback_diagnostic");
3149+
}
3150+
31313151
enum class TypeOperation { None,
31323152
Join,
31333153
JoinInout,

lib/Sema/CSSolver.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1175,6 +1175,8 @@ ConstraintSystem::solveImpl(Expr *&expr,
11751175
if (auto generatedExpr = generateConstraints(expr))
11761176
expr = generatedExpr;
11771177
else {
1178+
if (listener)
1179+
listener->constraintGenerationFailed(expr);
11781180
return SolutionKind::Error;
11791181
}
11801182

lib/Sema/CodeSynthesis.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1323,7 +1323,9 @@ static void synthesizeLazyGetterBody(TypeChecker &TC, AccessorDecl *Get,
13231323
// FIXME: we should really have stronger invariants than this. Leaving it
13241324
// unwrapped may expose both expressions to naive walkers
13251325
if (wasInitializerChecked) {
1326+
auto initType = InitValue->getType();
13261327
InitValue = new (Ctx) LazyInitializerExpr(InitValue);
1328+
InitValue->setType(initType);
13271329
}
13281330

13291331
Pattern *Tmp2PBDPattern = new (Ctx) NamedPattern(Tmp2VD, /*implicit*/true);

0 commit comments

Comments
 (0)