go.tools/go/types: report init dependencies via method values
- one-line fix - comprehensive set of test cases added Fixes golang/go#7963. LGTM=adonovan R=adonovan CC=golang-codereviews https://golang.org/cl/100320043
This commit is contained in:
parent
4700b7a612
commit
51d8ee0ff8
|
@ -408,6 +408,8 @@ func (check *checker) selector(x *operand, e *ast.SelectorExpr) {
|
||||||
sig.recv = nil
|
sig.recv = nil
|
||||||
x.typ = &sig
|
x.typ = &sig
|
||||||
|
|
||||||
|
check.addDeclDep(obj)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
unreachable()
|
unreachable()
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,6 +57,7 @@ var tests = [][]string{
|
||||||
{"testdata/cycles4.src"},
|
{"testdata/cycles4.src"},
|
||||||
{"testdata/init0.src"},
|
{"testdata/init0.src"},
|
||||||
{"testdata/init1.src"},
|
{"testdata/init1.src"},
|
||||||
|
{"testdata/init2.src"},
|
||||||
{"testdata/decls0.src"},
|
{"testdata/decls0.src"},
|
||||||
{"testdata/decls1.src"},
|
{"testdata/decls1.src"},
|
||||||
{"testdata/decls2a.src", "testdata/decls2b.src"},
|
{"testdata/decls2a.src", "testdata/decls2b.src"},
|
||||||
|
|
|
@ -96,11 +96,11 @@ func (T1) m() bool { _ = x11; return false }
|
||||||
|
|
||||||
var x11 /* ERROR initialization cycle */ = T1.m(T1{})
|
var x11 /* ERROR initialization cycle */ = T1.m(T1{})
|
||||||
|
|
||||||
// no cycles via method values
|
// cycles via method values
|
||||||
|
|
||||||
type T2 struct{}
|
type T2 struct{}
|
||||||
|
|
||||||
func (T2) m() bool { _ = x12; return false }
|
func (T2) m() bool { _ = x12; return false }
|
||||||
|
|
||||||
var t1 T2
|
var t1 T2
|
||||||
var x12 = t1.m
|
var x12 /* ERROR initialization cycle */ = t1.m
|
||||||
|
|
|
@ -14,7 +14,7 @@ func (T0) m() int { return y0 }
|
||||||
|
|
||||||
var x0 = T0{}
|
var x0 = T0{}
|
||||||
|
|
||||||
var y0 = x0.m() // no cycle reported
|
var y0 /* ERROR initialization cycle */ = x0.m()
|
||||||
|
|
||||||
type T1 struct{}
|
type T1 struct{}
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ var x1 interface {
|
||||||
m() int
|
m() int
|
||||||
} = T1{}
|
} = T1{}
|
||||||
|
|
||||||
var y1 = x1.m() // no cycle reported
|
var y1 = x1.m() // no cycle reported, x1 is of interface type
|
||||||
|
|
||||||
// issue 6703 (modified)
|
// issue 6703 (modified)
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ func (T3) m() int {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
var x4 = T4{}.m // <<<< added {}
|
var x4 /* ERROR initialization cycle */ = T4{}.m // <<<< added {}
|
||||||
|
|
||||||
var y4 = x4
|
var y4 = x4
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ func (T4) m() int {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
var x5 = T5{}.m() // <<<< added ()
|
var x5 /* ERROR initialization cycle */ = T5{}.m() // <<<< added ()
|
||||||
|
|
||||||
var y5 = x5
|
var y5 = x5
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,139 @@
|
||||||
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// initialization cycles
|
||||||
|
|
||||||
|
package init2
|
||||||
|
|
||||||
|
// cycles through functions
|
||||||
|
|
||||||
|
func f1() int { _ = x1; return 0 }
|
||||||
|
var x1 /* ERROR initialization cycle */ = f1
|
||||||
|
|
||||||
|
func f2() int { _ = x2; return 0 }
|
||||||
|
var x2 /* ERROR initialization cycle */ = f2()
|
||||||
|
|
||||||
|
// cycles through method expressions
|
||||||
|
|
||||||
|
type T3 int
|
||||||
|
func (T3) m() int { _ = x3; return 0 }
|
||||||
|
var x3 /* ERROR initialization cycle */ = T3.m
|
||||||
|
|
||||||
|
type T4 int
|
||||||
|
func (T4) m() int { _ = x4; return 0 }
|
||||||
|
var x4 /* ERROR initialization cycle */ = T4.m(0)
|
||||||
|
|
||||||
|
type T3p int
|
||||||
|
func (*T3p) m() int { _ = x3p; return 0 }
|
||||||
|
var x3p /* ERROR initialization cycle */ = (*T3p).m
|
||||||
|
|
||||||
|
type T4p int
|
||||||
|
func (*T4p) m() int { _ = x4p; return 0 }
|
||||||
|
var x4p /* ERROR initialization cycle */ = (*T4p).m(nil)
|
||||||
|
|
||||||
|
// cycles through method expressions of embedded methods
|
||||||
|
|
||||||
|
type T5 struct { E5 }
|
||||||
|
type E5 int
|
||||||
|
func (E5) m() int { _ = x5; return 0 }
|
||||||
|
var x5 /* ERROR initialization cycle */ = T5.m
|
||||||
|
|
||||||
|
type T6 struct { E6 }
|
||||||
|
type E6 int
|
||||||
|
func (E6) m() int { _ = x6; return 0 }
|
||||||
|
var x6 /* ERROR initialization cycle */ = T6.m(T6{0})
|
||||||
|
|
||||||
|
type T5p struct { E5p }
|
||||||
|
type E5p int
|
||||||
|
func (*E5p) m() int { _ = x5p; return 0 }
|
||||||
|
var x5p /* ERROR initialization cycle */ = (*T5p).m
|
||||||
|
|
||||||
|
type T6p struct { E6p }
|
||||||
|
type E6p int
|
||||||
|
func (*E6p) m() int { _ = x6p; return 0 }
|
||||||
|
var x6p /* ERROR initialization cycle */ = (*T6p).m(nil)
|
||||||
|
|
||||||
|
// cycles through method values
|
||||||
|
|
||||||
|
type T7 int
|
||||||
|
func (T7) m() int { _ = x7; return 0 }
|
||||||
|
var x7 /* ERROR initialization cycle */ = T7(0).m
|
||||||
|
|
||||||
|
type T8 int
|
||||||
|
func (T8) m() int { _ = x8; return 0 }
|
||||||
|
var x8 /* ERROR initialization cycle */ = T8(0).m()
|
||||||
|
|
||||||
|
type T7p int
|
||||||
|
func (*T7p) m() int { _ = x7p; return 0 }
|
||||||
|
var x7p /* ERROR initialization cycle */ = new(T7p).m
|
||||||
|
|
||||||
|
type T8p int
|
||||||
|
func (*T8p) m() int { _ = x8p; return 0 }
|
||||||
|
var x8p /* ERROR initialization cycle */ = new(T8p).m()
|
||||||
|
|
||||||
|
type T7v int
|
||||||
|
func (T7v) m() int { _ = x7v; return 0 }
|
||||||
|
var x7var T7v
|
||||||
|
var x7v /* ERROR initialization cycle */ = x7var.m
|
||||||
|
|
||||||
|
type T8v int
|
||||||
|
func (T8v) m() int { _ = x8v; return 0 }
|
||||||
|
var x8var T8v
|
||||||
|
var x8v /* ERROR initialization cycle */ = x8var.m()
|
||||||
|
|
||||||
|
type T7pv int
|
||||||
|
func (*T7pv) m() int { _ = x7pv; return 0 }
|
||||||
|
var x7pvar *T7pv
|
||||||
|
var x7pv /* ERROR initialization cycle */ = x7pvar.m
|
||||||
|
|
||||||
|
type T8pv int
|
||||||
|
func (*T8pv) m() int { _ = x8pv; return 0 }
|
||||||
|
var x8pvar *T8pv
|
||||||
|
var x8pv /* ERROR initialization cycle */ = x8pvar.m()
|
||||||
|
|
||||||
|
// cycles through method values of embedded methods
|
||||||
|
|
||||||
|
type T9 struct { E9 }
|
||||||
|
type E9 int
|
||||||
|
func (E9) m() int { _ = x9; return 0 }
|
||||||
|
var x9 /* ERROR initialization cycle */ = T9{0}.m
|
||||||
|
|
||||||
|
type T10 struct { E10 }
|
||||||
|
type E10 int
|
||||||
|
func (E10) m() int { _ = x10; return 0 }
|
||||||
|
var x10 /* ERROR initialization cycle */ = T10{0}.m()
|
||||||
|
|
||||||
|
type T9p struct { E9p }
|
||||||
|
type E9p int
|
||||||
|
func (*E9p) m() int { _ = x9p; return 0 }
|
||||||
|
var x9p /* ERROR initialization cycle */ = new(T9p).m
|
||||||
|
|
||||||
|
type T10p struct { E10p }
|
||||||
|
type E10p int
|
||||||
|
func (*E10p) m() int { _ = x10p; return 0 }
|
||||||
|
var x10p /* ERROR initialization cycle */ = new(T10p).m()
|
||||||
|
|
||||||
|
type T9v struct { E9v }
|
||||||
|
type E9v int
|
||||||
|
func (E9v) m() int { _ = x9v; return 0 }
|
||||||
|
var x9var T9v
|
||||||
|
var x9v /* ERROR initialization cycle */ = x9var.m
|
||||||
|
|
||||||
|
type T10v struct { E10v }
|
||||||
|
type E10v int
|
||||||
|
func (E10v) m() int { _ = x10v; return 0 }
|
||||||
|
var x10var T10v
|
||||||
|
var x10v /* ERROR initialization cycle */ = x10var.m()
|
||||||
|
|
||||||
|
type T9pv struct { E9pv }
|
||||||
|
type E9pv int
|
||||||
|
func (*E9pv) m() int { _ = x9pv; return 0 }
|
||||||
|
var x9pvar *T9pv
|
||||||
|
var x9pv /* ERROR initialization cycle */ = x9pvar.m
|
||||||
|
|
||||||
|
type T10pv struct { E10pv }
|
||||||
|
type E10pv int
|
||||||
|
func (*E10pv) m() int { _ = x10pv; return 0 }
|
||||||
|
var x10pvar *T10pv
|
||||||
|
var x10pv /* ERROR initialization cycle */ = x10pvar.m()
|
Loading…
Reference in New Issue