1// compile
2
3// Copyright 2019 The Go Authors. All rights reserved.
4// Use of this source code is governed by a BSD-style
5// license that can be found in the LICENSE file.
6
7// Test iota inside a function in a ConstSpec is accepted
8package main
9
10import (
11	"unsafe"
12)
13
14// iotas are usable inside closures in constant declarations (#22345)
15const (
16	_ = iota
17	_ = len([iota]byte{})
18	_ = unsafe.Sizeof(iota)
19	_ = unsafe.Sizeof(func() { _ = iota })
20	_ = unsafe.Sizeof(func() { var _ = iota })
21	_ = unsafe.Sizeof(func() { const _ = iota })
22	_ = unsafe.Sizeof(func() { type _ [iota]byte })
23	_ = unsafe.Sizeof(func() { func() int { return iota }() })
24)
25
26// verify inner and outer const declarations have distinct iotas
27const (
28	zero = iota
29	one  = iota
30	_    = unsafe.Sizeof(func() {
31		var x [iota]int // [2]int
32		var y [iota]int // [2]int
33		const (
34			Zero = iota
35			One
36			Two
37			_ = unsafe.Sizeof([iota - 1]int{} == x) // assert types are equal
38			_ = unsafe.Sizeof([iota - 2]int{} == y) // assert types are equal
39			_ = unsafe.Sizeof([Two]int{} == x)      // assert types are equal
40		)
41		var z [iota]int                  // [2]int
42		_ = unsafe.Sizeof([2]int{} == z) // assert types are equal
43	})
44	three = iota // the sequence continues
45)
46
47var _ [three]int = [3]int{} // assert 'three' has correct value
48
49func main() {
50
51	const (
52		_ = iota
53		_ = len([iota]byte{})
54		_ = unsafe.Sizeof(iota)
55		_ = unsafe.Sizeof(func() { _ = iota })
56		_ = unsafe.Sizeof(func() { var _ = iota })
57		_ = unsafe.Sizeof(func() { const _ = iota })
58		_ = unsafe.Sizeof(func() { type _ [iota]byte })
59		_ = unsafe.Sizeof(func() { func() int { return iota }() })
60	)
61
62	const (
63		zero = iota
64		one  = iota
65		_    = unsafe.Sizeof(func() {
66			var x [iota]int // [2]int
67			var y [iota]int // [2]int
68			const (
69				Zero = iota
70				One
71				Two
72				_ = unsafe.Sizeof([iota - 1]int{} == x) // assert types are equal
73				_ = unsafe.Sizeof([iota - 2]int{} == y) // assert types are equal
74				_ = unsafe.Sizeof([Two]int{} == x)      // assert types are equal
75			)
76			var z [iota]int                  // [2]int
77			_ = unsafe.Sizeof([2]int{} == z) // assert types are equal
78		})
79		three = iota // the sequence continues
80	)
81
82	var _ [three]int = [3]int{} // assert 'three' has correct value
83}
84