Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use right hand side references even when not compatible #47065

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

ericstj
Copy link
Member

@ericstj ericstj commented Feb 24, 2025

Fixes #46834
Related to #35214

Not using references at all creates a problem when comparing against API that requires a core-assembly for resolving syntax (EG: Nullable<> -> ?)

Whenever a package is replacing a more specific assembly with a less specific assembly it still needs to be compatible with the less specific references.

Not using references at all creates a problem when comparing against API
that requires a core-assembly for resolving syntax (EG: Nullable<> -> `?`)

Whenever a package is replacing a more specific assembly with a less
specific assembly it still needs to be compatible with the less specific
references.
@ericstj ericstj requested a review from a team as a code owner February 24, 2025 17:29
@dotnet-issue-labeler dotnet-issue-labeler bot added Area-ApiCompat untriaged Request triage from a team member labels Feb 24, 2025
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot reviewed 1 out of 1 changed files in this pull request and generated 1 comment.

@@ -42,6 +42,12 @@ public static void QueueApiCompatFromContentItem(this IApiCompatRunner apiCompat
{
fallbackAssemblyReferences = rightPackage.FindBestAssemblyReferencesForFramework(leftTargetFramework);
}

// if we cannot find references for the left framework, then just use the same right references for the left assembly
if (fallbackAssemblyReferences is null && rightContentItems[0].Properties.TryGetValue("tfm", out tfmObj) && tfmObj is NuGetFramework rightTargetFramework)
Copy link
Preview

Copilot AI Feb 24, 2025

Choose a reason for hiding this comment

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

Using rightContentItems[0] without checking if the list is non-empty may lead to an exception when rightContentItems is empty. Consider adding a check to ensure that rightContentItems contains at least one element before accessing its first element.

Suggested change
if (fallbackAssemblyReferences is null && rightContentItems[0].Properties.TryGetValue("tfm", out tfmObj) && tfmObj is NuGetFramework rightTargetFramework)
if (fallbackAssemblyReferences is null && rightContentItems.Count > 0 && rightContentItems[0].Properties.TryGetValue("tfm", out tfmObj) && tfmObj is NuGetFramework rightTargetFramework)

Copilot is powered by AI, so mistakes are possible. Review output carefully before use.

Positive Feedback
Negative Feedback

Provide additional feedback

Please help us improve GitHub Copilot by sharing more details about this comment.

Please select one or more of the options
Copy link
Member

Choose a reason for hiding this comment

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

Looks like Copilot is unaware of nullability checks. We already have a Debug.Assert(rightContentItems.Count > 0); in line 26.

// if we cannot find references for the left framework, then just use the same right references for the left assembly
if (fallbackAssemblyReferences is null && rightContentItems[0].Properties.TryGetValue("tfm", out tfmObj) && tfmObj is NuGetFramework rightTargetFramework)
{
fallbackAssemblyReferences = rightPackage.FindBestAssemblyReferencesForFramework(rightTargetFramework);
Copy link
Member Author

Choose a reason for hiding this comment

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

We might want to emit a diagnostic here. So long as all the types that were in the more-specific framework are in the less specific framework and are forwarded from the assembly name (excluding version) roslyn will still load them.

Copy link
Member

Choose a reason for hiding this comment

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

What do you mean by "less-specific" and "more-specific"?

@ViktorHofer
Copy link
Member

ViktorHofer commented Feb 24, 2025

I remember discussing this with Santi and later Akhil. Back then we were not convinced that using the current assemblies for the baseline is the right thing to do. We have this comment in the AssemblySymbolLoader which talks about checking assembly versions during the load:

// TODO: add version check and add a warning if it doesn't match?
using FileStream resolvedStream = File.OpenRead(potentialPath);
CreateAndAddReferenceToCompilation(assemblyReferenceName, rootAssemblyDisplayString, resolvedStream, referenceAssemblyNamesToIgnore, assemblyName);

I assume that this wouldn't work then anymore?
Can you imagine a case in which this wouldn't work and might result in incorrect execution or even an exception?

@ericstj
Copy link
Member Author

ericstj commented Feb 24, 2025

Yeah if we introduced a check on assembly versions of dependencies it wouldn't work, because left in this case references System.Runtime 8.x.x.x and right has System.Runtime 4.x.x.x.

If someone actually tried to take the assembly referencing S.R 8 and run it in an environment with only S.R 4 it would of course result in exceptions. That's not what we're trying to check for here though - we're trying to say that if we had a project targeting net8 and upgraded to the new package which only targets netstandard2.0, is the surface area exposed by net8 assembly the same as the that now exposed by the netstandard2.0 assembly. We just don't have the net8.0 references to use to evaluate the difference.

I think for certain it's more correct to resolve references against the exact framework targeted. I tend to think it's also more correct to run with some references rather than none at all.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-ApiCompat untriaged Request triage from a team member
Projects
None yet
3 participants