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

[SR-15507] Compiler crashes with "SIL verification failed: external declaration of internal SILFunction not allowed: F->isAvailableExternally()" #57812

Closed
WowbaggersLiquidLunch opened this issue Nov 22, 2021 · 7 comments

Comments

@WowbaggersLiquidLunch
Copy link
Collaborator

@WowbaggersLiquidLunch WowbaggersLiquidLunch commented Nov 22, 2021

Previous ID SR-15507
Radar None
Original Reporter @WowbaggersLiquidLunch
Type Bug
Status Closed
Resolution Done

Attachment: Download

Environment

macOS 12.1 Beta (21C5021h)
Xcode 13.2 beta 2 (13C5081f)
Swift Development Snapshot 2021-11-20 (a)

Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Bug, CompilerCrash
Assignee cbjeukendrup (JIRA)
Priority Medium

md5: b8e359859c2ecdc36022925c041ff831

blocks:

  • SR-15464 Compiler crash with "abort trap: 6"

Issue Description:

The following code crashes the compiler with “SIL verification failed: external declaration of internal SILFunction not allowed: F->isAvailableExternally()”:

public struct Point: Sendable {
    public let coordinates: [Double]
}

extension Point {
    public func euclideanDistance(to other: Self) async -> Double {
        await squareOfEuclideanDistance(to: other).squareRoot()
    }
    
    @inlinable
    public func squareOfEuclideanDistance(to other: Self) async -> Double {
        let zippedCoordinates = zip(self.coordinates, other.coordinates)
        
        return await withTaskGroup(of: Double.self) { group -> Double in
            for coordinatePair in zippedCoordinates {
                group.addTask {
                    return squareOfDistance(between: coordinatePair)
                }
            }
            return await group.reduce(0, +)
        }
        
        @Sendable
        func squareOfDistance(between coordinatePair: (Double, Double)) -> Double {
            let distance = coordinatePair.0 - coordinatePair.1
            return distance * distance
        }
    }
}

I’m not able to further reduce the code, but I noticed that the compiler doesn’t crash if either of these 2 changes is made to the code example:

  • Remove public from Point’s declaration.

  • Remove @inlinable from squareOfEuclideanDistance’s declaration.

The crash log is here: https://gist.github.com/WowbaggersLiquidLunch/c6e1d931bc184937c557e985ec8d4d92

A package containing the code is attached to this report.

@WowbaggersLiquidLunch
Copy link
Collaborator Author

@WowbaggersLiquidLunch WowbaggersLiquidLunch commented Nov 22, 2021

This is half of SR-15464, that surfaced after SR-15254 was resolved.

@swift-ci
Copy link
Collaborator

@swift-ci swift-ci commented Dec 5, 2021

Comment by Casper Jeukendrup (JIRA)

I think I have found a significantly simpler way to reproduce this:

@inlinable // This is crucial
func globalFunc() -> Int {
    return localFunc() 

    // Declaration after return statement
    func localFunc() -> Int {
        return 42
    }
}

Or alternatively:

@inlinable
func globalFunc2() -> () -> Int {
    return localFunc

    func localFunc() -> Int {
        return 42
    }
}

Normally, it seems to work well to use a local function before its declaration, but the problem occurs specifically when the local function is declared after the return statement that uses it in an inlinable function.

Should it even be valid to use a local function before its declaration?

@swift-ci
Copy link
Collaborator

@swift-ci swift-ci commented Jan 8, 2022

Comment by Casper Jeukendrup (JIRA)

I created a pull request with a fix: #40773

@WowbaggersLiquidLunch
Copy link
Collaborator Author

@WowbaggersLiquidLunch WowbaggersLiquidLunch commented Jan 8, 2022

Sorry for the late reply!

I was distracted by toggling public and @inlinable, and wasn't able to make the example code simpler. Thanks for further reducing it!

This pitch from a year ago by @slavapestov suggests that it should be valid to use a local function before its declaration. Even if it should be invalid, then the behaviour should be consistent whether or not the outer function is public or @inlinable.

I think it should be valid, and I see that's what your fix is in the PR.

@swift-ci
Copy link
Collaborator

@swift-ci swift-ci commented Jan 8, 2022

Comment by Casper Jeukendrup (JIRA)

Thanks for your reply! I didn't know about that pitch yet, but indeed I assumed that it should be valid (just like it is for local structs). Indeed, it turns out that my PR is in line with the proposal, so that's good news 🙂

It would be great if someone could start the CI for my PR, because it seems I don't have permission to do so myself.

@slavapestov
Copy link
Member

@slavapestov slavapestov commented Jan 17, 2022

@jckarter fixed this: #40792

@WowbaggersLiquidLunch
Copy link
Collaborator Author

@WowbaggersLiquidLunch WowbaggersLiquidLunch commented Feb 28, 2022

I verified that this is resolved in the 2022-02-25 trunk snapshot.

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants