diff --git a/Src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests.cs b/Src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests.cs index 0a5b02ff53b6e09070158a122ebc1d55c18a767e..16787e387fbc82065545073fa2af29545ed72b4a 100644 --- a/Src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests.cs +++ b/Src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests.cs @@ -7248,6 +7248,31 @@ class Test Assert.Equal("Bug1020038", m.ReferencedAssemblies[1].Name); }); } + + [Fact, WorkItem(937575, "DevDiv"), WorkItem(121, "CodePlex")] + public void Bug937575() + { + var source = @" +using System; +class XAttribute : Attribute { } +class C +{ + public void M<[X]U>() { } +} +"; + + var compilation = CreateCompilationWithMscorlib(source, options: TestOptions.DebugDll); + + CompileAndVerify(compilation, symbolValidator: (m) => + { + var cc = m.GlobalNamespace.GetTypeMember("C"); + var mm = cc.GetMember("M"); + + Assert.True(cc.TypeParameters.Single().GetAttributes().IsEmpty); + Assert.Equal("XAttribute", mm.TypeParameters.Single().GetAttributes().Single().ToString()); + }, + emitOptions: TestEmitters.RefEmitBug); + } #endregion } } diff --git a/Src/Compilers/CSharp/Test/Emit/Emit/EditAndContinue/EditAndContinueTests.cs b/Src/Compilers/CSharp/Test/Emit/Emit/EditAndContinue/EditAndContinueTests.cs index 6cf262dc060a53ff5ebfc7e34bc718b4b43b53b9..059079b8504067e5e8015fce94d3e38767a5cc02 100644 --- a/Src/Compilers/CSharp/Test/Emit/Emit/EditAndContinue/EditAndContinueTests.cs +++ b/Src/Compilers/CSharp/Test/Emit/Emit/EditAndContinue/EditAndContinueTests.cs @@ -1408,9 +1408,9 @@ class C Handle(2, TableIndex.GenericParam), Handle(2, TableIndex.MethodSpec)); CheckAttributes(reader1, + new CustomAttributeRow(Handle(1, TableIndex.GenericParam), Handle(1, TableIndex.MethodDef)), new CustomAttributeRow(Handle(2, TableIndex.Property), Handle(2, TableIndex.MethodDef)), new CustomAttributeRow(Handle(2, TableIndex.Event), Handle(1, TableIndex.MethodDef)), - new CustomAttributeRow(Handle(2, TableIndex.GenericParam), Handle(1, TableIndex.MethodDef)), new CustomAttributeRow(Handle(3, TableIndex.Field), Handle(1, TableIndex.MethodDef)), new CustomAttributeRow(Handle(4, TableIndex.Field), Handle(11, TableIndex.MemberRef)), new CustomAttributeRow(Handle(4, TableIndex.Field), Handle(12, TableIndex.MemberRef)), diff --git a/Src/Compilers/Core/Portable/Emit/EditAndContinue/DeltaMetadataWriter.cs b/Src/Compilers/Core/Portable/Emit/EditAndContinue/DeltaMetadataWriter.cs index 0166a61699ef30aae6cd9cde9f857f73dbfe6b2f..b8411e3c36e81de23f5b367c93b11f7d22b5a031 100644 --- a/Src/Compilers/Core/Portable/Emit/EditAndContinue/DeltaMetadataWriter.cs +++ b/Src/Compilers/Core/Portable/Emit/EditAndContinue/DeltaMetadataWriter.cs @@ -312,11 +312,6 @@ protected override IReadOnlyList GetParameterDefs() return this.parameterDefs.GetRows(); } - protected override uint GetGenericParameterIndex(IGenericParameter def) - { - return this.genericParameters[def]; - } - protected override IReadOnlyList GetGenericParameters() { return this.genericParameters.GetRows(); diff --git a/Src/Compilers/Core/Portable/PEWriter/FullMetadataWriter.cs b/Src/Compilers/Core/Portable/PEWriter/FullMetadataWriter.cs index c8561914f0c97fd5d041730928999c5aad82e9a0..2e1dda46f9a0a40dc9049d1491b2ea4c1d0b1522 100644 --- a/Src/Compilers/Core/Portable/PEWriter/FullMetadataWriter.cs +++ b/Src/Compilers/Core/Portable/PEWriter/FullMetadataWriter.cs @@ -166,11 +166,6 @@ protected override IReadOnlyList GetParameterDefs() return this.parameterDefs.Rows; } - protected override uint GetGenericParameterIndex(IGenericParameter def) - { - return this.genericParameters[def]; - } - protected override IReadOnlyList GetGenericParameters() { return this.genericParameters.Rows; diff --git a/Src/Compilers/Core/Portable/PEWriter/MetadataWriter.cs b/Src/Compilers/Core/Portable/PEWriter/MetadataWriter.cs index 63b7cd9c7e9beeaff9d84180efa4d85c6e74894f..17afa12ddbddc50f225ebfd8932a661fc282254e 100644 --- a/Src/Compilers/Core/Portable/PEWriter/MetadataWriter.cs +++ b/Src/Compilers/Core/Portable/PEWriter/MetadataWriter.cs @@ -247,12 +247,6 @@ internal Guid ModuleVersionId /// protected abstract IReadOnlyList GetParameterDefs(); - /// - /// The 1-based index of the generic parameter definition. - /// The index is into the full metadata. - /// - protected abstract uint GetGenericParameterIndex(IGenericParameter def); - /// /// The generic parameter definitions to be emitted, in row order. These /// are just the generic parameter definitions from the current generation. @@ -2864,7 +2858,7 @@ private void PopulateCustomAttributeTableRows() // TODO: exported types 17 // TODO: this.AddCustomAttributesToTable(assembly.Resources, 18); - // The indices of this.genericParameterList do not correspond to the table indices because the + // The indices of this.GetGenericParameters() do not correspond to the table indices because the // the table may be sorted after the list has been constructed. // Note that in all other cases, tables that are sorted are sorted in an order that depends // only on list indices. The generic parameter table is the sole exception. @@ -2874,7 +2868,7 @@ private void PopulateCustomAttributeTableRows() sortedGenericParameterList.Add(genericParamRow.GenericParameter); } - this.AddCustomAttributesToTable(sortedGenericParameterList, 19, this.GetGenericParameterIndex); + this.AddCustomAttributesToTable(sortedGenericParameterList, 19); this.customAttributeTable.Sort(new CustomAttributeRowComparer()); } @@ -2949,12 +2943,12 @@ private void AddModuleAttributesToTable(IModule module, uint tag) } } - private void AddCustomAttributesToTable(IEnumerable parentList, uint tag) + private void AddCustomAttributesToTable(IEnumerable parentList, uint tag) + where T : IReference { uint parentIndex = 0; - foreach (IReference parent in parentList) + foreach (var parent in parentList) { - Debug.Assert(this.IsFullMetadata); // parentToken is not relative parentIndex++; uint parentToken = (parentIndex << 5) | tag; foreach (ICustomAttribute customAttribute in parent.GetAttributes(Context))