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

.environment(\.font, .custom(...)) type inference fails with a confusing error message #347

Open
dfabulich opened this issue Feb 19, 2025 · 4 comments

Comments

@dfabulich
Copy link

In SwiftUI, you can use the .environment() modifier to set a custom default font, like this:

.environment(\.font, .custom("Protest Guerrilla", size: 30.0))

But Skip has a type inference bug in this code: you have to call it with Font.custom() and not with simply .custom(), or it will fail to compile on Android.

I know that type-inference bugs are something I just have to deal with in Skip, but instead of saying, "Cannot infer type for this parameter", I get a really cryptic error message.

To reproduce this bug, I forked the Showcase app https://github.com/dfabulich/skipapp-showcase/tree/environment-font-bug-example and added a one-line commit: dfabulich/skipapp-showcase@4d55295

Expected: Build fails with "Cannot infer type for this parameter" error

Actual:

Argument type mismatch: actual type is 'kotlin.Function1<ERROR CLASS: Unknown return lambda parameter type, ERROR CLASS: Unknown return lambda parameter type>', but 'kotlin.String' was expected.

@aabewhite
Copy link
Contributor

Thanks for the report. Could also use .font(.custom...)

@dfabulich
Copy link
Author

dfabulich commented Feb 19, 2025

Could also use .font(.custom...)

.font(.custom…) does work, and the type is correctly inferred, but the whole point of setting the environment() font is that it applies to all subviews recursively, so I don't have to add .font(.custom("My Font", size: 15)) on every Text() view in my app.

@aabewhite
Copy link
Contributor

I think there's a misunderstanding. .font(_:) is defined on View and establishes the default font for everything in the View. It is exactly equivalent to .environment(.font, ...)

The same pattern applies to most SwiftUI modifiers - it is very rare to need to set .environment(.key, ...) directly

@dfabulich
Copy link
Author

TIL! https://developer.apple.com/documentation/swiftui/view/font(_:)

Font information flows down the view hierarchy as part of the environment, and remains in effect unless overridden at the level of an individual view or view container.

So, I guess the .font() modifier just makes an .environment call under the hood…?

FWIW, this is the top hit in Google Search for changing the default font. https://stackoverflow.com/a/75992302/54829

So I think this issue is still a bit of a footgun for folks who don't know that .font() affects the environment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants