mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Merge pull request #42036 from xedin/dont-infer-from-magic-defaults
[TypeChecker] SE-0347: Avoid type inference from caller-site defaults
This commit is contained in:
@@ -7067,6 +7067,10 @@ Expr *ParamDecl::getTypeCheckedDefaultExpr() const {
|
||||
Type ParamDecl::getTypeOfDefaultExpr() const {
|
||||
auto &ctx = getASTContext();
|
||||
|
||||
// If this is a caller-side default, the type is determined based on
|
||||
// a particular call site.
|
||||
assert(!hasCallerSideDefaultExpr());
|
||||
|
||||
if (Type type = evaluateOrDefault(
|
||||
ctx.evaluator,
|
||||
DefaultArgumentTypeRequest{const_cast<ParamDecl *>(this)}, nullptr)) {
|
||||
|
||||
@@ -1782,6 +1782,11 @@ static ConstraintSystem::TypeMatchResult matchCallArguments(
|
||||
if (!PD->getInterfaceType()->hasTypeParameter())
|
||||
continue;
|
||||
|
||||
// The type of the default value is going to be determined
|
||||
// based on a type deduced for the parameter at this call site.
|
||||
if (PD->hasCallerSideDefaultExpr())
|
||||
continue;
|
||||
|
||||
auto defaultExprType = PD->getTypeOfDefaultExpr();
|
||||
|
||||
// A caller side default.
|
||||
|
||||
@@ -468,6 +468,11 @@ Type TypeChecker::typeCheckParameterDefault(Expr *&defaultValue,
|
||||
if (!ctx.TypeCheckerOpts.EnableTypeInferenceFromDefaultArguments)
|
||||
return Type();
|
||||
|
||||
// Caller-side defaults are always type-checked based on the concrete
|
||||
// type of the argument deduced at a particular call site.
|
||||
if (isa<MagicIdentifierLiteralExpr>(defaultValue))
|
||||
return Type();
|
||||
|
||||
// Parameter type doesn't have any generic parameters mentioned
|
||||
// in it, so there is nothing to infer.
|
||||
if (!paramInterfaceTy->hasTypeParameter())
|
||||
|
||||
@@ -167,3 +167,11 @@ func main() {
|
||||
takesRectangle(.init())
|
||||
// expected-error@-1 {{cannot convert default value of type 'Rectangle' to expected argument type 'Circle' for parameter #0}}
|
||||
}
|
||||
|
||||
func test_magic_defaults() {
|
||||
func with_magic(_: Int = #function) {} // expected-error {{default argument value of type 'String' cannot be converted to type 'Int'}}
|
||||
func generic_with_magic<T>(_: T = #line) -> T {} // expected-error {{default argument value of type 'Int' cannot be converted to type 'T'}}
|
||||
|
||||
let _ = with_magic()
|
||||
let _: String = generic_with_magic()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user