mirror of
				https://github.com/golang/go.git
				synced 2025-10-31 16:50:58 +00:00 
			
		
		
		
	 12e15d430d
			
		
	
	
		12e15d430d
		
	
	
	
	
		
			
			- Have to delay the extra transformation on methods invoked on a type param, since the actual transformation (including path through embedded fields) will depend on the instantiated type. I am currently doing the transformation during the stencil substitution phase. We probably should have a separate pass after noder2 and stenciling, which drives the extra transformations that were in the old typechecker. - We handle method values (that are not called) and method calls. We don't currently handle method expressions. - Handle type substitution in function types, which is needed for function args in generic functions. - Added stringer.go and map.go tests, testing the above changes (including constraints with embedded interfaces). Change-Id: I3831a937d2b8814150f75bebf9f23ab10b93fa00 Reviewed-on: https://go-review.googlesource.com/c/go/+/290550 TryBot-Result: Go Bot <gobot@golang.org> Trust: Dan Scales <danscales@google.com> Trust: Robert Griesemer <gri@golang.org> Run-TryBot: Dan Scales <danscales@google.com> Reviewed-by: Robert Griesemer <gri@golang.org>
		
			
				
	
	
		
			88 lines
		
	
	
	
		
			1.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			88 lines
		
	
	
	
		
			1.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // run -gcflags=-G=3
 | |
| 
 | |
| // Copyright 2021 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 method calls on type parameters
 | |
| 
 | |
| package main
 | |
| 
 | |
| import (
 | |
| 	"fmt"
 | |
| 	"reflect"
 | |
| 	"strconv"
 | |
| )
 | |
| 
 | |
| // Simple constraint
 | |
| type Stringer interface {
 | |
| 	String() string
 | |
| }
 | |
| 
 | |
| func stringify[T Stringer](s []T) (ret []string) {
 | |
| 	for _, v := range s {
 | |
| 		ret = append(ret, v.String())
 | |
| 	}
 | |
| 	return ret
 | |
| }
 | |
| 
 | |
| type myint int
 | |
| 
 | |
| func (i myint) String() string {
 | |
| 	return strconv.Itoa(int(i))
 | |
| }
 | |
| 
 | |
| // Constraint with an embedded interface, but still only requires String()
 | |
| type Stringer2 interface {
 | |
| 	CanBeStringer2() int
 | |
| 	SubStringer2
 | |
| }
 | |
| 
 | |
| type SubStringer2 interface {
 | |
| 	CanBeSubStringer2() int
 | |
| 	String() string
 | |
| }
 | |
| 
 | |
| func stringify2[T Stringer2](s []T) (ret []string) {
 | |
| 	for _, v := range s {
 | |
| 		ret = append(ret, v.String())
 | |
| 	}
 | |
| 	return ret
 | |
| }
 | |
| 
 | |
| func (myint) CanBeStringer2() int {
 | |
| 	return 0
 | |
| }
 | |
| 
 | |
| func (myint) CanBeSubStringer2() int {
 | |
| 	return 0
 | |
| }
 | |
| 
 | |
| // Test use of method values that are not called
 | |
| func stringify3[T Stringer](s []T) (ret []string) {
 | |
| 	for _, v := range s {
 | |
| 		f := v.String
 | |
| 		ret = append(ret, f())
 | |
| 	}
 | |
| 	return ret
 | |
| }
 | |
| 
 | |
| func main() {
 | |
| 	x := []myint{myint(1), myint(2), myint(3)}
 | |
| 
 | |
| 	got := stringify(x)
 | |
| 	want := []string{"1", "2", "3"}
 | |
| 	if !reflect.DeepEqual(got, want) {
 | |
| 		panic(fmt.Sprintf("Got %s, want %s", got, want))
 | |
| 	}
 | |
| 
 | |
| 	got = stringify2(x)
 | |
| 	if !reflect.DeepEqual(got, want) {
 | |
| 		panic(fmt.Sprintf("Got %s, want %s", got, want))
 | |
| 	}
 | |
| 
 | |
| 	got = stringify3(x)
 | |
| 	if !reflect.DeepEqual(got, want) {
 | |
| 		panic(fmt.Sprintf("Got %s, want %s", got, want))
 | |
| 	}
 | |
| }
 |