Skip to content

Commit 53617f0

Browse files
authored
Merge pull request #42036 from xedin/dont-infer-from-magic-defaults
[TypeChecker] SE-0347: Avoid type inference from caller-site defaults
2 parents 12095cb + 5b9b497 commit 53617f0

File tree

4 files changed

+22
-0
lines changed

4 files changed

+22
-0
lines changed

lib/AST/Decl.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7067,6 +7067,10 @@ Expr *ParamDecl::getTypeCheckedDefaultExpr() const {
70677067
Type ParamDecl::getTypeOfDefaultExpr() const {
70687068
auto &ctx = getASTContext();
70697069

7070+
// If this is a caller-side default, the type is determined based on
7071+
// a particular call site.
7072+
assert(!hasCallerSideDefaultExpr());
7073+
70707074
if (Type type = evaluateOrDefault(
70717075
ctx.evaluator,
70727076
DefaultArgumentTypeRequest{const_cast<ParamDecl *>(this)}, nullptr)) {

lib/Sema/CSSimplify.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1782,6 +1782,11 @@ static ConstraintSystem::TypeMatchResult matchCallArguments(
17821782
if (!PD->getInterfaceType()->hasTypeParameter())
17831783
continue;
17841784

1785+
// The type of the default value is going to be determined
1786+
// based on a type deduced for the parameter at this call site.
1787+
if (PD->hasCallerSideDefaultExpr())
1788+
continue;
1789+
17851790
auto defaultExprType = PD->getTypeOfDefaultExpr();
17861791

17871792
// A caller side default.

lib/Sema/TypeCheckConstraints.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,11 @@ Type TypeChecker::typeCheckParameterDefault(Expr *&defaultValue,
468468
if (!ctx.TypeCheckerOpts.EnableTypeInferenceFromDefaultArguments)
469469
return Type();
470470

471+
// Caller-side defaults are always type-checked based on the concrete
472+
// type of the argument deduced at a particular call site.
473+
if (isa<MagicIdentifierLiteralExpr>(defaultValue))
474+
return Type();
475+
471476
// Parameter type doesn't have any generic parameters mentioned
472477
// in it, so there is nothing to infer.
473478
if (!paramInterfaceTy->hasTypeParameter())

test/Constraints/type_inference_from_default_exprs.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,3 +167,11 @@ func main() {
167167
takesRectangle(.init())
168168
// expected-error@-1 {{cannot convert default value of type 'Rectangle' to expected argument type 'Circle' for parameter #0}}
169169
}
170+
171+
func test_magic_defaults() {
172+
func with_magic(_: Int = #function) {} // expected-error {{default argument value of type 'String' cannot be converted to type 'Int'}}
173+
func generic_with_magic<T>(_: T = #line) -> T {} // expected-error {{default argument value of type 'Int' cannot be converted to type 'T'}}
174+
175+
let _ = with_magic()
176+
let _: String = generic_with_magic()
177+
}

0 commit comments

Comments
 (0)