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

Covariant returns part1 #43576

Merged
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/Compilers/CSharp/Portable/CSharpResources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -6070,4 +6070,7 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ
<data name="WRN_GeneratorFailedDuringInitialization_Title" xml:space="preserve">
<value>Generator failed to initialize.</value>
</data>
<data name="IDS_FeatureCovariantReturnsForOverrides" xml:space="preserve">
<value>covariant returns</value>
</data>
</root>
2 changes: 2 additions & 0 deletions src/Compilers/CSharp/Portable/Errors/MessageID.cs
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ internal enum MessageID
IDS_FeatureMemberNotNull = MessageBase + 12768,
IDS_FeatureNativeInt = MessageBase + 12769,
IDS_FeatureTargetTypedObjectCreation = MessageBase + 12770,
IDS_FeatureCovariantReturnsForOverrides = MessageBase + 12771,
}

// Message IDs may refer to strings that need to be localized.
Expand Down Expand Up @@ -305,6 +306,7 @@ internal static LanguageVersion RequiredVersion(this MessageID feature)
case MessageID.IDS_FeatureTargetTypedObjectCreation: // syntax check
case MessageID.IDS_FeatureMemberNotNull:
case MessageID.IDS_FeatureNativeInt:
case MessageID.IDS_FeatureCovariantReturnsForOverrides: // semantic check
return LanguageVersion.Preview;

// C# 8.0 features.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,12 +155,11 @@ internal class MemberSignatureComparer : IEqualityComparer<Symbol>
/// <summary>
/// This instance is used to check whether one property or event overrides another, according to the C# definition.
/// <para>NOTE: C# ignores accessor member names.</para>
/// <para>CAVEAT: considers return types so that getters and setters will be treated the same.</para>
/// </summary>
public static readonly MemberSignatureComparer CSharpAccessorOverrideComparer = new MemberSignatureComparer(
Copy link
Member

@jcouv jcouv Apr 23, 2020

Choose a reason for hiding this comment

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

CSharpAccessorOverrideComparer [](start = 55, length = 30)

Looking at the call sites that use this comparer, I see that they also use RuntimeSignatureComparer (for example in MakePropertyAccessorOverriddenOrHiddenMembers depending on accessorIsFromSomeCompilation).
Should RuntimeSignatureComparer also be adjusted?

Also, I notice that this PR hasn't updated MakePropertyAccessorOverriddenOrHiddenMembers. That means it is using a relaxed comparison, which is not constrained by new covariance rules.
Oh, I see that's what you meant by "Note that we now consider a get accessor with the wrong return type to still be an override.". Should probably be marked as PROTOTYPE #Closed

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 are not changing the runtime's rules for implicit overriding. It includes the return type. The language's concept doesn't. So no change to the other comparer is needed.

The "relaxed" comparison is the C# language rules. This is not a temporary PROTOTYPE. It is the new rules.


In reply to: 413964273 [](ancestors = 413964273)

considerName: false,
considerExplicitlyImplementedInterfaces: false, //Bug: DevDiv #15775
considerReturnType: true,
considerReturnType: false,
Copy link
Member

@jcouv jcouv Apr 23, 2020

Choose a reason for hiding this comment

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

I see that this comparer is used for properties/indexers and also events. Can you add tests for event accessors? #Closed

Copy link
Member Author

Choose a reason for hiding this comment

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

Sure, but events have an add accessor which will prevent overriding with a different return type.


In reply to: 413965442 [](ancestors = 413965442)

considerTypeConstraints: false,
considerCallingConvention: false, //ignore static-ness
considerRefKindDifferences: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -701,8 +701,11 @@ private void CheckNewModifier(Symbol symbol, bool isNew, DiagnosticBag diagnosti
}
}

