@@ -6163,7 +6163,54 @@ bool InaccessibleMemberFailure::diagnoseAsError() {
61636163
61646164 auto loc = nameLoc.isValid () ? nameLoc.getStartLoc () : ::getLoc (anchor);
61656165 auto accessLevel = Member->getFormalAccessScope ().accessLevelForDiagnostics ();
6166- if (auto *CD = dyn_cast<ConstructorDecl>(Member)) {
6166+ bool suppressDeclHereNote = false ;
6167+ if (accessLevel == AccessLevel::Public) {
6168+ auto definingModule = Member->getDeclContext ()->getParentModule ();
6169+ emitDiagnosticAt (loc, diag::candidate_from_missing_import,
6170+ Member->getDescriptiveKind (), Member->getName (),
6171+ definingModule->getName ());
6172+
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 ();
6195+ if (loc.isValid ()) {
6196+ bestLoc = Lexer::getLocForStartOfLine (srcMgr, loc);
6197+ break ;
6198+ }
6199+ }
6200+
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);
6209+ }
6210+ }
6211+
6212+ suppressDeclHereNote = true ;
6213+ } else if (auto *CD = dyn_cast<ConstructorDecl>(Member)) {
61676214 emitDiagnosticAt (loc, diag::init_candidate_inaccessible,
61686215 CD->getResultInterfaceType (), accessLevel)
61696216 .highlight (nameLoc.getSourceRange ());
0 commit comments