Skip to content

Commit 2129101

Browse files
authored
Merge pull request #12113 from xedin/rdar-33613329
2 parents 2a40647 + 9d9a6c6 commit 2129101

File tree

2 files changed

+73
-4
lines changed

2 files changed

+73
-4
lines changed

lib/Sema/CSDiag.cpp

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3289,18 +3289,42 @@ namespace {
32893289
patternElt.first->setType(patternElt.second);
32903290

32913291
for (auto paramDeclElt : ParamDeclTypes)
3292-
if (!paramDeclElt.first->hasType())
3293-
paramDeclElt.first->setType(paramDeclElt.second);
3292+
if (!paramDeclElt.first->hasType()) {
3293+
paramDeclElt.first->setType(getParamBaseType(paramDeclElt));
3294+
}
32943295

32953296
for (auto paramDeclIfaceElt : ParamDeclInterfaceTypes)
3296-
if (!paramDeclIfaceElt.first->hasInterfaceType())
3297-
paramDeclIfaceElt.first->setInterfaceType(paramDeclIfaceElt.second);
3297+
if (!paramDeclIfaceElt.first->hasInterfaceType()) {
3298+
paramDeclIfaceElt.first->setInterfaceType(
3299+
getParamBaseType(paramDeclIfaceElt));
3300+
}
32983301

32993302
if (!PossiblyInvalidDecls.empty())
33003303
for (auto D : PossiblyInvalidDecls)
33013304
if (D->hasInterfaceType())
33023305
D->setInvalid(D->getInterfaceType()->hasError());
33033306
}
3307+
3308+
private:
3309+
static Type getParamBaseType(std::pair<ParamDecl *, Type> &storedParam) {
3310+
ParamDecl *param;
3311+
Type storedType;
3312+
3313+
std::tie(param, storedType) = storedParam;
3314+
3315+
// FIXME: We are currently in process of removing `InOutType`
3316+
// so `VarDecl::get{Interface}Type` is going to wrap base
3317+
// type into `InOutType` if its flag indicates that it's
3318+
// an `inout` parameter declaration. But such type can't
3319+
// be restored directly using `VarDecl::set{Interface}Type`
3320+
// caller needs additional logic to extract base type.
3321+
if (auto *IOT = storedType->getAs<InOutType>()) {
3322+
assert(param->isInOut());
3323+
return IOT->getObjectType();
3324+
}
3325+
3326+
return storedType;
3327+
}
33043328
};
33053329
} // end anonymous namespace
33063330

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// RUN: %target-typecheck-verify-swift %s
2+
3+
precedencegroup BindingPrecedence {
4+
higherThan: DefaultPrecedence
5+
}
6+
7+
infix operator ~>
8+
infix operator ≈> : BindingPrecedence
9+
10+
struct M<L : P, R> {
11+
let f: L
12+
let b: (inout L.B) -> R
13+
14+
init(f: L, b: @escaping (inout L.B) -> R) {
15+
self.f = f
16+
self.b = b
17+
}
18+
}
19+
20+
protocol P {
21+
associatedtype A
22+
associatedtype B
23+
24+
func `in`<R>(_ a: inout A, apply body: (inout B) -> R) -> R
25+
26+
static func ~> (_: A, _: Self) -> B
27+
}
28+
29+
extension P {
30+
static func ≈> <R>(f: Self, b: @escaping (inout B) -> R) -> M<Self, R> {}
31+
}
32+
33+
extension WritableKeyPath : P {
34+
typealias A = Root
35+
typealias B = Value
36+
37+
func `in`<R>(_ a: inout A, apply body: (inout B) -> R) -> R {}
38+
39+
static func ~> (a: A, path: WritableKeyPath) -> B {}
40+
}
41+
42+
struct X { var y: Int = 0 }
43+
var x = X()
44+
x ~> \X.y ≈> { a in a += 1; return 3 }
45+
// expected-error@-1 {{cannot convert call result type 'M<WritableKeyPath<X, Int>, _>' to expected type 'WritableKeyPath<_, _>'}}

0 commit comments

Comments
 (0)