diff --git a/AyCode.Core.Serializers.SourceGenerator/AcBinarySourceGenerator.cs b/AyCode.Core.Serializers.SourceGenerator/AcBinarySourceGenerator.cs
index c7556c5..fc85f56 100644
--- a/AyCode.Core.Serializers.SourceGenerator/AcBinarySourceGenerator.cs
+++ b/AyCode.Core.Serializers.SourceGenerator/AcBinarySourceGenerator.cs
@@ -835,6 +835,37 @@ public class AcBinarySourceGenerator : IIncrementalGenerator
/// Emits direct object write — bypasses GetWrapper + WriteObject entirely.
#region Scan Pass Code Generation
+ ///
+ /// Compile-time check: will EmitScanProp produce any scan work for this property?
+ /// When false, the entire block (including PropertyFilter guard) is skipped.
+ ///
+ private static bool HasScanWork(PropInfo p) => p.TypeKind switch
+ {
+ PropertyTypeKind.String => p.InterningFlags != 0,
+ PropertyTypeKind.Complex when p.HasGeneratedWriter => p.ChildNeedsScan,
+ PropertyTypeKind.Complex => true,
+ PropertyTypeKind.Collection => HasCollectionScanWork(p),
+ PropertyTypeKind.Dictionary => HasDictionaryScanWork(p),
+ _ => false
+ };
+
+ private static bool HasCollectionScanWork(PropInfo p) => p.ElementKind switch
+ {
+ PropertyTypeKind.String => p.InterningFlags != 0,
+ PropertyTypeKind.Complex when p.ElementHasGeneratedWriter && p.CollectionKind != null => p.ElementNeedsScan,
+ PropertyTypeKind.Complex => true,
+ _ => false
+ };
+
+ private static bool HasDictionaryScanWork(PropInfo p)
+ {
+ if (p.DictKeyKind == PropertyTypeKind.String && p.InterningFlags != 0) return true;
+ if (p.DictValueKind == PropertyTypeKind.String && p.InterningFlags != 0) return true;
+ if (p.DictValueKind == PropertyTypeKind.Complex && p.DictValueHasGeneratedWriter) return p.DictValueNeedsScan;
+ if (p.DictValueKind == PropertyTypeKind.Complex) return true;
+ return false;
+ }
+
///
/// Emits scan pass code for a single property.
/// String: interning check + ScanInternString.
@@ -844,6 +875,9 @@ public class AcBinarySourceGenerator : IIncrementalGenerator
///
private static void EmitScanProp(StringBuilder sb, PropInfo p, string i, string fullTypeName)
{
+ // Compile-time proven: no scan work for this property — skip entirely (including PropertyFilter guard)
+ if (!HasScanWork(p)) return;
+
var a = $"obj.{p.Name}";
// PropertyFilter: must match write pass — if filter skips property, scan must skip too