...
1
2
3
4
5 package types2
6
7 import (
8 "cmd/compile/internal/syntax"
9 "fmt"
10 "go/version"
11 "internal/goversion"
12 "strings"
13 )
14
15
16
17
18 type goVersion string
19
20
21
22 func asGoVersion(v string) goVersion {
23 return goVersion(version.Lang(v))
24 }
25
26
27 func (v goVersion) isValid() bool {
28 return v != ""
29 }
30
31
32
33 func (x goVersion) cmp(y goVersion) int {
34 return version.Compare(string(x), string(y))
35 }
36
37 var (
38
39 go1_9 = asGoVersion("go1.9")
40 go1_13 = asGoVersion("go1.13")
41 go1_14 = asGoVersion("go1.14")
42 go1_17 = asGoVersion("go1.17")
43 go1_18 = asGoVersion("go1.18")
44 go1_20 = asGoVersion("go1.20")
45 go1_21 = asGoVersion("go1.21")
46 go1_22 = asGoVersion("go1.22")
47
48
49 go_current = asGoVersion(fmt.Sprintf("go1.%d", goversion.Version))
50 )
51
52
53
54 func (check *Checker) langCompat(lit *syntax.BasicLit) {
55 s := lit.Value
56 if len(s) <= 2 || check.allowVersion(check.pkg, lit, go1_13) {
57 return
58 }
59
60 if strings.Contains(s, "_") {
61 check.versionErrorf(lit, go1_13, "underscores in numeric literals")
62 return
63 }
64 if s[0] != '0' {
65 return
66 }
67 radix := s[1]
68 if radix == 'b' || radix == 'B' {
69 check.versionErrorf(lit, go1_13, "binary literals")
70 return
71 }
72 if radix == 'o' || radix == 'O' {
73 check.versionErrorf(lit, go1_13, "0o/0O-style octal literals")
74 return
75 }
76 if lit.Kind != syntax.IntLit && (radix == 'x' || radix == 'X') {
77 check.versionErrorf(lit, go1_13, "hexadecimal floating-point literals")
78 }
79 }
80
81
82 func (check *Checker) allowVersion(pkg *Package, at poser, v goVersion) bool {
83
84
85 if pkg != check.pkg {
86 return true
87 }
88
89
90
91 var fileVersion goVersion
92 if pos := at.Pos(); pos.IsKnown() {
93
94
95
96 fileVersion = asGoVersion(check.versions[base(pos)])
97 }
98 return !fileVersion.isValid() || fileVersion.cmp(v) >= 0
99 }
100
101
102
103
104 func (check *Checker) verifyVersionf(at poser, v goVersion, format string, args ...interface{}) bool {
105 if !check.allowVersion(check.pkg, at, v) {
106 check.versionErrorf(at, v, format, args...)
107 return false
108 }
109 return true
110 }
111
112
113
114
115 func base(pos syntax.Pos) *syntax.PosBase {
116 assert(pos.IsKnown())
117 b := pos.Base()
118 for {
119 bb := b.Pos().Base()
120 if bb == nil || bb == b {
121 break
122 }
123 b = bb
124 }
125 return b
126 }
127
View as plain text