private static void CheckEffectiveAndDeducedBaseTypes(ConversionsBase conversions, TypeSymbol effectiveBase, TypeSymbol deducedBase) { Debug.Assert((object)deducedBase != null); Debug.Assert((object)effectiveBase != null); HashSet <DiagnosticInfo> useSiteDiagnostics = null; Debug.Assert(deducedBase.IsErrorType() || effectiveBase.IsErrorType() || conversions.HasIdentityOrImplicitReferenceConversion(deducedBase, effectiveBase, ref useSiteDiagnostics) || conversions.HasBoxingConversion(deducedBase, effectiveBase, ref useSiteDiagnostics)); }
private static bool SatisfiesConstraintType( ConversionsBase conversions, TypeSymbol typeArgument, TypeSymbol constraintType, ref HashSet <DiagnosticInfo> useSiteDiagnostics) { if (constraintType.IsErrorType()) { return(false); } // Spec 4.4.4 describes the valid conversions from // type argument A to constraint type C: // "An identity conversion (6.1.1). // An implicit reference conversion (6.1.6). ..." if (conversions.HasIdentityOrImplicitReferenceConversion(typeArgument, constraintType, ref useSiteDiagnostics)) { return(true); } // "... A boxing conversion (6.1.7), provided that type A is a non-nullable value type. ..." // NOTE: we extend this to allow, for example, a conversion from Nullable<T> to object. if (typeArgument.IsValueType && conversions.HasBoxingConversion(typeArgument.IsNullableType() ? ((NamedTypeSymbol)typeArgument).ConstructedFrom : typeArgument, constraintType, ref useSiteDiagnostics)) { return(true); } if (typeArgument.TypeKind == TypeKind.TypeParameter) { var typeParameter = (TypeParameterSymbol)typeArgument; // "... An implicit reference, boxing, or type parameter conversion // from type parameter A to C." if (conversions.HasImplicitTypeParameterConversion(typeParameter, constraintType, ref useSiteDiagnostics)) { return(true); } // TypeBind::SatisfiesBound allows cases where one of the // type parameter constraints satisfies the constraint. foreach (var typeArgumentConstraint in typeParameter.ConstraintTypesWithDefinitionUseSiteDiagnostics(ref useSiteDiagnostics)) { if (SatisfiesConstraintType(conversions, typeArgumentConstraint, constraintType, ref useSiteDiagnostics)) { return(true); } } } return(false); }
/// <summary> /// Returns true if type a is encompassed by type b (spec 6.4.3), /// and returns false otherwise. /// </summary> private static bool IsEncompassedBy(ConversionsBase conversions, TypeSymbol a, TypeSymbol b, ref HashSet<DiagnosticInfo> useSiteDiagnostics) { Debug.Assert(IsValidEncompassedByArgument(a)); Debug.Assert(IsValidEncompassedByArgument(b)); return conversions.HasIdentityOrImplicitReferenceConversion(a, b, ref useSiteDiagnostics) || conversions.HasBoxingConversion(a, b, ref useSiteDiagnostics); }
private static bool SatisfiesConstraintType( ConversionsBase conversions, TypeSymbol typeArgument, TypeSymbol constraintType, ref HashSet<DiagnosticInfo> useSiteDiagnostics) { if (constraintType.IsErrorType()) { return false; } // Spec 4.4.4 describes the valid conversions from // type argument A to constraint type C: // "An identity conversion (6.1.1). // An implicit reference conversion (6.1.6). ..." if (conversions.HasIdentityOrImplicitReferenceConversion(typeArgument, constraintType, ref useSiteDiagnostics)) { return true; } // "... A boxing conversion (6.1.7), provided that type A is a non-nullable value type. ..." // NOTE: we extend this to allow, for example, a conversion from Nullable<T> to object. if (typeArgument.IsValueType && conversions.HasBoxingConversion(typeArgument.IsNullableType() ? ((NamedTypeSymbol)typeArgument).ConstructedFrom : typeArgument, constraintType, ref useSiteDiagnostics)) { return true; } if (typeArgument.TypeKind == TypeKind.TypeParameter) { var typeParameter = (TypeParameterSymbol)typeArgument; // "... An implicit reference, boxing, or type parameter conversion // from type parameter A to C." if (conversions.HasImplicitTypeParameterConversion(typeParameter, constraintType, ref useSiteDiagnostics)) { return true; } // TypeBind::SatisfiesBound allows cases where one of the // type parameter constraints satisfies the constraint. foreach (var typeArgumentConstraint in typeParameter.ConstraintTypesWithDefinitionUseSiteDiagnostics(ref useSiteDiagnostics)) { if (SatisfiesConstraintType(conversions, typeArgumentConstraint, constraintType, ref useSiteDiagnostics)) { return true; } } } return false; }
private static void CheckEffectiveAndDeducedBaseTypes(ConversionsBase conversions, TypeSymbol effectiveBase, TypeSymbol deducedBase) { Debug.Assert((object)deducedBase != null); Debug.Assert((object)effectiveBase != null); HashSet<DiagnosticInfo> useSiteDiagnostics = null; Debug.Assert(deducedBase.IsErrorType() || effectiveBase.IsErrorType() || conversions.HasIdentityOrImplicitReferenceConversion(deducedBase, effectiveBase, ref useSiteDiagnostics) || conversions.HasBoxingConversion(deducedBase, effectiveBase, ref useSiteDiagnostics)); }
/// <summary> /// Returns true if type a is encompassed by type b (spec 6.4.3), /// and returns false otherwise. /// </summary> private static bool IsEncompassedBy(ConversionsBase conversions, TypeSymbol a, TypeSymbol b, ref HashSet <DiagnosticInfo> useSiteDiagnostics) { Debug.Assert(IsValidEncompassedByArgument(a)); Debug.Assert(IsValidEncompassedByArgument(b)); return(conversions.HasIdentityOrImplicitReferenceConversion(a, b, ref useSiteDiagnostics) || conversions.HasBoxingConversion(a, b, ref useSiteDiagnostics)); }