Closure/func variable leading to runtime error in Swift 5.6 (fine on 5.5)

Moving to Swift 5.6 (with the latest Xcode 13.3), some code broke at runtime.

This is the function:

func outputImage(extent inext: CGRect? = nil, params: [Any], roiCallback roi: CIKernelROICallback? = nil) -> CIImage? {
	let roi: CIKernelROICallback = roi ?? self.roiCallback ?? Self.identityRoiCallback
	
	switch kind {
		case .generic:
			if let im = params.first, let image = im as? CIImage {
				let extent: CGRect = inext ?? image.extent
				return genericKernel.apply(extent: extent, roiCallback: roi, arguments: params)
			} else if let im = params.first, let sampler = im as? CISampler {
				let extent: CGRect = inext ?? sampler.extent
				return genericKernel.apply(extent: extent, roiCallback: roi, arguments: params)
			} else { return nil }
		case .color:
			if let im = params.first, let image = im as? CIImage {
				let extent: CGRect = inext ?? image.extent
				let res2: CIImage? = colorKernel.apply(extent: extent, arguments: params)
				return res2
			}
			else { return nil }
		case .blend:
			if params.count == 2, let im = params.first, let image = im as? CIImage,
				let image2 = params[1] as? CIImage {
				let res = blendKernel.apply(foreground: image, background: image2)
				return res
			}
			else { return nil }
		case .warp:
			if let im = params.first, let image = im as? CIImage {
				let extent: CGRect = inext ?? image.extent
				let res = warpKernel.apply(extent: extent, roiCallback: roi, image: image, arguments: Array(params.suffix(from: 1)))
				return res
			}
			else { return nil }
	}
}

with

private let roiCallback: CIKernelROICallback?

static let identityRoiCallback: CIKernelROICallback = { (index, rect) -> CGRect in
	return rect
}

Specifically, the program receives a systematic EXC_BAD_ACCESS on return res2 (under .color case). This code was running apparently fine on Swift 5.5 and earlier. After investigation, changing the way the roi let variable is defined can solve the problem:

let roi: CIKernelROICallback = (roi ?? self.roiCallback) ?? Self.identityRoiCallback

that is, parentheses for the first 2 works (last 2 still fails). There are other constructs that also work.

Are there any changes in Swift 5.6 that could explain that? A mix-up between closure and functions maybe? It sounds like a compiler bug, or am I not using it as expected?

Thank you.

1 Like