You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[release/10.0] Fix LoadExactInterfaceMap for sub-interfaces with complex type arguments under special marker parents (#124835)
Backport of #124684 to release/10.0
/cc @davidwrighton
## Customer Impact
- [x] Customer reported
- [ ] Found internally
The earlier fix for #123254 did not fix all possible cases where the
incorrect type would be loaded. This fix fills out the special case
matrix some more, and I believe should fix all the issues found.
## Regression
- [x] Yes
- [ ] No
This issue was introduced with PR #120712, and mitigated somewhat with
PR #123520. This fix builds on that fix to fix additional issues found
by @reduckted.
## Testing
The fix includes a fairly large test suite covering possible ways type
loading could fail around this fix. It was missed previously in the
previous small fix as the importance of comparing the fully loaded, and
partially loaded interface maps on the generic type definition was
missed during test development. This fix has also been tested by
delivering a hotfixed build to @reduckted which which he was able to
verify fixed the issues he had seen in production as well as in testing.
## Risk
Low. Its filling out more special cases in the new codepaths added in PR
#123520.
**IMPORTANT**: If this backport is for a servicing release, please
verify that:
- For .NET 8 and .NET 9: The PR target branch is `release/X.0-staging`,
not `release/X.0`.
- For .NET 10+: The PR target branch is `release/X.0` (no `-staging`
suffix).
## Package authoring no longer needed in .NET 9
**IMPORTANT**: Starting with .NET 9, you no longer need to edit a NuGet
package's csproj to enable building and bump the version.
Keep in mind that we still need package authoring in .NET 8 and older
versions.
---------
Co-authored-by: David Wrighton <davidwr@microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
// 2. It is a special marker type, AND pNewItfMT is a special marker type. Compute the exact instantiation as containing entirely a list of types corresponding to calling GetSpecialInstantiationType on pMT (This rule works based on the current behavior of GetSpecialInstantiationType where it treats all interfaces the same)
9675
-
// 3. It is a special marker type, but pNewItfMT is NOT a special marker type. Compute the exact instantiation as containing entirely a list of types corresponding to calling GetSpecialInstantiationType on pNewItfMT
9676
-
// 4. It is an exact instantiation
9674
+
// 2. It is a special marker type, AND pNewIntfMT is a special marker type. Compute the exact instantiation as containing entirely a list of
9675
+
// types corresponding to calling GetSpecialInstantiationType on pMT (This rule works based on the current behavior of
9676
+
// GetSpecialInstantiationType where it treats all interfaces the same)
9677
+
// 3. It is a special marker type, but pNewIntfMT is NOT a special marker type. Compute the exact instantiation as containing entirely a list
9678
+
// of types corresponding to calling GetSpecialInstantiationType on pNewIntfMT
9679
+
// 4. It is an exact instantiation, but pNewIntfMT was a special marker type, and the exact instantiation type found here could have been a
9680
+
// special marker type. This should produce a result equivalent to case 2 (the special marker type)
9681
+
// 5. It is an exact instantiation, but pNewIntfMT was a special marker type, and the exact instantiation type is NOT one which would have
9682
+
// been on the exact instantiation of pNewIntfMT if it were not a special marker type. In theory we could reconstruct this, but this is a
9683
+
// rare scenario, so we just fallback to the retry with exact interfaces pathway
9684
+
// 6. It is an exact instantiation, and pNewIntfMT is NOT a special marker type, compute the result and insert either a special marker or
9685
+
// the exact instantiation already found.
9677
9686
//
9678
-
// NOTE: pItfPossiblyApprox must not be considered a special marker type if pNewItfMT has the MayHaveOpenInterfacesInInterfaceMap flag set
9687
+
// NOTE: pItfPossiblyApprox must not be considered a special marker type if pNewIntfMT has the MayHaveOpenInterfacesInInterfaceMap flag set
9679
9688
//
9680
9689
// Then determine if all of the following conditions hold true.
9681
9690
// 1. All generic arguments are the same (always true for cases 2 and 3 above)
// Validated that all generic arguments are the same, and that the first generic argument in the instantiation is exactly the value of calling GetSpecialInstantiationType on pMT
if (ClassLoader::EligibleForSpecialMarkerTypeUsage(pItfPossiblyApprox->GetInstantiation(), pNewIntfMT))
9742
+
{
9743
+
// Case 4 - we have an exact instantiation, but pNewIntfMT was a special marker type, and the exact instantiation type found here could have been a special marker type. We need to check if the exact instantiation we found
9744
+
// here could have been a special marker type. If it is, we need to insert the special marker type here.
else if (pItfPossiblyApprox->ContainsGenericVariables())
9748
+
{
9749
+
// Case 5
9750
+
// If the instantiation contains generic variables and can't be converted to the special marker type, then we would need to fully re-instantiate the type with a deep substitution to get the exact instantiation, which is complex and expensive, and we expect this to be a rare case, so we can just fallback to the retry with exact interfaces pathway in this case.
9751
+
retry = true;
9752
+
break;
9753
+
}
9754
+
// If we reach here, we've already found the correct pItfToInsert (case 4), OR we can proceed to case 6 since pItfPossiblyApprox was an exact type defined on the generic type.
9734
9755
}
9735
-
else
9756
+
9757
+
if (pItfToInsert == NULL)
9736
9758
{
9737
-
pItfToInsert = pItfPossiblyApprox;
9738
-
intendedExactMatch = true;
9759
+
// Case 6, this is an exact instantiation of exactly the right type. Insert it here.
9760
+
if (ClassLoader::EligibleForSpecialMarkerTypeUsage(pItfPossiblyApprox->GetInstantiation(), pMT))
9761
+
{
9762
+
// Validated that all generic arguments are the same, and that the first generic argument in the instantiation is exactly the value of calling GetSpecialInstantiationType on pMT
0 commit comments