ronantakizawa/codereview-bench huggingface dataset:
Repository: sympy/sympy
File: sympy/combinatorics/graycode.py (Python)

Code before:

def get_subset_from_bitstring(super_set: List[Any], bitstring: str) -> List[Any]:
    """
    Gets the subset defined by the bitstring.

    Examples
    ========

    >>> from sympy.combinatorics.graycode import get_subset_from_bitstring
    >>> get_subset_from_bitstring(['a', 'b', 'c', 'd'], '0011')
    ['c', 'd']
    >>> get_subset_from_bitstring(['c', 'a', 'c', 'c'], '1100')
    ['c', 'a']

    See Also
    ========

    graycode_subsets
    """
    if len(super_set) != len(bitstring):
        raise ValueError("The sizes of the lists are not equal")
    return [super_set[i] for i, j in enumerate(bitstring)
            if bitstring[i] == '1']


def graycode_subsets(gray_code_set: List[Any]) -> Iterator[List[Any]]:
    """
    Generates the subsets as enumerated by a Gray code.

    Examples
    ========

    >>> from sympy.combinatorics.graycode import graycode_subsets
    >>> list(graycode_subsets(['a', 'b', 'c']))
    [[], ['c'], ['b', 'c'], ['b'], ['a', 'b'], ['a', 'b', 'c'], \
    ['a', 'c'], ['a']]
    >>> list(graycode_subsets(['a', 'b', 'c', 'c']))
    [[], ['c'], ['c', 'c'], ['c'], ['b', 'c'], ['b', 'c', 'c'], \
    ['b', 'c'], ['b'], ['a', 'b'], ['a', 'b', 'c'], ['a', 'b', 'c', 'c'], \
    ['a', 'b', 'c'], ['a', 'c'], ['a', 'c', 'c'], ['a', 'c'], ['a']]

    See Also
    ========

    get_subset_from_bitstring
    """
    for bitstring in list(GrayCode(len(gray_code_set)).generate_gray()):
        yield get_subset_from_bitstring(gray_code_set, bitstring)


Review comment (suggestion):
Use list instead of List. Also try to use concrete type instead of Any.

Code after:
    return ''.join(b)


def get_subset_from_bitstring(super_set: list[T], bitstring: str) -> list[T]:
    """
    Gets the subset defined by the bitstring.

    Examples
    ========

    >>> from sympy.combinatorics.graycode import get_subset_from_bitstring
    >>> get_subset_from_bitstring(['a', 'b', 'c', 'd'], '0011')
    ['c', 'd']
    >>> get_subset_from_bitstring(['c', 'a', 'c', 'c'], '1100')
    ['c', 'a']

    See Also
    ========

    graycode_subsets
    """
    if len(super_set) != len(bitstring):
        raise ValueError("The sizes of the lists are not equal")
    return [super_set[i] for i, j in enumerate(bitstring)
            if bitstring[i] == '1']


def graycode_subsets(gray_code_set: list[T]) -> Iterator[list[T]]:
    """
    Generates the subsets as enumerated by a Gray code.

    Examples
    ========

    >>> from sympy.combinatorics.graycode import graycode_subsets
    >>> list(graycode_subsets(['a', 'b', 'c']))
    [[], ['c'], ['b', 'c'], ['b'], ['a', 'b'], ['a', 'b', 'c'], \
    ['a', 'c'], ['a']]
    >>> list(graycode_subsets(['a', 'b', 'c', 'c']))
    [[], ['c'], ['c', 'c'], ['c'], ['b', 'c'], ['b', 'c', 'c'], \
    ['b', 'c'], ['b'], ['a', 'b'], ['a', 'b', 'c'], ['a', 'b', 'c', 'c'], \
    ['a', 'b', 'c'], ['a', 'c'], ['a', 'c', 'c'], ['a', 'c'], ['a']]

    See Also
    ========

    get_subset_from_bitstring
    """
    for bitstring in list(GrayCode(len(gray_code_set)).generate_gray()):
        yield get_subset_from_bitstring(gray_code_set, bitstring)
