Skip to content

Commit ffff354

Browse files
committed
Restore Top-Level Placeholder Restrictions in Expression Position
Respect the text of https://github.com/apple/swift-evolution/blob/main/proposals/0315-placeholder-types.md#top-level-type-placeholders and re-restrict the usage of placeholders in top-level expressions.
1 parent 7afe3fc commit ffff354

File tree

3 files changed

+16
-11
lines changed

3 files changed

+16
-11
lines changed

lib/Sema/CSGen.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1318,6 +1318,11 @@ namespace {
13181318
if (result->hasError()) {
13191319
return Type();
13201320
}
1321+
// Diagnose top-level usages of placeholder types.
1322+
if (isa<TopLevelCodeDecl>(CS.DC) && isa<PlaceholderTypeRepr>(repr)) {
1323+
CS.getASTContext().Diags.diagnose(repr->getLoc(),
1324+
diag::placeholder_type_not_allowed);
1325+
}
13211326
return result;
13221327
}
13231328

test/Sema/placeholder_type.swift

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ let arr = [_](repeating: "hi", count: 3)
1010
func foo(_ arr: [_] = [0]) {} // expected-error {{type placeholder may not appear in top-level parameter}}
1111
// expected-note@-1 {{replace the placeholder with the inferred type 'Int'}}
1212

13-
let foo = _.foo // expected-error {{could not infer type for placeholder}}
13+
let foo = _.foo // expected-error {{type placeholder not allowed here}} expected-error {{could not infer type for placeholder}}
1414
let zero: _ = .zero // expected-error {{cannot infer contextual base in reference to member 'zero'}}
1515

1616
struct S<T> {
@@ -49,7 +49,7 @@ func dictionary<K, V>(ofType: [K: V].Type) -> [K: V] { [:] }
4949

5050
let _: [String: _] = dictionary(ofType: [_: Int].self)
5151
let _: [_: _] = dictionary(ofType: [String: Int].self)
52-
let _: [String: Int] = dictionary(ofType: _.self)
52+
let _: [String: Int] = dictionary(ofType: _.self) // expected-error {{type placeholder not allowed here}}
5353

5454
let _: @convention(c) _ = { 0 } // expected-error {{@convention attribute only applies to function types}}
5555
let _: @convention(c) (_) -> _ = { (x: Double) in 0 }
@@ -107,18 +107,18 @@ extension Bar {
107107
}
108108

109109
// FIXME: We should probably have better diagnostics for these situations--the user probably meant to use implicit member syntax
110-
let _: Int = _() // expected-error {{type of expression is ambiguous without more context}}
111-
let _: () -> Int = { _() } // expected-error {{unable to infer closure type in the current context}}
112-
let _: Int = _.init() // expected-error {{could not infer type for placeholder}}
113-
let _: () -> Int = { _.init() } // expected-error {{could not infer type for placeholder}}
110+
let _: Int = _() // expected-error {{type placeholder not allowed here}} expected-error {{type of expression is ambiguous without more context}}
111+
let _: () -> Int = { _() } // expected-error 2 {{type placeholder not allowed here}} expected-error {{unable to infer closure type in the current context}}
112+
let _: Int = _.init() // expected-error {{type placeholder not allowed here}} expected-error {{could not infer type for placeholder}}
113+
let _: () -> Int = { _.init() } // expected-error 2 {{type placeholder not allowed here}} expected-error {{could not infer type for placeholder}}
114114

115115
func returnsInt() -> Int { _() } // expected-error {{type of expression is ambiguous without more context}}
116116
func returnsIntClosure() -> () -> Int { { _() } } // expected-error {{unable to infer closure type in the current context}}
117117
func returnsInt2() -> Int { _.init() } // expected-error {{could not infer type for placeholder}}
118118
func returnsIntClosure2() -> () -> Int { { _.init() } } // expected-error {{could not infer type for placeholder}}
119119

120120
let _: Int.Type = _ // expected-error {{'_' can only appear in a pattern or on the left side of an assignment}}
121-
let _: Int.Type = _.self
121+
let _: Int.Type = _.self // expected-error {{type placeholder not allowed here}}
122122

123123
struct SomeSuperLongAndComplexType {}
124124
func getSomething() -> SomeSuperLongAndComplexType? { .init() }
@@ -200,13 +200,13 @@ extension Publisher {
200200
}
201201
}
202202

203-
let _: SetFailureType<Int, String> = Just<Int>().setFailureType(to: _.self)
203+
let _: SetFailureType<Int, String> = Just<Int>().setFailureType(to: _.self) // expected-error {{type placeholder not allowed here}}
204204
let _: SetFailureType<Int, [String]> = Just<Int>().setFailureType(to: [_].self)
205205
let _: SetFailureType<Int, (String) -> Double> = Just<Int>().setFailureType(to: ((_) -> _).self)
206206
let _: SetFailureType<Int, (String, Double)> = Just<Int>().setFailureType(to: (_, _).self)
207207

208208
// TODO: Better error message here? Would be nice if we could point to the placeholder...
209-
let _: SetFailureType<Int, String> = Just<Int>().setFailureType(to: _.self).setFailureType(to: String.self) // expected-error {{generic parameter 'T' could not be inferred}}
209+
let _: SetFailureType<Int, String> = Just<Int>().setFailureType(to: _.self).setFailureType(to: String.self) // expected-error {{type placeholder not allowed here}} expected-error {{generic parameter 'T' could not be inferred}}
210210

211211
let _: (_) = 0 as Int
212212
let _: Int = 0 as (_)
@@ -225,7 +225,7 @@ _ = (1...10)
225225
x.boolValue ? intValue : 0
226226
}
227227

228-
let _: SetFailureType<Int, String> = Just<Int>().setFailureType(to: _.self).setFailureType(to: String.self) // expected-error {{generic parameter 'T' could not be inferred}}
228+
let _: SetFailureType<Int, String> = Just<Int>().setFailureType(to: _.self).setFailureType(to: String.self) // expected-error {{type placeholder not allowed here}} expected-error {{generic parameter 'T' could not be inferred}}
229229

230230
// N.B. The parallel structure of the annotation and inferred default
231231
// initializer types is all wrong. Plus, we do not trust

test/expr/expressions.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -865,7 +865,7 @@ func r20802757(_ z: inout Int = &g20802757) { // expected-error {{cannot provide
865865
print(z)
866866
}
867867

868-
_ = _.foo // expected-error {{could not infer type for placeholder}}
868+
_ = _.foo // expected-error {{type placeholder not allowed here}} expected-error {{could not infer type for placeholder}}
869869

870870
// <rdar://problem/22211854> wrong arg list crashing sourcekit
871871
func r22211854() {

0 commit comments

Comments
 (0)