Skip to content

Commit 22ad19f

Browse files
committed
Revert "[Sema] Diagnose and reject top-level placeholders"
This reverts commit f6b6bff.
1 parent dd984b1 commit 22ad19f

File tree

10 files changed

+44
-93
lines changed

10 files changed

+44
-93
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3624,8 +3624,6 @@ ERROR(cannot_force_unwrap_nil_literal,none,
36243624

36253625
ERROR(could_not_infer_placeholder,none,
36263626
"could not infer type for placeholder", ())
3627-
ERROR(top_level_placeholder_type,none,
3628-
"placeholders are not allowed as top-level types", ())
36293627

36303628
ERROR(type_of_expression_is_ambiguous,none,
36313629
"type of expression is ambiguous without more context", ())

lib/Sema/PreCheckExpr.cpp

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1506,9 +1506,7 @@ TypeExpr *PreCheckExpression::simplifyNestedTypeExpr(UnresolvedDotExpr *UDE) {
15061506
},
15071507
// FIXME: Don't let placeholder types escape type resolution.
15081508
// For now, just return the placeholder type.
1509-
[](auto &ctx, auto *originator) {
1510-
return Type();
1511-
});
1509+
PlaceholderType::get);
15121510
const auto BaseTy = resolution.resolveType(InnerTypeRepr);
15131511

15141512
if (BaseTy->mayHaveMembers()) {
@@ -2061,9 +2059,7 @@ Expr *PreCheckExpression::simplifyTypeConstructionWithLiteralArg(Expr *E) {
20612059
},
20622060
// FIXME: Don't let placeholder types escape type resolution.
20632061
// For now, just return the placeholder type.
2064-
[](auto &ctx, auto *originator) {
2065-
return Type();
2066-
});
2062+
PlaceholderType::get);
20672063
const auto result = resolution.resolveType(typeExpr->getTypeRepr());
20682064
if (result->hasError())
20692065
return nullptr;

lib/Sema/TypeCheckDecl.cpp

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2309,9 +2309,7 @@ static Type validateParameterType(ParamDecl *decl) {
23092309
};
23102310
// FIXME: Don't let placeholder types escape type resolution.
23112311
// For now, just return the placeholder type.
2312-
placeholderHandler = [](auto &ctx, auto *originator) {
2313-
return Type();
2314-
};
2312+
placeholderHandler = PlaceholderType::get;
23152313
} else if (isa<AbstractFunctionDecl>(dc)) {
23162314
options = TypeResolutionOptions(TypeResolverContext::AbstractFunctionDecl);
23172315
} else if (isa<SubscriptDecl>(dc)) {
@@ -2950,9 +2948,7 @@ ExtendedTypeRequest::evaluate(Evaluator &eval, ExtensionDecl *ext) const {
29502948
},
29512949
// FIXME: Don't let placeholder types escape type resolution.
29522950
// For now, just return the placeholder type.
2953-
[](auto &ctx, auto *originator) {
2954-
return Type();
2955-
});
2951+
PlaceholderType::get);
29562952

29572953
const auto extendedType = resolution.resolveType(extendedRepr);
29582954

