Skip to content

Commit 6e628c4

Browse files
committed
[CSGen] Fallback to a type variable if preferred type for placeholder is invalid
Type inside of an editor placeholder is more of a hint than anything else, so if it's incorrect let's diagnose that and use type variable instead to allow solver to make forward progress. Resolves: SR-14213 Resolves: rdar://74356736
1 parent 13ab6ec commit 6e628c4

File tree

3 files changed

+26
-8
lines changed

3 files changed

+26
-8
lines changed

lib/Sema/CSGen.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3034,10 +3034,12 @@ namespace {
30343034

30353035
Type visitEditorPlaceholderExpr(EditorPlaceholderExpr *E) {
30363036
if (auto *placeholderRepr = E->getPlaceholderTypeRepr()) {
3037-
// Just resolve the referenced type.
3038-
return resolveTypeReferenceInExpression(
3039-
placeholderRepr, TypeResolverContext::InExpression,
3040-
CS.getConstraintLocator(E));
3037+
// Let's try to use specified type, if that's impossible,
3038+
// fallback to a type variable.
3039+
if (auto preferredTy = resolveTypeReferenceInExpression(
3040+
placeholderRepr, TypeResolverContext::InExpression,
3041+
CS.getConstraintLocator(E)))
3042+
return preferredTy;
30413043
}
30423044

30433045
auto locator = CS.getConstraintLocator(E);

test/Sema/editor_placeholders.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
// RUN: %target-typecheck-verify-swift
22

3-
func foo(_ x: Int) -> Int {}
4-
func foo(_ x: Float) -> Float {}
5-
func foo<T>(_ t: T) -> T {}
3+
func foo(_ x: Int) -> Int {} // expected-note {{found this candidate}}
4+
func foo(_ x: Float) -> Float {} // expected-note {{found this candidate}}
5+
func foo<T>(_ t: T) -> T {} // expected-note {{found this candidate}}
66

77
var v = foo(<#T##x: Float##Float#>) // expected-error {{editor placeholder}}
88
v = "" // expected-error {{cannot assign value of type 'String' to type 'Float'}}
@@ -11,7 +11,7 @@ if (true) {
1111
<#code#> // expected-error {{editor placeholder}}
1212
}
1313

14-
foo(<#T##x: Undeclared##Undeclared#>) // expected-error {{editor placeholder}} expected-error {{cannot find type 'Undeclared' in scope}}
14+
foo(<#T##x: Undeclared##Undeclared#>) // expected-error {{editor placeholder}} expected-error {{cannot find type 'Undeclared' in scope}} expected-error {{ambiguous use of 'foo'}}
1515

1616
func f(_ n: Int) {}
1717
let a1 = <#T#> // expected-error{{editor placeholder in source file}}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// RUN: %target-typecheck-verify-swift -target x86_64-apple-macosx10.15 -swift-version 5
2+
3+
// REQUIRES: objc_interop
4+
// REQUIRES: OS=macosx
5+
6+
import SwiftUI
7+
8+
struct Experiment: View {
9+
var body: some View {
10+
HStack { // expected-error {{generic parameter 'Content' could not be inferred}} expected-note {{explicitly specify the generic arguments to fix this issue}}emacs
11+
Slider(value: <#T##Binding<BinaryFloatingPoint>#>, in: <#T##ClosedRange<BinaryFloatingPoint>#>, label: <#T##() -> _#>) // expected-error 3 {{editor placeholder in source file}} expected-error {{expected type for function result}}
12+
// expected-error@-1 {{protocol 'BinaryFloatingPoint' as a type cannot conform to 'Comparable'}}
13+
// expected-note@-2 {{only concrete types such as structs, enums and classes can conform to protocols}}
14+
}
15+
}
16+
}

0 commit comments

Comments
 (0)