@@ -6164,49 +6164,60 @@ bool InaccessibleMemberFailure::diagnoseAsError() {
61646164 auto loc = nameLoc.isValid () ? nameLoc.getStartLoc () : ::getLoc (anchor);
61656165 auto accessLevel = Member->getFormalAccessScope ().accessLevelForDiagnostics ();
61666166 bool suppressDeclHereNote = false ;
6167- if (accessLevel == AccessLevel::Public) {
6167+ if (accessLevel == AccessLevel::Public &&
6168+ !Member->findImport (getDC ())) {
61686169 auto definingModule = Member->getDeclContext ()->getParentModule ();
61696170 emitDiagnosticAt (loc, diag::candidate_from_missing_import,
61706171 Member->getDescriptiveKind (), Member->getName (),
61716172 definingModule->getName ());
61726173
6173- if (auto enclosingSF = getDC ()->getParentSourceFile ()) {
6174- SourceLoc bestLoc;
6175- SourceManager &srcMgr = Member->getASTContext ().SourceMgr ;
6176- for (auto item : enclosingSF->getTopLevelItems ()) {
6177- // If we found an import declaration, we want to insert after it.
6178- if (auto importDecl =
6179- dyn_cast_or_null<ImportDecl>(item.dyn_cast <Decl *>())) {
6180- SourceLoc loc = importDecl->getEndLoc ();
6181- if (loc.isValid ()) {
6182- bestLoc = Lexer::getLocForEndOfLine (srcMgr, loc);
6183- }
6184-
6185- // Keep looking for more import declarations.
6186- continue ;
6187- }
6188-
6189- // If we got a location based on import declarations, we're done.
6190- if (bestLoc.isValid ())
6191- break ;
6192-
6193- // For any other item, we want to insert before it.
6194- SourceLoc loc = item.getStartLoc ();
6174+ auto enclosingSF = getDC ()->getParentSourceFile ();
6175+ SourceLoc bestLoc;
6176+ SourceManager &srcMgr = Member->getASTContext ().SourceMgr ;
6177+ for (auto item : enclosingSF->getTopLevelItems ()) {
6178+ // If we found an import declaration, we want to insert after it.
6179+ if (auto importDecl =
6180+ dyn_cast_or_null<ImportDecl>(item.dyn_cast <Decl *>())) {
6181+ SourceLoc loc = importDecl->getEndLoc ();
61956182 if (loc.isValid ()) {
6196- bestLoc = Lexer::getLocForStartOfLine (srcMgr, loc);
6197- break ;
6183+ bestLoc = Lexer::getLocForEndOfLine (srcMgr, loc);
61986184 }
6185+
6186+ // Keep looking for more import declarations.
6187+ continue ;
6188+ }
6189+
6190+ // If we got a location based on import declarations, we're done.
6191+ if (bestLoc.isValid ())
6192+ break ;
6193+
6194+ // For any other item, we want to insert before it.
6195+ SourceLoc loc = item.getStartLoc ();
6196+ if (loc.isValid ()) {
6197+ bestLoc = Lexer::getLocForStartOfLine (srcMgr, loc);
6198+ break ;
61996199 }
6200+ }
6201+
6202+ if (bestLoc.isValid ()) {
6203+ llvm::SmallString<64 > importText;
62006204
6201- if (bestLoc. isValid ()) {
6202- llvm::SmallString< 64 > importText;
6203- importText += " import " ;
6204- importText += definingModule-> getName (). str ();
6205- importText += " \n " ;
6206- emitDiagnosticAt (bestLoc, diag::candidate_add_import,
6207- definingModule-> getName ())
6208- . fixItInsert (bestLoc, importText);
6205+ // @_spi imports.
6206+ if (Member-> isSPI ()) {
6207+ auto spiGroups = Member-> getSPIGroups () ;
6208+ if (!spiGroups. empty ()) {
6209+ importText += " @_spi( " ;
6210+ importText += spiGroups[ 0 ]. str ();
6211+ importText += " ) " ;
6212+ }
62096213 }
6214+
6215+ importText += " import " ;
6216+ importText += definingModule->getName ().str ();
6217+ importText += " \n " ;
6218+ emitDiagnosticAt (bestLoc, diag::candidate_add_import,
6219+ definingModule->getName ())
6220+ .fixItInsert (bestLoc, importText);
62106221 }
62116222
62126223 suppressDeclHereNote = true ;
@@ -6220,7 +6231,8 @@ bool InaccessibleMemberFailure::diagnoseAsError() {
62206231 .highlight (nameLoc.getSourceRange ());
62216232 }
62226233
6223- emitDiagnosticAt (Member, diag::decl_declared_here, Member);
6234+ if (!suppressDeclHereNote)
6235+ emitDiagnosticAt (Member, diag::decl_declared_here, Member);
62246236 return true ;
62256237}
62266238
0 commit comments