diff --git a/compiler/src/dotty/tools/dotc/core/tasty/AttributePickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/AttributePickler.scala index 5aea55bce4de..cd2756f4c752 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/AttributePickler.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/AttributePickler.scala @@ -14,13 +14,21 @@ object AttributePickler: ): Unit = pickler.newSection(AttributesSection, buf) + var lastTag = -1 + def assertTagOrder(tag: Int): Unit = + assert(tag != lastTag, s"duplicate attribute tag: $tag") + assert(tag > lastTag, s"attribute tags are not ordered: $tag after $lastTag") + lastTag = tag + for tag <- attributes.booleanTags do assert(isBooleanAttrTag(tag), "Not a boolean attribute tag: " + tag) + assertTagOrder(tag) buf.writeByte(tag) assert(attributes.stringTagValues.exists(_._1 == SOURCEFILEattr)) for (tag, value) <- attributes.stringTagValues do assert(isStringAttrTag(tag), "Not a string attribute tag: " + tag) + assertTagOrder(tag) val utf8Ref = pickler.nameBuffer.utf8Index(value) buf.writeByte(tag) buf.writeNat(utf8Ref.index) diff --git a/compiler/src/dotty/tools/dotc/core/tasty/AttributeUnpickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/AttributeUnpickler.scala index 405f110dbca1..43a2bea27216 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/AttributeUnpickler.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/AttributeUnpickler.scala @@ -15,6 +15,7 @@ class AttributeUnpickler(reader: TastyReader, nameAtRef: NameTable): val booleanTags = BitSet.newBuilder val stringTagValue = List.newBuilder[(Int, String)] + var lastTag = -1 while !isAtEnd do val tag = readByte() if isBooleanAttrTag(tag) then @@ -26,6 +27,11 @@ class AttributeUnpickler(reader: TastyReader, nameAtRef: NameTable): else assert(false, "unknown attribute tag: " + tag) + assert(tag != lastTag, s"duplicate attribute tag: $tag") + assert(tag > lastTag, s"attribute tags are not ordered: $tag after $lastTag") + lastTag = tag + end while + new Attributes(booleanTags.result(), stringTagValue.result()) } diff --git a/tasty/src/dotty/tools/tasty/TastyFormat.scala b/tasty/src/dotty/tools/tasty/TastyFormat.scala index e1a8cf1d50ae..adadd3267aac 100644 --- a/tasty/src/dotty/tools/tasty/TastyFormat.scala +++ b/tasty/src/dotty/tools/tasty/TastyFormat.scala @@ -281,6 +281,7 @@ Standard Section: "Attributes" Attribute* OUTLINEattr SOURCEFILEattr Utf8Ref ``` +Attribute tags cannot be repeated in an attribute section. Attributes are ordered by the tag ordinal. Note: Attribute tags are grouped into categories that determine what follows, and thus allow to compute the size of the tagged tree in a generic way. Unassigned categories can be used to extend and existing category or to add new kinds of attributes