Linking error in Release mode #1556
-
Hoping someone can explain what's going on here. In prepping some work for a Release build, I got some strange build errors. These only show up in a Release build. Debug works fine.
Here's the failing type: public struct WelcomeBackFeature: ReducerProtocol {
public enum State: Equatable {
case welcomeScreen(WelcomeScreen.State)
case upgradeOfferScreen(UpgradeOfferScreen.State)
init() { self = .welcomeScreen(.init()) }
}
public enum Action: Equatable {
case welcomeScreen(WelcomeScreen.Action)
case upgradeOfferScreen(UpgradeOfferScreen.Action)
}
public var body: some ReducerProtocol<State, Action> {
Core()
.ifCaseLet(/State.welcomeScreen, action: /Action.welcomeScreen, then: WelcomeScreen.init)
.ifCaseLet(/State.upgradeOfferScreen, action: /Action.upgradeOfferScreen, then: UpgradeOfferScreen.init)
}
struct Core: ReducerProtocol {
func reduce(into state: inout State, action: Action) -> EffectTask<Action> {
switch action {
case .welcomeScreen(.welcomeMessageContinueButtonTappped):
state = .upgradeOfferScreen(.init())
return .none
case .upgradeOfferScreen:
return .none
}
}
}
} (Side note: I've been exploring this pattern of a nested After much trial and error, the fix is to make public struct Core: ReducerProtocol {
public func reduce(into state: inout State, action: Action) -> EffectTask<Action> { I haven't yet figured out how to reproduce this in a new project, nor with a minimal new feature in the same project. Starting with this, where does the problem come from? public struct CoreContainingFeature: ReducerProtocol {
public struct State: Equatable {
}
public enum Action: Equatable {
}
public var body: some ReducerProtocol<State, Action> {
Core()
}
struct Core: ReducerProtocol {
func reduce(into state: inout State, action: Action) -> EffectTask<Action> {
return .none
}
}
} |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 13 replies
-
Hey @rcarver. This is a bug I've noticed a few months ago. Swift optimizer sometimes prunes non-public nested types that are only referenced in I didn't manage to reproduce it in a standalone project, and I forgot to report it. It can bite you really easily with internal or private enums that you're using as identifiers. That's why I'm now declaring them as public and relocate them in the reducer itself, beside We should definitely find a repro and report it properly, as the issue will occur more and more given the way we organize features nowadays. |
Beta Was this translation helpful? Give feedback.
-
Has anyone submitted a feedback on this yet? We've been bit by this problem as well. |
Beta Was this translation helpful? Give feedback.
-
Just a heads up, I ran into exactly this due to an internal struct (that conformed to the ReducerProtocol) where its State and Action types were just internal typealiases of a parent reducer, as well. Making the struct and its State/Action public fixed it immediately. |
Beta Was this translation helpful? Give feedback.
Hey @rcarver. This is a bug I've noticed a few months ago. Swift optimizer sometimes prunes non-public nested types that are only referenced in
@ResultBuilder
s functions, likeReducerProtocol
andSwiftUI
'sbody
s.I didn't manage to reproduce it in a standalone project, and I forgot to report it.
It can bite you really easily with internal or private enums that you're using as identifiers. That's why I'm now declaring them as public and relocate them in the reducer itself, beside
State
andAction
.We should definitely find a repro and report it properly, as the issue will occur more and more given the way we organize features nowadays.