Repository: sympy/sympy
File: sympy/combinatorics/graycode.py (Python)

Code before:
from sympy.core import Basic, Integer

import random


class GrayCode(Basic):
    """
    A Gray code is essentially a Hamiltonian walk on
    a n-dimensional cube with edge length of one.
    The vertices of the cube are represented by vectors
    whose values are binary. The Hamilton walk visits
    each vertex exactly once. The Gray code for a 3d
    cube is ['000','100','110','010','011','111','101',
    '001'].

    A Gray code solves the problem of sequentially
    generating all possible subsets of n objects in such
    a way that each subset is obtained from the previous
    one by either deleting or adding a single object.
    In the above example, 1 indicates that the object is
    present, and 0 indicates that its absent.

    Gray codes have applications in statistics as well when
    we want to compute various statistics related to subsets
    in an efficient manner.

    Examples

Review comment (suggestion):
You can import Type_Checking and put the imports in if block
Also, lets remove the Any its useless here

Code after:
from __future__ import annotations
from typing import Iterator, Any, TypeVar
from sympy.core import Basic, Integer

import random

T = TypeVar('T')

class GrayCode(Basic):
    """
    A Gray code is essentially a Hamiltonian walk on
    a n-dimensional cube with edge length of one.
    The vertices of the cube are represented by vectors
    whose values are binary. The Hamilton walk visits
    each vertex exactly once. The Gray code for a 3d
    cube is ['000','100','110','010','011','111','101',
    '001'].

    A Gray code solves the problem of sequentially
    generating all possible subsets of n objects in such
    a way that each subset is obtained from the previous
    one by either deleting or adding a single object.
    In the above example, 1 indicates that the object is
    present, and 0 indicates that its absent.

    Gray codes have applications in statistics as well when
    we want to compute various statistics related to subsets
Repository: sympy/sympy
File: sympy/geometry/plane.py (Python)

Code before:
            a = self.equation()
            b = o.equation()
            return cancel(a/b).is_constant()
        else:
            return False


    def equation(self, x=None, y=None, z=None):
        """The equation of the Plane.

        Examples
        ========

        >>> from sympy import Point3D, Plane
        >>> a = Plane(Point3D(1, 1, 2), Point3D(2, 4, 7), Point3D(3, 5, 1))
        >>> a.equation()
        -23*x + 11*y - 2*z + 16
        >>> a = Plane(Point3D(1, 4, 2), normal_vector=(6, 6, 6))
        >>> a.equation()
        6*x + 6*y + 6*z - 42

        """
        coords = {x, y, z} - {None}
        if coords & self.free_symbols:
            raise ValueError(
                "Plane.equation(): provided symbols clash with symbols used to define the plane."
            )
        x, y, z = [i if i else Symbol(j, real=True) for i, j in zip((x, y, z), 'xyz')]
        a = Point3D(x, y, z)
        b = self.p1.direction_ratio(a)
        c = self.normal_vector
        return (sum(i*j for i, j in zip(b, c)))


    def intersection(self, o):
        """ The intersection with other geometrical entity.

        Parameters
        ==========

        Point, Point3D, LinearEntity, LinearEntity3D, Plane

        Returns
        =======

        List

        Examples
        ========

        >>> from sympy import Point3D, Line3D, Plane

Review comment (suggestion):
I don't think "Plane.equation():" needs to be specified here, see how error messages are written in this file and rewrite this. 

Code after:
            a = self.equation()
            b = o.equation()
            return cancel(a/b).is_constant()
        else:
            return False


    def equation(self, x=None, y=None, z=None):
        """The equation of the Plane.

        Examples
        ========

        >>> from sympy import Point3D, Plane
        >>> a = Plane(Point3D(1, 1, 2), Point3D(2, 4, 7), Point3D(3, 5, 1))
        >>> a.equation()
        -23*x + 11*y - 2*z + 16
        >>> a = Plane(Point3D(1, 4, 2), normal_vector=(6, 6, 6))
        >>> a.equation()
        6*x + 6*y + 6*z - 42

        """
        coords = {x, y, z} - {None}
        if coords & self.free_symbols:
            raise ValueError("Provided symbols clash with symbols used to define the plane")
        x, y, z = [i if i else Symbol(j, real=True) for i, j in zip((x, y, z), 'xyz')]
        a = Point3D(x, y, z)
        b = self.p1.direction_ratio(a)
        c = self.normal_vector
        return (sum(i*j for i, j in zip(b, c)))


    def intersection(self, o):
        """ The intersection with other geometrical entity.

        Parameters
        ==========

        Point, Point3D, LinearEntity, LinearEntity3D, Plane

        Returns
        =======

        List

        Examples
        ========

        >>> from sympy import Point3D, Line3D, Plane
        >>> a = Plane(Point3D(1, 2, 3), normal_vector=(1, 1, 1))
        >>> b = Point3D(1, 2, 3)
