Why #warning() not allowed in some source location?

I use #warning when I file bug report so I need to pin point where the bug is, but it's sometime not allowed (compile error) in certain code location:

import SwiftUI

struct BugHereSomewhere: View {
    var body: some View {
        #warning("#warning here is allowed")
        VStack {
            Text("Hello")
        }
        #warning("#warning here is not allowed!")
        .ignoresSafeArea()
    }
}

why can't I put #warning anywhere I want?

1 Like

#warning doesn’t get preprocessed out the way it does in C. Unfortunately that means it breaks up expressions like this and makes it so the .ignoresSafeArea() doesn’t get applied to the VStack, it tries to get applied to the #warning, which isn’t an expression. This may be worth a bug on bugs.swift.org.

4 Likes

:ok_hand:https://bugs.swift.org/browse/SR-13436

1 Like

Looks like we don't allow this in general too (I was thinking it was specific to function builders...). For example:

func foo() {
    #warning("Works")
    "Hello, world!"
    #warning("Does not work")
    .description
}

leads to an error: reference to member 'description' cannot be resolved without a contextual type.

1 Like

FYI, I'll be returning this as "behaves correctly". Swift (intentionally) doesn't have the C-preprocessor-like behavior of letting # directives go anywhere: #warning is a declaration, so it cannot be in the middle of a postfix-expression chain.

Doug

6 Likes

Could still be worth a diagnostic special case, though: if a line starts with an implicit member reference that can't be resolved, check what the previous statement was?

3 Likes