public static bool TryGetElementTypesIfTupleOrCompatible(this TypeSymbol type, out ImmutableArray <TypeSymbol> elementTypes) { if (type.IsTupleType) { elementTypes = ((TupleTypeSymbol)type).TupleElementTypes; return(true); } // The following codepath should be very uncommon since it would be rare // to see a tuple underlying type not represented as a tuple. // It still might happen since tuple underlying types are creatable via public APIs // and it is also possible that they would be passed in. // PERF: if allocations here become nuisance, consider caching the results // in the type symbols that can actually be tuple compatible int cardinality; if (!type.IsTupleCompatible(out cardinality)) { // source not a tuple or compatible elementTypes = default(ImmutableArray <TypeSymbol>); return(false); } var elementTypesBuilder = ArrayBuilder <TypeSymbol> .GetInstance(cardinality); TupleTypeSymbol.AddElementTypes((NamedTypeSymbol)type, elementTypesBuilder); Debug.Assert(elementTypesBuilder.Count == cardinality); elementTypes = elementTypesBuilder.ToImmutableAndFree(); return(true); }
protected override bool HasImplicitTupleConversion(BoundExpression source, TypeSymbol destination, ref HashSet <DiagnosticInfo> useSiteDiagnostics) { if (source.Kind != BoundKind.TupleLiteral) { // source must be a tuple literal with no conversions return(false); } var tupleExpression = (BoundTupleLiteral)source; var arguments = tupleExpression.Arguments; // check if the type is actually compatible type for a tuple of given cardinality if (!destination.IsTupleOrCompatibleWithTupleOfCardinality(arguments.Length)) { return(false); } var targetElementTypes = ArrayBuilder <TypeSymbol> .GetInstance(arguments.Length); TupleTypeSymbol.AddElementTypes((NamedTypeSymbol)destination, targetElementTypes); Debug.Assert(arguments.Length == targetElementTypes.Count); try { // check arguments against flattened list of target element types for (int i = 0; i < arguments.Length; i++) { var argument = arguments[i]; var result = ClassifyImplicitConversionFromExpression(argument, targetElementTypes[i], ref useSiteDiagnostics); if (!result.Exists) { return(false); } } return(true); } finally { targetElementTypes.Free(); } }
public static ImmutableArray <TypeSymbol> GetElementTypesOfTupleOrCompatible(this TypeSymbol type) { if (type.IsTupleType) { return(((TupleTypeSymbol)type).TupleElementTypes); } // The following codepath should be very uncommon since it would be rare // to see a tuple underlying type not represented as a tuple. // It still might happen since tuple underlying types are creatable via public APIs // and it is also possible that they would be passed in. Debug.Assert(type.IsTupleCompatible()); // PERF: if allocations here become nuisance, consider caching the results // in the type symbols that can actually be tuple compatible var elementTypesBuilder = ArrayBuilder <TypeSymbol> .GetInstance(); TupleTypeSymbol.AddElementTypes((NamedTypeSymbol)type, elementTypesBuilder); return(elementTypesBuilder.ToImmutableAndFree()); }