switch prev := seen[m.Sym]; {
case prev == nil:
seen[m.Sym] = m
- case langSupported(1, 14) && !explicit && types.Identical(m.Type, prev.Type):
+ case langSupported(1, 14, t.Pkg()) && !explicit && types.Identical(m.Type, prev.Type):
return
default:
yyerrorl(m.Pos, "duplicate method %s", m.Sym.Name)
// any language version is supported.
var langWant lang
-// langSupported reports whether language version major.minor is supported.
-func langSupported(major, minor int) bool {
+// langSupported reports whether language version major.minor is
+// supported in a particular package.
+func langSupported(major, minor int, pkg *types.Pkg) bool {
+ if pkg == nil {
+ // TODO(mdempsky): Set Pkg for local types earlier.
+ pkg = localpkg
+ }
+ if pkg != localpkg {
+ // Assume imported packages passed type-checking.
+ return true
+ }
+
if langWant.major == 0 && langWant.minor == 0 {
return true
}
}
nod := p.nod(decl, ODCLTYPE, n, nil)
- if param.Alias && !langSupported(1, 9) {
+ if param.Alias && !langSupported(1, 9, localpkg) {
yyerrorl(nod.Pos, "type aliases only supported as of -lang=go1.9")
}
return nod
// literal is not compatible with the current language version.
func checkLangCompat(lit *syntax.BasicLit) {
s := lit.Value
- if len(s) <= 2 || langSupported(1, 13) {
+ if len(s) <= 2 || langSupported(1, 13, localpkg) {
return
}
// len(s) > 2
n.Type = nil
return n
}
- if t.IsSigned() && !langSupported(1, 13) {
+ if t.IsSigned() && !langSupported(1, 13, curpkg()) {
yyerrorv("go1.13", "invalid operation: %v (signed shift count type %v)", n, r.Type)
n.Type = nil
return n
return -1
}
+
+// curpkg returns the current package, based on Curfn.
+func curpkg() *types.Pkg {
+ fn := Curfn
+ if fn == nil {
+ // Initialization expressions for package-scope variables.
+ return localpkg
+ }
+
+ // TODO(mdempsky): Standardize on either ODCLFUNC or ONAME for
+ // Curfn, rather than mixing them.
+ if fn.Op == ODCLFUNC {
+ fn = fn.Func.Nname
+ }
+
+ return fnpkg(fn)
+}
--- /dev/null
+# Test that dependencies can use Go language features newer than the
+# Go version specified by the main module.
+
+env GO111MODULE=on
+
+go build
+
+-- go.mod --
+module m
+go 1.12
+require (
+ sub.1 v1.0.0
+)
+replace (
+ sub.1 => ./sub
+)
+
+-- x.go --
+package x
+
+import "sub.1"
+
+func F() { sub.F(0, 0) }
+
+var A sub.Alias
+var D sub.Defined
+
+-- sub/go.mod --
+module m
+go 1.14
+
+-- sub/sub.go --
+package sub
+
+// signed shift counts added in Go 1.13
+func F(l, r int) int { return l << r }
+
+type m1 interface { M() }
+type m2 interface { M() }
+
+// overlapping interfaces added in Go 1.14
+type Alias = interface { m1; m2; M() }
+type Defined interface { m1; m2; M() }