private void ResolveSignatureTypesInFunction(FunctionDeclarationSyntax function) { function.Type.BeginFulfilling(); var diagnosticCount = diagnostics.Count; // Resolve the declaring type because we need its type for things like `self` if (function.DeclaringType != null) ResolveSignatureTypesInTypeDeclaration(function.DeclaringType); var selfType = ResolveSelfType(function); var resolver = new ExpressionTypeResolver(function.File, diagnostics, selfType); if (function.GenericParameters != null) ResolveTypesInGenericParameters(function.GenericParameters, resolver); var parameterTypes = ResolveTypesInParameters(function, resolver); var returnType = ResolveReturnType(function, resolver); DataType functionType = new FunctionType(parameterTypes, returnType); if (function.GenericParameters?.Any() ?? false) functionType = new MetaFunctionType(function.GenericParameters.Select(p => p.Type.Fulfilled()), functionType); function.Type.Fulfill(functionType); if (diagnosticCount != diagnostics.Count) function.Poison(); }
public override void VisitVariableDeclarationStatement(VariableDeclarationStatementSyntax variableDeclaration, BindingScope bindingScope) { base.VisitVariableDeclarationStatement(variableDeclaration, bindingScope); if (bindingScope.Lookup(variableDeclaration.Name, out var binding)) { if (binding.MutableBinding) { diagnostics.Add(SemanticError.CantRebindMutableBinding(function.File, variableDeclaration.NameSpan)); function.Poison(); } else if (variableDeclaration.MutableBinding) { diagnostics.Add(SemanticError.CantRebindAsMutableBinding(function.File, variableDeclaration.NameSpan)); function.Poison(); } } }
public override void VisitIdentifierName(IdentifierNameSyntax identifierName, bool lvalue) { if (!lvalue || identifierName.ReferencedSymbol.MutableBinding) { return; } diagnostics.Add(SemanticError.CantAssignToImmutable(function.File, identifierName.Span)); function.Poison(); }
private void CheckAssignment(DataType assignToType, ExpressionSyntax value) { if (assignToType is ReferenceType referenceType && referenceType.IsOwned) { if (value.ValueSemantics != ValueSemantics.Move) { diagnostics.Add(SemanticError.CantMove(function.File, value)); function.Poison(); } } }
private void ResolveBodyTypesInFunction(FunctionDeclarationSyntax function) { if (function.Body == null) return; var diagnosticCount = diagnostics.Count; // TODO the return types of constructors and init functions should probably be void for purposes of expressions var resolver = new ExpressionTypeResolver(function.File, diagnostics, (Metatype)function.DeclaringType?.Type.Fulfilled(), function.ReturnType.Fulfilled()); // The body of a function shouldn't itself evaluate to anything. // There should be no `=> value` for the block, so the type is `void`. resolver.CheckExpressionType(function.Body, DataType.Void); if (diagnosticCount != diagnostics.Count) function.Poison(); }