Exemplo n.º 1
0
        public override Conversion GetStackAllocConversion(BoundStackAllocArrayCreation sourceExpression, TypeSymbol destination, ref HashSet <DiagnosticInfo> useSiteDiagnostics)
        {
            if (sourceExpression.Syntax.IsVariableDeclarationInitialization())
            {
                Debug.Assert((object)sourceExpression.Type == null);
                Debug.Assert(sourceExpression.ElementType != null);

                var sourceAsPointer   = new PointerTypeSymbol(sourceExpression.ElementType);
                var pointerConversion = ClassifyImplicitConversionFromType(sourceAsPointer, destination, ref useSiteDiagnostics);

                if (pointerConversion.IsValid)
                {
                    return(Conversion.MakeStackAllocToPointerType(pointerConversion));
                }
                else
                {
                    var spanType = _binder.GetWellKnownType(WellKnownType.System_Span_T, ref useSiteDiagnostics);
                    if (spanType.TypeKind == TypeKind.Struct && spanType.IsByRefLikeType)
                    {
                        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);
        }
Exemplo n.º 2
0
        public override Conversion GetStackAllocConversion(BoundStackAllocArrayCreation sourceExpression, TypeSymbol destination, ref HashSet <DiagnosticInfo> useSiteDiagnostics)
        {
            if (sourceExpression.Syntax.IsVariableDeclarationInitialization())
            {
                Debug.Assert((object)sourceExpression.Type == null);
                Debug.Assert(sourceExpression.ElementType != null);

                var pointerConversion = default(Conversion);
                var sourceAsPointer   = new PointerTypeSymbol(sourceExpression.ElementType);
                pointerConversion = ClassifyImplicitConversionFromType(sourceAsPointer, destination, ref useSiteDiagnostics);

                if (pointerConversion.IsValid)
                {
                    // Report unsafe errors
                    _binder.ReportUnsafeIfNotAllowed(sourceExpression.Syntax.Location, ref useSiteDiagnostics);

                    return(Conversion.MakeStackAllocToPointerType(pointerConversion));
                }
                else
                {
                    var spanType = _binder.GetWellKnownType(WellKnownType.System_Span_T, ref useSiteDiagnostics);
                    if (spanType.TypeKind == TypeKind.Struct && spanType.IsByRefLikeType)
                    {
                        var spanType_T     = spanType.Construct(sourceExpression.ElementType);
                        var spanConversion = ClassifyImplicitConversionFromType(spanType_T, destination, ref useSiteDiagnostics);

                        if (spanConversion.Exists)
                        {
                            // Report errors if Span ctor is missing, or using an older C# version
                            Binder.CheckFeatureAvailability(sourceExpression.Syntax, MessageID.IDS_FeatureRefStructs, ref useSiteDiagnostics);
                            Binder.GetWellKnownTypeMember(_binder.Compilation, WellKnownMember.System_Span_T__ctor, out DiagnosticInfo memberDiagnosticInfo);
                            HashSetExtensions.InitializeAndAdd(ref useSiteDiagnostics, memberDiagnosticInfo);

                            return(Conversion.MakeStackAllocToSpanType(spanConversion));
                        }
                    }
                }
            }

            return(Conversion.NoConversion);
        }