Skip to content

Conversation

@smasher164
Copy link
Contributor

The diagnostic emitted that this PR suppressed accurately identified a mismatch in the type arguments to TypeConverterAttribute. PR dotnet/runtime#75235 addresses that mismatch, and it's unclear if internal type arguments actually need to be excluded from the attribute rule.

Reverts #27648

@ViktorHofer
Copy link
Member

PR dotnet/runtime#75235 addresses that mismatch, and it's unclear if internal type arguments actually need to be excluded from the attribute rule.

Do you know why this was the case in the old ApiCompat?

@smasher164
Copy link
Contributor Author

PR dotnet/runtime#75235 addresses that mismatch, and it's unclear if internal type arguments actually need to be excluded from the attribute rule.

Do you know why this was the case in the old ApiCompat?

After speaking with @ericstj, it was apparently due to the fact that the PublicOnlyCciFilter didn't even visit attribute arguments invisible outside the assembly. See https://github.com/dotnet/arcade/blob/e7ede87875f41a9b3df898ae08da5ebc96e24f56/src/Microsoft.Cci.Extensions/Filters/PublicOnlyCciFilter.cs#L72. I'm not sure why that was, but it has something to do with the fact that the Cci filters were used in code generation?

@ericstj
Copy link
Member

ericstj commented Sep 9, 2022

I'm not sure why that was, but it has something to do with the fact that the Cci filters were used in code generation?

That’s my best guess. Otherwise GenAPI would emit code that didn’t compile. There wouldn’t be any override to tell GenAPI to exclude that one applied attribute - or include the internal type.

For API Compat I think it makes more sense to include here if the user is telling us that they think the Attribute should be tested. They have opted into treating uses of that attribute on public API as public.

",
new CompatDifference[] {
CompatDifference.CreateWithDefaultMetadata(DiagnosticIds.CannotChangeAttribute, "", DifferenceType.Changed, "T:CompatTests.First:[T:CompatTests.FooAttribute]")
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we desire this behavior can we add an explicit test for it? That should avoid having this discussion again in the future :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To clarify, do you mean adding a test that asserts that changes to internal type arguments are caught?

Copy link
Member

@ericstj ericstj Sep 12, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah. For instance add a test that might catch if we had an inconsistent namespace between the internal type argument on left and right. The test should prove that we look at the internal type argument and compare it, and have a comment around why.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't we only validate internal members when this flag is set to true?

/// <summary>
/// Determines if internal members should be validated.
/// </summary>
public readonly bool IncludeInternalSymbols;

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think so. That flag will only be set when people want to track their internal API and catch breaking changes in their internal API.

In this case this is not an internal API. It's an attribute on public API that a compiler is treating like public API. The concept of internal/public on attributes is not well defined -- the uses of attributes by design time tools are case-by-case reading of the metadata. The application of the attribute itself does not have a public/internal distinction. We have data here that shows there are cases where design time tools treat the application of the attribute as public even when it points at an internal type, so I believe the correct behavior here is to treat it as public.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The concept of internal/public on attributes is not well defined

Based on the previous behavior, right now, IncludeInternalSymbols applies to the attribute class as well. If we didn't want to do that, then I can remove that behavior as well.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We still filter out attributes which aren't visible outside of the assembly, even with this PR; but we don't filter out visible attributes which contain internal members anymore. That's the desired behavior, correct?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that is correct. The internal type arguments should still be considered, no matter what.

@smasher164 smasher164 requested a review from ericstj September 12, 2022 21:02
",
new CompatDifference[] {}
new CompatDifference[] {
CompatDifference.CreateWithDefaultMetadata(DiagnosticIds.CannotChangeAttribute, "", DifferenceType.Changed, "T:CompatTests.First:[T:CompatTests.FooAttribute]"),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for adding the test - you may want to also include some comments that explain why it's important to examine internal types.

@ViktorHofer
Copy link
Member

@smasher164 do you want to get this into release/7.0?

@smasher164
Copy link
Contributor Author

@smasher164 do you want to get this into release/7.0?

Yes. I believe we decided that internal type arguments to a public attribute shouldn't be filtered out by typ.IsVisibleOutsideOfAssembly.

@ViktorHofer
Copy link
Member

Cool. I was asking because we are past RC2 now and still getting changes into .NET 7 becomes harder with every day. Do you know what is missing to get this one in? Do we still need to reach consensus?

@ViktorHofer
Copy link
Member

@smasher164 gentle ping regarding status. I just yesterday backported an APICompat change into release/7.0.1xx and that required Tactics approval (even for a non binary impacting change).

@ViktorHofer ViktorHofer merged commit bab7883 into main Sep 28, 2022
@ViktorHofer ViktorHofer deleted the revert-27648-internal-type-attribute branch September 28, 2022 16:15
@ViktorHofer
Copy link
Member

Great, this is now in. Can you please backport this change to release/7.0.1xx and fill in the servicing template, apply the servicing-consider label and send a mail to Tactics? Feel free to reach out to Eric or me offline regarding the template or the process.

ViktorHofer pushed a commit that referenced this pull request Sep 30, 2022
…pe" (#27774) (#28233)

* Revert "do not emit diagnostic when attribute argument is internal type (#27648)"

This reverts commit c533dcc.

* add test for internal type arguments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants