diff --git a/src/cmd/compile/internal/gc/main.go b/src/cmd/compile/internal/gc/main.go index 339e8e08cd..09378bab6e 100644 --- a/src/cmd/compile/internal/gc/main.go +++ b/src/cmd/compile/internal/gc/main.go @@ -480,7 +480,7 @@ func Main(archInit func(*Arch)) { // Process top-level declarations in phases. - // Phase 1: const, type, and names and types of funcs. + // Phase 1: type, and names and types of funcs. // This will gather all the information about types // and methods but doesn't depend on any of it. defercheckwidth() @@ -489,16 +489,29 @@ func Main(archInit func(*Arch)) { timings.Start("fe", "typecheck", "top1") for i := 0; i < len(xtop); i++ { n := xtop[i] - if op := n.Op; op != ODCL && op != OAS && op != OAS2 { + if op := n.Op; op != ODCL && op != OAS && op != OAS2 && op != ODCLCONST { xtop[i] = typecheck(n, Etop) } } - // Phase 2: Variable assignments. - // To check interface assignments, depends on phase 1. + // Phase 2: Constant declarations. + // To have named types fully type checked, depends on phase 1. // Don't use range--typecheck can add closures to xtop. timings.Start("fe", "typecheck", "top2") + for i := 0; i < len(xtop); i++ { + n := xtop[i] + if op := n.Op; op == ODCLCONST { + xtop[i] = typecheck(n, Etop) + } + } + + // Phase 3: Variable assignments. + // To check interface assignments, depends on phase 1. + // To use constants, depends on phase 2. + + // Don't use range--typecheck can add closures to xtop. + timings.Start("fe", "typecheck", "top3") for i := 0; i < len(xtop); i++ { n := xtop[i] if op := n.Op; op == ODCL || op == OAS || op == OAS2 { diff --git a/test/fixedbugs/issue24755.go b/test/fixedbugs/issue24755.go new file mode 100644 index 0000000000..07c9d5a418 --- /dev/null +++ b/test/fixedbugs/issue24755.go @@ -0,0 +1,16 @@ +// errorcheck + +// Copyright 2018 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. + +// Tests that all types and functions are type-checked before any constant +// declaration is. Issue #24755. +package p + +type I interface{ F() } +type T struct{} + +const _ = I(T{}) // ERROR "const initializer I\(T literal\) is not a constant" + +func (T) F() {}