From de61f99822e9fe338af947b0a1ac15065a761824 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 26 Nov 2025 17:37:40 +0000 Subject: [PATCH 1/2] Initial plan From 93574f781cae40ad3102870e21d576a23303f604 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 26 Nov 2025 18:29:32 +0000 Subject: [PATCH 2/2] Fix mojibake in error messages when .slang-module can't find source file The issue was that when loading binary modules, the IncludeSystem::loadFile was creating a SourceFile with the binary module content. Later, when diagnostics were raised for missing imports, the code would find this existing SourceFile and try to display "source lines" from binary data, resulting in mojibake. The fix ensures that when creating a source location for a serialized module's diagnostics, we always create a fresh empty source file rather than reusing one that might contain binary data. Co-authored-by: bmillsNV <163073245+bmillsNV@users.noreply.github.com> --- .../compiler-core/slang-diagnostic-sink.cpp | 24 ++++++++++++++----- source/slang/slang-session.cpp | 20 ++++++++++------ 2 files changed, 31 insertions(+), 13 deletions(-) diff --git a/source/compiler-core/slang-diagnostic-sink.cpp b/source/compiler-core/slang-diagnostic-sink.cpp index de8bdf52c23..21592b7e5c9 100644 --- a/source/compiler-core/slang-diagnostic-sink.cpp +++ b/source/compiler-core/slang-diagnostic-sink.cpp @@ -282,12 +282,18 @@ static void _sourceLocationNoteDiagnostic( return; } - UnownedStringSlice content = sourceFile->getContent(); - - // Make sure the offset is within content. + // Check if the source file has actual content available. // This is important because it's possible to have a 'SourceFile' that doesn't contain any // content (for example when reconstructed via serialization with just line offsets, the actual // source text 'content' isn't available). + if (!sourceFile->hasContent()) + { + return; + } + + UnownedStringSlice content = sourceFile->getContent(); + + // Make sure the offset is within content. const int offset = sourceView->getRange().getOffset(sourceLoc); if (offset < 0 || offset >= content.getLength()) { @@ -388,12 +394,18 @@ static void _tokenLengthNoteDiagnostic( return; } - UnownedStringSlice content = sourceFile->getContent(); - - // Make sure the offset is within content. + // Check if the source file has actual content available. // This is important because it's possible to have a 'SourceFile' that doesn't contain any // content (for example when reconstructed via serialization with just line offsets, the actual // source text 'content' isn't available). + if (!sourceFile->hasContent()) + { + return; + } + + UnownedStringSlice content = sourceFile->getContent(); + + // Make sure the offset is within content. const int offset = sourceView->getRange().getOffset(sourceLoc); if (offset < 0 || offset >= content.getLength()) { diff --git a/source/slang/slang-session.cpp b/source/slang/slang-session.cpp index 6b3338e0efd..14de8a53b43 100644 --- a/source/slang/slang-session.cpp +++ b/source/slang/slang-session.cpp @@ -2039,13 +2039,19 @@ SlangResult Linkage::loadSerializedModuleContents( // SourceLoc serializedModuleLoc; { - auto sourceFile = - sourceManager->findSourceFileByPathRecursively(moduleFilePathInfo.foundPath); - if (!sourceFile) - { - sourceFile = sourceManager->createSourceFileWithString(moduleFilePathInfo, String()); - sourceManager->addSourceFile(moduleFilePathInfo.getMostUniqueIdentity(), sourceFile); - } + // For the purposes of diagnostics, we create a source file to represent + // the binary module file. We intentionally create this with empty content + // to avoid displaying binary data in error messages. + // + // Note: We do NOT reuse any existing source file for this path, because + // an earlier code path (e.g., IncludeSystem::loadFile) may have loaded + // the binary module content into a source file, and we don't want to + // display that binary data when showing diagnostic source lines. + // + auto sourceFile = sourceManager->createSourceFileWithString(moduleFilePathInfo, String()); + sourceManager->addSourceFileIfNotExist( + moduleFilePathInfo.getMostUniqueIdentity(), + sourceFile); auto sourceView = sourceManager->createSourceView(sourceFile, &moduleFilePathInfo, SourceLoc()); serializedModuleLoc = sourceView->getRange().begin;