Skip to content

Commit 2869dff

Browse files
committed
[CSOptimizer] Increase score when type matches opaque type
Since erasure of a concrete type into an existential value yields score of 1, we need to bump the score in cases where a type passed to a generic parameter satisfies all of its protocol conformance requirements and that parameter represents an opaque type.
1 parent 0fc6806 commit 2869dff

File tree

2 files changed

+53
-1
lines changed

2 files changed

+53
-1
lines changed

lib/Sema/CSOptimizer.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,8 +314,14 @@ static void determineBestChoicesInContext(
314314

315315
if (llvm::all_of(protocolRequirements, [&](ProtocolDecl *protocol) {
316316
return bool(cs.lookupConformance(candidateType, protocol));
317-
}))
317+
})) {
318+
if (auto *GP = paramType->getAs<GenericTypeParamType>()) {
319+
auto *paramDecl = GP->getDecl();
320+
if (paramDecl && paramDecl->isOpaqueType())
321+
return 1.0;
322+
}
318323
return 0.7;
324+
}
319325
}
320326

321327
// Parameter is generic, let's check whether top-level

test/Constraints/operator.swift

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,3 +329,49 @@ enum I60954 {
329329
}
330330
init?<S>(_ string: S) where S: StringProtocol {} // expected-note{{where 'S' = 'I60954'}}
331331
}
332+
333+
infix operator <<<>>> : DefaultPrecedence
334+
335+
protocol P5 {
336+
}
337+
338+
struct Expr : P6 {}
339+
340+
protocol P6: P5 {
341+
}
342+
343+
extension P6 {
344+
public static func <<<>>> (lhs: Self, rhs: (any P5)?) -> Expr { Expr() }
345+
public static func <<<>>> (lhs: (any P5)?, rhs: Self) -> Expr { Expr() }
346+
public static func <<<>>> (lhs: Self, rhs: some P6) -> Expr { Expr() }
347+
348+
public static prefix func ! (value: Self) -> Expr {
349+
Expr()
350+
}
351+
}
352+
353+
extension P6 {
354+
public static func != (lhs: Self, rhs: some P6) -> Expr {
355+
!(lhs <<<>>> rhs) // Ok
356+
}
357+
}
358+
359+
do {
360+
struct Value : P6 {
361+
}
362+
363+
struct Column: P6 {
364+
}
365+
366+
func test(col: Column, val: Value) -> Expr {
367+
col <<<>>> val // Ok
368+
}
369+
370+
func test(col: Column, val: some P6) -> Expr {
371+
col <<<>>> val // Ok
372+
}
373+
374+
func test(col: some P6, val: Value) -> Expr {
375+
col <<<>>> val // Ok
376+
}
377+
}

0 commit comments

Comments
 (0)