cmd/vet: backport of https://go-review.googlesource.com/#/c/10777/3
Change-Id: I8d63575f2053eda2d7f0a63f3ff862bf0de88d31 Reviewed-on: https://go-review.googlesource.com/10807 Reviewed-by: Alan Donovan <adonovan@google.com>
This commit is contained in:
		
							parent
							
								
									ac303766f5
								
							
						
					
					
						commit
						a6d2a4254e
					
				|  | @ -19,8 +19,8 @@ var imports = make(map[string]*types.Package) | ||||||
| 
 | 
 | ||||||
| var ( | var ( | ||||||
| 	errorType     *types.Interface | 	errorType     *types.Interface | ||||||
| 	stringerType  *types.Interface | 	stringerType  *types.Interface // possibly nil
 | ||||||
| 	formatterType *types.Interface | 	formatterType *types.Interface // possibly nil
 | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func init() { | func init() { | ||||||
|  | @ -37,13 +37,12 @@ func init() { | ||||||
| 
 | 
 | ||||||
| // importType returns the type denoted by the qualified identifier
 | // importType returns the type denoted by the qualified identifier
 | ||||||
| // path.name, and adds the respective package to the imports map
 | // path.name, and adds the respective package to the imports map
 | ||||||
| // as a side effect.
 | // as a side effect. In case of an error, importType returns nil.
 | ||||||
| func importType(path, name string) types.Type { | func importType(path, name string) types.Type { | ||||||
| 	pkg, err := types.DefaultImport(imports, path) | 	pkg, err := types.DefaultImport(imports, path) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		// This can happen if fmt hasn't been compiled yet.
 | 		// This can happen if the package at path hasn't been compiled yet.
 | ||||||
| 		// Since nothing uses formatterType anyway, don't complain.
 | 		warnf("import failed: %v", err) | ||||||
| 		//warnf("import failed: %v", err)
 |  | ||||||
| 		return nil | 		return nil | ||||||
| 	} | 	} | ||||||
| 	if obj, ok := pkg.Scope().Lookup(name).(*types.TypeName); ok { | 	if obj, ok := pkg.Scope().Lookup(name).(*types.TypeName); ok { | ||||||
|  | @ -136,16 +135,13 @@ func (f *File) matchArgTypeInternal(t printfArgType, typ types.Type, arg ast.Exp | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	// If the type implements fmt.Formatter, we have nothing to check.
 | 	// If the type implements fmt.Formatter, we have nothing to check.
 | ||||||
| 	// But (see issue 6259) that's not easy to verify, so instead we see
 | 	// formatterTyp may be nil - be conservative and check for Format method in that case.
 | ||||||
| 	// if its method set contains a Format function. We could do better,
 | 	if formatterType != nil && types.Implements(typ, formatterType) || f.hasMethod(typ, "Format") { | ||||||
| 	// even now, but we don't need to be 100% accurate. Wait for 6259 to
 |  | ||||||
| 	// be fixed instead. TODO.
 |  | ||||||
| 	if f.hasMethod(typ, "Format") { |  | ||||||
| 		return true | 		return true | ||||||
| 	} | 	} | ||||||
| 	// If we can use a string, might arg (dynamically) implement the Stringer or Error interface?
 | 	// If we can use a string, might arg (dynamically) implement the Stringer or Error interface?
 | ||||||
| 	if t&argString != 0 { | 	if t&argString != 0 { | ||||||
| 		if types.AssertableTo(errorType, typ) || types.AssertableTo(stringerType, typ) { | 		if types.AssertableTo(errorType, typ) || stringerType != nil && types.AssertableTo(stringerType, typ) { | ||||||
| 			return true | 			return true | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | @ -319,8 +315,10 @@ func (f *File) isErrorMethodCall(call *ast.CallExpr) bool { | ||||||
| 	if typ != nil { | 	if typ != nil { | ||||||
| 		// We know it's called "Error", so just check the function signature
 | 		// We know it's called "Error", so just check the function signature
 | ||||||
| 		// (stringerType has exactly one method, String).
 | 		// (stringerType has exactly one method, String).
 | ||||||
|  | 		if stringerType != nil && stringerType.NumMethods() == 1 { | ||||||
| 			return types.Identical(f.pkg.types[call.Fun].Type, stringerType.Method(0).Type()) | 			return types.Identical(f.pkg.types[call.Fun].Type, stringerType.Method(0).Type()) | ||||||
| 		} | 		} | ||||||
|  | 	} | ||||||
| 	// Without types, we can still check by hand.
 | 	// Without types, we can still check by hand.
 | ||||||
| 	// Is it a selector expression? Otherwise it's a function call, not a method call.
 | 	// Is it a selector expression? Otherwise it's a function call, not a method call.
 | ||||||
| 	sel, ok := call.Fun.(*ast.SelectorExpr) | 	sel, ok := call.Fun.(*ast.SelectorExpr) | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue