blob: e8bc8cde3ba767cd7e488a61c237f39dbeeb8328 [file] [log] [blame]
// Copyright 2023 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package a
import (
"fmt"
"time"
)
func Since() (t time.Duration) {
return
}
func x(time.Duration) {}
func x2(float64) {}
func good() {
// The following are OK because func is not evaluated in defer invocation.
now := time.Now()
defer func() {
fmt.Println(time.Since(now)) // OK because time.Since is not evaluated in defer
}()
evalBefore := time.Since(now)
defer fmt.Println(evalBefore)
do := func(f func()) {}
defer do(func() { time.Since(now) })
defer fmt.Println(Since()) // OK because Since function is not in module time
}
type y struct{}
func (y) A(float64) {}
func (*y) B(float64) {}
func (y) C(time.Duration) {}
func (*y) D(time.Duration) {}
func bad() {
var zero time.Time
now := time.Now()
defer time.Since(zero) // want "call to time.Since is not deferred"
defer time.Since(now) // want "call to time.Since is not deferred"
defer fmt.Println(time.Since(now)) // want "call to time.Since is not deferred"
defer fmt.Println(time.Since(time.Now())) // want "call to time.Since is not deferred"
defer x(time.Since(now)) // want "call to time.Since is not deferred"
defer x2(time.Since(now).Seconds()) // want "call to time.Since is not deferred"
defer y{}.A(time.Since(now).Seconds()) // want "call to time.Since is not deferred"
defer (&y{}).B(time.Since(now).Seconds()) // want "call to time.Since is not deferred"
defer y{}.C(time.Since(now)) // want "call to time.Since is not deferred"
defer (&y{}).D(time.Since(now)) // want "call to time.Since is not deferred"
}
func ugly() {
// The following is ok even though time.Since is evaluated. We don't
// walk into function literals or check what function definitions are doing.
defer x((func() time.Duration { return time.Since(time.Now()) })())
}