@@ -47,11 +47,6 @@ void Failure::dump(SourceManager *sm, raw_ostream &out) const {
47
47
<< " and " << getSecondType ().getString ();
48
48
break ;
49
49
50
- case NoPublicInitializers:
51
- out << getFirstType ().getString ()
52
- << " does not have any public initializers" ;
53
- break ;
54
-
55
50
case IsNotMaterializable:
56
51
out << getFirstType ().getString () << " is not materializable" ;
57
52
break ;
@@ -593,14 +588,6 @@ static bool diagnoseFailure(ConstraintSystem &cs, Failure &failure,
593
588
}
594
589
// FIXME: diagnose other cases
595
590
return false ;
596
-
597
- case Failure::NoPublicInitializers: {
598
- tc.diagnose (loc, diag::no_accessible_initializers, failure.getFirstType ())
599
- .highlight (range);
600
- if (targetLocator && !useExprLoc)
601
- noteTargetOfDiagnostic (cs, &failure, targetLocator);
602
- break ;
603
- }
604
591
605
592
case Failure::IsNotMaterializable: {
606
593
tc.diagnose (loc, diag::cannot_bind_generic_parameter_to_type,
@@ -992,6 +979,7 @@ namespace {
992
979
enum CandidateCloseness {
993
980
CC_ExactMatch, // /< This is a perfect match for the arguments.
994
981
CC_Unavailable, // /< Marked unavailable with @available.
982
+ CC_Inaccessible, // /< Not accessible from the current context.
995
983
CC_NonLValueInOut, // /< First arg is inout but no lvalue present.
996
984
CC_SelfMismatch, // /< Self argument mismatches.
997
985
CC_OneArgumentNearMismatch, // /< All arguments except one match, near miss.
@@ -1157,6 +1145,11 @@ namespace {
1157
1145
// / argument labels don't match up, diagnose that error and return true.
1158
1146
bool diagnoseAnyStructuralArgumentError (Expr *fnExpr, Expr *argExpr);
1159
1147
1148
+ // / Emit a diagnostic and return true if this is an error condition we can
1149
+ // / handle uniformly. This should be called after filtering the candidate
1150
+ // / list.
1151
+ bool diagnoseSimpleErrors (SourceLoc loc);
1152
+
1160
1153
void dump () const LLVM_ATTRIBUTE_USED;
1161
1154
1162
1155
private:
@@ -1199,6 +1192,19 @@ void CalleeCandidateInfo::filterList(ClosenessPredicate predicate) {
1199
1192
!CS->TC .getLangOpts ().DisableAvailabilityChecking )
1200
1193
declCloseness.first = CC_Unavailable;
1201
1194
1195
+ // Likewise, if the candidate is inaccessible from the scope it is being
1196
+ // accessed from, mark it as inaccessible or a general mismatch.
1197
+ if (!decl.decl ->isAccessibleFrom (CS->DC )) {
1198
+ // If this was an exact match, downgrade it to inaccessible, so that
1199
+ // accessible decls that are also an exact match will take precedence.
1200
+ // Otherwise consider it to be a general mismatch so we only list it in
1201
+ // an overload set as a last resort.
1202
+ if (declCloseness.first == CC_ExactMatch)
1203
+ declCloseness.first = CC_Inaccessible;
1204
+ else
1205
+ declCloseness.first = CC_GeneralMismatch;
1206
+ }
1207
+
1202
1208
closenessList.push_back (declCloseness);
1203
1209
closeness = std::min (closeness, closenessList.back ().first );
1204
1210
}
@@ -1393,11 +1399,12 @@ void CalleeCandidateInfo::collectCalleeCandidates(Expr *fn) {
1393
1399
1394
1400
if (auto TE = dyn_cast<TypeExpr>(fn)) {
1395
1401
// It's always a metatype type, so use the instance type name.
1396
- auto instanceType =TE->getType ()-> castTo <MetatypeType>()-> getInstanceType ();
1402
+ auto instanceType =TE->getInstanceType ();
1397
1403
1398
1404
// TODO: figure out right value for isKnownPrivate
1399
1405
if (!instanceType->getAs <TupleType>()) {
1400
- auto ctors = CS->TC .lookupConstructors (CS->DC , instanceType);
1406
+ auto ctors = CS->TC .lookupConstructors (CS->DC , instanceType,
1407
+ NameLookupFlags::IgnoreAccessibility);
1401
1408
for (auto ctor : ctors)
1402
1409
if (ctor->hasType ())
1403
1410
candidates.push_back ({ ctor, 1 });
@@ -1658,9 +1665,23 @@ suggestPotentialOverloads(SourceLoc loc, bool isResult) {
1658
1665
// / labels don't match up, diagnose that error and return true.
1659
1666
bool CalleeCandidateInfo::diagnoseAnyStructuralArgumentError (Expr *fnExpr,
1660
1667
Expr *argExpr) {
1668
+ // If we are invoking a constructor and there are absolutely no candidates,
1669
+ // then they must all be private.
1670
+ if (auto *MTT = fnExpr->getType ()->getAs <MetatypeType>()) {
1671
+ if (!MTT->getInstanceType ()->is <TupleType>() &&
1672
+ (size () == 0 ||
1673
+ (size () == 1 && isa<ProtocolDecl>(candidates[0 ].decl )))) {
1674
+ CS->TC .diagnose (fnExpr->getLoc (), diag::no_accessible_initializers,
1675
+ MTT->getInstanceType ());
1676
+ return true ;
1677
+ }
1678
+ }
1679
+
1680
+
1661
1681
// TODO: We only handle the situation where there is exactly one candidate
1662
1682
// here.
1663
- if (size () != 1 ) return false ;
1683
+ if (size () != 1 )
1684
+ return false ;
1664
1685
1665
1686
1666
1687
auto args = decomposeArgParamType (argExpr->getType ());
@@ -1829,7 +1850,35 @@ bool CalleeCandidateInfo::diagnoseAnyStructuralArgumentError(Expr *fnExpr,
1829
1850
return false ;
1830
1851
}
1831
1852
1853
+ // / Emit a diagnostic and return true if this is an error condition we can
1854
+ // / handle uniformly. This should be called after filtering the candidate
1855
+ // / list.
1856
+ bool CalleeCandidateInfo::diagnoseSimpleErrors (SourceLoc loc) {
1857
+ // Handle symbols marked as explicitly unavailable.
1858
+ if (closeness == CC_Unavailable)
1859
+ return CS->TC .diagnoseExplicitUnavailability (candidates[0 ].decl , loc,
1860
+ CS->DC );
1861
+
1862
+ // Handle symbols that are matches, but are not accessible from the current
1863
+ // scope.
1864
+ if (closeness == CC_Inaccessible) {
1865
+ auto decl = candidates[0 ].decl ;
1866
+ if (auto *CD = dyn_cast<ConstructorDecl>(decl)) {
1867
+ CS->TC .diagnose (loc, diag::init_candidate_inaccessible,
1868
+ CD->getResultType (), decl->getFormalAccess ());
1869
+
1870
+ } else {
1871
+ CS->TC .diagnose (loc, diag::candidate_inaccessible, decl->getName (),
1872
+ decl->getFormalAccess ());
1873
+ }
1874
+ for (auto cand : candidates)
1875
+ CS->TC .diagnose (cand.decl , diag::decl_declared_here, decl->getName ());
1876
+
1877
+ return true ;
1878
+ }
1832
1879
1880
+ return false ;
1881
+ }
1833
1882
1834
1883
1835
1884
@@ -3604,13 +3653,10 @@ bool FailureDiagnosis::visitSubscriptExpr(SubscriptExpr *SE) {
3604
3653
3605
3654
return true ;
3606
3655
}
3607
-
3608
- if (calleeInfo.closeness == CC_Unavailable) {
3609
- if (CS->TC .diagnoseExplicitUnavailability (calleeInfo[0 ].decl ,
3610
- SE->getLoc (), CS->DC ))
3611
- return true ;
3612
- return false ;
3613
- }
3656
+
3657
+ // Diagnose some simple and common errors.
3658
+ if (calleeInfo.diagnoseSimpleErrors (SE->getLoc ()))
3659
+ return true ;
3614
3660
3615
3661
// If the closest matches all mismatch on self, we either have something that
3616
3662
// cannot be subscripted, or an ambiguity.
@@ -3811,10 +3857,10 @@ bool FailureDiagnosis::visitApplyExpr(ApplyExpr *callExpr) {
3811
3857
}
3812
3858
3813
3859
3814
- // Handle uses of unavailable symbols .
3815
- if (calleeInfo.closeness == CC_Unavailable )
3816
- return CS-> TC . diagnoseExplicitUnavailability (calleeInfo[ 0 ]. decl ,
3817
- callExpr-> getLoc (), CS-> DC );
3860
+ // Diagnose some simple and common errors .
3861
+ if (calleeInfo.diagnoseSimpleErrors (callExpr-> getLoc ()) )
3862
+ return true ;
3863
+
3818
3864
3819
3865
// A common error is to apply an operator that only has inout forms (e.g. +=)
3820
3866
// to non-lvalues (e.g. a local let). Produce a nice diagnostic for this
@@ -4721,8 +4767,9 @@ bool FailureDiagnosis::visitUnresolvedMemberExpr(UnresolvedMemberExpr *E) {
4721
4767
}
4722
4768
4723
4769
case CC_Unavailable:
4724
- if (CS->TC .diagnoseExplicitUnavailability (candidateInfo[0 ].decl ,
4725
- E->getLoc (), CS->DC ))
4770
+ case CC_Inaccessible:
4771
+ // Diagnose some simple and common errors.
4772
+ if (candidateInfo.diagnoseSimpleErrors (E->getLoc ()))
4726
4773
return true ;
4727
4774
return false ;
4728
4775
0 commit comments