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 {
|
Type ParamDecl::getTypeOfDefaultExpr() const {
|
||||||
auto &ctx = getASTContext();
|
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(
|
if (Type type = evaluateOrDefault(
|
||||||
ctx.evaluator,
|
ctx.evaluator,
|
||||||
DefaultArgumentTypeRequest{const_cast<ParamDecl *>(this)}, nullptr)) {
|
DefaultArgumentTypeRequest{const_cast<ParamDecl *>(this)}, nullptr)) {
|
||||||
|
|||||||
@@ -1782,6 +1782,11 @@ static ConstraintSystem::TypeMatchResult matchCallArguments(
|
|||||||
if (!PD->getInterfaceType()->hasTypeParameter())
|
if (!PD->getInterfaceType()->hasTypeParameter())
|
||||||
continue;
|
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();
|
auto defaultExprType = PD->getTypeOfDefaultExpr();
|
||||||
|
|
||||||
// A caller side default.
|
// A caller side default.
|
||||||
|
|||||||
@@ -468,6 +468,11 @@ Type TypeChecker::typeCheckParameterDefault(Expr *&defaultValue,
|
|||||||
if (!ctx.TypeCheckerOpts.EnableTypeInferenceFromDefaultArguments)
|
if (!ctx.TypeCheckerOpts.EnableTypeInferenceFromDefaultArguments)
|
||||||
return Type();
|
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
|
// Parameter type doesn't have any generic parameters mentioned
|
||||||
// in it, so there is nothing to infer.
|
// in it, so there is nothing to infer.
|
||||||
if (!paramInterfaceTy->hasTypeParameter())
|
if (!paramInterfaceTy->hasTypeParameter())
|
||||||
|
|||||||
@@ -167,3 +167,11 @@ func main() {
|
|||||||
takesRectangle(.init())
|
takesRectangle(.init())
|
||||||
// expected-error@-1 {{cannot convert default value of type 'Rectangle' to expected argument type 'Circle' for parameter #0}}
|
// 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