@@ -2810,7 +2810,8 @@ diagnoseUnviableLookupResults(MemberLookupResult &result, Type baseObjTy,
2810
2810
}
2811
2811
assert (TypeDC->isTypeContext () && " Expected type decl context!" );
2812
2812
2813
- if (TypeDC->getDeclaredTypeOfContext ()->isEqual (instanceTy)) {
2813
+ if (TypeDC->getAsNominalTypeOrNominalTypeExtensionContext () ==
2814
+ instanceTy->getAnyNominal ()) {
2814
2815
if (propertyInitializer)
2815
2816
CS->TC .diagnose (nameLoc, diag::instance_member_in_initializer,
2816
2817
memberName);
@@ -4931,6 +4932,115 @@ static bool diagnoseImplicitSelfErrors(Expr *fnExpr, Expr *argExpr,
4931
4932
return false ;
4932
4933
}
4933
4934
4935
+ // It is a somewhat common error to try to access an instance method as a
4936
+ // curried member on the type, instead of using an instance, e.g. the user
4937
+ // wrote:
4938
+ //
4939
+ // Foo.doThing(42, b: 19)
4940
+ //
4941
+ // instead of:
4942
+ //
4943
+ // myFoo.doThing(42, b: 19)
4944
+ //
4945
+ // Check for this situation and handle it gracefully.
4946
+ static bool
4947
+ diagnoseInstanceMethodAsCurriedMemberOnType (CalleeCandidateInfo &CCI,
4948
+ Expr *fnExpr, Expr *argExpr) {
4949
+ for (auto &candidate : CCI.candidates ) {
4950
+ auto argTy = candidate.getArgumentType ();
4951
+ if (!argTy)
4952
+ return false ;
4953
+
4954
+ auto *decl = candidate.getDecl ();
4955
+ if (!decl)
4956
+ return false ;
4957
+
4958
+ // If this is an exact match at the level 1 of the parameters, but
4959
+ // there is still something wrong with the expression nevertheless
4960
+ // it might be worth while to check if it's instance method as curried
4961
+ // member of type problem.
4962
+ if (CCI.closeness == CC_ExactMatch &&
4963
+ (decl->isInstanceMember () && candidate.level == 1 ))
4964
+ continue ;
4965
+
4966
+ auto params = decomposeParamType (argTy, decl, candidate.level );
4967
+ // If one of the candidates is an instance method with a single parameter
4968
+ // at the level 0, this might be viable situation for calling instance
4969
+ // method as curried member of type problem.
4970
+ if (params.size () != 1 || !decl->isInstanceMember () || candidate.level > 0 )
4971
+ return false ;
4972
+ }
4973
+
4974
+ auto &TC = CCI.CS ->TC ;
4975
+
4976
+ if (auto UDE = dyn_cast<UnresolvedDotExpr>(fnExpr)) {
4977
+ auto baseExpr = UDE->getBase ();
4978
+ auto baseType = baseExpr->getType ();
4979
+ if (auto *MT = baseType->getAs <MetatypeType>()) {
4980
+ auto DC = CCI.CS ->DC ;
4981
+ auto instanceType = MT->getInstanceType ();
4982
+
4983
+ // If the base is an implicit self type reference, and we're in a
4984
+ // an initializer, then the user wrote something like:
4985
+ //
4986
+ // class Foo { let val = initFn() }
4987
+ // or
4988
+ // class Bar { func something(x: Int = initFn()) }
4989
+ //
4990
+ // which runs in type context, not instance context. Produce a tailored
4991
+ // diagnostic since this comes up and is otherwise non-obvious what is
4992
+ // going on.
4993
+ if (baseExpr->isImplicit () && isa<Initializer>(DC)) {
4994
+ auto *TypeDC = DC->getParent ();
4995
+ bool propertyInitializer = true ;
4996
+ // If the parent context is not a type context, we expect it
4997
+ // to be a defaulted parameter in a function declaration.
4998
+ if (!TypeDC->isTypeContext ()) {
4999
+ assert (TypeDC->getContextKind () ==
5000
+ DeclContextKind::AbstractFunctionDecl &&
5001
+ " Expected function decl context for initializer!" );
5002
+ TypeDC = TypeDC->getParent ();
5003
+ propertyInitializer = false ;
5004
+ }
5005
+ assert (TypeDC->isTypeContext () && " Expected type decl context!" );
5006
+
5007
+ if (TypeDC->getAsNominalTypeOrNominalTypeExtensionContext () ==
5008
+ instanceType->getAnyNominal ()) {
5009
+ if (propertyInitializer)
5010
+ TC.diagnose (UDE->getLoc (), diag::instance_member_in_initializer,
5011
+ UDE->getName ());
5012
+ else
5013
+ TC.diagnose (UDE->getLoc (),
5014
+ diag::instance_member_in_default_parameter,
5015
+ UDE->getName ());
5016
+ return true ;
5017
+ }
5018
+ }
5019
+
5020
+ // If this is a situation like this `self.foo(A())()` and self != A
5021
+ // let's say that `self` is not convertible to A.
5022
+ if (auto nominalType = argExpr->getType ()->getAs <NominalType>()) {
5023
+ if (!instanceType->isEqual (nominalType)) {
5024
+ TC.diagnose (argExpr->getStartLoc (), diag::types_not_convertible,
5025
+ false , nominalType, instanceType);
5026
+ return true ;
5027
+ }
5028
+ }
5029
+
5030
+ // Otherwise, complain about use of instance value on type.
5031
+ auto diagnostic = isa<TypeExpr>(baseExpr)
5032
+ ? diag::instance_member_use_on_type
5033
+ : diag::could_not_use_instance_member_on_type;
5034
+
5035
+ TC.diagnose (UDE->getLoc (), diagnostic, instanceType, UDE->getName ())
5036
+ .highlight (baseExpr->getSourceRange ());
5037
+ return true ;
5038
+ }
5039
+ }
5040
+
5041
+ return false ;
5042
+ }
5043
+
4934
5044
// / Emit a class of diagnostics that we only know how to generate when there is
4935
5045
// / exactly one candidate we know about. Return true if an error is emitted.
4936
5046
static bool diagnoseSingleCandidateFailures (CalleeCandidateInfo &CCI,
@@ -4949,69 +5059,6 @@ static bool diagnoseSingleCandidateFailures(CalleeCandidateInfo &CCI,
4949
5059
auto params = decomposeParamType (argTy, candidate.getDecl (), candidate.level );
4950
5060
auto args = decomposeArgType (argExpr->getType (), argLabels);
4951
5061
4952
- // It is a somewhat common error to try to access an instance method as a
4953
- // curried member on the type, instead of using an instance, e.g. the user
4954
- // wrote:
4955
- //
4956
- // Foo.doThing(42, b: 19)
4957
- //
4958
- // instead of:
4959
- //
4960
- // myFoo.doThing(42, b: 19)
4961
- //
4962
- // Check for this situation and handle it gracefully.
4963
- if (params.size () == 1 && candidate.getDecl () &&
4964
- candidate.getDecl ()->isInstanceMember () &&
4965
- candidate.level == 0 ) {
4966
- if (auto UDE = dyn_cast<UnresolvedDotExpr>(fnExpr))
4967
- if (isa<TypeExpr>(UDE->getBase ())) {
4968
- auto baseType = candidate.getArgumentType ();
4969
- auto DC = CCI.CS ->DC ;
4970
-
4971
- // If the base is an implicit self type reference, and we're in a
4972
- // an initializer, then the user wrote something like:
4973
- //
4974
- // class Foo { let val = initFn() }
4975
- // or
4976
- // class Bar { func something(x: Int = initFn()) }
4977
- //
4978
- // which runs in type context, not instance context. Produce a tailored
4979
- // diagnostic since this comes up and is otherwise non-obvious what is
4980
- // going on.
4981
- if (UDE->getBase ()->isImplicit () && isa<Initializer>(DC)) {
4982
- auto *TypeDC = DC->getParent ();
4983
- bool propertyInitializer = true ;
4984
- // If the parent context is not a type context, we expect it
4985
- // to be a defaulted parameter in a function declaration.
4986
- if (!TypeDC->isTypeContext ()) {
4987
- assert (TypeDC->getContextKind () ==
4988
- DeclContextKind::AbstractFunctionDecl &&
4989
- " Expected function decl context for initializer!" );
4990
- TypeDC = TypeDC->getParent ();
4991
- propertyInitializer = false ;
4992
- }
4993
- assert (TypeDC->isTypeContext () && " Expected type decl context!" );
4994
-
4995
- if (TypeDC->getDeclaredTypeOfContext ()->isEqual (baseType)) {
4996
- if (propertyInitializer)
4997
- TC.diagnose (UDE->getLoc (), diag::instance_member_in_initializer,
4998
- UDE->getName ());
4999
- else
5000
- TC.diagnose (UDE->getLoc (),
5001
- diag::instance_member_in_default_parameter,
5002
- UDE->getName ());
5003
- return true ;
5004
- }
5005
- }
5006
-
5007
- // Otherwise, complain about use of instance value on type.
5008
- TC.diagnose (UDE->getLoc (), diag::instance_member_use_on_type,
5009
- baseType, UDE->getName ())
5010
- .highlight (UDE->getBase ()->getSourceRange ());
5011
- return true ;
5012
- }
5013
- }
5014
-
5015
5062
// Check the case where a raw-representable type is constructed from an
5016
5063
// argument with the same type:
5017
5064
//
@@ -5353,6 +5400,9 @@ bool FailureDiagnosis::diagnoseParameterErrors(CalleeCandidateInfo &CCI,
5353
5400
if (diagnoseImplicitSelfErrors (fnExpr, argExpr, CCI, argLabels, CS))
5354
5401
return true ;
5355
5402
5403
+ if (diagnoseInstanceMethodAsCurriedMemberOnType (CCI, fnExpr, argExpr))
5404
+ return true ;
5405
+
5356
5406
// Do all the stuff that we only have implemented when there is a single
5357
5407
// candidate.
5358
5408
if (diagnoseSingleCandidateFailures (CCI, fnExpr, argExpr, argLabels))
0 commit comments