Skip to content

Commit 232a244

Browse files
committed
Deserializer: better error message if types of referenced functions don't match
So far this resulted in an assert (in best case). Now a readable error is printed.
1 parent 823db1f commit 232a244

File tree

3 files changed

+33
-8
lines changed

3 files changed

+33
-8
lines changed

include/swift/AST/DiagnosticsSIL.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,10 @@ ERROR(function_type_mismatch,none,
126126
NOTE(function_declared_here,none,
127127
"function declared here", ())
128128

129+
ERROR(deserialize_function_type_mismatch,Fatal,
130+
"type mismatch of function '%0', declared as %1 but used in a swift module as %2",
131+
(StringRef, Type, Type))
132+
129133
// Capture before declaration diagnostics.
130134
ERROR(capture_before_declaration,none,
131135
"closure captures %0 before it is declared", (Identifier))

lib/Serialization/DeserializeSIL.cpp

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "SILFormat.h"
2121
#include "SILSerializationFunctionBuilder.h"
2222

23+
#include "swift/AST/DiagnosticsSIL.h"
2324
#include "swift/AST/GenericSignature.h"
2425
#include "swift/AST/PrettyStackTrace.h"
2526
#include "swift/AST/ProtocolConformance.h"
@@ -392,7 +393,8 @@ SILDeserializer::getSILDifferentiabilityWitnessForReference(
392393

393394
/// Helper function to find a SILFunction, given its name and type.
394395
SILFunction *SILDeserializer::getFuncForReference(StringRef name,
395-
SILType type) {
396+
SILType type,
397+
TypeExpansionContext context) {
396398
// Check to see if we have a function by this name already.
397399
SILFunction *fn = SILMod.lookUpFunction(name);
398400
if (!fn) {
@@ -410,11 +412,27 @@ SILFunction *SILDeserializer::getFuncForReference(StringRef name,
410412
}
411413
}
412414

413-
// FIXME: check for matching types.
414-
415415
// At this point, if fn is set, we know that we have a good function to use.
416-
if (fn)
416+
if (fn) {
417+
SILType fnType = fn->getLoweredTypeInContext(context);
418+
if (fnType != type &&
419+
// It can happen that opaque return types cause a mismatch when merging
420+
// modules, without causing any further assertion failures.
421+
// TODO: fix the underlying problem
422+
fnType.hasOpaqueArchetype() == type.hasOpaqueArchetype()) {
423+
StringRef fnName = fn->getName();
424+
if (auto *dc = fn->getDeclContext()) {
425+
if (auto *decl = dyn_cast_or_null<AbstractFunctionDecl>(dc->getAsDecl()))
426+
fnName = decl->getNameStr();
427+
}
428+
fn->getModule().getASTContext().Diags.diagnose(
429+
fn->getLocation().getSourceLoc(),
430+
diag::deserialize_function_type_mismatch,
431+
fnName, fnType.getASTType(), type.getASTType());
432+
exit(1);
433+
}
417434
return fn;
435+
}
418436

419437
// Otherwise, create a function declaration with the right type and a bogus
420438
// source location. This ensures that we can at least parse the rest of the
@@ -1969,7 +1987,8 @@ bool SILDeserializer::readSILInstruction(SILFunction *Fn,
19691987
ResultInst = Builder.createFunctionRef(
19701988
Loc,
19711989
getFuncForReference(
1972-
FuncName, getSILType(Ty, (SILValueCategory)TyCategory, nullptr)));
1990+
FuncName, getSILType(Ty, (SILValueCategory)TyCategory, nullptr),
1991+
Builder.getTypeExpansionContext()));
19731992
break;
19741993
}
19751994
case SILInstructionKind::DynamicFunctionRefInst: {
@@ -1978,7 +1997,8 @@ bool SILDeserializer::readSILInstruction(SILFunction *Fn,
19781997
ResultInst = Builder.createDynamicFunctionRef(
19791998
Loc,
19801999
getFuncForReference(
1981-
FuncName, getSILType(Ty, (SILValueCategory)TyCategory, nullptr)));
2000+
FuncName, getSILType(Ty, (SILValueCategory)TyCategory, nullptr),
2001+
Builder.getTypeExpansionContext()));
19822002
break;
19832003
}
19842004
case SILInstructionKind::PreviousDynamicFunctionRefInst: {
@@ -1987,7 +2007,8 @@ bool SILDeserializer::readSILInstruction(SILFunction *Fn,
19872007
ResultInst = Builder.createPreviousDynamicFunctionRef(
19882008
Loc,
19892009
getFuncForReference(
1990-
FuncName, getSILType(Ty, (SILValueCategory)TyCategory, nullptr)));
2010+
FuncName, getSILType(Ty, (SILValueCategory)TyCategory, nullptr),
2011+
Builder.getTypeExpansionContext()));
19912012
break;
19922013
}
19932014
case SILInstructionKind::MarkDependenceInst: {

lib/Serialization/DeserializeSIL.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ namespace swift {
142142
SILDifferentiabilityWitness *
143143
getSILDifferentiabilityWitnessForReference(StringRef mangledKey);
144144

145-
SILFunction *getFuncForReference(StringRef Name, SILType Ty);
145+
SILFunction *getFuncForReference(StringRef Name, SILType Ty, TypeExpansionContext context);
146146
SILFunction *getFuncForReference(StringRef Name);
147147
SILVTable *readVTable(serialization::DeclID);
148148
SILMoveOnlyDeinit *readMoveOnlyDeinit(serialization::DeclID);

0 commit comments

Comments
 (0)