public override Conversion GetStackAllocConversion(BoundStackAllocArrayCreation sourceExpression, TypeSymbol destination, ref HashSet <DiagnosticInfo> useSiteDiagnostics) { if (sourceExpression.Syntax.IsVariableDeclarationInitialization()) { Debug.Assert((object)sourceExpression.Type == null); Debug.Assert((object)sourceExpression.ElementType != null); var sourceAsPointer = new PointerTypeSymbol(TypeSymbolWithAnnotations.Create(sourceExpression.ElementType)); var pointerConversion = ClassifyImplicitConversionFromType(sourceAsPointer, destination, ref useSiteDiagnostics); if (pointerConversion.IsValid) { return(Conversion.MakeStackAllocToPointerType(pointerConversion)); } else { var spanType = _binder.GetWellKnownType(WellKnownType.core_Span_T, ref useSiteDiagnostics); if (spanType.TypeKind == TypeKind.Struct && spanType.IsRefLikeType) { var spanType_T = spanType.Construct(sourceExpression.ElementType); var spanConversion = ClassifyImplicitConversionFromType(spanType_T, destination, ref useSiteDiagnostics); if (spanConversion.Exists) { return(Conversion.MakeStackAllocToSpanType(spanConversion)); } } } } return(Conversion.NoConversion); }
public override BoundNode VisitStackAllocArrayCreation(BoundStackAllocArrayCreation stackAllocNode) { var rewrittenCount = VisitExpression(stackAllocNode.Count); var type = stackAllocNode.Type; if (rewrittenCount.ConstantValue?.Int32Value == 0) { // either default(span) or nullptr return(_factory.Default(type)); } var elementType = stackAllocNode.ElementType; var initializerOpt = stackAllocNode.InitializerOpt; if (initializerOpt != null) { initializerOpt = initializerOpt.Update(VisitList(initializerOpt.Initializers)); } if (type.IsPointerType()) { var stackSize = RewriteStackAllocCountToSize(rewrittenCount, elementType); return(new BoundConvertedStackAllocExpression(stackAllocNode.Syntax, elementType, stackSize, initializerOpt, stackAllocNode.Type)); } else if (TypeSymbol.Equals(type.OriginalDefinition, _compilation.GetWellKnownType(WellKnownType.core_Span_T), TypeCompareKind.ConsiderEverything2)) { var spanType = (NamedTypeSymbol)stackAllocNode.Type; var sideEffects = ArrayBuilder <BoundExpression> .GetInstance(); var locals = ArrayBuilder <LocalSymbol> .GetInstance(); var countTemp = CaptureExpressionInTempIfNeeded(rewrittenCount, sideEffects, locals); var stackSize = RewriteStackAllocCountToSize(countTemp, elementType); stackAllocNode = new BoundConvertedStackAllocExpression(stackAllocNode.Syntax, elementType, stackSize, initializerOpt, spanType); BoundExpression constructorCall; if (TryGetWellKnownTypeMember(stackAllocNode.Syntax, WellKnownMember.System_Span_T__ctor, out MethodSymbol spanConstructor)) { constructorCall = _factory.New((MethodSymbol)spanConstructor.SymbolAsMember(spanType), stackAllocNode, countTemp); } else { constructorCall = new BoundBadExpression( syntax: stackAllocNode.Syntax, resultKind: LookupResultKind.NotInvocable, symbols: ImmutableArray <Symbol> .Empty, childBoundNodes: ImmutableArray <BoundExpression> .Empty, type: ErrorTypeSymbol.UnknownResultType); } return(new BoundSequence( syntax: stackAllocNode.Syntax, locals: locals.ToImmutableAndFree(), sideEffects: sideEffects.ToImmutableAndFree(), value: constructorCall, type: spanType)); } else { throw ExceptionUtilities.UnexpectedValue(type); } }
public override Conversion GetStackAllocConversion(BoundStackAllocArrayCreation sourceExpression, TypeSymbol destination, ref HashSet <DiagnosticInfo> useSiteDiagnostics) { // Conversions involving stackalloc expressions require a Binder. throw ExceptionUtilities.Unreachable; }