2021-03-05 23:07:56 -07:00
|
|
|
// run -gcflags=-G=3
|
|
|
|
|
|
|
|
// Copyright 2020 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 main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
cmd/compile: getting more built-ins to work with generics
For Builtin ops, we currently stay with using the old
typechecker to transform the call to a more specific expression
and possibly use more specific ops. However, for a bunch of the
ops, we delay calling the old typechecker if any of the args have
type params, for a variety of reasons.
In the near future, we will start creating separate functions that do
the same transformations as the old typechecker for calls, builtins,
indexing, comparisons, etc. These functions can then be called at noder
time for nodes with no type params, and at stenciling time for nodes
with type params.
Remove unnecessary calls to types1 typechecker for most kinds of
statements (still need it for SendStmt, AssignStmt, ReturnStmt, and
SelectStmt). In particular, we don't need it for RangeStmt, and this
avoids some complaints by the types1 typechecker on generic code.
Other small changes:
- Fix check on whether to delay calling types1-typechecker on type
conversions. Should check if HasTParam is true, rather than if the
type is directly a TYPEPARAM.
- Don't call types1-typechecker on an indexing operation if the left
operand has a typeparam in its type and is not obviously a TMAP,
TSLICE, or TARRAY. As above, we will eventually have to create a new
function that can do the required transformations (for complicated
cases) at noder time or stenciling time.
- Copy n.BuiltinOp in subster.node()
- The complex arithmetic example in absdiff.go now works.
- Added new tests double.go and append.go
- Added new example with a new() call in settable.go
Change-Id: I8f377afb6126cab1826bd3c2732aa8cdf1f7e0b4
Reviewed-on: https://go-review.googlesource.com/c/go/+/301951
Run-TryBot: Dan Scales <danscales@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: Dan Scales <danscales@google.com>
Trust: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
2021-03-12 12:36:02 -07:00
|
|
|
"math"
|
2021-03-05 23:07:56 -07:00
|
|
|
)
|
|
|
|
|
|
|
|
type Numeric interface {
|
2021-06-02 19:12:14 -06:00
|
|
|
~int | ~int8 | ~int16 | ~int32 | ~int64 |
|
|
|
|
~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr |
|
|
|
|
~float32 | ~float64 |
|
|
|
|
~complex64 | ~complex128
|
2021-03-05 23:07:56 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// numericAbs matches numeric types with an Abs method.
|
|
|
|
type numericAbs[T any] interface {
|
|
|
|
Numeric
|
|
|
|
Abs() T
|
|
|
|
}
|
|
|
|
|
|
|
|
// AbsDifference computes the absolute value of the difference of
|
|
|
|
// a and b, where the absolute value is determined by the Abs method.
|
|
|
|
func absDifference[T numericAbs[T]](a, b T) T {
|
|
|
|
d := a - b
|
|
|
|
return d.Abs()
|
|
|
|
}
|
|
|
|
|
|
|
|
// orderedNumeric matches numeric types that support the < operator.
|
|
|
|
type orderedNumeric interface {
|
2021-06-02 19:12:14 -06:00
|
|
|
~int | ~int8 | ~int16 | ~int32 | ~int64 |
|
|
|
|
~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr |
|
|
|
|
~float32 | ~float64
|
2021-03-05 23:07:56 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// Complex matches the two complex types, which do not have a < operator.
|
|
|
|
type Complex interface {
|
2021-06-02 19:12:14 -06:00
|
|
|
~complex64 | ~complex128
|
2021-03-05 23:07:56 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// orderedAbs is a helper type that defines an Abs method for
|
|
|
|
// ordered numeric types.
|
|
|
|
type orderedAbs[T orderedNumeric] T
|
|
|
|
|
|
|
|
func (a orderedAbs[T]) Abs() orderedAbs[T] {
|
[dev.typeparams] cmd/compile: export/import of recursive generic types.
Deal with export/import of recursive generic types. This includes
typeparams which have bounds that reference the typeparam.
There are three main changes:
- Change export/import of typeparams to have an implicit "declaration"
(doDecl). We need to do a declaration of typeparams (via the
typeparam's package and unique name), because it may be referenced
within its bound during its own definition.
- We delay most of the processing of the Instantiate call until we
finish the creation of the top-most type (similar to the way we
delay CheckSize). This is because we can't do the full instantiation
properly until the base type is fully defined (with methods). The
functions delayDoInst() and resumeDoInst() delay and resume the
processing of the instantiations.
- To do the full needed type substitutions for type instantiations
during import, I had to separate out the type subster in stencil.go
and move it to subr.go in the typecheck package. The subster in
stencil.go now does node substitution and makes use of the type
subster to do type substitutions.
Notable other changes:
- In types/builtins.go, put the newly defined typeparam for a union type
(related to use of real/imag, etc.) in the current package, rather
than the builtin package, so exports/imports work properly.
- In types2, allowed NewTypeParam() to be called with a nil bound, and
allow setting the bound later. (Needed to import a typeparam whose
bound refers to the typeparam itself.)
- During import of typeparams in types2 (importer/import.go), we need
to keep an index of the typeparams by their package and unique name
(with id). Use a new map typParamIndex[] for that. Again, this is
needed to deal with typeparams whose bounds refer to the typeparam
itself.
- Added several new tests absdiffimp.go and orderedmapsimp.go. Some of
the orderemapsimp tests are commented out for now, because there are
some issues with closures inside instantiations (relating to unexported
names of closure structs).
- Renamed some typeparams in test value.go to make them all T (to make
typeparam uniqueness is working fine).
Change-Id: Ib47ed9471c19ee8e9fbb34e8506907dad3021e5a
Reviewed-on: https://go-review.googlesource.com/c/go/+/323029
Trust: Dan Scales <danscales@google.com>
Trust: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
2021-05-17 16:00:39 -06:00
|
|
|
if a < 0 {
|
2021-03-05 23:07:56 -07:00
|
|
|
return -a
|
|
|
|
}
|
|
|
|
return a
|
|
|
|
}
|
|
|
|
|
|
|
|
// complexAbs is a helper type that defines an Abs method for
|
|
|
|
// complex types.
|
cmd/compile: getting more built-ins to work with generics
For Builtin ops, we currently stay with using the old
typechecker to transform the call to a more specific expression
and possibly use more specific ops. However, for a bunch of the
ops, we delay calling the old typechecker if any of the args have
type params, for a variety of reasons.
In the near future, we will start creating separate functions that do
the same transformations as the old typechecker for calls, builtins,
indexing, comparisons, etc. These functions can then be called at noder
time for nodes with no type params, and at stenciling time for nodes
with type params.
Remove unnecessary calls to types1 typechecker for most kinds of
statements (still need it for SendStmt, AssignStmt, ReturnStmt, and
SelectStmt). In particular, we don't need it for RangeStmt, and this
avoids some complaints by the types1 typechecker on generic code.
Other small changes:
- Fix check on whether to delay calling types1-typechecker on type
conversions. Should check if HasTParam is true, rather than if the
type is directly a TYPEPARAM.
- Don't call types1-typechecker on an indexing operation if the left
operand has a typeparam in its type and is not obviously a TMAP,
TSLICE, or TARRAY. As above, we will eventually have to create a new
function that can do the required transformations (for complicated
cases) at noder time or stenciling time.
- Copy n.BuiltinOp in subster.node()
- The complex arithmetic example in absdiff.go now works.
- Added new tests double.go and append.go
- Added new example with a new() call in settable.go
Change-Id: I8f377afb6126cab1826bd3c2732aa8cdf1f7e0b4
Reviewed-on: https://go-review.googlesource.com/c/go/+/301951
Run-TryBot: Dan Scales <danscales@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: Dan Scales <danscales@google.com>
Trust: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
2021-03-12 12:36:02 -07:00
|
|
|
type complexAbs[T Complex] T
|
2021-03-05 23:07:56 -07:00
|
|
|
|
cmd/compile: getting more built-ins to work with generics
For Builtin ops, we currently stay with using the old
typechecker to transform the call to a more specific expression
and possibly use more specific ops. However, for a bunch of the
ops, we delay calling the old typechecker if any of the args have
type params, for a variety of reasons.
In the near future, we will start creating separate functions that do
the same transformations as the old typechecker for calls, builtins,
indexing, comparisons, etc. These functions can then be called at noder
time for nodes with no type params, and at stenciling time for nodes
with type params.
Remove unnecessary calls to types1 typechecker for most kinds of
statements (still need it for SendStmt, AssignStmt, ReturnStmt, and
SelectStmt). In particular, we don't need it for RangeStmt, and this
avoids some complaints by the types1 typechecker on generic code.
Other small changes:
- Fix check on whether to delay calling types1-typechecker on type
conversions. Should check if HasTParam is true, rather than if the
type is directly a TYPEPARAM.
- Don't call types1-typechecker on an indexing operation if the left
operand has a typeparam in its type and is not obviously a TMAP,
TSLICE, or TARRAY. As above, we will eventually have to create a new
function that can do the required transformations (for complicated
cases) at noder time or stenciling time.
- Copy n.BuiltinOp in subster.node()
- The complex arithmetic example in absdiff.go now works.
- Added new tests double.go and append.go
- Added new example with a new() call in settable.go
Change-Id: I8f377afb6126cab1826bd3c2732aa8cdf1f7e0b4
Reviewed-on: https://go-review.googlesource.com/c/go/+/301951
Run-TryBot: Dan Scales <danscales@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: Dan Scales <danscales@google.com>
Trust: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
2021-03-12 12:36:02 -07:00
|
|
|
func (a complexAbs[T]) Abs() complexAbs[T] {
|
|
|
|
r := float64(real(a))
|
|
|
|
i := float64(imag(a))
|
|
|
|
d := math.Sqrt(r * r + i * i)
|
|
|
|
return complexAbs[T](complex(d, 0))
|
|
|
|
}
|
2021-03-05 23:07:56 -07:00
|
|
|
|
|
|
|
// OrderedAbsDifference returns the absolute value of the difference
|
|
|
|
// between a and b, where a and b are of an ordered type.
|
|
|
|
func orderedAbsDifference[T orderedNumeric](a, b T) T {
|
|
|
|
return T(absDifference(orderedAbs[T](a), orderedAbs[T](b)))
|
|
|
|
}
|
|
|
|
|
|
|
|
// ComplexAbsDifference returns the absolute value of the difference
|
|
|
|
// between a and b, where a and b are of a complex type.
|
cmd/compile: getting more built-ins to work with generics
For Builtin ops, we currently stay with using the old
typechecker to transform the call to a more specific expression
and possibly use more specific ops. However, for a bunch of the
ops, we delay calling the old typechecker if any of the args have
type params, for a variety of reasons.
In the near future, we will start creating separate functions that do
the same transformations as the old typechecker for calls, builtins,
indexing, comparisons, etc. These functions can then be called at noder
time for nodes with no type params, and at stenciling time for nodes
with type params.
Remove unnecessary calls to types1 typechecker for most kinds of
statements (still need it for SendStmt, AssignStmt, ReturnStmt, and
SelectStmt). In particular, we don't need it for RangeStmt, and this
avoids some complaints by the types1 typechecker on generic code.
Other small changes:
- Fix check on whether to delay calling types1-typechecker on type
conversions. Should check if HasTParam is true, rather than if the
type is directly a TYPEPARAM.
- Don't call types1-typechecker on an indexing operation if the left
operand has a typeparam in its type and is not obviously a TMAP,
TSLICE, or TARRAY. As above, we will eventually have to create a new
function that can do the required transformations (for complicated
cases) at noder time or stenciling time.
- Copy n.BuiltinOp in subster.node()
- The complex arithmetic example in absdiff.go now works.
- Added new tests double.go and append.go
- Added new example with a new() call in settable.go
Change-Id: I8f377afb6126cab1826bd3c2732aa8cdf1f7e0b4
Reviewed-on: https://go-review.googlesource.com/c/go/+/301951
Run-TryBot: Dan Scales <danscales@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: Dan Scales <danscales@google.com>
Trust: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
2021-03-12 12:36:02 -07:00
|
|
|
func complexAbsDifference[T Complex](a, b T) T {
|
|
|
|
return T(absDifference(complexAbs[T](a), complexAbs[T](b)))
|
|
|
|
}
|
2021-03-05 23:07:56 -07:00
|
|
|
|
|
|
|
func main() {
|
|
|
|
if got, want := orderedAbsDifference(1.0, -2.0), 3.0; got != want {
|
|
|
|
panic(fmt.Sprintf("got = %v, want = %v", got, want))
|
|
|
|
}
|
|
|
|
if got, want := orderedAbsDifference(-1.0, 2.0), 3.0; got != want {
|
|
|
|
panic(fmt.Sprintf("got = %v, want = %v", got, want))
|
|
|
|
}
|
|
|
|
if got, want := orderedAbsDifference(-20, 15), 35; got != want {
|
|
|
|
panic(fmt.Sprintf("got = %v, want = %v", got, want))
|
|
|
|
}
|
|
|
|
|
cmd/compile: getting more built-ins to work with generics
For Builtin ops, we currently stay with using the old
typechecker to transform the call to a more specific expression
and possibly use more specific ops. However, for a bunch of the
ops, we delay calling the old typechecker if any of the args have
type params, for a variety of reasons.
In the near future, we will start creating separate functions that do
the same transformations as the old typechecker for calls, builtins,
indexing, comparisons, etc. These functions can then be called at noder
time for nodes with no type params, and at stenciling time for nodes
with type params.
Remove unnecessary calls to types1 typechecker for most kinds of
statements (still need it for SendStmt, AssignStmt, ReturnStmt, and
SelectStmt). In particular, we don't need it for RangeStmt, and this
avoids some complaints by the types1 typechecker on generic code.
Other small changes:
- Fix check on whether to delay calling types1-typechecker on type
conversions. Should check if HasTParam is true, rather than if the
type is directly a TYPEPARAM.
- Don't call types1-typechecker on an indexing operation if the left
operand has a typeparam in its type and is not obviously a TMAP,
TSLICE, or TARRAY. As above, we will eventually have to create a new
function that can do the required transformations (for complicated
cases) at noder time or stenciling time.
- Copy n.BuiltinOp in subster.node()
- The complex arithmetic example in absdiff.go now works.
- Added new tests double.go and append.go
- Added new example with a new() call in settable.go
Change-Id: I8f377afb6126cab1826bd3c2732aa8cdf1f7e0b4
Reviewed-on: https://go-review.googlesource.com/c/go/+/301951
Run-TryBot: Dan Scales <danscales@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: Dan Scales <danscales@google.com>
Trust: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
2021-03-12 12:36:02 -07:00
|
|
|
if got, want := complexAbsDifference(5.0 + 2.0i, 2.0 - 2.0i), 5+0i; got != want {
|
|
|
|
panic(fmt.Sprintf("got = %v, want = %v", got, want))
|
|
|
|
}
|
|
|
|
if got, want := complexAbsDifference(2.0 - 2.0i, 5.0 + 2.0i), 5+0i; got != want {
|
|
|
|
panic(fmt.Sprintf("got = %v, want = %v", got, want))
|
|
|
|
}
|
2021-03-05 23:07:56 -07:00
|
|
|
}
|