diff --git a/lib/Sema/TypeCheckAttr.cpp b/lib/Sema/TypeCheckAttr.cpp index 5720c88d727ab..6e16fdee3f8a0 100644 --- a/lib/Sema/TypeCheckAttr.cpp +++ b/lib/Sema/TypeCheckAttr.cpp @@ -2166,6 +2166,9 @@ static FuncDecl *findReplacedAccessor(DeclName replacedVarName, Type replacementStorageType = getDynamicComparisonType(replacementStorage); results.erase(std::remove_if(results.begin(), results.end(), [&](ValueDecl *result) { + // Protocol requirements are not replaceable. + if (isa(result->getDeclContext())) + return true; // Check for static/instance mismatch. if (result->isStatic() != replacementStorage->isStatic()) return true; @@ -2247,9 +2250,13 @@ findReplacedFunction(DeclName replacedFunctionName, lookupReplacedDecl(replacedFunctionName, attr, replacement, results); for (auto *result : results) { + // Protocol requirements are not replaceable. + if (isa(result->getDeclContext())) + continue; // Check for static/instance mismatch. if (result->isStatic() != replacement->isStatic()) continue; + if (TC) TC->validateDecl(result); TypeMatchOptions matchMode = TypeMatchFlags::AllowABICompatible; diff --git a/test/attr/Inputs/dynamicReplacementC.swift b/test/attr/Inputs/dynamicReplacementC.swift index 31bac2490cb61..2d2409c80e570 100644 --- a/test/attr/Inputs/dynamicReplacementC.swift +++ b/test/attr/Inputs/dynamicReplacementC.swift @@ -13,3 +13,23 @@ public class K { public convenience init(c : Int) { self.init(i : c) } public final func finalFunction() {} } + + +public protocol P { + var v: Int { get } + subscript(i: Int) -> Int { get } + func f() +} + +extension P { + public var v: Int { return 0 } + + public subscript(i: Int) -> Int { + get { + return 0 + } + } + + public func f() { + } +} diff --git a/test/attr/dynamicReplacement.swift b/test/attr/dynamicReplacement.swift index 7f313133262ff..34faeb9b30aaa 100644 --- a/test/attr/dynamicReplacement.swift +++ b/test/attr/dynamicReplacement.swift @@ -57,3 +57,21 @@ extension undeclared { // expected-error{{use of undeclared type 'undeclared'}} @_dynamicReplacement(for: func) // expected-error{{replaced function 'func' could not be found}} func func2() -> Int { return 2 } } + +extension P { + @_dynamicReplacement(for: v) + var replacement_v : Int { + return 1 + } + + @_dynamicReplacement(for: subscript(_:)) + subscript(y y: Int) -> Int { + get { + return 1 + } + } + + @_dynamicReplacement(for: f()) + func replacement_f() { + } +}