@@ -2306,18 +2306,48 @@ diagnoseUnviableLookupResults(MemberLookupResult &result, Type baseObjTy,
2306
2306
return ;
2307
2307
case MemberLookupResult::UR_InstanceMemberOnType:
2308
2308
// If the base is an implicit self type reference, and we're in a
2309
- // property initializer, then the user wrote something like:
2309
+ // an initializer, then the user wrote something like:
2310
2310
//
2311
2311
// class Foo { let x = 1, y = x }
2312
2312
//
2313
- // which runs in type context, not instance context. Produce a tailored
2314
- // diagnostic since this comes up and is otherwise non-obvious what is
2315
- // going on.
2316
- if (baseExpr && baseExpr->isImplicit () && isa<Initializer>(CS->DC ) &&
2317
- CS->DC ->getParent ()->getDeclaredTypeOfContext ()->isEqual (instanceTy)){
2318
- CS->TC .diagnose (nameLoc, diag::instance_member_in_initializer,
2319
- memberName);
2320
- return ;
2313
+ // which runs in type context, not instance context, or
2314
+ //
2315
+ // class Bar {
2316
+ // let otherwise = 1 // instance member
2317
+ // var x: Int
2318
+ // func init(x: Int =otherwise) { // default parameter
2319
+ // self.x = x
2320
+ // }
2321
+ // }
2322
+ //
2323
+ // in which an instance member is used as a default value for a
2324
+ // parameter.
2325
+ //
2326
+ // Produce a tailored diagnostic for these cases since this
2327
+ // comes up and is otherwise non-obvious what is going on.
2328
+ if (baseExpr && baseExpr->isImplicit () && isa<Initializer>(CS->DC )) {
2329
+ auto *TypeDC = CS->DC ->getParent ();
2330
+ bool propertyInitializer = true ;
2331
+ // If the parent context is not a type context, we expect it
2332
+ // to be a defaulted parameter in a function declaration.
2333
+ if (!TypeDC->isTypeContext ()) {
2334
+ assert (TypeDC->getContextKind () ==
2335
+ DeclContextKind::AbstractFunctionDecl &&
2336
+ " Expected function decl context for initializer!" );
2337
+ TypeDC = TypeDC->getParent ();
2338
+ propertyInitializer = false ;
2339
+ }
2340
+ assert (TypeDC->isTypeContext () && " Expected type decl context!" );
2341
+
2342
+ if (TypeDC->getDeclaredTypeOfContext ()->isEqual (instanceTy)) {
2343
+ if (propertyInitializer)
2344
+ CS->TC .diagnose (nameLoc, diag::instance_member_in_initializer,
2345
+ memberName);
2346
+ else
2347
+ CS->TC .diagnose (nameLoc, diag::instance_member_in_default_parameter,
2348
+ memberName);
2349
+ return ;
2350
+ }
2321
2351
}
2322
2352
2323
2353
diagnose (loc, diag::could_not_use_instance_member_on_type,
@@ -4006,18 +4036,39 @@ static bool diagnoseSingleCandidateFailures(CalleeCandidateInfo &CCI,
4006
4036
auto DC = CCI.CS ->DC ;
4007
4037
4008
4038
// If the base is an implicit self type reference, and we're in a
4009
- // property initializer, then the user wrote something like:
4039
+ // an initializer, then the user wrote something like:
4010
4040
//
4011
4041
// class Foo { let val = initFn() }
4042
+ // or
4043
+ // class Bar { func something(x: Int = initFn()) }
4012
4044
//
4013
4045
// which runs in type context, not instance context. Produce a tailored
4014
4046
// diagnostic since this comes up and is otherwise non-obvious what is
4015
4047
// going on.
4016
- if (UDE->getBase ()->isImplicit () && isa<Initializer>(DC) &&
4017
- DC->getParent ()->getDeclaredTypeOfContext ()->isEqual (baseType)){
4018
- TC.diagnose (UDE->getLoc (), diag::instance_member_in_initializer,
4048
+ if (UDE->getBase ()->isImplicit () && isa<Initializer>(DC)) {
4049
+ auto *TypeDC = DC->getParent ();
4050
+ bool propertyInitializer = true ;
4051
+ // If the parent context is not a type context, we expect it
4052
+ // to be a defaulted parameter in a function declaration.
4053
+ if (!TypeDC->isTypeContext ()) {
4054
+ assert (TypeDC->getContextKind () ==
4055
+ DeclContextKind::AbstractFunctionDecl &&
4056
+ " Expected function decl context for initializer!" );
4057
+ TypeDC = TypeDC->getParent ();
4058
+ propertyInitializer = false ;
4059
+ }
4060
+ assert (TypeDC->isTypeContext () && " Expected type decl context!" );
4061
+
4062
+ if (TypeDC->getDeclaredTypeOfContext ()->isEqual (baseType)) {
4063
+ if (propertyInitializer)
4064
+ TC.diagnose (UDE->getLoc (), diag::instance_member_in_initializer,
4019
4065
UDE->getName ());
4020
- return true ;
4066
+ else
4067
+ TC.diagnose (UDE->getLoc (),
4068
+ diag::instance_member_in_default_parameter,
4069
+ UDE->getName ());
4070
+ return true ;
4071
+ }
4021
4072
}
4022
4073
4023
4074
// Otherwise, complain about use of instance value on type.
0 commit comments