]> Cypherpunks repositories - gostls13.git/commitdiff
go/types, types2: better internal comment, added suitable test case
authorRobert Griesemer <gri@golang.org>
Fri, 24 Feb 2023 05:26:46 +0000 (21:26 -0800)
committerGopher Robot <gobot@golang.org>
Wed, 1 Mar 2023 21:01:45 +0000 (21:01 +0000)
Change-Id: If55cd001ab3d274cd9c61c06f73bb98162aa12a8
Reviewed-on: https://go-review.googlesource.com/c/go/+/471019
Auto-Submit: Robert Griesemer <gri@google.com>
Reviewed-by: Robert Griesemer <gri@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Robert Griesemer <gri@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
src/cmd/compile/internal/types2/infer.go
src/go/types/infer.go
src/internal/types/testdata/check/funcinference.go

index 4d842fa3882a9f6122e36d897ba8405f14f89688..2328671f1029732d8746f9ed69aecb631b48e09c 100644 (file)
@@ -73,8 +73,25 @@ func (check *Checker) infer(pos syntax.Pos, tparams []*TypeParam, targs []Type,
 
        // Substitute type arguments for their respective type parameters in params,
        // if any. Note that nil targs entries are ignored by check.subst.
-       // TODO(gri) Can we avoid this (we're setting known type arguments below,
-       //           but that doesn't impact the isParameterized check for now).
+       // We do this for better error messages; it's not needed for correctness.
+       // For instance, given:
+       //
+       //   func f[P, Q any](P, Q) {}
+       //
+       //   func _(s string) {
+       //           f[int](s, s) // ERROR
+       //   }
+       //
+       // With substitution, we get the error:
+       //   "cannot use s (variable of type string) as int value in argument to f[int]"
+       //
+       // Without substitution we get the (worse) error:
+       //   "type string of s does not match inferred type int for P"
+       // even though the type int was provided (not inferred) for P.
+       //
+       // TODO(gri) We might be able to finesse this in the error message reporting
+       //           (which only happens in case of an error) and then avoid doing
+       //           the substitution (which always happens).
        if params.Len() > 0 {
                smap := makeSubstMap(tparams, targs)
                params = check.subst(nopos, params, smap, nil, check.context()).(*Tuple)
index 59f982b584fc7bb308aa13f5360a8918602b1ecd..4143d2aabecde8f0f0aba102f6f786311e89accd 100644 (file)
@@ -75,8 +75,25 @@ func (check *Checker) infer(posn positioner, tparams []*TypeParam, targs []Type,
 
        // Substitute type arguments for their respective type parameters in params,
        // if any. Note that nil targs entries are ignored by check.subst.
-       // TODO(gri) Can we avoid this (we're setting known type arguments below,
-       //           but that doesn't impact the isParameterized check for now).
+       // We do this for better error messages; it's not needed for correctness.
+       // For instance, given:
+       //
+       //   func f[P, Q any](P, Q) {}
+       //
+       //   func _(s string) {
+       //           f[int](s, s) // ERROR
+       //   }
+       //
+       // With substitution, we get the error:
+       //   "cannot use s (variable of type string) as int value in argument to f[int]"
+       //
+       // Without substitution we get the (worse) error:
+       //   "type string of s does not match inferred type int for P"
+       // even though the type int was provided (not inferred) for P.
+       //
+       // TODO(gri) We might be able to finesse this in the error message reporting
+       //           (which only happens in case of an error) and then avoid doing
+       //           the substitution (which always happens).
        if params.Len() > 0 {
                smap := makeSubstMap(tparams, targs)
                params = check.subst(nopos, params, smap, nil, check.context()).(*Tuple)
index fedf1991dd80917b21dee91c8ebc12e0aa806ffb..e0e978f25a331dcd994dfb2eab6ad4e17055593e 100644 (file)
@@ -102,3 +102,11 @@ func (p *Settable) Set(s string) {
 }
 
 var _ = FromStrings[Settable]([]string{"1", "2"})
+
+// Suitable error message when the type parameter is provided (rather than inferred).
+
+func f8[P, Q any](P, Q) {}
+
+func _(s string) {
+       f8[int](s /* ERROR "cannot use s (variable of type string) as int value in argument to f8[int]" */ , s)
+}