Revert "[Sema] Diagnose and reject top-level placeholders"

This reverts commit f6b6bff6de.
This commit is contained in:
Robert Widmann
2021-10-06 13:25:32 -07:00
parent dd984b14f7
commit 22ad19f64b
10 changed files with 43 additions and 92 deletions

View File

@@ -3624,8 +3624,6 @@ ERROR(cannot_force_unwrap_nil_literal,none,
ERROR(could_not_infer_placeholder,none,
"could not infer type for placeholder", ())
ERROR(top_level_placeholder_type,none,
"placeholders are not allowed as top-level types", ())
ERROR(type_of_expression_is_ambiguous,none,
"type of expression is ambiguous without more context", ())

View File

@@ -1506,9 +1506,7 @@ TypeExpr *PreCheckExpression::simplifyNestedTypeExpr(UnresolvedDotExpr *UDE) {
},
// FIXME: Don't let placeholder types escape type resolution.
// For now, just return the placeholder type.
[](auto &ctx, auto *originator) {
return Type();
});
PlaceholderType::get);
const auto BaseTy = resolution.resolveType(InnerTypeRepr);
if (BaseTy->mayHaveMembers()) {
@@ -2061,9 +2059,7 @@ Expr *PreCheckExpression::simplifyTypeConstructionWithLiteralArg(Expr *E) {
},
// FIXME: Don't let placeholder types escape type resolution.
// For now, just return the placeholder type.
[](auto &ctx, auto *originator) {
return Type();
});
PlaceholderType::get);
const auto result = resolution.resolveType(typeExpr->getTypeRepr());
if (result->hasError())
return nullptr;

View File

@@ -2309,9 +2309,7 @@ static Type validateParameterType(ParamDecl *decl) {
};
// FIXME: Don't let placeholder types escape type resolution.
// For now, just return the placeholder type.
placeholderHandler = [](auto &ctx, auto *originator) {
return Type();
};
placeholderHandler = PlaceholderType::get;
} else if (isa<AbstractFunctionDecl>(dc)) {
options = TypeResolutionOptions(TypeResolverContext::AbstractFunctionDecl);
} else if (isa<SubscriptDecl>(dc)) {
@@ -2950,9 +2948,7 @@ ExtendedTypeRequest::evaluate(Evaluator &eval, ExtensionDecl *ext) const {
},
// FIXME: Don't let placeholder types escape type resolution.
// For now, just return the placeholder type.
[](auto &ctx, auto *originator) {
return Type();
});
PlaceholderType::get);
const auto extendedType = resolution.resolveType(extendedRepr);

View File