Repository: sympy/sympy
File: sympy/assumptions/refine.py (Python)

Code before:
    >>> x = Symbol('x')
    >>> y = Symbol('y')
    >>> refine(floor(x), Q.integer(x))
    x
    >>> refine(ceiling(x), Q.integer(x))
    x
    >>> refine(floor(x), ~Q.integer(x))
    floor(x)
    >>> refine(floor(x + y), Q.integer(x))
    x + floor(y)
    >>> refine(ceiling(x + y), Q.integer(x))
    x + ceiling(y)
    >>> refine(ceiling(x), Q.infinite(x))
    x
    >>> refine(ceiling(ceiling(x) + ceiling(y)), Q.complex(x) & Q.complex(y))
    ceiling(x) + ceiling(y)
    """
    arg = expr.args[0]
    if ask(Q.integer(arg), assumptions) or ask(Q.infinite(arg), assumptions):
        return arg

    if isinstance(arg, Add):
        simplified = []
        non_simplified = []
        for term in arg.args:
            if ask(Q.integer(term), assumptions) or isinstance(term, expr.func):
                simplified.append(term)
            else:
                non_simplified.append(term)
        return Add(*simplified) + expr.func(Add(*non_simplified))
    return expr


handlers_dict: dict[str, Callable[[Basic, Boolean | bool], Expr]] = {
    'Abs': refine_abs,
    'Pow': refine_Pow,
    'atan2': refine_atan2,
    're': refine_re,
    'im': refine_im,
    'arg': refine_arg,
    'sign': refine_sign,
    'MatrixElement': refine_matrixelement,
    'cos': refine_sin_cos,
    'sin': refine_sin_cos,
    'floor': refine_floor_ceiling,
    'ceiling' : refine_floor_ceiling,
}


Review comment (bug):
> expr.func

Wouldn't this logic work if it was either floor or ceiling? Does it actually matter if it's the same type of function? Or am I missing something and that would be incorrect for some cases? 

Code after:
    >>> x = Symbol('x')
    >>> y = Symbol('y')
    >>> refine(floor(x), Q.integer(x))
    x
    >>> refine(ceiling(x), Q.integer(x))
    x
    >>> refine(floor(x + y), Q.integer(x))
    x + floor(y)
    >>> refine(ceiling(x + y), Q.integer(x))
    x + ceiling(y)
    >>> refine(ceiling(x), Q.infinite(x))
    x
    >>> refine(ceiling(ceiling(x) + ceiling(y)))
    ceiling(x) + ceiling(y)
    """
    from sympy.functions.elementary.integers import floor, ceiling
    arg = expr.args[0]
    if ask(Q.integer(arg), assumptions) or ask(Q.infinite(arg), assumptions):
        return arg

    if isinstance(arg, Add):
        gaussian_integer_terms = []
        nongausian_intergers_terms = []
        for term in arg.args:
            if ask(Q.integer(term), assumptions) or isinstance(term, (floor, ceiling)):
                gaussian_integer_terms.append(term)
            else:
                nongausian_intergers_terms.append(term)
        return Add(*gaussian_integer_terms) + expr.func(Add(*nongausian_intergers_terms))
    return expr


