@@ -359,6 +359,26 @@ static bool isSubmodule(const ModuleDecl* M) {
359359void ImportResolver::visitImportDecl (ImportDecl *ID) {
360360 assert (unboundImports.empty ());
361361
362+ // `CxxStdlib` is the only accepted spelling of the C++ stdlib module name.
363+ ImportPath::Builder builder;
364+ const ImportPath path = ID->getRealImportPath (builder);
365+ const llvm::StringRef front = path.front ().Item .str ();
366+ if (front == " std" || front.starts_with (" std_" )) {
367+ SmallString<64 > modulePathStr;
368+ path.getString (modulePathStr);
369+ auto diagKind = ctx.LangOpts .DebuggerSupport ? diag::sema_no_import_repl
370+ : diag::sema_no_import;
371+ const SourceLoc importLoc = ID->getLoc ();
372+ const ImportPath sourcePath = ID->getImportPath ();
373+ const llvm::StringRef sourceFront = sourcePath.front ().Item .str ();
374+ ctx.Diags .diagnose (importLoc, diagKind, modulePathStr);
375+ ctx.Diags .diagnose (importLoc, diag::did_you_mean_cxxstdlib)
376+ .fixItReplaceChars (importLoc, importLoc.getAdvancedLoc (sourceFront.size ()), " CxxStdlib" );
377+ if (front != sourceFront)
378+ ctx.Diags .diagnose (importLoc, diag::sema_module_aliased, sourceFront, front);
379+ return ;
380+ }
381+
362382 unboundImports.emplace_back (ID);
363383 bindPendingImports ();
364384}
@@ -513,13 +533,15 @@ UnboundImport::getTopLevelModule(ModuleDecl *M, SourceFile &SF) {
513533// MARK: Implicit imports
514534// ===----------------------------------------------------------------------===//
515535
516- static void tryStdlibFixit (ASTContext &ctx,
517- StringRef moduleName,
518- SourceLoc loc) {
519- if (moduleName.starts_with (" std" )) {
520- ctx.Diags .diagnose (loc, diag::did_you_mean_cxxstdlib)
521- .fixItReplaceChars (loc, loc.getAdvancedLoc (3 ), " CxxStdlib" );
536+ ImportPath::Module getRealModulePath (ImportPath::Builder &builder, ImportPath::Module path, ASTContext &ctx) {
537+ for (size_t i = 0 ; i < path.size (); i++) {
538+ if (i == 0 ) {
539+ builder.push_back (ctx.getRealModuleName (path[i].Item ));
540+ } else {
541+ builder.push_back (path[i]);
542+ }
522543 }
544+ return builder.get ().getModulePath (false );
523545}
524546
525547static void diagnoseNoSuchModule (ModuleDecl *importingModule,
@@ -534,13 +556,20 @@ static void diagnoseNoSuchModule(ModuleDecl *importingModule,
534556 importingModule->getName ());
535557 } else {
536558 SmallString<64 > modulePathStr;
537- modulePath.getString (modulePathStr);
559+ ImportPath::Builder builder;
560+ ImportPath::Module realModulePath = getRealModulePath (builder, modulePath, ctx);
561+ realModulePath.getString (modulePathStr);
538562
539563 auto diagKind = diag::sema_no_import;
540564 if (nonfatalInREPL && ctx.LangOpts .DebuggerSupport )
541565 diagKind = diag::sema_no_import_repl;
542566 ctx.Diags .diagnose (importLoc, diagKind, modulePathStr);
543- tryStdlibFixit (ctx, modulePathStr, importLoc);
567+
568+ const llvm::StringRef sourceFront = modulePath.front ().Item .str ();
569+ const llvm::StringRef realFront = realModulePath.front ().Item .str ();
570+ if (realFront != sourceFront)
571+ ctx.Diags .diagnose (importLoc, diag::sema_module_aliased, sourceFront,
572+ realFront);
544573 }
545574
546575 if (ctx.SearchPathOpts .getSDKPath ().empty () &&
0 commit comments