public override void ExitReturnStatement(ReturnStatement returnStatement) { var ancestor = returnStatement.NearestAncestorOfAnyType(typeof(MethodDeclaration), typeof(LambdaExpression), typeof(GetterDeclaration)); if (ancestor is INamedDeclaration namedDeclaration) { ITypeNode returnType = null; switch (namedDeclaration) { case MethodDeclaration methodDeclaration: returnType = methodDeclaration.ReturnType; break; case GetterDeclaration getterDeclaration: returnType = getterDeclaration.ReturnType; break; } var returnStatementType = returnStatement?.Value.Type ?? new VoidType(returnStatement.Context); if (returnType != null) { if (!returnStatementType.IsAssignableTo(returnType)) { Errors.Add(new CompilationError(returnStatement.Context, $"{returnStatementType} is not assignable to the return type of the method: {returnType}.")); } } else if (!(returnStatementType is ITypeNode returnStatementTypeNode)) { Errors.Add(new CompilationError(returnStatement.Context, $"Invalid return value: {returnStatementType}")); } else { var typeList = inferredMethodTypes[namedDeclaration]; if (!typeList.Any(x => x.IsEquivalentTo(returnStatementType))) { typeList.Add(returnStatementTypeNode); } } }