}
p.typ(t)
if n > 0 {
- if name := parName(q, numbered); name != "" {
- p.string(name)
+ name := parName(q, numbered)
+ if name == "" {
+ // Sometimes we see an empty name even for n > 0.
+ // This appears to happen for interface methods
+ // with _ (blank) parameter names. Make sure we
+ // have a proper name and package so we don't crash
+ // during import (see also issue #15470).
+ // (parName uses "" instead of "?" as in fmt.go)
+ // TODO(gri) review parameter name encoding
+ name = "_"
+ }
+ p.string(name)
+ if name != "_" {
// Because of (re-)exported inlined functions
// the importpkg may not be the package to which this
// function (and thus its parameter) belongs. We need to
// supply the parameter package here. We need the package
// when the function is inlined so we can properly resolve
- // the name.
+ // the name. The _ (blank) parameter cannot be accessed, so
+ // we don't need to export a package.
+ //
// TODO(gri) This is compiler-specific. Try using importpkg
// here and then update the symbols if we find an inlined
// body only. Otherwise, the parameter name is ignored and
// the package doesn't matter. This would remove an int
// (likely 1 byte) for each named parameter.
p.pkg(q.Sym.Pkg)
- } else {
- // Sometimes we see an empty name even for n > 0.
- // This appears to happen for interface methods
- // with _ (blank) parameter names. Make sure we
- // have a proper name and package so we don't crash
- // during import (see also issue #15470).
- // TODO(gri) review parameter encoding
- p.string("_")
- p.pkg(localpkg)
}
}
// TODO(gri) This is compiler-specific (escape info).
if s.Name[1] == 'r' { // originally an unnamed result
return "" // s = nil
} else if s.Name[1] == 'b' { // originally the blank identifier _
- return "_"
+ return "_" // belongs to localpkg
}
}
} else {
}
}
+ // we should never see a _ (blank) here - these are accessible ("read") fields
+ // TODO(gri) can we assert this with an explicit check?
p.string(name)
if !exportname(name) {
p.pkg(s.Pkg)
// we should never see an empty package name
if name == "" {
- Fatalf("importer: empty package name in import")
+ Fatalf("importer: empty package name for path %q", path)
}
// we should never see a bad import path
if isbadimport(path) {
- Fatalf("importer: bad path in import: %q", path)
+ Fatalf("importer: bad package path %q for package %s", path, name)
}
// an empty path denotes the package we are currently importing;
if pkg.Name == "" {
pkg.Name = name
} else if pkg.Name != name {
- Fatalf("importer: conflicting names %s and %s for package %q", pkg.Name, name, path)
+ Fatalf("importer: conflicting package names %s and %s for path %q", pkg.Name, name, path)
}
p.pkgList = append(p.pkgList, pkg)
// During imports, unqualified non-exported identifiers are from builtinpkg
// (see parser.go:sym). The binary exporter only exports blank as a non-exported
// identifier without qualification.
- pkg = localpkg
+ pkg = builtinpkg
} else if name == "?" || name != "" && !exportname(name) {
if name == "?" {
name = ""
}
// TODO(gri) Supply function/method package rather than
// encoding the package for each parameter repeatedly.
- pkg := p.pkg()
+ pkg := localpkg
+ if name != "_" {
+ pkg = p.pkg()
+ }
n.Left = newname(pkg.Lookup(name))
}