diff --git a/lib/Sema/TypeCheckDeclPrimary.cpp b/lib/Sema/TypeCheckDeclPrimary.cpp index d00d1dcc8f95c..95f137573b909 100644 --- a/lib/Sema/TypeCheckDeclPrimary.cpp +++ b/lib/Sema/TypeCheckDeclPrimary.cpp @@ -754,35 +754,38 @@ CheckRedeclarationRequest::evaluate(Evaluator &eval, ValueDecl *current) const { declToDiagnose->diagnose(diag::invalid_redecl_implicit, current->getDescriptiveKind(), isProtocolRequirement, other->getName()); - } - // Emit a specialized note if the one of the declarations is - // the backing storage property ('_foo') or projected value - // property ('$foo') for a wrapped property. The backing or - // projected var has the same source location as the wrapped - // property we diagnosed above, so we don't need to extract - // the original property. - const VarDecl *varToDiagnose = nullptr; - auto kind = PropertyWrapperSynthesizedPropertyKind::Backing; - if (auto currentVD = dyn_cast(current)) { - if (auto currentKind = - currentVD->getPropertyWrapperSynthesizedPropertyKind()) { - varToDiagnose = currentVD; - kind = *currentKind; + // Emit a specialized note if the one of the declarations is + // the backing storage property ('_foo') or projected value + // property ('$foo') for a wrapped property. The backing or + // projected var has the same source location as the wrapped + // property we diagnosed above, so we don't need to extract + // the original property. + const VarDecl *varToDiagnose = nullptr; + auto kind = PropertyWrapperSynthesizedPropertyKind::Backing; + if (auto currentVD = dyn_cast(current)) { + if (auto currentKind = + currentVD->getPropertyWrapperSynthesizedPropertyKind()) { + varToDiagnose = currentVD; + kind = *currentKind; + } } - } - if (auto otherVD = dyn_cast(other)) { - if (auto otherKind = - otherVD->getPropertyWrapperSynthesizedPropertyKind()) { - varToDiagnose = otherVD; - kind = *otherKind; + if (auto otherVD = dyn_cast(other)) { + if (auto otherKind = + otherVD->getPropertyWrapperSynthesizedPropertyKind()) { + varToDiagnose = otherVD; + kind = *otherKind; + } + } + + if (varToDiagnose) { + assert(declToDiagnose); + varToDiagnose->diagnose( + diag::invalid_redecl_implicit_wrapper, varToDiagnose->getName(), + kind == PropertyWrapperSynthesizedPropertyKind::Backing); } - } - if (varToDiagnose) { - varToDiagnose->diagnose( - diag::invalid_redecl_implicit_wrapper, varToDiagnose->getName(), - kind == PropertyWrapperSynthesizedPropertyKind::Backing); + current->setInvalid(); } } else { ctx.Diags.diagnoseWithNotes( @@ -790,8 +793,9 @@ CheckRedeclarationRequest::evaluate(Evaluator &eval, ValueDecl *current) const { current->getName()), [&]() { other->diagnose(diag::invalid_redecl_prev, other->getName()); }); + + current->setInvalid(); } - current->setInvalid(); } // Make sure we don't do this checking again for the same decl. We also diff --git a/validation-test/compiler_crashers_2_fixed/rdar67259506.swift b/validation-test/compiler_crashers_2_fixed/rdar67259506.swift new file mode 100644 index 0000000000000..4f3360980adc4 --- /dev/null +++ b/validation-test/compiler_crashers_2_fixed/rdar67259506.swift @@ -0,0 +1,29 @@ +// RUN: %target-swift-frontend -emit-ir %s + +public func foo(_: T, _: S.A) {} + +public protocol P { + associatedtype A + + func foo() -> A +} + +public protocol Q { + associatedtype A + + func bar() -> A +} + +public struct S {} + +extension S : P where T : P { + public func foo() -> Int { + return 0 + } +} + +extension S : Q where T : Q { + public func bar() -> Int { + return 0 + } +}