handlers_dict: dict[str, Callable[[Basic, Boolean | bool], Expr]] = {
    'Abs': refine_abs,
    'Pow': refine_Pow,
    'atan2': refine_atan2,
    're': refine_re,
    'im': refine_im,
    'arg': refine_arg,
    'sign': refine_sign,
    'MatrixElement': refine_matrixelement,
    'cos': refine_sin_cos,
    'sin': refine_sin_cos,
    'floor': refine_floor_ceiling,
    'ceiling' : refine_floor_ceiling,
}
Repository: sympy/sympy
File: sympy/assumptions/tests/test_refine.py (Python)

Code before:
                  Q.integer(n) & Q.odd(k) & Q.integer(m)) == \
        (-1)**(n + (k + 1)/2) * sin(x + m*pi/2)
    assert refine(sin(x + n*pi + k*pi/2 + m*pi/2), \
                  Q.integer(n) & Q.odd(k) & Q.integer(m)) == \
        (-1)**(n + (k + 3)/2) * cos(x + m*pi/2)
    assert refine(cos(x + n*pi/2 + k*pi/2 + m*pi/2), \
                  Q.odd(n) & Q.odd(k) & Q.integer(m)) == \
        (-1)**((n + k)/2) * cos(x + m*pi/2)


def test_floor_ceiling():
    assert refine(floor(x), Q.integer(x)) == x
    assert refine(ceiling(x), Q.integer(x)) == x
    assert refine(floor(x), Q.infinite(x)) == x
    assert refine(ceiling(x), Q.infinite(x)) == x

    assert refine(floor(y), Q.real(y)) == floor(y)
    assert refine(ceiling(y), Q.real(y)) == ceiling(y)

    assert refine(floor(x + y), Q.integer(x)) == x + floor(y)
    assert refine(ceiling(x + y), Q.integer(x)) == x + ceiling(y)
    assert refine(floor(x + y + z), Q.integer(x) & Q.integer(y)) == x + y + floor(z)
    assert refine(ceiling(x + y + z), Q.integer(x) & Q.integer(z)) == x + z + ceiling(y)

    assert refine(floor(floor(x)+ floor(y)), Q.complex(x) & Q.complex(y)) == floor(x) + floor(y)
    assert refine(ceiling(ceiling(x) - ceiling(y)), Q.complex(x) & Q.complex(y)) == ceiling(x) - ceiling(y)


Review comment (refactor):
Oh, you should also add some tests here without the assumptions that don't simplify. Sorry I didn't notice this until I had already hit "submit review" and it's not grouped with my other comments. 

Code after:
                  Q.integer(n) & Q.odd(k) & Q.integer(m)) == \
        (-1)**(n + (k + 1)/2) * sin(x + m*pi/2)
    assert refine(sin(x + n*pi + k*pi/2 + m*pi/2), \
                  Q.integer(n) & Q.odd(k) & Q.integer(m)) == \
        (-1)**(n + (k + 3)/2) * cos(x + m*pi/2)
    assert refine(cos(x + n*pi/2 + k*pi/2 + m*pi/2), \
                  Q.odd(n) & Q.odd(k) & Q.integer(m)) == \
        (-1)**((n + k)/2) * cos(x + m*pi/2)


