private void UpperBoundTypeArgumentInference(NamedTypeSymbol source, NamedTypeSymbol target, ref HashSet<DiagnosticInfo> useSiteDiagnostics) { // SPEC: The choice of inference for the i-th type argument is made // SPEC: based on the declaration of the i-th type parameter of C, as // SPEC: follows: // SPEC: * if Ui is known to be of reference type and the i-th type parameter // SPEC: was declared as covariant then an upper-bound inference is made. // SPEC: * if Ui is known to be of reference type and the i-th type parameter // SPEC: was declared as contravariant then a lower-bound inference is made. // SPEC: * otherwise, an exact inference is made. Debug.Assert((object)source != null); Debug.Assert((object)target != null); Debug.Assert(source.OriginalDefinition == target.OriginalDefinition); var typeParameters = ArrayBuilder<TypeParameterSymbol>.GetInstance(); var sourceTypeArguments = ArrayBuilder<TypeSymbol>.GetInstance(); var targetTypeArguments = ArrayBuilder<TypeSymbol>.GetInstance(); source.OriginalDefinition.GetAllTypeParameters(typeParameters); source.GetAllTypeArguments(sourceTypeArguments, ref useSiteDiagnostics); target.GetAllTypeArguments(targetTypeArguments, ref useSiteDiagnostics); Debug.Assert(typeParameters.Count == sourceTypeArguments.Count); Debug.Assert(typeParameters.Count == targetTypeArguments.Count); for (int arg = 0; arg < sourceTypeArguments.Count; ++arg) { var typeParameter = typeParameters[arg]; var sourceTypeArgument = sourceTypeArguments[arg]; var targetTypeArgument = targetTypeArguments[arg]; if (sourceTypeArgument.IsReferenceType && typeParameter.Variance == VarianceKind.Out) { UpperBoundInference(sourceTypeArgument, targetTypeArgument, ref useSiteDiagnostics); } else if (sourceTypeArgument.IsReferenceType && typeParameter.Variance == VarianceKind.In) { LowerBoundInference(sourceTypeArgument, targetTypeArgument, ref useSiteDiagnostics); } else { ExactInference(sourceTypeArgument, targetTypeArgument, ref useSiteDiagnostics); } } typeParameters.Free(); sourceTypeArguments.Free(); targetTypeArguments.Free(); }
private void ExactTypeArgumentInference(NamedTypeSymbol source, NamedTypeSymbol target, ref HashSet<DiagnosticInfo> useSiteDiagnostics) { Debug.Assert((object)source != null); Debug.Assert((object)target != null); Debug.Assert(source.OriginalDefinition == target.OriginalDefinition); var sourceTypeArguments = ArrayBuilder<TypeSymbol>.GetInstance(); var targetTypeArguments = ArrayBuilder<TypeSymbol>.GetInstance(); source.GetAllTypeArguments(sourceTypeArguments, ref useSiteDiagnostics); target.GetAllTypeArguments(targetTypeArguments, ref useSiteDiagnostics); Debug.Assert(sourceTypeArguments.Count == targetTypeArguments.Count); for (int arg = 0; arg < sourceTypeArguments.Count; ++arg) { ExactInference(sourceTypeArguments[arg], targetTypeArguments[arg], ref useSiteDiagnostics); } sourceTypeArguments.Free(); targetTypeArguments.Free(); }