esimonov / ifshort

Go linter for checking that your code uses short syntax for if-statements whenever possible.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

false positive when value modified inside switch statement

nixpanic opened this issue · comments

The code below generates this warning:

internal/rbd/rbd_util.go:1619:2: variable 'removeOldKey' is only used in the if-statement (internal/rbd/rbd_util.go:1639:2); consider using short syntax (ifshort)
	removeOldKey := false
	^

removeOldKey is initialized to false, but only set to true in one case inside the switch statement. The warning does not seem to be correct to me (or I fail to see how to rewrite it to a shorter syntax).

// MigrateMetadata reads the metadata contents from oldKey and stores it in
// newKey. In case oldKey was not set, the defaultValue is stored in newKey.
// Once done, oldKey will be removed as well.
func (ri *rbdImage) MigrateMetadata(oldKey, newKey, defaultValue string) (string, error) {
        value, err := ri.GetMetadata(newKey)
        if err == nil {
                return value, nil
        } else if !errors.Is(err, librbd.ErrNotFound) {
                return "", err
        }

        // migrate contents from oldKey to newKey
        removeOldKey := false
        value, err = ri.GetMetadata(oldKey)
        switch {
        case err == nil: 
                // oldKey was fetched without error, remove it afterwards
                removeOldKey = true 
        case errors.Is(err, librbd.ErrNotFound):
                // in case oldKey was not set, set newKey to defaultValue
                value = defaultValue
        default:
                return "", err
        }

        // newKey was not set, set it now to prevent regular error cases for missing metadata
        err = ri.SetMetadata(newKey, value)
        if err != nil {
                return "", err
        }

        // the newKey was set with data from oldKey, oldKey is not needed anymore
        if removeOldKey {
                err = ri.RemoveMetadata(oldKey)
                if err != nil {
                        return "", err
                }
        }

        return value, nil
}

Another, simpler sample:

package main

import "math/rand"

func main() {
	x := rand.Intn(42)
	y := 100
	switch x {
	case 1:
		y = 1
	case 2:
		y = 2
	}
	if y < 5 { // variable 'y' is only used in the if-statement (...); consider using short syntax
	}
}

For this, there is a fine change that serves as a workaround, but the "consider using short syntax" suggestion doesn't really point towards it:

--- main.go.orig        2021-08-18 09:43:44.546404636 +0300
+++ main.go     2021-08-18 09:43:58.542486027 +0300
@@ -6,3 +6,3 @@
        x := rand.Intn(42)
-       y := 100
+       var y int
        switch x {
@@ -12,2 +12,4 @@
                y = 2
+       default:
+               y = 100
        }