isErrorReturnNonnil returns true if the error return is guaranteed to be nonnil, false otherwise
(rootNode *RootAssertionNode, errRet ast.Expr)
| 245 | |
| 246 | // isErrorReturnNonnil returns true if the error return is guaranteed to be nonnil, false otherwise |
| 247 | func isErrorReturnNonnil(rootNode *RootAssertionNode, errRet ast.Expr) bool { |
| 248 | // The error value's type is not inhabited by nil (e.g., a named basic type such as |
| 249 | // `type Error string`), so it can never be nil. |
| 250 | if rootNode.Pass().ExprBarsNilness(errRet) { |
| 251 | return true |
| 252 | } |
| 253 | // The error value is a custom error type (struct or pointer-to-struct), e.g. a returned |
| 254 | // `&MyErr{}` or `MyErr{}`. Such values are assumed non-nil: a concrete value boxed into the |
| 255 | // error interface yields a non-nil interface. |
| 256 | if t := rootNode.Pass().TypesInfo.TypeOf(errRet); typeshelper.AsDeeplyStruct(t) != nil { |
| 257 | return true |
| 258 | } |
| 259 | // The error value is the return of a hook-modeled function known to produce a non-nil error. |
| 260 | if callExpr, ok := errRet.(*ast.CallExpr); ok { |
| 261 | if hook.AssumeReturn(rootNode.Pass(), callExpr) != nil { |
| 262 | return true |
| 263 | } |
| 264 | } |
| 265 | |
| 266 | return false |
| 267 | } |
| 268 | |
| 269 | // handleErrorReturns handles the special case for error returning functions (n-th result of type `error` which guards at least one of the first n-1 non-error results). |
| 270 | // It generates consumers by applying the error contract: |
no test coverage detected