def test_floor_ceiling():
    assert refine(floor(x), Q.integer(x)) == x
    assert refine(ceiling(x), Q.integer(x)) == x
    assert refine(floor(x), Q.infinite(x)) == x
    assert refine(ceiling(x), Q.infinite(x)) == x

    assert refine(floor(y), Q.real(y)) == floor(y)
    assert refine(ceiling(y), Q.real(y)) == ceiling(y)

    assert refine(floor(x + y), Q.integer(x)) == x + floor(y)
    assert refine(ceiling(x + y), Q.integer(x)) == x + ceiling(y)
    assert refine(floor(x + y + z), Q.integer(x) & Q.integer(y)) == x + y + floor(z)
    assert refine(ceiling(x + y + z), Q.integer(x) & Q.integer(z)) == x + z + ceiling(y)
    assert refine(floor(x + y - z)) == floor (x + y - z)
    assert refine(ceiling(ceiling(x) + y + floor(z))) == ceiling(x) + ceiling(y) + floor(z)

    assert refine(floor(floor(x)+ floor(y))) == floor(x) + floor(y)
    assert refine(ceiling(ceiling(x) - ceiling(y))) == ceiling(x) - ceiling(y)
Repository: syncthing/syncthing
File: internal/db/virtualmtime.go (Go)

Code before:
		ns: NewNamespacedKV(ldb, prefix),
	}
}

func (r *VirtualMtimeRepo) UpdateMtime(path string, diskMtime, actualMtime time.Time) {
	if debug {
		l.Debugf("virtual mtime: storing values for path:%v disk:%v actual:%v", path, diskMtime, actualMtime)
	}

	diskBytes, _ := diskMtime.MarshalBinary()
	actualBytes, _ := actualMtime.MarshalBinary()

	data := append(diskBytes, actualBytes...)

	r.ns.PutBytes(path, data)
}

func (r *VirtualMtimeRepo) GetMtime(path string, diskMtime time.Time) time.Time {
	var debugResult string

	if data, exists := r.ns.Bytes(path); exists {
		var mtime time.Time

		if err := mtime.UnmarshalBinary(data[:len(data)/2]); err != nil {
			panic(fmt.Sprintf("Can't unmarshal stored mtime at path %v: %v", path, err))
		}

		if mtime.Equal(diskMtime) {
			if err := mtime.UnmarshalBinary(data[len(data)/2:]); err != nil {
				panic(fmt.Sprintf("Can't unmarshal stored mtime at path %v: %v", path, err))
			}

			debugResult = "got it"
			diskMtime = mtime
		} else if debug {
			debugResult = fmt.Sprintf("record exists, but mismatch inDisk:%v dbDisk:%v", diskMtime, mtime)
		}
	} else {
		debugResult = "record does not exist"
	}

	if debug {
		l.Debugf("virtual mtime: value get result:%v path:%v", debugResult, path)
	}

	return diskMtime
}

func (r *VirtualMtimeRepo) DeleteMtime(path string) {
	r.ns.Delete(path)
}

Review comment (bug):
So to me, this function doesn't look go'ish.

I guess you could do early returns in case of failure to make itlook more like it. This way you could also drop the debug variable and just print stuff straight away.


Code after:
type VirtualMtimeRepo struct {
	ns *NamespacedKV
}

func NewVirtualMtimeRepo(ldb *leveldb.DB, folder string) *VirtualMtimeRepo {
	prefix := string(KeyTypeVirtualMtime) + folder

	return &VirtualMtimeRepo{
		ns: NewNamespacedKV(ldb, prefix),
	}
}

func (r *VirtualMtimeRepo) UpdateMtime(path string, diskMtime, actualMtime time.Time) {
	if debug {
		l.Debugf("virtual mtime: storing values for path:%s disk:%v actual:%v", path, diskMtime, actualMtime)
	}

	diskBytes, _ := diskMtime.MarshalBinary()
	actualBytes, _ := actualMtime.MarshalBinary()

	data := append(diskBytes, actualBytes...)

	r.ns.PutBytes(path, data)
}

