Skip to content

Commit

Permalink
Turn "unused" errors into warnings
Browse files Browse the repository at this point in the history
  • Loading branch information
tux3 committed Mar 10, 2021
1 parent c139d6d commit 4ed7675
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 6 deletions.
4 changes: 2 additions & 2 deletions src/cmd/compile/internal/gc/main.go
Expand Up @@ -1352,9 +1352,9 @@ func pkgnotused(lineno src.XPos, path string, name string) {
elem = elem[i+1:]
}
if name == "" || elem == name {
yyerrorl(lineno, "imported and not used: %q", path)
yywarningl(lineno, "imported and not used: %q", path)
} else {
yyerrorl(lineno, "imported and not used: %q as %s", path, name)
yywarningl(lineno, "imported and not used: %q as %s", path, name)
}
}

Expand Down
72 changes: 71 additions & 1 deletion src/cmd/compile/internal/gc/subr.go
Expand Up @@ -26,6 +26,7 @@ type Error struct {
msg string
}

var warnings []Error
var errors []Error

// largeStack is info about a function whose stack frame is too large (rare).
Expand Down Expand Up @@ -59,6 +60,13 @@ func adderrorname(n *Node) {
}
}

func addwarn(pos src.XPos, format string, args ...interface{}) {
warnings = append(warnings, Error{
pos: pos,
msg: fmt.Sprintf("%v: warning: %s\n", linestr(pos), fmt.Sprintf(format, args...)),
})
}

func adderr(pos src.XPos, format string, args ...interface{}) {
msg := fmt.Sprintf(format, args...)
// Only add the position if know the position.
Expand Down Expand Up @@ -95,6 +103,22 @@ func flusherrors() {
errors = errors[:0]
}

// flushwarnings sorts warnings seen so far by line number, prints them to stdout,
// and empties the warnings array.
func flushwarnings() {
Ctxt.Bso.Flush()
if len(warnings) == 0 {
return
}
sort.Stable(byPos(warnings))
for i, err := range warnings {
if i == 0 || err.msg != warnings[i-1].msg {
fmt.Printf("%s", err.msg)
}
}
warnings = warnings[:0]
}

func hcrash() {
if Debug.h != 0 {
flusherrors()
Expand All @@ -119,13 +143,59 @@ var lasterror struct {
msg string // error message of last non-syntax error
}

// lastwarning keeps track of the most recently issued warning.
// It is used to avoid multiple warning messages on the same
// line.
var lastwarning struct {
syntax src.XPos // source position of last syntax warning
other src.XPos // source position of last non-syntax warning
msg string // warning message of last non-syntax warning
}

// sameline reports whether two positions a, b are on the same line.
func sameline(a, b src.XPos) bool {
p := Ctxt.PosTable.Pos(a)
q := Ctxt.PosTable.Pos(b)
return p.Base() == q.Base() && p.Line() == q.Line()
}

func yywarningl(pos src.XPos, format string, args ...interface{}) {
msg := fmt.Sprintf(format, args...)

if strings.HasPrefix(msg, "syntax error") {
// only one syntax error per line, no matter what error
if sameline(lastwarning.syntax, pos) {
return
}
lastwarning.syntax = pos
} else {
// only one of multiple equal non-syntax errors per line
// (flusherrors shows only one of them, so we filter them
// here as best as we can (they may not appear in order)
// so that we don't count them here and exit early, and
// then have nothing to show for.)
if sameline(lastwarning.other, pos) && lastwarning.msg == msg {
return
}
lastwarning.other = pos
lastwarning.msg = msg
}

addwarn(pos, "%s", msg)

hcrash()
flushwarnings()
}

func yywarningv(lang string, format string, args ...interface{}) {
what := fmt.Sprintf(format, args...)
yywarningl(lineno, "%s requires %s or later (-lang was set to %s; check go.mod)", what, lang, flag_lang)
}

func yywarning(format string, args ...interface{}) {
yywarningl(lineno, format, args...)
}

func yyerrorl(pos src.XPos, format string, args ...interface{}) {
msg := fmt.Sprintf(format, args...)

Expand Down Expand Up @@ -302,7 +372,7 @@ func importdot(opkg *types.Pkg, pack *Node) {

if n == 0 {
// can't possibly be used - there were no symbols
yyerrorl(pack.Pos, "imported and not used: %q", opkg.Path)
yywarningl(pack.Pos, "imported and not used: %q", opkg.Path)
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/cmd/compile/internal/gc/swt.go
Expand Up @@ -32,7 +32,7 @@ func typecheckTypeSwitch(n *Node) {
// declaration itself. So if there are no cases, we won't
// notice that it went unused.
if v := n.Left.Left; v != nil && !v.isBlank() && n.List.Len() == 0 {
yyerrorl(v.Pos, "%v declared but not used", v.Sym)
yywarningl(v.Pos, "%v declared but not used", v.Sym)
}

var defCase, nilCase *Node
Expand Down
4 changes: 2 additions & 2 deletions src/cmd/compile/internal/gc/walk.go
Expand Up @@ -51,10 +51,10 @@ func walk(fn *Node) {
if defn.Left.Name.Used() {
continue
}
yyerrorl(defn.Left.Pos, "%v declared but not used", ln.Sym)
yywarningl(defn.Left.Pos, "%v declared but not used", ln.Sym)
defn.Left.Name.SetUsed(true) // suppress repeats
} else {
yyerrorl(ln.Pos, "%v declared but not used", ln.Sym)
yywarningl(ln.Pos, "%v declared but not used", ln.Sym)
}
}

Expand Down

0 comments on commit 4ed7675

Please sign in to comment.