slog: remove error argument from Error

Remove the Error argument from the Error function and
Logger.Error methods.

Remove the ErrorKey constant.

Change-Id: I433e82e62075dbb85db1c938c00804c1cc460e9e
Reviewed-on: https://go-review.googlesource.com/c/exp/+/475295
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Alan Donovan <adonovan@google.com>
Run-TryBot: Jonathan Amsterdam <jba@google.com>
diff --git a/slog/example_custom_levels_test.go b/slog/example_custom_levels_test.go
index 3d64cc6..40085e4 100644
--- a/slog/example_custom_levels_test.go
+++ b/slog/example_custom_levels_test.go
@@ -5,7 +5,6 @@
 package slog_test
 
 import (
-	"fmt"
 	"os"
 
 	"golang.org/x/exp/slog"
@@ -75,7 +74,7 @@
 
 	logger := slog.New(th)
 	logger.Log(nil, LevelEmergency, "missing pilots")
-	logger.Error("failed to start engines", fmt.Errorf("missing fuel"))
+	logger.Error("failed to start engines", "err", "missing fuel")
 	logger.Warn("falling back to default value")
 	logger.Log(nil, LevelNotice, "all systems are running")
 	logger.Info("initiating launch")
diff --git a/slog/handler.go b/slog/handler.go
index 3818470..c1b9037 100644
--- a/slog/handler.go
+++ b/slog/handler.go
@@ -185,9 +185,6 @@
 	// SourceKey is the key used by the built-in handlers for the source file
 	// and line of the log call. The associated value is a string.
 	SourceKey = "source"
-	// ErrorKey is the key used for errors by Logger.Error.
-	// The associated value is an [error].
-	ErrorKey = "err"
 )
 
 type commonHandler struct {
diff --git a/slog/logger.go b/slog/logger.go
index 043ba15..8f021e6 100644
--- a/slog/logger.go
+++ b/slog/logger.go
@@ -160,7 +160,7 @@
 //     into an Attr.
 //   - Otherwise, the argument is treated as a value with key "!BADKEY".
 func (l *Logger) Log(ctx context.Context, level Level, msg string, args ...any) {
-	l.log(ctx, nil, level, msg, args...)
+	l.log(ctx, level, msg, args...)
 }
 
 // LogAttrs is a more efficient version of [Logger.Log] that accepts only Attrs.
@@ -170,53 +170,48 @@
 
 // Debug logs at LevelDebug.
 func (l *Logger) Debug(msg string, args ...any) {
-	l.log(nil, nil, LevelDebug, msg, args...)
+	l.log(nil, LevelDebug, msg, args...)
 }
 
 // DebugCtx logs at LevelDebug with the given context.
 func (l *Logger) DebugCtx(ctx context.Context, msg string, args ...any) {
-	l.log(ctx, nil, LevelDebug, msg, args...)
+	l.log(ctx, LevelDebug, msg, args...)
 }
 
 // Info logs at LevelInfo.
 func (l *Logger) Info(msg string, args ...any) {
-	l.log(nil, nil, LevelInfo, msg, args...)
+	l.log(nil, LevelInfo, msg, args...)
 }
 
 // InfoCtx logs at LevelInfo with the given context.
 func (l *Logger) InfoCtx(ctx context.Context, msg string, args ...any) {
-	l.log(ctx, nil, LevelInfo, msg, args...)
+	l.log(ctx, LevelInfo, msg, args...)
 }
 
 // Warn logs at LevelWarn.
 func (l *Logger) Warn(msg string, args ...any) {
-	l.log(nil, nil, LevelWarn, msg, args...)
+	l.log(nil, LevelWarn, msg, args...)
 }
 
 // WarnCtx logs at LevelWarn with the given context.
 func (l *Logger) WarnCtx(ctx context.Context, msg string, args ...any) {
-	l.log(ctx, nil, LevelWarn, msg, args...)
+	l.log(ctx, LevelWarn, msg, args...)
 }
 
 // Error logs at LevelError.
-// If err is non-nil, Error adds Any(ErrorKey, err)
-// before the list of attributes.
-func (l *Logger) Error(msg string, err error, args ...any) {
-	l.log(nil, err, LevelError, msg, args...)
+func (l *Logger) Error(msg string, args ...any) {
+	l.log(nil, LevelError, msg, args...)
 }
 
 // ErrorCtx logs at LevelError with the given context.
-// If err is non-nil, it adds Any(ErrorKey, err)
-// before the list of attributes.
-func (l *Logger) ErrorCtx(ctx context.Context, msg string, err error, args ...any) {
-	l.log(ctx, err, LevelError, msg, args...)
+func (l *Logger) ErrorCtx(ctx context.Context, msg string, args ...any) {
+	l.log(ctx, LevelError, msg, args...)
 }
 
 // log is the low-level logging method for methods that take ...any.
 // It must always be called directly by an exported logging method
 // or function, because it uses a fixed call depth to obtain the pc.
-// The err argument is for [Logger.Error]; other callers pass nil.
-func (l *Logger) log(ctx context.Context, err error, level Level, msg string, args ...any) {
+func (l *Logger) log(ctx context.Context, level Level, msg string, args ...any) {
 	if !l.Enabled(ctx, level) {
 		return
 	}
@@ -228,10 +223,6 @@
 		pc = pcs[0]
 	}
 	r := NewRecord(time.Now(), level, msg, pc)
-	if err != nil {
-		r.front[0] = Any(ErrorKey, err)
-		r.nFront++
-	}
 	r.Add(args...)
 	if ctx == nil {
 		ctx = context.Background()
@@ -261,47 +252,47 @@
 
 // Debug calls Logger.Debug on the default logger.
 func Debug(msg string, args ...any) {
-	Default().log(nil, nil, LevelDebug, msg, args...)
+	Default().log(nil, LevelDebug, msg, args...)
 }
 
 // DebugCtx calls Logger.DebugCtx on the default logger.
 func DebugCtx(ctx context.Context, msg string, args ...any) {
-	Default().log(ctx, nil, LevelDebug, msg, args...)
+	Default().log(ctx, LevelDebug, msg, args...)
 }
 
 // Info calls Logger.Info on the default logger.
 func Info(msg string, args ...any) {
-	Default().log(nil, nil, LevelInfo, msg, args...)
+	Default().log(nil, LevelInfo, msg, args...)
 }
 
 // InfoCtx calls Logger.InfoCtx on the default logger.
 func InfoCtx(ctx context.Context, msg string, args ...any) {
-	Default().log(ctx, nil, LevelInfo, msg, args...)
+	Default().log(ctx, LevelInfo, msg, args...)
 }
 
 // Warn calls Logger.Warn on the default logger.
 func Warn(msg string, args ...any) {
-	Default().log(nil, nil, LevelWarn, msg, args...)
+	Default().log(nil, LevelWarn, msg, args...)
 }
 
 // WarnCtx calls Logger.WarnCtx on the default logger.
 func WarnCtx(ctx context.Context, msg string, args ...any) {
-	Default().log(ctx, nil, LevelWarn, msg, args...)
+	Default().log(ctx, LevelWarn, msg, args...)
 }
 
 // Error calls Logger.Error on the default logger.
-func Error(msg string, err error, args ...any) {
-	Default().log(nil, err, LevelError, msg, args...)
+func Error(msg string, args ...any) {
+	Default().log(nil, LevelError, msg, args...)
 }
 
 // ErrorCtx calls Logger.ErrorCtx on the default logger.
-func ErrorCtx(ctx context.Context, msg string, err error, args ...any) {
-	Default().log(ctx, err, LevelError, msg, args...)
+func ErrorCtx(ctx context.Context, msg string, args ...any) {
+	Default().log(ctx, LevelError, msg, args...)
 }
 
 // Log calls Logger.Log on the default logger.
 func Log(ctx context.Context, level Level, msg string, args ...any) {
-	Default().log(ctx, nil, level, msg, args...)
+	Default().log(ctx, level, msg, args...)
 }
 
 // LogAttrs calls Logger.LogAttrs on the default logger.
diff --git a/slog/logger_test.go b/slog/logger_test.go
index 6a7c852..2f04540 100644
--- a/slog/logger_test.go
+++ b/slog/logger_test.go
@@ -45,8 +45,8 @@
 	l.Warn("w", Duration("dur", 3*time.Second))
 	check(`level=WARN msg=w dur=3s`)
 
-	l.Error("bad", io.EOF, "a", 1)
-	check(`level=ERROR msg=bad err=EOF a=1`)
+	l.Error("bad", "a", 1)
+	check(`level=ERROR msg=bad a=1`)
 
 	l.Log(nil, LevelWarn+1, "w", Int("a", 1), String("b", "two"))
 	check(`level=WARN\+1 msg=w a=1 b=two`)
@@ -82,7 +82,7 @@
 	Warn("msg", "b", 2)
 	checkLogOutput(t, logbuf.String(), `logger_test.go:\d+: WARN msg b=2`)
 	logbuf.Reset()
-	Error("msg", io.EOF, "c", 3)
+	Error("msg", "err", io.EOF, "c", 3)
 	checkLogOutput(t, logbuf.String(), `logger_test.go:\d+: ERROR msg err=EOF c=3`)
 
 	// Levels below Info are not printed.
@@ -199,7 +199,7 @@
 	check(3)
 	logger.Warn("")
 	check(4)
-	logger.Error("", nil)
+	logger.Error("")
 	check(5)
 	Debug("")
 	check(6)
@@ -207,7 +207,7 @@
 	check(7)
 	Warn("")
 	check(8)
-	Error("", nil)
+	Error("")
 	check(9)
 	Log(nil, LevelInfo, "")
 	check(10)
@@ -224,7 +224,7 @@
 		wantAllocs(t, 0, func() { Info("hello") })
 	})
 	t.Run("Error", func(t *testing.T) {
-		wantAllocs(t, 0, func() { Error("hello", io.EOF) })
+		wantAllocs(t, 0, func() { Error("hello") })
 	})
 	t.Run("logger.Info", func(t *testing.T) {
 		wantAllocs(t, 0, func() { dl.Info("hello") })
@@ -361,10 +361,10 @@
 		return a
 	}
 	l := New(HandlerOptions{ReplaceAttr: removeTime}.NewTextHandler(&buf))
-	l.Error("msg", io.EOF, "a", 1)
+	l.Error("msg", "err", io.EOF, "a", 1)
 	checkLogOutput(t, buf.String(), `level=ERROR msg=msg err=EOF a=1`)
 	buf.Reset()
-	l.Error("msg", io.EOF, "a")
+	l.Error("msg", "err", io.EOF, "a")
 	checkLogOutput(t, buf.String(), `level=ERROR msg=msg err=EOF !BADKEY=a`)
 }