|
17 | 17 | #include "MiscDiagnostics.h" |
18 | 18 | #include "TypeCheckAvailability.h" |
19 | 19 | #include "TypeCheckConcurrency.h" |
| 20 | +#include "TypeCheckInvertible.h" |
20 | 21 | #include "TypeChecker.h" |
21 | 22 | #include "swift/AST/ASTWalker.h" |
22 | 23 | #include "swift/AST/DiagnosticsSema.h" |
@@ -6313,103 +6314,24 @@ bool swift::diagnoseUnhandledThrowsInAsyncContext(DeclContext *dc, |
6313 | 6314 | return false; |
6314 | 6315 | } |
6315 | 6316 |
|
6316 | | -//===----------------------------------------------------------------------===// |
6317 | | -// Copyable Type Containing Move Only Type Visitor |
6318 | | -//===----------------------------------------------------------------------===// |
| 6317 | +// If we haven't enabled the NoncopyableGenerics feature, force a |
| 6318 | +// Copyable conformance check now. |
| 6319 | +void swift::forceCopyableConformanceCheckIfNeeded(NominalTypeDecl *nom) { |
| 6320 | + auto &ctx = nom->getASTContext(); |
6319 | 6321 |
|
6320 | | -void swift::diagnoseCopyableTypeContainingMoveOnlyType( |
6321 | | - NominalTypeDecl *copyableNominalType) { |
6322 | | - auto &ctx = copyableNominalType->getASTContext(); |
6323 | 6322 | if (ctx.LangOpts.hasFeature(Feature::NoncopyableGenerics)) |
6324 | 6323 | return; // taken care of in conformance checking |
6325 | 6324 |
|
6326 | | - // If we already have a move only type, just bail, we have no further work to |
6327 | | - // do. |
6328 | | - if (!copyableNominalType->canBeCopyable()) |
6329 | | - return; |
6330 | | - |
6331 | | - LLVM_DEBUG(llvm::dbgs() << "DiagnoseCopyableType for: " |
6332 | | - << copyableNominalType->getName() << '\n'); |
6333 | | - |
6334 | | - auto &DE = copyableNominalType->getASTContext().Diags; |
6335 | | - auto emitError = [©ableNominalType, |
6336 | | - &DE](PointerUnion<EnumElementDecl *, VarDecl *> |
6337 | | - topFieldToError, |
6338 | | - DeclBaseName parentName, DescriptiveDeclKind fieldKind, |
6339 | | - DeclBaseName fieldName) { |
6340 | | - assert(!topFieldToError.isNull()); |
6341 | | - if (auto *eltDecl = topFieldToError.dyn_cast<EnumElementDecl *>()) { |
6342 | | - DE.diagnoseWithNotes( |
6343 | | - copyableNominalType->diagnose( |
6344 | | - diag::noncopyable_within_copyable, |
6345 | | - copyableNominalType), |
6346 | | - [&]() { |
6347 | | - eltDecl->diagnose( |
6348 | | - diag:: |
6349 | | - noncopyable_within_copyable_location, |
6350 | | - fieldKind, parentName.userFacingName(), |
6351 | | - fieldName.userFacingName()); |
6352 | | - }); |
6353 | | - return; |
6354 | | - } |
| 6325 | + auto *copyable = ctx.getProtocol(KnownProtocolKind::Copyable); |
| 6326 | + Type selfTy = nom->getDeclaredInterfaceType(); |
6355 | 6327 |
|
6356 | | - auto *varDecl = topFieldToError.get<VarDecl *>(); |
6357 | | - DE.diagnoseWithNotes( |
6358 | | - copyableNominalType->diagnose( |
6359 | | - diag::noncopyable_within_copyable, |
6360 | | - copyableNominalType), |
6361 | | - [&]() { |
6362 | | - varDecl->diagnose( |
6363 | | - diag::noncopyable_within_copyable_location, |
6364 | | - fieldKind, parentName.userFacingName(), |
6365 | | - fieldName.userFacingName()); |
6366 | | - }); |
6367 | | - }; |
| 6328 | + auto conformanceRef = nom->getModuleContext()->lookupConformance(selfTy, |
| 6329 | + copyable, |
| 6330 | + /*allowMissing=*/false); |
6368 | 6331 |
|
6369 | | - // If we have a struct decl... |
6370 | | - if (auto *structDecl = dyn_cast<StructDecl>(copyableNominalType)) { |
6371 | | - // Visit each of the stored property var decls of the struct decl... |
6372 | | - for (auto *fieldDecl : structDecl->getStoredProperties()) { |
6373 | | - LLVM_DEBUG(llvm::dbgs() |
6374 | | - << "Visiting struct field: " << fieldDecl->getName() << '\n'); |
6375 | | - if (!fieldDecl->getInterfaceType()->isNoncopyable()) |
6376 | | - continue; |
6377 | | - emitError(fieldDecl, structDecl->getBaseName(), |
6378 | | - fieldDecl->getDescriptiveKind(), fieldDecl->getBaseName()); |
6379 | | - } |
6380 | | - // We completed our checking, just return. |
| 6332 | + // it's never copyable |
| 6333 | + if (conformanceRef.isInvalid()) |
6381 | 6334 | return; |
6382 | | - } |
6383 | | - |
6384 | | - if (auto *enumDecl = dyn_cast<EnumDecl>(copyableNominalType)) { |
6385 | | - // If we have an enum but we don't have any elements, just continue, we |
6386 | | - // have nothing to check. |
6387 | | - if (enumDecl->getAllElements().empty()) |
6388 | | - return; |
6389 | | - |
6390 | | - // Otherwise for each element... |
6391 | | - for (auto *enumEltDecl : enumDecl->getAllElements()) { |
6392 | | - // If the element doesn't have any associated values, we have nothing to |
6393 | | - // check, so continue. |
6394 | | - if (!enumEltDecl->hasAssociatedValues()) |
6395 | | - continue; |
6396 | 6335 |
|
6397 | | - LLVM_DEBUG(llvm::dbgs() << "Visiting enum elt decl: " |
6398 | | - << enumEltDecl->getName() << '\n'); |
6399 | | - |
6400 | | - // Otherwise, we have a case and need to check the types of the |
6401 | | - // parameters of the case payload. |
6402 | | - for (auto payloadParam : *enumEltDecl->getParameterList()) { |
6403 | | - LLVM_DEBUG(llvm::dbgs() << "Visiting payload param: " |
6404 | | - << payloadParam->getName() << '\n'); |
6405 | | - if (payloadParam->getInterfaceType()->isNoncopyable()) { |
6406 | | - emitError(enumEltDecl, enumDecl->getBaseName(), |
6407 | | - enumEltDecl->getDescriptiveKind(), |
6408 | | - enumEltDecl->getBaseName()); |
6409 | | - } |
6410 | | - } |
6411 | | - } |
6412 | | - // We have finished processing this enum... so return. |
6413 | | - return; |
6414 | | - } |
| 6336 | + swift::checkCopyableConformance(nom, conformanceRef); |
6415 | 6337 | } |
0 commit comments