@@ -2303,18 +2303,48 @@ diagnoseUnviableLookupResults(MemberLookupResult &result, Type baseObjTy,
2303
2303
return ;
2304
2304
case MemberLookupResult::UR_InstanceMemberOnType:
2305
2305
// If the base is an implicit self type reference, and we're in a
2306
- // property initializer, then the user wrote something like:
2306
+ // an initializer, then the user wrote something like:
2307
2307
//
2308
2308
// class Foo { let x = 1, y = x }
2309
2309
//
2310
- // which runs in type context, not instance context. Produce a tailored
2311
- // diagnostic since this comes up and is otherwise non-obvious what is
2312
- // going on.
2313
- if (baseExpr && baseExpr->isImplicit () && isa<Initializer>(CS->DC ) &&
2314
- CS->DC ->getParent ()->getDeclaredTypeOfContext ()->isEqual (instanceTy)){
2315
- CS->TC .diagnose (nameLoc, diag::instance_member_in_initializer,
2316
- memberName);
2317
- return ;
2310
+ // which runs in type context, not instance context, or
2311
+ //
2312
+ // class Bar {
2313
+ // let otherwise = 1 // instance member
2314
+ // var x: Int
2315
+ // func init(x: Int =otherwise) { // default parameter
2316
+ // self.x = x
2317
+ // }
2318
+ // }
2319
+ //
2320
+ // in which an instance member is used as a default value for a
2321
+ // parameter.
2322
+ //
2323
+ // Produce a tailored diagnostic for these cases since this
2324
+ // comes up and is otherwise non-obvious what is going on.
2325
+ if (baseExpr && baseExpr->isImplicit () && isa<Initializer>(CS->DC )) {
2326
+ auto *TypeDC = CS->DC ->getParent ();
2327
+ bool propertyInitializer = true ;
2328
+ // If the parent context is not a type context, we expect it
2329
+ // to be a defaulted parameter in a function declaration.
2330
+ if (!TypeDC->isTypeContext ()) {
2331
+ assert (TypeDC->getContextKind () ==
2332
+ DeclContextKind::AbstractFunctionDecl &&
2333
+ " Expected function decl context for initializer!" );
2334
+ TypeDC = TypeDC->getParent ();
2335
+ propertyInitializer = false ;
2336
+ }
2337
+ assert (TypeDC->isTypeContext () && " Expected type decl context!" );
2338
+
2339
+ if (TypeDC->getDeclaredTypeOfContext ()->isEqual (instanceTy)) {
2340
+ if (propertyInitializer)
2341
+ CS->TC .diagnose (nameLoc, diag::instance_member_in_initializer,
2342
+ memberName);
2343
+ else
2344
+ CS->TC .diagnose (nameLoc, diag::instance_member_in_default_parameter,
2345
+ memberName);
2346
+ return ;
2347
+ }
2318
2348
}
2319
2349
2320
2350
diagnose (loc, diag::could_not_use_instance_member_on_type,
@@ -3963,18 +3993,39 @@ static bool diagnoseSingleCandidateFailures(CalleeCandidateInfo &CCI,
3963
3993
auto DC = CCI.CS ->DC ;
3964
3994
3965
3995
// If the base is an implicit self type reference, and we're in a
3966
- // property initializer, then the user wrote something like:
3996
+ // an initializer, then the user wrote something like:
3967
3997
//
3968
3998
// class Foo { let val = initFn() }
3999
+ // or
4000
+ // class Bar { func something(x: Int = initFn()) }
3969
4001
//
3970
4002
// which runs in type context, not instance context. Produce a tailored
3971
4003
// diagnostic since this comes up and is otherwise non-obvious what is
3972
4004
// going on.
3973
- if (UDE->getBase ()->isImplicit () && isa<Initializer>(DC) &&
3974
- DC->getParent ()->getDeclaredTypeOfContext ()->isEqual (baseType)){
3975
- TC.diagnose (UDE->getLoc (), diag::instance_member_in_initializer,
4005
+ if (UDE->getBase ()->isImplicit () && isa<Initializer>(DC)) {
4006
+ auto *TypeDC = DC->getParent ();
4007
+ bool propertyInitializer = true ;
4008
+ // If the parent context is not a type context, we expect it
4009
+ // to be a defaulted parameter in a function declaration.
4010
+ if (!TypeDC->isTypeContext ()) {
4011
+ assert (TypeDC->getContextKind () ==
4012
+ DeclContextKind::AbstractFunctionDecl &&
4013
+ " Expected function decl context for initializer!" );
4014
+ TypeDC = TypeDC->getParent ();
4015
+ propertyInitializer = false ;
4016
+ }
4017
+ assert (TypeDC->isTypeContext () && " Expected type decl context!" );
4018
+
4019
+ if (TypeDC->getDeclaredTypeOfContext ()->isEqual (baseType)) {
4020
+ if (propertyInitializer)
4021
+ TC.diagnose (UDE->getLoc (), diag::instance_member_in_initializer,
3976
4022
UDE->getName ());
3977
- return true ;
4023
+ else
4024
+ TC.diagnose (UDE->getLoc (),
4025
+ diag::instance_member_in_default_parameter,
4026
+ UDE->getName ());
4027
+ return true ;
4028
+ }
3978
4029
}
3979
4030
3980
4031
// Otherwise, complain about use of instance value on type.
0 commit comments