internal override ImmutableBindingDiagnostic <AssemblySymbol> GetConstantValueDiagnostics(BoundExpression boundInitValue) => _underlyingLocal.GetConstantValueDiagnostics(boundInitValue);
protected BoundLocalDeclaration BindVariableDeclaration( SourceLocalSymbol localSymbol, LocalDeclarationKind kind, bool isVar, VariableDeclaratorSyntax declarator, TypeSyntax typeSyntax, TypeSymbol declTypeOpt, AliasSymbol aliasOpt, DiagnosticBag diagnostics, CSharpSyntaxNode associatedSyntaxNode = null) { Debug.Assert(declarator != null); Debug.Assert((object)declTypeOpt != null || isVar); Debug.Assert(typeSyntax != null); var localDiagnostics = DiagnosticBag.GetInstance(); // if we are not given desired syntax, we use declarator associatedSyntaxNode = associatedSyntaxNode ?? declarator; bool hasErrors = false; BoundExpression initializerOpt; // Check for variable declaration errors. hasErrors |= this.ValidateDeclarationNameConflictsInScope(localSymbol, localDiagnostics); EqualsValueClauseSyntax equalsValueClauseSyntax = declarator.Initializer; if (isVar) { aliasOpt = null; var binder = new ImplicitlyTypedLocalBinder(this, localSymbol); initializerOpt = binder.BindInferredVariableInitializer(localDiagnostics, equalsValueClauseSyntax, declarator); // If we got a good result then swap the inferred type for the "var" if ((object)initializerOpt?.Type != null) { declTypeOpt = initializerOpt.Type; if (declTypeOpt.SpecialType == SpecialType.System_Void) { Error(localDiagnostics, ErrorCode.ERR_ImplicitlyTypedVariableAssignedBadValue, declarator, declTypeOpt); declTypeOpt = CreateErrorType("var"); hasErrors = true; } if (!declTypeOpt.IsErrorType()) { if (declTypeOpt.IsStatic) { Error(localDiagnostics, ErrorCode.ERR_VarDeclIsStaticClass, typeSyntax, initializerOpt.Type); hasErrors = true; } } } else { declTypeOpt = CreateErrorType("var"); hasErrors = true; } } else { if (ReferenceEquals(equalsValueClauseSyntax, null)) { initializerOpt = null; } else { // Basically inlined BindVariableInitializer, but with conversion optional. initializerOpt = BindPossibleArrayInitializer(equalsValueClauseSyntax.Value, declTypeOpt, localDiagnostics); if (kind != LocalDeclarationKind.FixedVariable) { // If this is for a fixed statement, we'll do our own conversion since there are some special cases. initializerOpt = GenerateConversionForAssignment(declTypeOpt, initializerOpt, localDiagnostics); } } } Debug.Assert((object)declTypeOpt != null); if (kind == LocalDeclarationKind.FixedVariable) { // NOTE: this is an error, but it won't prevent further binding. if (isVar) { if (!hasErrors) { Error(localDiagnostics, ErrorCode.ERR_ImplicitlyTypedLocalCannotBeFixed, declarator); hasErrors = true; } } if (!declTypeOpt.IsPointerType()) { if (!hasErrors) { Error(localDiagnostics, ErrorCode.ERR_BadFixedInitType, declarator); hasErrors = true; } } else if (!IsValidFixedVariableInitializer(declTypeOpt, localSymbol, ref initializerOpt, localDiagnostics)) { hasErrors = true; } } if (this.ContainingMemberOrLambda.Kind == SymbolKind.Method && ((MethodSymbol)this.ContainingMemberOrLambda).IsAsync && declTypeOpt.IsRestrictedType()) { Error(localDiagnostics, ErrorCode.ERR_BadSpecialByRefLocal, typeSyntax, declTypeOpt); hasErrors = true; } DeclareLocalVariable( localSymbol, declarator.Identifier, declTypeOpt); Debug.Assert((object)localSymbol != null); ImmutableArray<BoundExpression> arguments = BindDeclaratorArguments(declarator, localDiagnostics); if (kind == LocalDeclarationKind.FixedVariable || kind == LocalDeclarationKind.UsingVariable) { // CONSIDER: The error message is "you must provide an initializer in a fixed // CONSIDER: or using declaration". The error message could be targetted to // CONSIDER: the actual situation. "you must provide an initializer in a // CONSIDER: 'fixed' declaration." if (initializerOpt == null) { Error(localDiagnostics, ErrorCode.ERR_FixedMustInit, declarator); hasErrors = true; } } else if (kind == LocalDeclarationKind.Constant && initializerOpt != null && !localDiagnostics.HasAnyResolvedErrors()) { var constantValueDiagnostics = localSymbol.GetConstantValueDiagnostics(initializerOpt); foreach (var diagnostic in constantValueDiagnostics) { diagnostics.Add(diagnostic); hasErrors = true; } } diagnostics.AddRangeAndFree(localDiagnostics); var boundDeclType = new BoundTypeExpression(typeSyntax, aliasOpt, inferredType: isVar, type: declTypeOpt); return new BoundLocalDeclaration(associatedSyntaxNode, localSymbol, boundDeclType, initializerOpt, arguments, hasErrors); }
internal override ImmutableArray <Diagnostic> GetConstantValueDiagnostics(BoundExpression boundInitValue) => _underlyingLocal.GetConstantValueDiagnostics(boundInitValue);