@@ -494,9 +494,7 @@ public:
},
// FIXME: Don't let placeholder types escape type resolution.
// For now, just return the placeholder type.
[](auto &ctx, auto *originator) {
return Type();
});
PlaceholderType::get);
const auto ty = resolution.resolveType(repr);
auto *enumDecl = dyn_cast_or_null<EnumDecl>(ty->getAnyNominal());
if (!enumDecl)
@@ -618,9 +616,7 @@ public:
},
// FIXME: Don't let placeholder types escape type resolution.
// For now, just return the placeholder type.
[](auto &ctx, auto *originator) {
return Type();
})
PlaceholderType::get)
.resolveType(prefixRepr);
auto *enumDecl = dyn_cast_or_null<EnumDecl>(enumTy->getAnyNominal());
if (!enumDecl)
@@ -830,9 +826,7 @@ Type PatternTypeRequest::evaluate(Evaluator &evaluator,
};
// FIXME: Don't let placeholder types escape type resolution.
// For now, just return the placeholder type.
placeholderHandler = [](auto &ctx, auto *originator) {
return Type();
};
placeholderHandler = PlaceholderType::get;
}
return validateTypedPattern(
cast<TypedPattern>(P),
@@ -900,9 +894,7 @@ Type PatternTypeRequest::evaluate(Evaluator &evaluator,
};
// FIXME: Don't let placeholder types escape type resolution.
// For now, just return the placeholder type.
placeholderHandler = [](auto &ctx, auto *originator) {
return Type();
};
placeholderHandler = PlaceholderType::get;
}
TypedPattern *TP = cast<TypedPattern>(somePat->getSubPattern());
const auto type = validateTypedPattern(

View File

@@ -1937,31 +1937,6 @@ Type ResolveTypeRequest::evaluate(Evaluator &evaluator,
if (validateAutoClosureAttributeUse(ctx.Diags, TyR, result, options))
return ErrorType::get(ctx);
// Diagnose an attempt to use a placeholder at the top level.
if (result->getCanonicalType()->is<PlaceholderType>() &&
resolution->getOptions().contains(TypeResolutionFlags::Direct)) {
if (!resolution->getOptions().contains(TypeResolutionFlags::SilenceErrors))
ctx.Diags.diagnose(loc, diag::top_level_placeholder_type);
TyR->setInvalid();
return ErrorType::get(ctx);
}
// Now that top-level placeholders have been diagnosed, replace them according
// to the user-specified handler (if it exists).
if (const auto handlerFn = resolution->getPlaceholderHandler()) {
result = result.get().transform([&](Type ty) {
if (auto *oldTy = ty->getAs<PlaceholderType>()) {
auto originator = oldTy->getOriginator();
if (auto *repr = originator.dyn_cast<PlaceholderTypeRepr *>())
if (auto newTy = handlerFn(ctx, repr))
return newTy;
}
return ty;
});
}
return result;
}
@@ -2090,21 +2065,18 @@ NeverNullType TypeResolver::resolveType(TypeRepr *repr,
options);
case TypeReprKind::Placeholder: {
if (resolution.getPlaceholderHandler())
// For now, just form a `PlaceholderType` so that we can properly diagnose
// invalid top-level placeholders. `ResolveTypeRequest::evaluate` will
// take care of substituting the placeholder based on the caller-specified
// handler.
return PlaceholderType::get(getASTContext(),
cast<PlaceholderTypeRepr>(repr));
auto &ctx = getASTContext();
// Fill in the placeholder if there's an appropriate handler.
if (const auto handlerFn = resolution.getPlaceholderHandler())
if (const auto ty = handlerFn(ctx, cast<PlaceholderTypeRepr>(repr)))
return ty;
// If there's no handler, complain if we're allowed to and bail out with an
// error.
// Complain if we're allowed to and bail out with an error.
if (!options.contains(TypeResolutionFlags::SilenceErrors))
getASTContext().Diags.diagnose(repr->getLoc(),
ctx.Diags.diagnose(repr->getLoc(),
diag::placeholder_type_not_allowed);
return ErrorType::get(getASTContext());
return ErrorType::get(resolution.getASTContext());
}
case TypeReprKind::Fixed:

View File

@@ -285,9 +285,7 @@ public:
/// \returns the \c null type on failure.
using OpenUnboundGenericTypeFn = llvm::function_ref<Type(UnboundGenericType *)>;
/// A function reference used to handle a \c PlaceholderTypeRepr. If the
/// function returns a null type, then the unmodified \c PlaceholderType will be
/// used.
/// A function reference used to handle a PlaceholderTypeRepr.
using HandlePlaceholderTypeReprFn =
llvm::function_ref<Type(ASTContext &, PlaceholderTypeRepr *)>;

View File

@@ -378,9 +378,7 @@ Type swift::performTypeResolution(TypeRepr *TyR, ASTContext &Ctx,
},
// FIXME: Don't let placeholder types escape type resolution.
// For now, just return the placeholder type.
[](auto &ctx, auto *originator) {
return Type();
});
PlaceholderType::get);
Optional<DiagnosticSuppression> suppression;
if (!ProduceDiagnostics)

View File

