Skip to content

Commit 0ae0fdc

Browse files
committed
NFC: [TypeLowering] Handle @unchecked BC fields.
The appearance of a field whose type's conformance to BitwiseCopyable is @unchecked permits the type not to conform.
1 parent d9e1755 commit 0ae0fdc

File tree

1 file changed

+39
-13
lines changed

1 file changed

+39
-13
lines changed

lib/SIL/IR/TypeLowering.cpp

Lines changed: 39 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "swift/AST/Pattern.h"
2929
#include "swift/AST/PrettyStackTrace.h"
3030
#include "swift/AST/PropertyWrappers.h"
31+
#include "swift/AST/ProtocolConformance.h"
3132
#include "swift/AST/TypeDifferenceVisitor.h"
3233
#include "swift/AST/Types.h"
3334
#include "swift/ClangImporter/ClangModule.h"
@@ -3009,6 +3010,21 @@ void TypeConverter::verifyLexicalLowering(const TypeLowering &lowering,
30093010
}
30103011
}
30113012

3013+
static bool isUnchecked(ProtocolConformanceRef conformance) {
3014+
if (!conformance)
3015+
return false;
3016+
if (!conformance.isConcrete())
3017+
return false;
3018+
auto concrete = conformance.getConcrete();
3019+
assert(concrete);
3020+
auto *root = concrete->getRootConformance();
3021+
assert(root);
3022+
auto *normal = dyn_cast<NormalProtocolConformance>(root);
3023+
if (!normal)
3024+
return false;
3025+
return normal->isUnchecked();
3026+
}
3027+
30123028
void TypeConverter::verifyTrivialLowering(const TypeLowering &lowering,
30133029
AbstractionPattern origType,
30143030
CanType substType,
@@ -3042,10 +3058,17 @@ void TypeConverter::verifyTrivialLowering(const TypeLowering &lowering,
30423058
if (!nominal)
30433059
return false;
30443060

3045-
// Nominals with generic parameters must be explicitly conformed to
3046-
// BitwiseCopyable.
3047-
auto *generic = ty.getAnyGeneric();
3048-
if (generic && generic->isGenericContext()) {
3061+
// Don't walk into types whose conformance is unchecked--such
3062+
// conformances obstruct automatic inference of BitwiseCopyable.
3063+
auto conformance = M.checkConformance(ty, bitwiseCopyableProtocol);
3064+
if (isUnchecked(conformance)) {
3065+
return true;
3066+
}
3067+
3068+
// Nominals with fields that conditionally conform to BitwiseCopyable
3069+
// must be explicitly conditionally conformed. Such a field must be a
3070+
// generic context.
3071+
if (nominal->isGenericContext()) {
30493072
return true;
30503073
}
30513074

@@ -3059,10 +3082,12 @@ void TypeConverter::verifyTrivialLowering(const TypeLowering &lowering,
30593082
// Return false to indicate seeing a leaf which justifies the type
30603083
// being trivial but not conforming to BitwiseCopyable.
30613084

3062-
// A BitwiseCopyable conformer appearing within its layout doesn't
3063-
// explain why substType doesn't itself conform.
3064-
if (M.checkConformance(ty, bitwiseCopyableProtocol))
3065-
return true;
3085+
// A BitwiseCopyable conformer appearing within its layout explains a
3086+
// non-conformance iff the conformance is @unchecked.
3087+
auto conformance = M.checkConformance(ty, bitwiseCopyableProtocol);
3088+
if (conformance) {
3089+
return !isUnchecked(conformance);
3090+
}
30663091

30673092
// ModuleTypes are trivial but don't warrant being given a conformance
30683093
// to BitwiseCopyable.
@@ -3099,15 +3124,15 @@ void TypeConverter::verifyTrivialLowering(const TypeLowering &lowering,
30993124
return true;
31003125
}
31013126

3102-
/// A non-conforming generic nominal type justifies substType not
3103-
/// conforming.
3104-
auto *generic = ty.getAnyGeneric();
3105-
if (generic && generic->isGenericContext()) {
3127+
/// A field of conditionally-BitwiseCopyable type justifies the
3128+
/// aggregate not conforming because the aggregate must be conformed
3129+
/// explicitly in that case.
3130+
if (nominal->isGenericContext()) {
31063131
return false;
31073132
}
31083133

31093134
// The field is trivial and the whole type is nonconforming. That's
3110-
// legal iff the type is public.
3135+
// legal iff the field's type is public.
31113136
return !nominal
31123137
->getFormalAccessScope(
31133138
/*useDC=*/nullptr,
@@ -3148,6 +3173,7 @@ void TypeConverter::verifyTrivialLowering(const TypeLowering &lowering,
31483173
llvm::errs() << "Non-trivial type with _BitwiseCopyable conformance!?:\n"
31493174
<< substType << "\n";
31503175
conformance.print(llvm::errs());
3176+
llvm::errs() << "\n";
31513177
assert(false);
31523178
}
31533179
}

0 commit comments

Comments
 (0)