Repository: rclone/rclone
File: fs/operations/operations.go (Go)

Code before:
	// Move the copied file to its real destination.
	if remotePartial != remote && err == nil {
		dst, err = f.Features().Move(ctx, newDst, remote)
		if err == nil {
			fs.Debugf(newDst, "renamed to: %s", remote)
			newDst = dst
		} else {
			fs.Errorf(newDst, "partial file rename failed: %v", err)
			err = fs.CountError(err)
			removeFailedCopy(ctx, newDst)
			return newDst, err
		}
	}

	if newDst != nil && src.String() != newDst.String() {
		actionTaken = fmt.Sprintf("%s to: %s", actionTaken, newDst.String())
	}
	fs.Infof(src, "%s%s", actionTaken, fs.LogValueHide("size", fs.SizeSuffix(src.Size())))
	return newDst, err
}

// SameObject returns true if src and dst could be pointing to the
// same object.
func SameObject(src, dst fs.Object) bool {
	srcFs, dstFs := src.Fs(), dst.Fs()
	if !SameConfig(srcFs, dstFs) {
		// If same remote type then check ID of objects if available
		doSrcID, srcIDOK := src.(fs.IDer)
		doDstID, dstIDOK := dst.(fs.IDer)
		if srcIDOK && dstIDOK && SameRemoteType(srcFs, dstFs) {
			srcID, dstID := doSrcID.ID(), doDstID.ID()
			if srcID != "" && srcID == dstID {
				return true
			}
		}
		return false
	}
	srcPath := path.Join(srcFs.Root(), src.Remote())
	dstPath := path.Join(dstFs.Root(), dst.Remote())
	if dst.Fs().Features().CaseInsensitive {
		srcPath = strings.ToLower(srcPath)
		dstPath = strings.ToLower(dstPath)
	}
	return srcPath == dstPath
}

// Move src object to dst or fdst if nil.  If dst is nil then it uses
// remote as the name of the new object.
//
// Note that you must check the destination does not exist before
// calling this and pass it as dst.  If you pass dst=nil and the

Review comment (bug):
I'm a little confused why there's `dst` and `newDst` in this function. It might be because there are a lot of assignments to `dst` and `newDst` is updated to "carry the newly created file handle forward" when there were no errors.  

I think the error handling here is correct and the debug prints print sensible output too.  I'm just not 100% sure what should be returned from this path and how the `newDst` is used by the caller.

Code after:
	}

	// Verify hashes are the same after transfer - ignoring blank hashes
	if hashType != hash.None {
		// checkHashes has logged and counted errors
		equal, _, srcSum, dstSum, _ := checkHashes(ctx, src, dst, hashType)
		if !equal {
			err = fmt.Errorf("corrupted on transfer: %v hash differ %q vs %q", hashType, srcSum, dstSum)
			fs.Errorf(dst, "%v", err)
			err = fs.CountError(err)
			removeFailedCopy(ctx, dst)
			return newDst, err
		}
	}

	// Move the copied file to its real destination.
	if err == nil && !inplace && remotePartial != remote {
		dst, err = f.Features().Move(ctx, newDst, remote)
		if err == nil {
			fs.Debugf(newDst, "renamed to: %s", remote)
			newDst = dst
		} else {
			fs.Errorf(newDst, "partial file rename failed: %v", err)
			err = fs.CountError(err)
			removeFailedCopy(ctx, newDst)
			return newDst, err
		}
	}

	if newDst != nil && src.String() != newDst.String() {
		actionTaken = fmt.Sprintf("%s to: %s", actionTaken, newDst.String())
	}
	fs.Infof(src, "%s%s", actionTaken, fs.LogValueHide("size", fs.SizeSuffix(src.Size())))
	return newDst, err
}

// SameObject returns true if src and dst could be pointing to the
// same object.
func SameObject(src, dst fs.Object) bool {
	srcFs, dstFs := src.Fs(), dst.Fs()
	if !SameConfig(srcFs, dstFs) {
		// If same remote type then check ID of objects if available
		doSrcID, srcIDOK := src.(fs.IDer)
		doDstID, dstIDOK := dst.(fs.IDer)
		if srcIDOK && dstIDOK && SameRemoteType(srcFs, dstFs) {
			srcID, dstID := doSrcID.ID(), doDstID.ID()
			if srcID != "" && srcID == dstID {
				return true
			}
		}
		return false