Skip to content

Commit ab64e53

Browse files
committed
[Sema] Only resolve PlaceholderType result for FuncDecl with body
We allow resolving PlaceholderType here to allow MiscDiagnostics to suggest replacing it with the inferred result type, but we won't run that logic for non-FuncDecls and FuncDecls without bodies. Make sure we reject placeholders in those cases.
1 parent 5e1acf5 commit ab64e53

File tree

4 files changed

+49
-3
lines changed

4 files changed

+49
-3
lines changed

lib/Sema/TypeCheckDecl.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2121,10 +2121,17 @@ ResultTypeRequest::evaluate(Evaluator &evaluator, ValueDecl *decl) const {
21212121
if (decl->preconcurrency())
21222122
options |= TypeResolutionFlags::Preconcurrency;
21232123

2124+
// Placeholders are only currently allowed for FuncDecls with bodies, which
2125+
// we diagnose in ReturnTypePlaceholderReplacer.
2126+
HandlePlaceholderTypeReprFn placeholderOpener;
2127+
if (auto *FD = dyn_cast<FuncDecl>(decl)) {
2128+
if (FD->hasBody() && !FD->isBodySkipped())
2129+
placeholderOpener = PlaceholderType::get;
2130+
}
21242131
auto *const dc = decl->getInnermostDeclContext();
21252132
return TypeResolution::forInterface(dc, options,
21262133
/*unboundTyOpener*/ nullptr,
2127-
PlaceholderType::get,
2134+
placeholderOpener,
21282135
/*packElementOpener*/ nullptr)
21292136
.resolveType(resultTyRepr);
21302137
}

test/Sema/placeholder_type.swift

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,3 +291,42 @@ do {
291291
_ = X(content: <#T##() -> _#>) // expected-error {{editor placeholder in source file}}
292292
}
293293
}
294+
295+
// Make sure we reject placeholders here.
296+
protocol TestPlaceholderRequirement {
297+
func foo(_:_) // expected-error {{type placeholder may not appear in top-level parameter}}
298+
func bar() -> _ // expected-error {{type placeholder not allowed here}}
299+
func baz() -> [_] // expected-error {{type placeholder not allowed here}}
300+
func qux(_: [_]) // expected-error {{type placeholder may not appear in top-level parameter}}
301+
302+
// FIXME: Shouldn't diagnose twice
303+
subscript(_: _) -> Void { get } // expected-error 2{{type placeholder may not appear in top-level parameter}}
304+
subscript() -> _ { get } // expected-error {{type placeholder not allowed here}}
305+
}
306+
307+
func testPlaceholderFn1(_:_) {} // expected-error {{type placeholder may not appear in top-level parameter}}
308+
func testPlaceholderFn2() -> _ {} // expected-error {{type placeholder may not appear in function return type}}
309+
310+
var testPlaceholderComputed1: _ { 0 } // expected-error {{type placeholder not allowed here}}
311+
var testPlaceholderComputed2: [_] { [0] } // expected-error {{type placeholder not allowed here}}
312+
313+
struct TestPlaceholderSubscript {
314+
subscript(_: _) -> Void { () } // expected-error 2{{type placeholder may not appear in top-level parameter}}
315+
subscript(_: [_]) -> Void { () } // expected-error 2{{type placeholder may not appear in top-level parameter}}
316+
subscript() -> _ { () } // expected-error {{type placeholder not allowed here}}
317+
subscript() -> [_] { [0] } // expected-error {{type placeholder not allowed here}}
318+
}
319+
320+
enum TestPlaceholderInEnumElement {
321+
case a(_) // expected-error {{type placeholder may not appear in top-level parameter}}
322+
case b([_]) // expected-error {{type placeholder may not appear in top-level parameter}}
323+
}
324+
325+
@freestanding(expression) macro testPlaceholderMacro(_ x: _) -> String = #file
326+
// expected-error@-1 {{type placeholder may not appear in top-level parameter}}
327+
328+
@freestanding(expression) macro testPlaceholderMacro(_ x: [_]) -> String = #file
329+
// expected-error@-1 {{type placeholder may not appear in top-level parameter}}
330+
331+
@freestanding(expression) macro testPlaceholderMacro() -> _ = #file
332+
// expected-error@-1 {{type placeholder not allowed here}}

validation-test/compiler_crashers_2/ce57354c94ae5aad.swift renamed to validation-test/compiler_crashers_2_fixed/ce57354c94ae5aad.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// {"kind":"emit-silgen","signature":"swift::CanTypeVisitor<swift::Lowering::TypeConverter::computeLoweredRValueType(swift::TypeExpansionContext, swift::Lowering::AbstractionPattern, swift::CanType)::LoweredRValueTypeVisitor, swift::CanType>::visit(swift::CanType)"}
2-
// RUN: not --crash %target-swift-frontend -emit-silgen %s
2+
// RUN: not %target-swift-frontend -emit-silgen %s
33
protocol a {
44
func b() -> _
55
}

validation-test/compiler_crashers_2/edb1d98948183f4c.swift renamed to validation-test/compiler_crashers_2_fixed/edb1d98948183f4c.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// {"kind":"emit-silgen","signature":"emitRawApply(swift::Lowering::SILGenFunction&, swift::SILLocation, swift::Lowering::ManagedValue, swift::SubstitutionMap, llvm::ArrayRef<swift::Lowering::ManagedValue>, swift::CanTypeWrapper<swift::SILFunctionType>, swift::optionset::OptionSet<swift::ApplyFlags, unsigned char>, llvm::ArrayRef<swift::SILValue>, swift::SILValue, llvm::SmallVectorImpl<swift::SILValue>&, swift::Lowering::ExecutorBreadcrumb)"}
2-
// RUN: not --crash %target-swift-frontend -emit-silgen %s
2+
// RUN: not %target-swift-frontend -emit-silgen %s
33
protocol a {
44
func b() -> [(_) -> Self]
55
}

0 commit comments

Comments
 (0)