internal sealed override TypeSymbolWithAnnotations GetFieldType(ConsList <FieldSymbol> fieldsBeingBound) { Debug.Assert(fieldsBeingBound != null); if (!_lazyType.IsNull) { return(_lazyType.ToType()); } var declarator = VariableDeclarationNode; var fieldSyntax = GetFieldDeclaration(declarator); var typeSyntax = fieldSyntax.Declaration.Type; var compilation = this.DeclaringCompilation; var diagnostics = DiagnosticBag.GetInstance(); TypeSymbolWithAnnotations type = default; // When we have multiple declarators, we report the type diagnostics on only the first. DiagnosticBag diagnosticsForFirstDeclarator = DiagnosticBag.GetInstance(); Symbol associatedPropertyOrEvent = this.AssociatedSymbol; if ((object)associatedPropertyOrEvent != null && associatedPropertyOrEvent.Kind == SymbolKind.Event) { EventSymbol @event = (EventSymbol)associatedPropertyOrEvent; if (@event.IsWindowsRuntimeEvent) { NamedTypeSymbol tokenTableType = this.DeclaringCompilation.GetWellKnownType(WellKnownType.core_runtime_WindowsRuntime_EventRegistrationTokenTable_T); Binder.ReportUseSiteDiagnostics(tokenTableType, diagnosticsForFirstDeclarator, this.ErrorLocation); // CONSIDER: Do we want to guard against the possibility that someone has created their own EventRegistrationTokenTable<T> // type that has additional generic constraints? type = TypeSymbolWithAnnotations.Create(tokenTableType.Construct(ImmutableArray.Create(@event.Type))); } else { type = @event.Type; } } else { var binderFactory = compilation.GetBinderFactory(SyntaxTree); var binder = binderFactory.GetBinder(declarator); binder = binder.WithAdditionalFlagsAndContainingMemberOrLambda(BinderFlags.SuppressConstraintChecks, this); if (!ContainingType.IsScriptClass) { type = binder.BindType(typeSyntax, diagnosticsForFirstDeclarator); } else if (typeSyntax == null) { if (this.IsConst) { diagnosticsForFirstDeclarator.Add(ErrorCode.ERR_ImplicitlyTypedVariableCannotBeConst, typeSyntax.Location); } if (fieldsBeingBound.ContainsReference(this)) { diagnostics.Add(ErrorCode.ERR_RecursivelyTypedVariable, this.ErrorLocation, this); type = default; } else if (this.IsConst && this.ContainingType.IsScriptClass) { // For const var in script, we won't try to bind the initializer (case below), as it can lead to an unbound recursion type = default; } else { fieldsBeingBound = new ConsList <FieldSymbol>(this, fieldsBeingBound); var initializerBinder = new ImplicitlyTypedFieldBinder(binder, fieldsBeingBound); var initializerOpt = initializerBinder.BindInferredVariableInitializer(diagnostics, RefKind.None, (EqualsValueClauseSyntax)declarator.Initializer, declarator); if (initializerOpt != null) { if ((object)initializerOpt.Type != null && !initializerOpt.Type.IsErrorType()) { type = TypeSymbolWithAnnotations.Create(initializerOpt.Type); } _lazyFieldTypeInferred = 1; } } if (type.IsNull) { type = TypeSymbolWithAnnotations.Create(binder.CreateErrorType("var")); } } else { type = binder.BindType(typeSyntax, diagnostics); } if (IsFixedSizeBuffer) { type = TypeSymbolWithAnnotations.Create(new PointerTypeSymbol(type)); if (ContainingType.TypeKind != TypeKind.Struct) { diagnostics.Add(ErrorCode.ERR_FixedNotInStruct, ErrorLocation); } var elementType = ((PointerTypeSymbol)type.TypeSymbol).PointedAtType.TypeSymbol; int elementSize = elementType.FixedBufferElementSizeInBytes(); if (elementSize == 0) { var loc = typeSyntax.Location; diagnostics.Add(ErrorCode.ERR_IllegalFixedType, loc); } if (!binder.InUnsafeRegion) { diagnosticsForFirstDeclarator.Add(ErrorCode.ERR_UnsafeNeeded, declarator.Location); } } } // update the lazyType only if it contains value last seen by the current thread: if (_lazyType.InterlockedInitialize(type.WithModifiers(this.RequiredCustomModifiers))) { TypeChecks(type.TypeSymbol, diagnostics); // CONSIDER: SourceEventFieldSymbol would like to suppress these diagnostics. compilation.DeclarationDiagnostics.AddRange(diagnostics); compilation.DeclarationDiagnostics.AddRange(diagnosticsForFirstDeclarator); state.NotePartComplete(CompletionPart.Type); } diagnostics.Free(); diagnosticsForFirstDeclarator.Free(); return(_lazyType.ToType()); }