private static void CheckOverrideMember(Symbol overridingMember, OverriddenOrHiddenMembersResult overriddenOrHiddenMembers,
DiagnosticBag diagnostics, out bool suppressAccessors)
private void CheckOverrideMember(
Copy link
Member

@jcouv jcouv Apr 23, 2020

Choose a reason for hiding this comment

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

Should this PR target the features/records branch?
FYI, I am doing a refactoring of this method (simple breaking out of this massive and deeply nested method) in the records branch 68426e7
If covariant returns needs a dedicated feature branch, then consider cherry-picking that refactoring. #Closed

Copy link
Member Author

Choose a reason for hiding this comment

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

Covariant returns are a separate feature.


In reply to: 413984024 [](ancestors = 413984024)

Copy link
Member

@jcouv jcouv Apr 23, 2020

Choose a reason for hiding this comment

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

From standup meeting today, seems like folks are leaning towards using a separate branch for now. #Closed

Copy link
Member Author

Choose a reason for hiding this comment

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

Your delta is in a private branch and not yet integrated. I don't see an advantage of merging now and hoping you don't change things further. I know I will be changing things further. Will deal with the conflicts later.


In reply to: 414044555 [](ancestors = 414044555,413984024)

Symbol overridingMember,
OverriddenOrHiddenMembersResult overriddenOrHiddenMembers,
DiagnosticBag diagnostics,
out bool suppressAccessors)
{
Debug.Assert((object)overridingMember != null);
Debug.Assert(overriddenOrHiddenMembers != null);
Expand Down Expand Up @@ -877,7 +880,7 @@ private static void CheckOverrideMember(Symbol overridingMember, OverriddenOrHid
diagnostics.Add(ErrorCode.ERR_CantChangeRefReturnOnOverride, overridingMemberLocation, overridingMember, overriddenMember);
suppressAccessors = true; //we get really unhelpful errors from the accessor if the ref kind is mismatched
}
else if (!overridingMemberType.Equals(overriddenMemberType, TypeCompareKind.AllIgnoreOptions))
else if (!IsValidOverrideReturnType(overridingProperty, overridingMemberType, overriddenMemberType, diagnostics))
{
// if the type is or contains an error type, the type must be fixed before the override can be found, so suppress error
if (!isOrContainsErrorType(overridingMemberType.Type))
Copy link
Contributor

@AlekseyTs AlekseyTs Apr 27, 2020

Choose a reason for hiding this comment

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

if (!isOrContainsErrorType(overridingMemberType.Type)) [](start = 32, length = 54)

It looks like we are not reporting language version mismatch on this code path. Is the assumption that this would be covered by the getter? Consider adding a comment about that. #Closed

Copy link
Member Author

Choose a reason for hiding this comment

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

This appears to be addressed in #43673 iteration 1.


In reply to: 416157623 [](ancestors = 416157623)

Expand Down Expand Up @@ -981,13 +984,24 @@ private static void CheckOverrideMember(Symbol overridingMember, OverriddenOrHid
{
diagnostics.Add(ErrorCode.ERR_CantChangeRefReturnOnOverride, overridingMemberLocation, overridingMember, overriddenMember);
}
else if (!overridingMethod.ReturnTypeWithAnnotations.Equals(overriddenMethod.ReturnTypeWithAnnotations, TypeCompareKind.AllIgnoreOptions))
else if (!IsValidOverrideReturnType(overridingMethod, overridingMethod.ReturnTypeWithAnnotations, overriddenMethod.ReturnTypeWithAnnotations, diagnostics))
{
// if the Return type is or contains an error type, the return type must be fixed before the override can be found, so suppress error
if (!isOrContainsErrorType(overridingMethod.ReturnType))
{
// error CS0508: return type must be 'C<V>' to match overridden member 'M<T>()'
diagnostics.Add(ErrorCode.ERR_CantChangeReturnTypeOnOverride, overridingMemberLocation, overridingMember, overriddenMember, overriddenMethod.ReturnType);
// If the return type would be a valid covariant return, suggest using covariant return feature.
HashSet<DiagnosticInfo> discardedUseSiteDiagnostics = null;
if (DeclaringCompilation.Conversions.HasIdentityOrImplicitReferenceConversion(overridingMethod.ReturnTypeWithAnnotations.Type, overriddenMethod.ReturnTypeWithAnnotations.Type, ref discardedUseSiteDiagnostics))
Copy link
Member

@agocke agocke Apr 23, 2020

Choose a reason for hiding this comment

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

This seems strange. Shouldn't we check if it's valid, including a covariant return, then check if the feature is enabled and, if it isn't and the two types are not equal, produce an error? #ByDesign

Copy link
Member Author

Choose a reason for hiding this comment

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

I'd rather keep the error case separate. rather than blend the code for the correct case and the error case.


In reply to: 414069899 [](ancestors = 414069899)

Copy link
Contributor

@AlekseyTs AlekseyTs Apr 27, 2020

Choose a reason for hiding this comment

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

discardedUseSiteDiagnostics [](start = 216, length = 27)

I do not think we can discard use-site diagnostics for this scenario. It is quite possible that a missing reference is the root cause of the failure and we should report that. Also, we should track dependencies for success cases, this feature is still in a separate feature brunch, but each feature should be developed with it in mind so that merge goes as smooth as possible later. #Closed

Copy link
Contributor

Choose a reason for hiding this comment

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

I see that this check duplicates similar check in IsValidOverrideReturnType and in there we do not discard use-site diagnostics. So, reporting it here would be redundant.


In reply to: 416151997 [](ancestors = 416151997)

{
var diagnosticInfo = MessageID.IDS_FeatureCovariantReturnsForOverrides.GetFeatureAvailabilityDiagnosticInfo(this.DeclaringCompilation);
Debug.Assert(diagnosticInfo is { });
diagnostics.Add(diagnosticInfo, overridingMemberLocation);
}
else
{
// error CS0508: return type must be 'C<V>' to match overridden member 'M<T>()'
diagnostics.Add(ErrorCode.ERR_CantChangeReturnTypeOnOverride, overridingMemberLocation, overridingMember, overriddenMember, overriddenMethod.ReturnType);
Copy link
Member

@agocke agocke Apr 23, 2020

Choose a reason for hiding this comment

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

We should either never produce this error message any more, or we should change the text to match the new language design #Resolved

Copy link
Member Author

@gafter gafter Apr 23, 2020

Choose a reason for hiding this comment

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

This diagnostic is apropos for non-reference types or sealed reference types or in older language versions. I will add a prototype comment to adjust for inheritable reference types.


In reply to: 414071529 [](ancestors = 414071529)

}
}
}
else if (overriddenMethod.IsRuntimeFinalizer())
Expand Down Expand Up @@ -1058,6 +1072,29 @@ static void checkValidNullableMethodOverride(
}
}

/// <summary>
/// Return true if <paramref name="overridingReturnType"/> is valid for the return type of an override method when the overridden method's return type is <paramref name="overriddenReturnType"/>.
/// </summary>
private bool IsValidOverrideReturnType(Symbol overridingSymbol, TypeWithAnnotations overridingReturnType, TypeWithAnnotations overriddenReturnType, DiagnosticBag diagnostics)
Copy link
Member

@jcouv jcouv Apr 23, 2020

Choose a reason for hiding this comment

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

nit: could be a local function #Closed

Copy link
Member Author

Choose a reason for hiding this comment

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

I expect this will be useful elsewhere later.


In reply to: 413985145 [](ancestors = 413985145)

Copy link
Member

@jcouv jcouv Apr 23, 2020

Choose a reason for hiding this comment

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

IsValidOverrideReturnType [](start = 21, length = 25)

I'm curious why you structured this method this way. I would have expected:

  1. check if types are equal, if so, then return true
  2. check if the types are convertible, if so do the version check and report LangVer error here (so it doesn't have to be duplicated at various call sites)

The benefit of this approach is that it keeps the binding from depending on LangVer, and we don't have to duplicate the HasIdentityOrImplicitReferenceConversion check. We can verify that in testing the semantic model in error cases. #Closed

Copy link
Member Author

@gafter gafter Apr 23, 2020

Choose a reason for hiding this comment

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

Not all places where this is called deserve a language version diagnostic. For example, that probably isn't apropos for events.

I'm not concerned with an extra check in the case of an error, since errors such as this occur only rarely as an intermediate state during source development.


In reply to: 414000465 [](ancestors = 414000465)

Copy link
Member

Choose a reason for hiding this comment

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

Okay.
I'm still concerned that we're binding differently based on LangVer and that will be visible via symbols from semantic model.


In reply to: 414047588 [](ancestors = 414047588,414000465)

Copy link
Member Author

Choose a reason for hiding this comment

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

Verifying the symbol and semantic models is a future work item.


In reply to: 414049357 [](ancestors = 414049357,414047588,414000465)

Copy link
Member

Choose a reason for hiding this comment

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

Sorry to insist, but I don't feel good about punting because we can see there is an issue here (should not bind differently depending on LangVer). Let's avoid introducing this problem, rather than come back and fix it later.


In reply to: 414052536 [](ancestors = 414052536,414049357,414047588,414000465)

Copy link
Member Author

Choose a reason for hiding this comment

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

This doesn't affect binding. It only affects what diagnostics are produced. An override method with the wrong return type has always been an override of the base method. That is not changing. What is changing is when an error is produced.


In reply to: 414106079 [](ancestors = 414106079,414052536,414049357,414047588,414000465)

Copy link
Member

@jcouv jcouv Apr 23, 2020

Choose a reason for hiding this comment

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

Ah, thanks! :-) #Closed

{
if (DeclaringCompilation.LanguageVersion >= MessageID.IDS_FeatureCovariantReturnsForOverrides.RequiredVersion())
Copy link
Member

@jcouv jcouv Apr 23, 2020

Choose a reason for hiding this comment

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

IDS_FeatureCovariantReturnsForOverrides [](start = 66, length = 39)

Just to confirm, I think we can assume that language version implies newer platform (ie. one that supports covariant returns). If not, we should add a platform check as well #Closed

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 do not support emitting metadata (targeting any plaform) yet. When we do, I'll add a check if apropos.


In reply to: 414007929 [](ancestors = 414007929)

{
HashSet<DiagnosticInfo> useSiteDiagnostics = null;
var result = DeclaringCompilation.Conversions.HasIdentityOrImplicitReferenceConversion(overridingReturnType.Type, overriddenReturnType.Type, ref useSiteDiagnostics);
Copy link
Member

@jcouv jcouv Apr 23, 2020

Choose a reason for hiding this comment

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

HasIdentityOrImplicitReferenceConversion [](start = 62, length = 40)

This would allow overriding with a derived interface, no?
From the runtime PR, I see that's not going to be allowed: "Return types in covariant return methods can only be reference types: covariant interface return types are not supported." #Resolved

Copy link
Member Author

Choose a reason for hiding this comment

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

It can be any implicit reference conversion. What is not supported is covariant overrides of methods declared in interfaces.


In reply to: 414047290 [](ancestors = 414047290)

Copy link
Member

Choose a reason for hiding this comment

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

Should the description in runtime PR be corrected then?


In reply to: 414049729 [](ancestors = 414049729,414047290)

Copy link
Member Author

Choose a reason for hiding this comment

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

I've started an email thread about that question.


In reply to: 414050605 [](ancestors = 414050605,414049729,414047290)

if (useSiteDiagnostics != null)
{
Location symbolLocation = overridingSymbol.Locations.FirstOrDefault();
diagnostics.Add(symbolLocation, useSiteDiagnostics);
Copy link
Member

@jcouv jcouv Apr 23, 2020

Choose a reason for hiding this comment

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

Please add a test for this code path (ie. with a use-site diagnostic from conversion) #Closed

}

return result;
}
else
{
return overridingReturnType.Equals(overriddenReturnType, TypeCompareKind.AllIgnoreOptions);
}
}

static readonly ReportMismatchInReturnType<Location> ReportBadReturn =
(DiagnosticBag diagnostics, MethodSymbol overriddenMethod, MethodSymbol overridingMethod, bool topLevel, Location location)
=> diagnostics.Add(topLevel ?
Expand Down
5 changes: 5 additions & 0 deletions src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -894,6 +894,11 @@
<target state="translated">slučovací přiřazení</target>
<note />
</trans-unit>
<trans-unit id="IDS_FeatureCovariantReturnsForOverrides">
<source>covariant returns</source>
<target state="new">covariant returns</target>
<note />
</trans-unit>
<trans-unit id="IDS_FeatureDelegateGenericTypeConstraint">
<source>delegate generic type constraints</source>
<target state="translated">delegovat obecná omezení typu</target>
Expand Down
5 changes: 5 additions & 0 deletions src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -894,6 +894,11 @@
<target state="translated">Zusammenfügungszuweisung</target>
<note />
</trans-unit>
<trans-unit id="IDS_FeatureCovariantReturnsForOverrides">
<source>covariant returns</source>
<target state="new">covariant returns</target>
<note />
</trans-unit>
<trans-unit id="IDS_FeatureDelegateGenericTypeConstraint">
<source>delegate generic type constraints</source>
<target state="translated">Generische Typeneinschränkungen für Delegat</target>
Expand Down
5 changes: 5 additions & 0 deletions src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -894,6 +894,11 @@
<target state="translated">asignación de incorporación</target>
<note />
</trans-unit>
<trans-unit id="IDS_FeatureCovariantReturnsForOverrides">
<source>covariant returns</source>
<target state="new">covariant returns</target>
<note />
</trans-unit>
<trans-unit id="IDS_FeatureDelegateGenericTypeConstraint">
<source>delegate generic type constraints</source>
<target state="translated">restricciones de tipo genérico delegate</target>
Expand Down
5 changes: 5 additions & 0 deletions src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -894,6 +894,11 @@
<target state="translated">assignation de fusion</target>
<note />
</trans-unit>
<trans-unit id="IDS_FeatureCovariantReturnsForOverrides">
<source>covariant returns</source>
<target state="new">covariant returns</target>
<note />
</trans-unit>
<trans-unit id="IDS_FeatureDelegateGenericTypeConstraint">
<source>delegate generic type constraints</source>
<target state="translated">contraintes de type générique de délégué</target>
Expand Down
5 changes: 5 additions & 0 deletions src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -894,6 +894,11 @@
<target state="translated">assegnazione di coalescenza</target>
<note />
</trans-unit>
<trans-unit id="IDS_FeatureCovariantReturnsForOverrides">
<source>covariant returns</source>
<target state="new">covariant returns</target>
<note />
</trans-unit>
<trans-unit id="IDS_FeatureDelegateGenericTypeConstraint">
<source>delegate generic type constraints</source>
<target state="translated">vincoli di tipo generico delegato</target>
Expand Down
5 changes: 5 additions & 0 deletions src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -894,6 +894,11 @@
<target state="translated">合体代入</target>
<note />
</trans-unit>
<trans-unit id="IDS_FeatureCovariantReturnsForOverrides">
<source>covariant returns</source>
<target state="new">covariant returns</target>
<note />
</trans-unit>
<trans-unit id="IDS_FeatureDelegateGenericTypeConstraint">
<source>delegate generic type constraints</source>
<target state="translated">delegate ジェネリック型の制約</target>
Expand Down
5 changes: 5 additions & 0 deletions src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -894,6 +894,11 @@
<target state="translated">병합 할당</target>
<note />
</trans-unit>
<trans-unit id="IDS_FeatureCovariantReturnsForOverrides">
<source>covariant returns</source>
<target state="new">covariant returns</target>
<note />
</trans-unit>
<trans-unit id="IDS_FeatureDelegateGenericTypeConstraint">
<source>delegate generic type constraints</source>
<target state="translated">대리자 제네릭 형식 제약 조건</target>
Expand Down
5 changes: 5 additions & 0 deletions src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -894,6 +894,11 @@
<target state="translated">przypisanie łączące</target>
<note />
</trans-unit>
<trans-unit id="IDS_FeatureCovariantReturnsForOverrides">
<source>covariant returns</source>
<target state="new">covariant returns</target>
<note />
</trans-unit>
<trans-unit id="IDS_FeatureDelegateGenericTypeConstraint">
<source>delegate generic type constraints</source>
<target state="translated">ogólne ograniczenia typów delegowania</target>
Expand Down
5 changes: 5 additions & 0 deletions src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -892,6 +892,11 @@
<target state="translated">atribuição de união</target>
<note />
</trans-unit>
<trans-unit id="IDS_FeatureCovariantReturnsForOverrides">
<source>covariant returns</source>
<target state="new">covariant returns</target>
<note />
</trans-unit>
<trans-unit id="IDS_FeatureDelegateGenericTypeConstraint">
<source>delegate generic type constraints</source>
<target state="translated">restrições de tipo genérico delegate</target>
Expand Down
5 changes: 5 additions & 0 deletions src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -894,6 +894,11 @@
<target state="translated">назначение объединения</target>
<note />
</trans-unit>
<trans-unit id="IDS_FeatureCovariantReturnsForOverrides">
<source>covariant returns</source>
<target state="new">covariant returns</target>
<note />
</trans-unit>
<trans-unit id="IDS_FeatureDelegateGenericTypeConstraint">
<source>delegate generic type constraints</source>
<target state="translated">ограничения универсального типа для делегата</target>
Expand Down
5 changes: 5 additions & 0 deletions src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -894,6 +894,11 @@
<target state="translated">birleştirme ataması</target>
<note />
</trans-unit>
<trans-unit id="IDS_FeatureCovariantReturnsForOverrides">
<source>covariant returns</source>
<target state="new">covariant returns</target>
<note />
</trans-unit>
<trans-unit id="IDS_FeatureDelegateGenericTypeConstraint">
<source>delegate generic type constraints</source>
<target state="translated">delegate genel tür kısıtlamaları</target>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -894,6 +894,11 @@
<target state="translated">合并赋值</target>
<note />
</trans-unit>
<trans-unit id="IDS_FeatureCovariantReturnsForOverrides">
<source>covariant returns</source>
<target state="new">covariant returns</target>
<note />
</trans-unit>
<trans-unit id="IDS_FeatureDelegateGenericTypeConstraint">
<source>delegate generic type constraints</source>
<target state="translated">委托泛型类型约束</target>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -894,6 +894,11 @@
<target state="translated">聯合指派</target>
<note />
</trans-unit>
<trans-unit id="IDS_FeatureCovariantReturnsForOverrides">
<source>covariant returns</source>
<target state="new">covariant returns</target>
<note />
</trans-unit>
<trans-unit id="IDS_FeatureDelegateGenericTypeConstraint">
<source>delegate generic type constraints</source>
<target state="translated">委派泛型類型條件約束</target>
Expand Down
Loading