Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

if-return incorrectly treated as golint rule #537

Closed
rliebz opened this issue Jun 29, 2021 · 1 comment · Fixed by #538
Closed

if-return incorrectly treated as golint rule #537

rliebz opened this issue Jun 29, 2021 · 1 comment · Fixed by #538
Assignees
Labels

Comments

@rliebz
Copy link
Contributor

rliebz commented Jun 29, 2021

Describe the bug
The README describes if-return as a golint rule, and therefore includes it in the set of defaults here and in golangci-lint. This is no longer true as of 2018.

Because of this discrepancy, there is an increased barrier to adoption of revive over golint.

To Reproduce
Steps to reproduce the behavior:

  1. I updated revive go install github.com/mgechev/revive@latest
  2. I ran revive on the following file with no config.toml:
package example

import "errors"

// Foo ...
func Foo() error {
	if err := returnErr(); err != nil {
		return err
	}

	return nil
}

func returnErr() error {
	return errors.New("oh no")
}

And got the following results:

$ revive example.go
example.go:7:2: redundant if ...; err != nil check, just return error instead. 

With golint:

$ golint example.go
# no output

Expected behavior
I would expect the output from revive to be the same as golint, since this is what the README claims.

Logs
N/A

Desktop (please complete the following information):

  • OS: macOS 11.4
  • Version of Go: go version go1.16.5 darwin/amd64

Additional context
The same problem exists with golangci-lint:

$ golangci-lint run -E revive .
example.go:7:2: if-return: redundant if ...; err != nil check, just return error instead. (revive)
        if err := returnErr(); err != nil {
                return err
        }

$ golangci-lint run -E golint .
WARN [runner] The linter 'golint' is deprecated (since v1.41.0) due to: The repository of the linter has been archived by the owner.  Replaced by revive.

@chavacava
Copy link
Collaborator

Hi @rliebz, thanks for filling the issue. I expect to work on it in the coming days.

@chavacava chavacava self-assigned this Jun 29, 2021
@chavacava chavacava added the bug label Jun 29, 2021
chavacava added a commit that referenced this issue Jun 29, 2021
mgechev pushed a commit that referenced this issue Jun 29, 2021
rliebz added a commit to rliebz/revive that referenced this issue Jun 23, 2023
The `if-return` rule was originally a golint rule which was removed
from their ruleset for being out of scope. Similarly, it was dropped
from revive intentionally as a result of mgechev#537. More recently, it was
reintroduced into the default ruleset as a result of mgechev#799 due to a
discrepancy in documentation without a discussion of whether this rule
in particular belonged as a part of that default rule set.

While it is no longer a goal of this project to align 100% with the
golint defaults, I believe that this rule gives bad advice often enough
that it should not be enabled by default.

For example, consider the following code:

```go
if err := func1(); err != nil {
	return err
}

if err := func2(); err != nil {
	return err
}

if err := func3(); err != nil {
	return err
}

return nil
```

The `if-return` rule considers this a violation of style, and instead
suggests the following:

```go
if err := func1(); err != nil {
	return err
}

if err := func2(); err != nil {
	return err
}

return func3()
```

While this is more terse, it has a few shortcomings compared to the
original. In particular, it means extending the size of the diff if
changing the order of checks, adding logic after the call that currently
happens to be last, or choosing to wrap the error. And in that last
case, it can make it less obvious that there is an unwrapped error being
propagated up the call stack.

This in practice has a very similar effect to disabling trailing commas;
while it is not necessarily wrong as a style choice, I don't believe it
warrants a position as part of the default ruleset here.
rliebz added a commit to rliebz/revive that referenced this issue Jun 23, 2023
The `if-return` rule was originally a golint rule which was removed
from their ruleset for being out of scope. Similarly, it was dropped
from revive intentionally as a result of mgechev#537. More recently, it was
reintroduced into the default ruleset as a result of mgechev#799 due to a
discrepancy in documentation without a discussion of whether this rule
in particular belonged as a part of that default rule set.

