Skip to content

Commit 82f875d

Browse files
committed
[dev.typeparams] go/types: fix generic type indirection
This is a port of CL 333890 to go/types. Change-Id: I8ee20f405dad98083bb5e91636044d132a95d909 Reviewed-on: https://go-review.googlesource.com/c/go/+/335081 Trust: Robert Findley <[email protected]> Run-TryBot: Robert Findley <[email protected]> TryBot-Result: Go Bot <[email protected]> Reviewed-by: Robert Griesemer <[email protected]>
1 parent 62f6f13 commit 82f875d

File tree

2 files changed

+45
-5
lines changed

2 files changed

+45
-5
lines changed

src/go/types/expr.go

+16-5
Original file line numberDiff line numberDiff line change
@@ -1400,13 +1400,24 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind {
14001400
case typexpr:
14011401
x.typ = &Pointer{base: x.typ}
14021402
default:
1403-
if typ := asPointer(x.typ); typ != nil {
1404-
x.mode = variable
1405-
x.typ = typ.base
1406-
} else {
1407-
check.invalidOp(x, _InvalidIndirection, "cannot indirect %s", x)
1403+
var base Type
1404+
if !underIs(x.typ, func(u Type) bool {
1405+
p, _ := u.(*Pointer)
1406+
if p == nil {
1407+
check.invalidOp(x, _InvalidIndirection, "cannot indirect %s", x)
1408+
return false
1409+
}
1410+
if base != nil && !Identical(p.base, base) {
1411+
check.invalidOp(x, _Todo, "pointers of %s must have identical base types", x)
1412+
return false
1413+
}
1414+
base = p.base
1415+
return true
1416+
}) {
14081417
goto Error
14091418
}
1419+
x.mode = variable
1420+
x.typ = base
14101421
}
14111422

14121423
case *ast.UnaryExpr:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Copyright 2021 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package p
6+
7+
// indirection
8+
9+
func _[P any](p P) {
10+
_ = *p // ERROR cannot indirect p
11+
}
12+
13+
func _[P interface{ int }](p P) {
14+
_ = *p // ERROR cannot indirect p
15+
}
16+
17+
func _[P interface{ *int }](p P) {
18+
_ = *p
19+
}
20+
21+
func _[P interface{ *int | *string }](p P) {
22+
_ = *p // ERROR must have identical base types
23+
}
24+
25+
type intPtr *int
26+
27+
func _[P interface{ *int | intPtr } ](p P) {
28+
var _ int = *p
29+
}

0 commit comments

Comments
 (0)