. "internal/types/errors"
)
-func (err *error_) recordAltDecl(obj Object) {
- if pos := obj.Pos(); pos.IsKnown() {
- // We use "other" rather than "previous" here because
- // the first declaration seen may not be textually
- // earlier in the source.
- err.addf(pos, "other declaration of %s", obj.Name())
- }
-}
-
func (check *Checker) declare(scope *Scope, id *syntax.Name, obj Object, pos syntax.Pos) {
// spec: "The blank identifier, represented by the underscore
// character _, may be used in a declaration like any other
if alt := scope.Insert(obj); alt != nil {
err := check.newError(DuplicateDecl)
err.addf(obj, "%s redeclared in this block", obj.Name())
- err.recordAltDecl(alt)
+ err.addAltDecl(alt)
err.report()
return
}
// method, and the alt decl on the field.
err := check.newError(DuplicateFieldAndMethod)
err.addf(alt, "field and method with the same name %s", fld.name)
- err.recordAltDecl(fld)
+ err.addAltDecl(fld)
err.report()
}
}
err.desc = append(err.desc, errorDesc{atPos(at), err.check.sprintf(format, args...)})
}
+// addAltDecl is a specialized form of addf reporting another declaration of obj.
+func (err *error_) addAltDecl(obj Object) {
+ if pos := obj.Pos(); pos.IsKnown() {
+ // We use "other" rather than "previous" here because
+ // the first declaration seen may not be textually
+ // earlier in the source.
+ err.addf(obj, "other declaration of %s", obj.Name())
+ }
+}
+
func (err *error_) empty() bool {
return err.desc == nil
}
} else {
check.handleError(0, err.pos(), err.code, err.msg(), err.soft)
}
+
+ // make sure the error is not reported twice
+ err.desc = nil
}
// handleError should only be called by error_.report.
err := check.newError(DuplicateLabel)
err.soft = true
err.addf(lbl.pos, "label %s already declared", name)
- err.recordAltDecl(alt)
+ err.addAltDecl(alt)
err.report()
// ok to continue
} else {
if alt := fileScope.Lookup(name); alt != nil {
err := check.newError(DuplicateDecl)
err.addf(s.LocalPkgName, "%s redeclared in this block", alt.Name())
- err.recordAltDecl(alt)
+ err.addAltDecl(alt)
err.report()
} else {
fileScope.insert(name, obj)
err := check.newError(DuplicateDecl)
if pkg, ok := obj.(*PkgName); ok {
err.addf(alt, "%s already declared through import of %s", alt.Name(), pkg.Imported())
- err.recordAltDecl(pkg)
+ err.addAltDecl(pkg)
} else {
err.addf(alt, "%s already declared through dot-import of %s", alt.Name(), obj.Pkg())
- // TODO(gri) dot-imported objects don't have a position; recordAltDecl won't print anything
- err.recordAltDecl(obj)
+ // TODO(gri) dot-imported objects don't have a position; addAltDecl won't print anything
+ err.addAltDecl(obj)
}
err.report()
}
scope.Squash(func(obj, alt Object) {
err := check.newError(DuplicateDecl)
err.addf(obj, "%s redeclared in this block", obj.Name())
- err.recordAltDecl(alt)
+ err.addAltDecl(alt)
err.report()
})
if alt := oset.insert(obj); alt != nil {
err := check.newError(DuplicateDecl)
err.addf(pos, "%s redeclared", obj.Name())
- err.recordAltDecl(alt)
+ err.addAltDecl(alt)
err.report()
return false
}
. "internal/types/errors"
)
-func (check *Checker) reportAltDecl(obj Object) {
- if pos := obj.Pos(); pos.IsValid() {
- // We use "other" rather than "previous" here because
- // the first declaration seen may not be textually
- // earlier in the source.
- check.errorf(obj, DuplicateDecl, "\tother declaration of %s", obj.Name()) // secondary error, \t indented
- }
-}
-
func (check *Checker) declare(scope *Scope, id *ast.Ident, obj Object, pos token.Pos) {
// spec: "The blank identifier, represented by the underscore
// character _, may be used in a declaration like any other
// binding."
if obj.Name() != "_" {
if alt := scope.Insert(obj); alt != nil {
- check.errorf(obj, DuplicateDecl, "%s redeclared in this block", obj.Name())
- check.reportAltDecl(alt)
+ err := check.newError(DuplicateDecl)
+ err.addf(obj, "%s redeclared in this block", obj.Name())
+ err.addAltDecl(alt)
+ err.report()
return
}
obj.setScopePos(pos)
return
}
+ err := check.newError(InvalidDeclCycle)
if tname != nil {
- check.errorf(obj, InvalidDeclCycle, "invalid recursive type %s", objName)
+ err.addf(obj, "invalid recursive type %s", objName)
} else {
- check.errorf(obj, InvalidDeclCycle, "invalid cycle in declaration of %s", objName)
+ err.addf(obj, "invalid cycle in declaration of %s", objName)
}
i := start
for range cycle {
- check.errorf(obj, InvalidDeclCycle, "\t%s refers to", objName) // secondary error, \t indented
+ err.addf(obj, "%s refers to", objName)
i++
if i >= len(cycle) {
i = 0
obj = cycle[i]
objName = name(obj)
}
- check.errorf(obj, InvalidDeclCycle, "\t%s", objName)
+ err.addf(obj, "%s", objName)
+ err.report()
}
// firstInSrc reports the index of the object with the "smallest"
// For historical consistency, we report the primary error on the
// method, and the alt decl on the field.
- check.errorf(alt, DuplicateFieldAndMethod, "field and method with the same name %s", fld.name)
- check.reportAltDecl(fld)
+ err := check.newError(DuplicateFieldAndMethod)
+ err.addf(alt, "field and method with the same name %s", fld.name)
+ err.addAltDecl(fld)
+ err.report()
}
}
}
err.desc = append(err.desc, errorDesc{at, err.check.sprintf(format, args...)})
}
+// addAltDecl is a specialized form of addf reporting another declaration of obj.
+func (err *error_) addAltDecl(obj Object) {
+ if pos := obj.Pos(); pos.IsValid() {
+ // We use "other" rather than "previous" here because
+ // the first declaration seen may not be textually
+ // earlier in the source.
+ err.addf(obj, "other declaration of %s", obj.Name())
+ }
+}
+
func (err *error_) empty() bool {
return err.desc == nil
}
} else {
check.handleError(0, err.posn(), err.code, err.msg(), err.soft)
}
+
+ // make sure the error is not reported twice
+ err.desc = nil
}
// handleError should only be called by error_.report.
if name := s.Label.Name; name != "_" {
lbl := NewLabel(s.Label.Pos(), check.pkg, name)
if alt := all.Insert(lbl); alt != nil {
- check.softErrorf(lbl, DuplicateLabel, "label %s already declared", name)
- check.reportAltDecl(alt)
+ err := check.newError(DuplicateLabel)
+ err.soft = true
+ err.addf(lbl, "label %s already declared", name)
+ err.addAltDecl(alt)
+ err.report()
// ok to continue
} else {
b.insert(s)
// the object may be imported into more than one file scope
// concurrently. See go.dev/issue/32154.)
if alt := fileScope.Lookup(name); alt != nil {
- check.errorf(d.spec.Name, DuplicateDecl, "%s redeclared in this block", alt.Name())
- check.reportAltDecl(alt)
+ err := check.newError(DuplicateDecl)
+ err.addf(d.spec.Name, "%s redeclared in this block", alt.Name())
+ err.addAltDecl(alt)
+ err.report()
} else {
fileScope.insert(name, obj)
check.dotImportMap[dotImportKey{fileScope, name}] = pkgName
for name, obj := range scope.elems {
if alt := pkg.scope.Lookup(name); alt != nil {
obj = resolve(name, obj)
+ err := check.newError(DuplicateDecl)
if pkg, ok := obj.(*PkgName); ok {
- check.errorf(alt, DuplicateDecl, "%s already declared through import of %s", alt.Name(), pkg.Imported())
- check.reportAltDecl(pkg)
+ err.addf(alt, "%s already declared through import of %s", alt.Name(), pkg.Imported())
+ err.addAltDecl(pkg)
} else {
- check.errorf(alt, DuplicateDecl, "%s already declared through dot-import of %s", alt.Name(), obj.Pkg())
- // TODO(gri) dot-imported objects don't have a position; reportAltDecl won't print anything
- check.reportAltDecl(obj)
+ err.addf(alt, "%s already declared through dot-import of %s", alt.Name(), obj.Pkg())
+ // TODO(gri) dot-imported objects don't have a position; addAltDecl won't print anything
+ err.addAltDecl(obj)
}
+ err.report()
}
}
}
params, variadic := check.collectParams(scope, ftyp.Params, true, scopePos)
results, _ := check.collectParams(scope, ftyp.Results, false, scopePos)
scope.squash(func(obj, alt Object) {
- check.errorf(obj, DuplicateDecl, "%s redeclared in this block", obj.Name())
- check.reportAltDecl(alt)
+ err := check.newError(DuplicateDecl)
+ err.addf(obj, "%s redeclared in this block", obj.Name())
+ err.addAltDecl(alt)
+ err.report()
})
if recvPar != nil {
// (quadratic algorithm, but these lists tend to be very short)
for _, vt := range seen[val] {
if Identical(v.typ, vt.typ) {
- check.errorf(&v, DuplicateCase, "duplicate case %s in expression switch", &v)
- check.error(atPos(vt.pos), DuplicateCase, "\tprevious case") // secondary error, \t indented
+ err := check.newError(DuplicateCase)
+ err.addf(&v, "duplicate case %s in expression switch", &v)
+ err.addf(atPos(vt.pos), "previous case")
+ err.report()
continue L
}
}
if T != nil {
Ts = TypeString(T, check.qualifier)
}
- check.errorf(e, DuplicateCase, "duplicate case %s in type switch", Ts)
- check.error(other, DuplicateCase, "\tprevious case") // secondary error, \t indented
+ err := check.newError(DuplicateCase)
+ err.addf(e, "duplicate case %s in type switch", Ts)
+ err.addf(other, "previous case")
+ err.report()
continue L
}
}
// with the same name as a result parameter is in scope at the place of the return."
for _, obj := range res.vars {
if alt := check.lookup(obj.name); alt != nil && alt != obj {
- check.errorf(s, OutOfScopeResult, "result parameter %s not in scope at return", obj.name)
- check.errorf(alt, OutOfScopeResult, "\tinner declaration of %s", obj)
+ err := check.newError(OutOfScopeResult)
+ err.addf(s, "result parameter %s not in scope at return", obj.name)
+ err.addf(alt, "inner declaration of %s", obj)
+ err.report()
// ok to continue
}
}
func (check *Checker) declareInSet(oset *objset, pos token.Pos, obj Object) bool {
if alt := oset.insert(obj); alt != nil {
- check.errorf(atPos(pos), DuplicateDecl, "%s redeclared", obj.Name())
- check.reportAltDecl(alt)
+ err := check.newError(DuplicateDecl)
+ err.addf(atPos(pos), "%s redeclared", obj.Name())
+ err.addAltDecl(alt)
+ err.report()
return false
}
return true