While it is no longer a goal of this project to align 100% with the
golint defaults, I believe that this rule gives bad advice often enough
that it should not be enabled by default.

For example, consider the following code:

```go
if err := func1(); err != nil {
	return err
}

if err := func2(); err != nil {
	return err
}

if err := func3(); err != nil {
	return err
}

return nil
```

The `if-return` rule considers this a violation of style, and instead
suggests the following:

```go
if err := func1(); err != nil {
	return err
}

if err := func2(); err != nil {
	return err
}

return func3()
```

While this is more terse, it has a few shortcomings compared to the
original. In particular, it means extending the size of the diff if
changing the order of checks, adding logic after the call that currently
happens to be last, or choosing to wrap the error. And in that last
case, it can make it less obvious that there is an unwrapped error being
propagated up the call stack.

This in practice has a very similar effect to disabling trailing commas;
while it is not necessarily wrong as a style choice, I don't believe it
warrants a position as part of the default ruleset here.
rliebz added a commit to rliebz/revive that referenced this issue Jun 23, 2023
The `if-return` rule was originally a golint rule which was removed
from their ruleset for being out of scope. Similarly, it was dropped
from revive intentionally as a result of mgechev#537. More recently, it was
reintroduced into the default ruleset as a result of mgechev#799 due to a
discrepancy in documentation without a discussion of whether this rule
in particular belonged as a part of that default rule set.

While it is no longer a goal of this project to align 100% with the
golint defaults, I believe that this rule gives bad advice often enough
that it should not be enabled by default.

For example, consider the following code:

```go
if err := func1(); err != nil {
	return err
}

if err := func2(); err != nil {
	return err
}

if err := func3(); err != nil {
	return err
}

return nil
```

The `if-return` rule considers this a violation of style, and instead
suggests the following:

```go
if err := func1(); err != nil {
	return err
}

if err := func2(); err != nil {
	return err
}

return func3()
```

While this is more terse, it has a few shortcomings compared to the
original. In particular, it means extending the size of the diff if
changing the order of checks, adding logic after the call that currently
happens to be last, or choosing to wrap the error. And in that last
case, it can make it less obvious that there is an unwrapped error being
propagated up the call stack.

This in practice has a very similar effect to disabling trailing commas;
while it is not necessarily wrong as a style choice, I don't believe it
warrants a position as part of the default ruleset here.

See-also: golang/lint#363
mgechev pushed a commit that referenced this issue Jun 26, 2023
The `if-return` rule was originally a golint rule which was removed
from their ruleset for being out of scope. Similarly, it was dropped
from revive intentionally as a result of #537. More recently, it was
reintroduced into the default ruleset as a result of #799 due to a
discrepancy in documentation without a discussion of whether this rule
in particular belonged as a part of that default rule set.

While it is no longer a goal of this project to align 100% with the
golint defaults, I believe that this rule gives bad advice often enough
that it should not be enabled by default.

For example, consider the following code:

```go
if err := func1(); err != nil {
	return err
}

if err := func2(); err != nil {
	return err
}

if err := func3(); err != nil {
	return err
}

return nil
```

The `if-return` rule considers this a violation of style, and instead
suggests the following:

```go
if err := func1(); err != nil {
	return err
}

if err := func2(); err != nil {
	return err
}

return func3()
```

While this is more terse, it has a few shortcomings compared to the
original. In particular, it means extending the size of the diff if
changing the order of checks, adding logic after the call that currently
happens to be last, or choosing to wrap the error. And in that last
case, it can make it less obvious that there is an unwrapped error being
propagated up the call stack.

This in practice has a very similar effect to disabling trailing commas;
while it is not necessarily wrong as a style choice, I don't believe it
warrants a position as part of the default ruleset here.

See-also: golang/lint#363
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants