@@ -511,14 +511,6 @@ class FailureDiagnosis :public ASTVisitor<FailureDiagnosis, /*exprresult*/bool>{
511
511
// / Produce a diagnostic for a general member-lookup failure (irrespective of
512
512
// / the exact expression kind).
513
513
bool diagnoseGeneralMemberFailure (Constraint *constraint);
514
-
515
- // / Diagnose the lookup of a static member or enum element as instance member.
516
- void diagnoseTypeMemberOnInstanceLookup (Type baseObjTy,
517
- Expr *baseExpr,
518
- DeclName memberName,
519
- DeclNameLoc nameLoc,
520
- ValueDecl *member,
521
- SourceLoc loc);
522
514
523
515
// / Given a result of name lookup that had no viable results, diagnose the
524
516
// / unviable ones.
@@ -779,140 +771,6 @@ bool FailureDiagnosis::diagnoseGeneralMemberFailure(Constraint *constraint) {
779
771
constraint->getFunctionRefKind (), locator);
780
772
}
781
773
782
- void FailureDiagnosis::
783
- diagnoseTypeMemberOnInstanceLookup (Type baseObjTy,
784
- Expr *baseExpr,
785
- DeclName memberName,
786
- DeclNameLoc nameLoc,
787
- ValueDecl *member,
788
- SourceLoc loc) {
789
- SourceRange baseRange = baseExpr ? baseExpr->getSourceRange () : SourceRange ();
790
-
791
- Optional<InFlightDiagnostic> Diag;
792
-
793
- // If the base of the lookup is a protocol metatype, suggest
794
- // to replace the metatype with 'Self'
795
- // error saying the lookup cannot be on a protocol metatype
796
- if (auto metatypeTy = baseObjTy->getAs <MetatypeType>()) {
797
- auto instanceTy = metatypeTy->getInstanceType ();
798
-
799
- // This will only happen if we have an unresolved dot expression
800
- // (.foo) where foo is a protocol member and the contextual type is
801
- // an optional protocol metatype.
802
- if (auto objectTy = instanceTy->getOptionalObjectType ()) {
803
- instanceTy = objectTy;
804
- baseObjTy = MetatypeType::get (objectTy);
805
- }
806
- assert (instanceTy->isExistentialType ());
807
-
808
- // Give a customized message if we're accessing a member type
809
- // of a protocol -- otherwise a diagnostic talking about
810
- // static members doesn't make a whole lot of sense
811
- if (auto TAD = dyn_cast<TypeAliasDecl>(member)) {
812
- Diag.emplace (diagnose (loc,
813
- diag::typealias_outside_of_protocol,
814
- TAD->getName ()));
815
- } else if (auto ATD = dyn_cast<AssociatedTypeDecl>(member)) {
816
- Diag.emplace (diagnose (loc,
817
- diag::assoc_type_outside_of_protocol,
818
- ATD->getName ()));
819
- } else if (isa<ConstructorDecl>(member)) {
820
- Diag.emplace (diagnose (loc,
821
- diag::construct_protocol_by_name,
822
- instanceTy));
823
- } else {
824
- Diag.emplace (diagnose (loc,
825
- diag::could_not_use_type_member_on_protocol_metatype,
826
- baseObjTy, memberName));
827
- }
828
-
829
- Diag->highlight (baseRange).highlight (nameLoc.getSourceRange ());
830
-
831
- // See through function decl context
832
- if (auto parent = CS.DC ->getInnermostTypeContext ()) {
833
- // If we are in a protocol extension of 'Proto' and we see
834
- // 'Proto.static', suggest 'Self.static'
835
- if (auto extensionContext = parent->getExtendedProtocolDecl ()) {
836
- if (extensionContext->getDeclaredType ()->isEqual (instanceTy)) {
837
- Diag->fixItReplace (baseRange, " Self" );
838
- }
839
- }
840
- }
841
-
842
- return ;
843
- }
844
-
845
- if (isa<EnumElementDecl>(member))
846
- Diag.emplace (diagnose (loc, diag::could_not_use_enum_element_on_instance,
847
- memberName));
848
- else
849
- Diag.emplace (diagnose (loc, diag::could_not_use_type_member_on_instance,
850
- baseObjTy, memberName));
851
-
852
- Diag->highlight (nameLoc.getSourceRange ());
853
-
854
- // No fix-it if the lookup was qualified
855
- if (baseExpr && !baseExpr->isImplicit ())
856
- return ;
857
-
858
- // Determine the contextual type of the expression
859
- Type contextualType;
860
- for (auto iterateCS = &CS; contextualType.isNull () && iterateCS;
861
- iterateCS = iterateCS->baseCS ) {
862
- contextualType = iterateCS->getContextualType ();
863
- }
864
-
865
- // Try to provide a fix-it that only contains a '.'
866
- if (contextualType) {
867
- if (baseObjTy->isEqual (contextualType)) {
868
- Diag->fixItInsert (loc, " ." );
869
- return ;
870
- }
871
- }
872
-
873
- // Check if the expression is the matching operator ~=, most often used in
874
- // case statements. If so, try to provide a single dot fix-it
875
- const Expr *contextualTypeNode = nullptr ;
876
- ConstraintSystem *lastCS = nullptr ;
877
- for (auto iterateCS = &CS; iterateCS; iterateCS = iterateCS->baseCS ) {
878
- lastCS = iterateCS;
879
- contextualTypeNode = iterateCS->getContextualTypeNode ();
880
- }
881
-
882
- // The '~=' operator is an overloaded decl ref inside a binaryExpr
883
- if (auto binaryExpr = dyn_cast<BinaryExpr>(contextualTypeNode)) {
884
- if (auto overloadedFn
885
- = dyn_cast<OverloadedDeclRefExpr>(binaryExpr->getFn ())) {
886
- if (!overloadedFn->getDecls ().empty ()) {
887
- // Fetch any declaration to check if the name is '~='
888
- ValueDecl *decl0 = overloadedFn->getDecls ()[0 ];
889
-
890
- if (decl0->getBaseName () == decl0->getASTContext ().Id_MatchOperator ) {
891
- assert (binaryExpr->getArg ()->getElements ().size () == 2 );
892
-
893
- // If the rhs of '~=' is the enum type, a single dot suffixes
894
- // since the type can be inferred
895
- Type secondArgType =
896
- lastCS->getType (binaryExpr->getArg ()->getElement (1 ));
897
- if (secondArgType->isEqual (baseObjTy)) {
898
- Diag->fixItInsert (loc, " ." );
899
- return ;
900
- }
901
- }
902
- }
903
- }
904
- }
905
-
906
- // Fall back to a fix-it with a full type qualifier
907
- auto nominal = member->getDeclContext ()->getSelfNominalTypeDecl ();
908
- SmallString<32 > typeName;
909
- llvm::raw_svector_ostream typeNameStream (typeName);
910
- typeNameStream << nominal->getSelfInterfaceType () << " ." ;
911
-
912
- Diag->fixItInsert (loc, typeNameStream.str ());
913
- return ;
914
- }
915
-
916
774
// / Given a result of name lookup that had no viable results, diagnose the
917
775
// / unviable ones.
918
776
void FailureDiagnosis::diagnoseUnviableLookupResults (
@@ -955,80 +813,20 @@ void FailureDiagnosis::diagnoseUnviableLookupResults(
955
813
instanceTy, memberName)
956
814
.highlight (baseRange).highlight (nameLoc.getSourceRange ());
957
815
return ;
958
- case MemberLookupResult::UR_InstanceMemberOnType: {
959
- // If the base is an implicit self type reference, and we're in a
960
- // an initializer, then the user wrote something like:
961
- //
962
- // class Foo { let x = 1, y = x }
963
- //
964
- // which runs in type context, not instance context, or
965
- //
966
- // class Bar {
967
- // let otherwise = 1 // instance member
968
- // var x: Int
969
- // func init(x: Int =otherwise) { // default parameter
970
- // self.x = x
971
- // }
972
- // }
973
- //
974
- // in which an instance member is used as a default value for a
975
- // parameter.
976
- //
977
- // Produce a tailored diagnostic for these cases since this
978
- // comes up and is otherwise non-obvious what is going on.
979
- if (baseExpr && baseExpr->isImplicit () && isa<Initializer>(CS.DC )) {
980
- auto *TypeDC = CS.DC ->getParent ();
981
- bool propertyInitializer = true ;
982
- // If the parent context is not a type context, we expect it
983
- // to be a defaulted parameter in a function declaration.
984
- if (!TypeDC->isTypeContext ()) {
985
- assert (TypeDC->getContextKind () ==
986
- DeclContextKind::AbstractFunctionDecl &&
987
- " Expected function decl context for initializer!" );
988
- TypeDC = TypeDC->getParent ();
989
- propertyInitializer = false ;
990
- }
991
- assert (TypeDC->isTypeContext () && " Expected type decl context!" );
992
-
993
- if (TypeDC->getSelfNominalTypeDecl () == instanceTy->getAnyNominal ()) {
994
- if (propertyInitializer)
995
- CS.TC .diagnose (nameLoc, diag::instance_member_in_initializer,
996
- memberName);
997
- else
998
- CS.TC .diagnose (nameLoc, diag::instance_member_in_default_parameter,
999
- memberName);
1000
- return ;
1001
- }
1002
- }
1003
-
1004
- // Check whether the instance member is declared on parent context and if so
1005
- // provide more specialized message.
1006
- auto memberTypeContext = member->getDeclContext ()->getInnermostTypeContext ();
1007
- auto currentTypeContext = CS.DC ->getInnermostTypeContext ();
1008
- if (memberTypeContext && currentTypeContext &&
1009
- memberTypeContext->getSemanticDepth () <
1010
- currentTypeContext->getSemanticDepth ()) {
1011
- diagnose (loc, diag::could_not_use_instance_member_on_type,
1012
- currentTypeContext->getDeclaredInterfaceType (), memberName,
1013
- memberTypeContext->getDeclaredInterfaceType (),
1014
- true )
1015
- .highlight (baseRange).highlight (nameLoc.getSourceRange ());
1016
- } else {
1017
- diagnose (loc, diag::could_not_use_instance_member_on_type,
1018
- instanceTy, memberName,
1019
- instanceTy,
1020
- false )
1021
- .highlight (baseRange).highlight (nameLoc.getSourceRange ());
1022
- }
816
+ case MemberLookupResult::UR_InstanceMemberOnType:
817
+ case MemberLookupResult::UR_TypeMemberOnInstance: {
818
+ auto locatorKind = isa<SubscriptExpr>(E)
819
+ ? ConstraintLocator::SubscriptMember
820
+ : ConstraintLocator::Member;
821
+ AllowTypeOrInstanceMemberFailure failure (
822
+ nullptr , CS, baseObjTy, memberName,
823
+ CS.getConstraintLocator (E, locatorKind));
824
+ auto diagnosed = failure.diagnoseAsError ();
825
+ assert (diagnosed &&
826
+ " Failed to produce missing or extraneous metatype diagnostic" );
827
+ (void )diagnosed;
1023
828
return ;
1024
829
}
1025
-
1026
- case MemberLookupResult::UR_TypeMemberOnInstance:
1027
- diagnoseTypeMemberOnInstanceLookup (baseObjTy, baseExpr,
1028
- memberName, nameLoc,
1029
- member, loc);
1030
- return ;
1031
-
1032
830
case MemberLookupResult::UR_MutatingMemberOnRValue:
1033
831
case MemberLookupResult::UR_MutatingGetterOnRValue: {
1034
832
auto diagIDsubelt = diag::cannot_pass_rvalue_mutating_subelement;
@@ -1062,9 +860,6 @@ void FailureDiagnosis::diagnoseUnviableLookupResults(
1062
860
}
1063
861
}
1064
862
1065
- // FIXME: Emit candidate set....
1066
-
1067
-
1068
863
// Otherwise, we don't have a specific issue to diagnose. Just say the vague
1069
864
// 'cannot use' diagnostic.
1070
865
if (!baseObjTy->isEqual (instanceTy))
@@ -3437,7 +3232,7 @@ diagnoseInstanceMethodAsCurriedMemberOnType(CalleeCandidateInfo &CCI,
3437
3232
} else {
3438
3233
TC.diagnose (UDE->getLoc (), diag::could_not_use_instance_member_on_type,
3439
3234
instanceType, UDE->getName (), instanceType, false )
3440
- .highlight (baseExpr->getSourceRange ());
3235
+ .highlight (baseExpr->getSourceRange ());
3441
3236
}
3442
3237
return true ;
3443
3238
}
@@ -5177,7 +4972,9 @@ bool FailureDiagnosis::visitApplyExpr(ApplyExpr *callExpr) {
5177
4972
auto diag = diagnose (arg->getStartLoc (),
5178
4973
diag::missing_init_on_metatype_initialization);
5179
4974
diag.highlight (fnExpr->getSourceRange ());
5180
- } else {
4975
+ }
4976
+
4977
+ if (!fnType->is <ExistentialMetatypeType>()) {
5181
4978
auto diag = diagnose (arg->getStartLoc (),
5182
4979
diag::cannot_call_non_function_value, fnType);
5183
4980
diag.highlight (fnExpr->getSourceRange ());
@@ -5625,6 +5422,36 @@ bool FailureDiagnosis::visitApplyExpr(ApplyExpr *callExpr) {
5625
5422
// If we have an argument list (i.e., a scalar, or a non-zero-element tuple)
5626
5423
// then diagnose with some specificity about the arguments.
5627
5424
bool isInitializer = isa<TypeExpr>(fnExpr);
5425
+ if (!fnType->is <AnyMetatypeType>() &&
5426
+ ((isa<TupleExpr>(argExpr) &&
5427
+ cast<TupleExpr>(argExpr)->getNumElements () == 1 ) ||
5428
+ (isa<ParenExpr>(argExpr) &&
5429
+ !isa<LoadExpr>(cast<ParenExpr>(argExpr)->getSubExpr ())))) {
5430
+ if (auto ctorRef = dyn_cast<UnresolvedDotExpr>(fnExpr)) {
5431
+ if (ctorRef->getName ().isSimpleName (DeclBaseName::createConstructor ())) {
5432
+ // Diagnose 'super.init', which can only appear inside another
5433
+ // initializer, specially.
5434
+ if (isa<SuperRefExpr>(ctorRef->getBase ())) {
5435
+ diagnose (fnExpr->getLoc (),
5436
+ diag::super_initializer_not_in_initializer);
5437
+ calleeInfo.suggestPotentialOverloads (fnExpr->getLoc ());
5438
+ return true ;
5439
+ }
5440
+
5441
+ // Suggest inserting a call to 'type(of:)' to construct another object
5442
+ // of the same dynamic type.
5443
+ SourceRange fixItRng = ctorRef->getNameLoc ().getSourceRange ();
5444
+
5445
+ // Surround the caller in `type(of:)`.
5446
+ diagnose (fnExpr->getLoc (), diag::init_not_instance_member)
5447
+ .fixItInsert (fixItRng.Start , " type(of: " )
5448
+ .fixItInsertAfter (fixItRng.End , " )" );
5449
+ calleeInfo.suggestPotentialOverloads (fnExpr->getLoc ());
5450
+ return true ;
5451
+ }
5452
+ }
5453
+ }
5454
+
5628
5455
if (isa<TupleExpr>(argExpr) &&
5629
5456
cast<TupleExpr>(argExpr)->getNumElements () == 0 ) {
5630
5457
// Emit diagnostics that say "no arguments".
0 commit comments