lib/Sema/TypeCheckPattern.cpp

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -494,9 +494,7 @@ class ResolvePattern : public ASTVisitor<ResolvePattern,
494494
},
495495
// FIXME: Don't let placeholder types escape type resolution.
496496
// For now, just return the placeholder type.
497-
[](auto &ctx, auto *originator) {
498-
return Type();
499-
});
497+
PlaceholderType::get);
500498
const auto ty = resolution.resolveType(repr);
501499
auto *enumDecl = dyn_cast_or_null<EnumDecl>(ty->getAnyNominal());
502500
if (!enumDecl)
@@ -618,9 +616,7 @@ class ResolvePattern : public ASTVisitor<ResolvePattern,
618616
},
619617
// FIXME: Don't let placeholder types escape type resolution.
620618
// For now, just return the placeholder type.
621-
[](auto &ctx, auto *originator) {
622-
return Type();
623-
})
619+
PlaceholderType::get)
624620
.resolveType(prefixRepr);
625621
auto *enumDecl = dyn_cast_or_null<EnumDecl>(enumTy->getAnyNominal());
626622
if (!enumDecl)
@@ -830,9 +826,7 @@ Type PatternTypeRequest::evaluate(Evaluator &evaluator,
830826
};
831827
// FIXME: Don't let placeholder types escape type resolution.
832828
// For now, just return the placeholder type.
833-
placeholderHandler = [](auto &ctx, auto *originator) {
834-
return Type();
835-
};
829+
placeholderHandler = PlaceholderType::get;
836830
}
837831
return validateTypedPattern(
838832
cast<TypedPattern>(P),
@@ -900,9 +894,7 @@ Type PatternTypeRequest::evaluate(Evaluator &evaluator,
900894
};
901895
// FIXME: Don't let placeholder types escape type resolution.
902896
// For now, just return the placeholder type.
903-
placeholderHandler = [](auto &ctx, auto *originator) {
904-
return Type();
905-
};
897+
placeholderHandler = PlaceholderType::get;
906898
}
907899
TypedPattern *TP = cast<TypedPattern>(somePat->getSubPattern());
908900
const auto type = validateTypedPattern(

lib/Sema/TypeCheckType.cpp

Lines changed: 9 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1937,31 +1937,6 @@ Type ResolveTypeRequest::evaluate(Evaluator &evaluator,
19371937
if (validateAutoClosureAttributeUse(ctx.Diags, TyR, result, options))
19381938
return ErrorType::get(ctx);
19391939

1940-
// Diagnose an attempt to use a placeholder at the top level.
1941-
if (result->getCanonicalType()->is<PlaceholderType>() &&
1942-
resolution->getOptions().contains(TypeResolutionFlags::Direct)) {
1943-
if (!resolution->getOptions().contains(TypeResolutionFlags::SilenceErrors))
1944-
ctx.Diags.diagnose(loc, diag::top_level_placeholder_type);
1945-
1946-
TyR->setInvalid();
1947-
return ErrorType::get(ctx);
1948-
}
1949-
1950-
// Now that top-level placeholders have been diagnosed, replace them according
1951-
// to the user-specified handler (if it exists).
1952-
if (const auto handlerFn = resolution->getPlaceholderHandler()) {
1953-
result = result.get().transform([&](Type ty) {
1954-
if (auto *oldTy = ty->getAs<PlaceholderType>()) {
1955-
auto originator = oldTy->getOriginator();
1956-
if (auto *repr = originator.dyn_cast<PlaceholderTypeRepr *>())
1957-
if (auto newTy = handlerFn(ctx, repr))
1958-
return newTy;
1959-
}
1960-
1961-
return ty;
1962-
});
1963-
}
1964-
19651940
return result;
19661941
}
19671942

@@ -2090,21 +2065,18 @@ NeverNullType TypeResolver::resolveType(TypeRepr *repr,
20902065
options);
20912066

20922067
case TypeReprKind::Placeholder: {
2093-
if (resolution.getPlaceholderHandler())
2094-
// For now, just form a `PlaceholderType` so that we can properly diagnose
2095-
// invalid top-level placeholders. `ResolveTypeRequest::evaluate` will
2096-
// take care of substituting the placeholder based on the caller-specified
2097-
// handler.
2098-
return PlaceholderType::get(getASTContext(),
2099-
cast<PlaceholderTypeRepr>(repr));
2100-
2101-
// If there's no handler, complain if we're allowed to and bail out with an
2102-
// error.
2068+
auto &ctx = getASTContext();
2069+
// Fill in the placeholder if there's an appropriate handler.
2070+
if (const auto handlerFn = resolution.getPlaceholderHandler())
2071+
if (const auto ty = handlerFn(ctx, cast<PlaceholderTypeRepr>(repr)))
2072+
return ty;
2073+
2074+
// Complain if we're allowed to and bail out with an error.
21032075
if (!options.contains(TypeResolutionFlags::SilenceErrors))
2104-
getASTContext().Diags.diagnose(repr->getLoc(),
2076+
ctx.Diags.diagnose(repr->getLoc(),
21052077
diag::placeholder_type_not_allowed);
21062078

2107-
return ErrorType::get(getASTContext());
2079+
return ErrorType::get(resolution.getASTContext());
21082080
}
21092081

21102082
case TypeReprKind::Fixed:

lib/Sema/TypeCheckType.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -285,9 +285,7 @@ class TypeResolutionOptions {
285285
/// \returns the \c null type on failure.
286286
using OpenUnboundGenericTypeFn = llvm::function_ref<Type(UnboundGenericType *)>;
287287

288-
/// A function reference used to handle a \c PlaceholderTypeRepr. If the
289-
/// function returns a null type, then the unmodified \c PlaceholderType will be
290-
/// used.
288+
/// A function reference used to handle a PlaceholderTypeRepr.
291289
using HandlePlaceholderTypeReprFn =
292290
llvm::function_ref<Type(ASTContext &, PlaceholderTypeRepr *)>;
293291

lib/Sema/TypeChecker.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -378,9 +378,7 @@ Type swift::performTypeResolution(TypeRepr *TyR, ASTContext &Ctx,
378378
},
379379
// FIXME: Don't let placeholder types escape type resolution.
380380
// For now, just return the placeholder type.
381-
[](auto &ctx, auto *originator) {
382-
return Type();
383-
});
381+
PlaceholderType::get);
384382

385383
Optional<DiagnosticSuppression> suppression;
386384
if (!ProduceDiagnostics)

test/Constraints/diagnostics.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1137,7 +1137,7 @@ func badTypes() {
11371137
// rdar://34357545
11381138
func unresolvedTypeExistential() -> Bool {
11391139
return (Int.self==_{})
1140-
// expected-error@-1 {{placeholders are not allowed as top-level types}}
1140+
// expected-error@-1 {{type of expression is ambiguous without more context}}
11411141
}
11421142

11431143
do {

test/Sema/placeholder_type.swift

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

3-
let x: _ = 0 // expected-error {{placeholders are not allowed as top-level types}}
3+
let x: _ = 0
44
let x2 = x
55
let dict1: [_: Int] = ["hi": 0]
66
let dict2: [Character: _] = ["h": 0]
@@ -9,8 +9,8 @@ let arr = [_](repeating: "hi", count: 3)
99

1010
func foo(_ arr: [_] = [0]) {} // expected-error {{type placeholder not allowed here}}
1111

12-
let foo = _.foo // expected-error {{placeholders are not allowed as top-level types}}
13-
let zero: _ = .zero // expected-error {{placeholders are not allowed as top-level types}}
12+
let foo = _.foo // expected-error {{could not infer type for placeholder}}
13+
let zero: _ = .zero // expected-error {{cannot infer contextual base in reference to member 'zero'}}
1414

1515
struct S<T> {
1616
var x: T
@@ -48,10 +48,9 @@ func dictionary<K, V>(ofType: [K: V].Type) -> [K: V] { [:] }
4848

4949
let _: [String: _] = dictionary(ofType: [_: Int].self)
5050
let _: [_: _] = dictionary(ofType: [String: Int].self)
51-
let _: [String: Int] = dictionary(ofType: _.self) // expected-error {{placeholders are not allowed as top-level types}}
51+
let _: [String: Int] = dictionary(ofType: _.self)
5252

5353
let _: @convention(c) _ = { 0 } // expected-error {{@convention attribute only applies to function types}}
54-
// expected-error@-1 {{placeholders are not allowed as top-level types}}
5554
let _: @convention(c) (_) -> _ = { (x: Double) in 0 }
5655
let _: @convention(c) (_) -> Int = { (x: Double) in 0 }
5756

@@ -99,18 +98,18 @@ extension Bar {
9998
}
10099

101100
// FIXME: We should probably have better diagnostics for these situations--the user probably meant to use implicit member syntax
102-
let _: Int = _() // expected-error {{placeholders are not allowed as top-level types}}
103-
let _: () -> Int = { _() } // expected-error {{unable to infer closure type in the current context}} expected-error {{placeholders are not allowed as top-level types}}
104-
let _: Int = _.init() // expected-error {{placeholders are not allowed as top-level types}}
105-
let _: () -> Int = { _.init() } // expected-error {{unable to infer closure type in the current context}} expected-error {{placeholders are not allowed as top-level types}}
101+
let _: Int = _() // expected-error {{type of expression is ambiguous without more context}}
102+
let _: () -> Int = { _() } // expected-error {{unable to infer closure type in the current context}}
103+
let _: Int = _.init() // expected-error {{could not infer type for placeholder}}
104+
let _: () -> Int = { _.init() } // expected-error {{could not infer type for placeholder}}
106105

107-
func returnsInt() -> Int { _() } // expected-error {{placeholders are not allowed as top-level types}}
108-
func returnsIntClosure() -> () -> Int { { _() } } // expected-error {{unable to infer closure type in the current context}} expected-error {{placeholders are not allowed as top-level types}}
109-
func returnsInt2() -> Int { _.init() } // expected-error {{placeholders are not allowed as top-level types}}
110-
func returnsIntClosure2() -> () -> Int { { _.init() } } // expected-error {{unable to infer closure type in the current context}} expected-error {{placeholders are not allowed as top-level types}}
106+
func returnsInt() -> Int { _() } // expected-error {{type of expression is ambiguous without more context}}
107+
func returnsIntClosure() -> () -> Int { { _() } } // expected-error {{unable to infer closure type in the current context}}
108+
func returnsInt2() -> Int { _.init() } // expected-error {{could not infer type for placeholder}}
109+
func returnsIntClosure2() -> () -> Int { { _.init() } } // expected-error {{could not infer type for placeholder}}
111110

112111
let _: Int.Type = _ // expected-error {{'_' can only appear in a pattern or on the left side of an assignment}}
113-
let _: Int.Type = _.self // expected-error {{placeholders are not allowed as top-level types}}
112+
let _: Int.Type = _.self
114113

115114
struct SomeSuperLongAndComplexType {}
116115
func getSomething() -> SomeSuperLongAndComplexType? { .init() }
@@ -136,13 +135,13 @@ let _ = [_].otherStaticMember.method()
136135
func f(x: Any, arr: [Int]) {
137136
// FIXME: Better diagnostics here. Maybe we should suggest replacing placeholders with 'Any'?
138137

139-
if x is _ {} // expected-error {{placeholders are not allowed as top-level types}}
138+
if x is _ {} // expected-error {{type of expression is ambiguous without more context}}
140139
if x is [_] {} // expected-error {{type of expression is ambiguous without more context}}
141140
if x is () -> _ {} // expected-error {{type of expression is ambiguous without more context}}
142-
if let y = x as? _ {} // expected-error {{placeholders are not allowed as top-level types}}
141+
if let y = x as? _ {} // expected-error {{type of expression is ambiguous without more context}}
143142
if let y = x as? [_] {} // expected-error {{type of expression is ambiguous without more context}}
144143
if let y = x as? () -> _ {} // expected-error {{type of expression is ambiguous without more context}}
145-
let y1 = x as! _ // expected-error {{placeholders are not allowed as top-level types}}
144+
let y1 = x as! _ // expected-error {{type of expression is ambiguous without more context}}
146145
let y2 = x as! [_] // expected-error {{type of expression is ambiguous without more context}}
147146
let y3 = x as! () -> _ // expected-error {{type of expression is ambiguous without more context}}
148147

@@ -155,13 +154,13 @@ func f(x: Any, arr: [Int]) {
155154
case let y as () -> _: break // expected-error {{type placeholder not allowed here}}
156155
}
157156

158-
if arr is _ {} // expected-error {{placeholders are not allowed as top-level types}}
157+
if arr is _ {} // expected-error {{type of expression is ambiguous without more context}}
159158
if arr is [_] {} // expected-error {{type of expression is ambiguous without more context}}
160159
if arr is () -> _ {} // expected-error {{type of expression is ambiguous without more context}}
161-
if let y = arr as? _ {} // expected-error {{placeholders are not allowed as top-level types}}
160+
if let y = arr as? _ {} // expected-error {{type of expression is ambiguous without more context}}
162161
if let y = arr as? [_] {} // expected-error {{type of expression is ambiguous without more context}}
163162
if let y = arr as? () -> _ {} // expected-error {{type of expression is ambiguous without more context}}
164-
let y1 = arr as! _ // expected-error {{placeholders are not allowed as top-level types}}
163+
let y1 = arr as! _ // expected-error {{type of expression is ambiguous without more context}}
165164
let y2 = arr as! [_] // expected-error {{type of expression is ambiguous without more context}}
166165
let y3 = arr as! () -> _ // expected-error {{type of expression is ambiguous without more context}}
167166

@@ -187,12 +186,12 @@ struct Just<Output>: Publisher {
187186
struct SetFailureType<Output, Failure>: Publisher {}
188187

189188
extension Publisher {
190-
func setFailureType<T>(to: T.Type) -> SetFailureType<Output, T> {
189+
func setFailureType<T>(to: T.Type) -> SetFailureType<Output, T> { // expected-note {{in call to function 'setFailureType(to:)'}}
191190
return .init()
192191
}
193192
}
194193

195-
let _: SetFailureType<Int, String> = Just<Int>().setFailureType(to: _.self) // expected-error {{placeholders are not allowed as top-level types}}
194+
let _: SetFailureType<Int, String> = Just<Int>().setFailureType(to: _.self)
196195
let _: SetFailureType<Int, [String]> = Just<Int>().setFailureType(to: [_].self)
197196
let _: SetFailureType<Int, (String) -> Double> = Just<Int>().setFailureType(to: ((_) -> _).self)
198197
let _: SetFailureType<Int, (String, Double)> = Just<Int>().setFailureType(to: (_, _).self)
@@ -216,3 +215,5 @@ _ = (1...10)
216215
.map { (intValue, x: (_, boolValue: _)) in
217216
x.boolValue ? intValue : 0
218217
}
218+
219+
let _: SetFailureType<Int, String> = Just<Int>().setFailureType(to: _.self).setFailureType(to: String.self) // expected-error {{generic parameter 'T' could not be inferred}}

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 {{placeholders are not allowed as top-level types}}
868+
_ = _.foo // 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)