func (r *VirtualMtimeRepo) GetMtime(path string, diskMtime time.Time) time.Time {
	var debugResult string

	if data, exists := r.ns.Bytes(path); exists {
		var mtime time.Time

		if err := mtime.UnmarshalBinary(data[:len(data)/2]); err != nil {
			panic(fmt.Sprintf("Can't unmarshal stored mtime at path %v: %v", path, err))
		}

		if mtime.Equal(diskMtime) {
			if err := mtime.UnmarshalBinary(data[len(data)/2:]); err != nil {
				panic(fmt.Sprintf("Can't unmarshal stored mtime at path %v: %v", path, err))
			}

			debugResult = "got it"
			diskMtime = mtime
		} else if debug {
			debugResult = fmt.Sprintf("record exists, but mismatch inDisk:%v dbDisk:%v", diskMtime, mtime)
		}
	} else {
		debugResult = "record does not exist"
	}

	if debug {
		l.Debugf("virtual mtime: value get result:%v path:%s", debugResult, path)
Repository: syncthing/syncthing
File: internal/db/virtualmtime.go (Go)

Code before:
		ns: NewNamespacedKV(ldb, prefix),
	}
}

func (r *VirtualMtimeRepo) UpdateMtime(path string, diskMtime, actualMtime time.Time) {
	if debug {
		l.Debugf("virtual mtime: storing values for path:%v disk:%v actual:%v", path, diskMtime, actualMtime)
	}

	diskBytes, _ := diskMtime.MarshalBinary()
	actualBytes, _ := actualMtime.MarshalBinary()

	data := append(diskBytes, actualBytes...)

	r.ns.PutBytes(path, data)
}

func (r *VirtualMtimeRepo) GetMtime(path string, diskMtime time.Time) time.Time {
	var debugResult string

	if data, exists := r.ns.Bytes(path); exists {
		var mtime time.Time

		if err := mtime.UnmarshalBinary(data[:len(data)/2]); err != nil {
			panic(fmt.Sprintf("Can't unmarshal stored mtime at path %v: %v", path, err))
		}

		if mtime.Equal(diskMtime) {
			if err := mtime.UnmarshalBinary(data[len(data)/2:]); err != nil {
				panic(fmt.Sprintf("Can't unmarshal stored mtime at path %v: %v", path, err))
			}

			debugResult = "got it"
			diskMtime = mtime
		} else if debug {
			debugResult = fmt.Sprintf("record exists, but mismatch inDisk:%v dbDisk:%v", diskMtime, mtime)
		}
	} else {
		debugResult = "record does not exist"
	}

	if debug {
		l.Debugf("virtual mtime: value get result:%v path:%v", debugResult, path)
	}

	return diskMtime
}

func (r *VirtualMtimeRepo) DeleteMtime(path string) {
	r.ns.Delete(path)
}

Review comment (bug):
That's how it was written before the debug output, but with the output my options are to do it this way or repeat a chunk of the debug message string, and I don't like repeating stuff.


Code after:
type VirtualMtimeRepo struct {
	ns *NamespacedKV
}

func NewVirtualMtimeRepo(ldb *leveldb.DB, folder string) *VirtualMtimeRepo {
	prefix := string(KeyTypeVirtualMtime) + folder

	return &VirtualMtimeRepo{
		ns: NewNamespacedKV(ldb, prefix),
	}
}

func (r *VirtualMtimeRepo) UpdateMtime(path string, diskMtime, actualMtime time.Time) {
	if debug {
		l.Debugf("virtual mtime: storing values for path:%s disk:%v actual:%v", path, diskMtime, actualMtime)
	}

	diskBytes, _ := diskMtime.MarshalBinary()
	actualBytes, _ := actualMtime.MarshalBinary()

	data := append(diskBytes, actualBytes...)

	r.ns.PutBytes(path, data)
}

