mirror of
https://github.com/golang/go
synced 2024-11-26 22:31:23 -07:00
638f112d69
There were multiple ad hoc ways to create method symbols, with subtle and confusing differences between them. This CL unifies them into a single well-documented encoding and implementation. This introduces some inconsequential changes to symbol format for the sake of simplicity and consistency. Two notable changes: 1) Symbol construction is now insensitive to the package currently being compiled. Previously, non-exported methods on anonymous types received different method symbols depending on whether the method was local or imported. 2) Symbols for method values parenthesized non-pointer receiver types and non-exported method names, and also always package-qualified non-exported method names. Now they use the same rules as normal method symbols. The methodSym function is also now stricter about rejecting non-sensical method/receiver combinations. Notably, this means that typecheckfunc needs to call addmethod to validate the method before calling declare, which also means we no longer emit errors about redeclaring bogus methods. Change-Id: I9501c7a53dd70ef60e5c74603974e5ecc06e2003 Reviewed-on: https://go-review.googlesource.com/104876 Reviewed-by: Robert Griesemer <gri@golang.org>
105 lines
2.5 KiB
Go
105 lines
2.5 KiB
Go
// errorcheck
|
|
|
|
// Copyright 2016 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.
|
|
|
|
// Test basic restrictions on type aliases.
|
|
|
|
package p
|
|
|
|
import (
|
|
"reflect"
|
|
. "reflect"
|
|
)
|
|
|
|
type T0 struct{}
|
|
|
|
// Valid type alias declarations.
|
|
|
|
type _ = T0
|
|
type _ = int
|
|
type _ = struct{}
|
|
type _ = reflect.Value
|
|
type _ = Value
|
|
|
|
type (
|
|
A0 = T0
|
|
A1 = int
|
|
A2 = struct{}
|
|
A3 = reflect.Value
|
|
A4 = Value
|
|
A5 = Value
|
|
|
|
N0 A0
|
|
)
|
|
|
|
// Methods can be declared on the original named type and the alias.
|
|
func (T0) m1() {} // GCCGO_ERROR "previous"
|
|
func (*T0) m1() {} // ERROR "method redeclared: T0\.m1|redefinition of .m1."
|
|
func (A0) m1() {} // ERROR "T0\.m1 redeclared in this block|redefinition of .m1."
|
|
func (A0) m1() {} // ERROR "T0\.m1 redeclared in this block|redefinition of .m1."
|
|
func (A0) m2() {}
|
|
|
|
// Type aliases and the original type name can be used interchangeably.
|
|
var _ A0 = T0{}
|
|
var _ T0 = A0{}
|
|
|
|
// But aliases and original types cannot be used with new types based on them.
|
|
var _ N0 = T0{} // ERROR "cannot use T0 literal \(type T0\) as type N0 in assignment|incompatible type"
|
|
var _ N0 = A0{} // ERROR "cannot use T0 literal \(type T0\) as type N0 in assignment|incompatible type"
|
|
|
|
var _ A5 = Value{}
|
|
|
|
var _ interface {
|
|
m1()
|
|
m2()
|
|
} = T0{}
|
|
|
|
var _ interface {
|
|
m1()
|
|
m2()
|
|
} = A0{}
|
|
|
|
func _() {
|
|
type _ = T0
|
|
type _ = int
|
|
type _ = struct{}
|
|
type _ = reflect.Value
|
|
type _ = Value
|
|
|
|
type (
|
|
A0 = T0
|
|
A1 = int
|
|
A2 = struct{}
|
|
A3 = reflect.Value
|
|
A4 = Value
|
|
A5 Value
|
|
|
|
N0 A0
|
|
)
|
|
|
|
var _ A0 = T0{}
|
|
var _ T0 = A0{}
|
|
|
|
var _ N0 = T0{} // ERROR "cannot use T0 literal \(type T0\) as type N0 in assignment|incompatible type"
|
|
var _ N0 = A0{} // ERROR "cannot use T0 literal \(type T0\) as type N0 in assignment|incompatible type"
|
|
|
|
var _ A5 = Value{} // ERROR "cannot use reflect\.Value literal \(type reflect.Value\) as type A5 in assignment|incompatible type"
|
|
}
|
|
|
|
// Invalid type alias declarations.
|
|
|
|
type _ = reflect.ValueOf // ERROR "reflect.ValueOf is not a type|expected type"
|
|
|
|
func (A1) m() {} // ERROR "cannot define new methods on non-local type int|may not define methods on non-local type"
|
|
func (A2) m() {} // ERROR "invalid receiver type"
|
|
func (A3) m() {} // ERROR "cannot define new methods on non-local type reflect.Value|may not define methods on non-local type"
|
|
func (A4) m() {} // ERROR "cannot define new methods on non-local type reflect.Value|may not define methods on non-local type"
|
|
|
|
type B1 = struct{}
|
|
|
|
func (B1) m() {} // ERROR "invalid receiver type"
|
|
|
|
// TODO(gri) expand
|