@@ -1137,7 +1137,7 @@ func badTypes() {
// rdar://34357545
func unresolvedTypeExistential() -> Bool {
return (Int.self==_{})
// expected-error@-1 {{placeholders are not allowed as top-level types}}
// expected-error@-1 {{type of expression is ambiguous without more context}}
}
do {

View File

@@ -1,6 +1,6 @@
// RUN: %target-typecheck-verify-swift
let x: _ = 0 // expected-error {{placeholders are not allowed as top-level types}}
let x: _ = 0
let x2 = x
let dict1: [_: Int] = ["hi": 0]
let dict2: [Character: _] = ["h": 0]
@@ -9,8 +9,8 @@ let arr = [_](repeating: "hi", count: 3)
func foo(_ arr: [_] = [0]) {} // expected-error {{type placeholder not allowed here}}
let foo = _.foo // expected-error {{placeholders are not allowed as top-level types}}
let zero: _ = .zero // expected-error {{placeholders are not allowed as top-level types}}
let foo = _.foo // expected-error {{could not infer type for placeholder}}
let zero: _ = .zero // expected-error {{cannot infer contextual base in reference to member 'zero'}}
struct S<T> {
var x: T
@@ -48,10 +48,9 @@ func dictionary<K, V>(ofType: [K: V].Type) -> [K: V] { [:] }
let _: [String: _] = dictionary(ofType: [_: Int].self)
let _: [_: _] = dictionary(ofType: [String: Int].self)
let _: [String: Int] = dictionary(ofType: _.self) // expected-error {{placeholders are not allowed as top-level types}}
let _: [String: Int] = dictionary(ofType: _.self)
let _: @convention(c) _ = { 0 } // expected-error {{@convention attribute only applies to function types}}
// expected-error@-1 {{placeholders are not allowed as top-level types}}
let _: @convention(c) (_) -> _ = { (x: Double) in 0 }
let _: @convention(c) (_) -> Int = { (x: Double) in 0 }
@@ -99,18 +98,18 @@ extension Bar {
}
// FIXME: We should probably have better diagnostics for these situations--the user probably meant to use implicit member syntax
let _: Int = _() // expected-error {{placeholders are not allowed as top-level types}}
let _: () -> Int = { _() } // expected-error {{unable to infer closure type in the current context}} expected-error {{placeholders are not allowed as top-level types}}
let _: Int = _.init() // expected-error {{placeholders are not allowed as top-level types}}
let _: () -> Int = { _.init() } // expected-error {{unable to infer closure type in the current context}} expected-error {{placeholders are not allowed as top-level types}}
let _: Int = _() // expected-error {{type of expression is ambiguous without more context}}
let _: () -> Int = { _() } // expected-error {{unable to infer closure type in the current context}}
let _: Int = _.init() // expected-error {{could not infer type for placeholder}}
let _: () -> Int = { _.init() } // expected-error {{could not infer type for placeholder}}
func returnsInt() -> Int { _() } // expected-error {{placeholders are not allowed as top-level types}}
func returnsIntClosure() -> () -> Int { { _() } } // expected-error {{unable to infer closure type in the current context}} expected-error {{placeholders are not allowed as top-level types}}
func returnsInt2() -> Int { _.init() } // expected-error {{placeholders are not allowed as top-level types}}
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}}
func returnsInt() -> Int { _() } // expected-error {{type of expression is ambiguous without more context}}
func returnsIntClosure() -> () -> Int { { _() } } // expected-error {{unable to infer closure type in the current context}}
func returnsInt2() -> Int { _.init() } // expected-error {{could not infer type for placeholder}}
func returnsIntClosure2() -> () -> Int { { _.init() } } // expected-error {{could not infer type for placeholder}}
let _: Int.Type = _ // expected-error {{'_' can only appear in a pattern or on the left side of an assignment}}
let _: Int.Type = _.self // expected-error {{placeholders are not allowed as top-level types}}
let _: Int.Type = _.self
struct SomeSuperLongAndComplexType {}
func getSomething() -> SomeSuperLongAndComplexType? { .init() }
@@ -136,13 +135,13 @@ let _ = [_].otherStaticMember.method()
func f(x: Any, arr: [Int]) {
// FIXME: Better diagnostics here. Maybe we should suggest replacing placeholders with 'Any'?
if x is _ {} // expected-error {{placeholders are not allowed as top-level types}}
if x is _ {} // expected-error {{type of expression is ambiguous without more context}}
if x is [_] {} // expected-error {{type of expression is ambiguous without more context}}
if x is () -> _ {} // expected-error {{type of expression is ambiguous without more context}}
if let y = x as? _ {} // expected-error {{placeholders are not allowed as top-level types}}
if let y = x as? _ {} // expected-error {{type of expression is ambiguous without more context}}
if let y = x as? [_] {} // expected-error {{type of expression is ambiguous without more context}}
if let y = x as? () -> _ {} // expected-error {{type of expression is ambiguous without more context}}
let y1 = x as! _ // expected-error {{placeholders are not allowed as top-level types}}
let y1 = x as! _ // expected-error {{type of expression is ambiguous without more context}}
let y2 = x as! [_] // expected-error {{type of expression is ambiguous without more context}}
let y3 = x as! () -> _ // expected-error {{type of expression is ambiguous without more context}}
@@ -155,13 +154,13 @@ func f(x: Any, arr: [Int]) {
case let y as () -> _: break // expected-error {{type placeholder not allowed here}}
}
if arr is _ {} // expected-error {{placeholders are not allowed as top-level types}}
if arr is _ {} // expected-error {{type of expression is ambiguous without more context}}
if arr is [_] {} // expected-error {{type of expression is ambiguous without more context}}
if arr is () -> _ {} // expected-error {{type of expression is ambiguous without more context}}
if let y = arr as? _ {} // expected-error {{placeholders are not allowed as top-level types}}
if let y = arr as? _ {} // expected-error {{type of expression is ambiguous without more context}}
if let y = arr as? [_] {} // expected-error {{type of expression is ambiguous without more context}}
if let y = arr as? () -> _ {} // expected-error {{type of expression is ambiguous without more context}}
let y1 = arr as! _ // expected-error {{placeholders are not allowed as top-level types}}
let y1 = arr as! _ // expected-error {{type of expression is ambiguous without more context}}
let y2 = arr as! [_] // expected-error {{type of expression is ambiguous without more context}}
let y3 = arr as! () -> _ // expected-error {{type of expression is ambiguous without more context}}
@@ -187,12 +186,12 @@ struct Just<Output>: Publisher {
struct SetFailureType<Output, Failure>: Publisher {}
extension Publisher {
func setFailureType<T>(to: T.Type) -> SetFailureType<Output, T> {
func setFailureType<T>(to: T.Type) -> SetFailureType<Output, T> { // expected-note {{in call to function 'setFailureType(to:)'}}
return .init()
}
}
let _: SetFailureType<Int, String> = Just<Int>().setFailureType(to: _.self) // expected-error {{placeholders are not allowed as top-level types}}
let _: SetFailureType<Int, String> = Just<Int>().setFailureType(to: _.self)
let _: SetFailureType<Int, [String]> = Just<Int>().setFailureType(to: [_].self)
let _: SetFailureType<Int, (String) -> Double> = Just<Int>().setFailureType(to: ((_) -> _).self)
let _: SetFailureType<Int, (String, Double)> = Just<Int>().setFailureType(to: (_, _).self)
@@ -216,3 +215,5 @@ _ = (1...10)
.map { (intValue, x: (_, boolValue: _)) in
x.boolValue ? intValue : 0
}
let _: SetFailureType<Int, String> = Just<Int>().setFailureType(to: _.self).setFailureType(to: String.self) // expected-error {{generic parameter 'T' could not be inferred}}

View File

@@ -865,7 +865,7 @@ func r20802757(_ z: inout Int = &g20802757) { // expected-error {{cannot provide
print(z)
}
_ = _.foo // expected-error {{placeholders are not allowed as top-level types}}
_ = _.foo // expected-error {{could not infer type for placeholder}}
// <rdar://problem/22211854> wrong arg list crashing sourcekit
func r22211854() {