func (r *VirtualMtimeRepo) GetMtime(path string, diskMtime time.Time) time.Time {
	var debugResult string

	if data, exists := r.ns.Bytes(path); exists {
		var mtime time.Time

		if err := mtime.UnmarshalBinary(data[:len(data)/2]); err != nil {
			panic(fmt.Sprintf("Can't unmarshal stored mtime at path %v: %v", path, err))
		}

		if mtime.Equal(diskMtime) {
			if err := mtime.UnmarshalBinary(data[len(data)/2:]); err != nil {
				panic(fmt.Sprintf("Can't unmarshal stored mtime at path %v: %v", path, err))
			}

			debugResult = "got it"
			diskMtime = mtime
		} else if debug {
			debugResult = fmt.Sprintf("record exists, but mismatch inDisk:%v dbDisk:%v", diskMtime, mtime)
		}
	} else {
		debugResult = "record does not exist"
	}

	if debug {
		l.Debugf("virtual mtime: value get result:%v path:%s", debugResult, path)
Repository: syncthing/syncthing
File: lib/scanner/walk.go (Go)

Code before:

		if w.Matcher.Match(path).IsIgnored() {
			// If the parent wasn't ignored already, set this path as the "highest" ignored parent
			if ignoredParent == "" || !strings.HasPrefix(path, ignoredParent+string(fs.PathSeparator)) {
				ignoredParent = path
			}
			l.Debugln("ignored (patterns):", path)
			if !w.Matcher.SkipIgnoredDirs() {
				return nil
			}
			return skip
		}
		if ignoredParent != "" {
			// Add parent directories of the current, not ignored path if needed
			if rel := strings.TrimPrefix(path, ignoredParent+string(fs.PathSeparator)); rel != path {
				for _, name := range strings.Split(filepath.Base(rel), string(fs.PathSeparator)) {
					if err = handleItem(ignoredParent); err != nil {
						return err
					}
					ignoredParent = filepath.Join(ignoredParent, name)
				}
			}
			ignoredParent = ""
		}

		return handleItem(path)
	}
}

func (w *walker) walkRegular(ctx context.Context, relPath string, info fs.FileInfo, fchan chan protocol.FileInfo) error {
	curMode := uint32(info.Mode())
	if runtime.GOOS == "windows" && osutil.IsWindowsExecutable(relPath) {
		curMode |= 0111
	}

	cf, ok := w.CurrentFiler.CurrentFile(relPath)

	f := protocol.FileInfo{
		Name:          relPath,
		Type:          protocol.FileInfoTypeFile,
		Version:       cf.Version.Update(w.ShortID),
		Permissions:   curMode & uint32(maskModePerm),
		NoPermissions: w.IgnorePerms,
		ModifiedS:     info.ModTime().Unix(),
		ModifiedNs:    int32(info.ModTime().Nanosecond()),
		ModifiedBy:    w.ShortID,
		Size:          info.Size(),
	}

	if ok {
		if cf.IsEquivalent(f, w.IgnorePerms, true) {

Review comment (suggestion):
Some comment what this whole new change is doing would be nice.
For now it's a bit of black magic, given the nested functional dynamic programming here,

Code after:
			ignoredParent = filepath.Join(ignoredParent, name)
			if err = w.handleItem(ctx, ignoredParent, fchan, dchan, skip); err != nil {
				return err
			}
		}
		ignoredParent = ""

		return nil
	}
}

func (w *walker) handleItem(ctx context.Context, path string, fchan, dchan chan protocol.FileInfo, skip error) error {
	info, err := w.Filesystem.Lstat(path)
	// An error here would be weird as we've already gotten to this point, but act on it nonetheless
	if err != nil {
		return skip
	}

	path, shouldSkip := w.normalizePath(path, info)
	if shouldSkip {
		return skip
	}

	switch {
	case info.IsSymlink():
		if err := w.walkSymlink(ctx, path, dchan); err != nil {
			return err
		}
		if info.IsDir() {
			// under no circumstances shall we descend into a symlink
			return fs.SkipDir
		}
		return nil

	case info.IsDir():
		err = w.walkDir(ctx, path, info, dchan)

	case info.IsRegular():
		err = w.walkRegular(ctx, path, info, fchan)
	}

	return err
}

func (w *walker) walkRegular(ctx context.Context, relPath string, info fs.FileInfo, fchan chan protocol.FileInfo) error {
	curMode := uint32(info.Mode())
	if runtime.GOOS == "windows" && osutil.IsWindowsExecutable(relPath) {
		curMode |= 0111
	}

	blockSize := protocol.MinBlockSize