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

New props infrastructure is not portable #34090

Closed
asklar opened this issue Jun 28, 2022 · 37 comments
Closed

New props infrastructure is not portable #34090

asklar opened this issue Jun 28, 2022 · 37 comments
Labels
Needs: React Native Team Attention p: Microsoft Partner: Microsoft Partner Tech: React Native Core Issue related to the Core of React Native

Comments

@asklar
Copy link
Contributor

asklar commented Jun 28, 2022

Description

This commit: 47280de

Introduced a compile-time string hashing mechanism (perhaps inspired by this) to do switch statements on string values.

However the resulting code uses clang-specific pragmas, which won't work with other compilers (e.g. MSVC).
This breaks ingestion of RN core into React Native Windows.

image

Version

main

Output of npx react-native info

n/a

Steps to reproduce

n/a

Snack, code example, screenshot, or link to a repository

n/a

@chiaramooney
Copy link
Contributor

Pipeline showing break in RNW: https://dev.azure.com/ms/react-native-windows/_build/results?buildId=323774&view=results
Broken Files: Props.cpp and BaseTextProps.cpp.
Pragma Code:

#define CONSTEXPR_RAW_PROPS_KEY_HASH(s) \
({ \
_Pragma("clang diagnostic push") _Pragma( \
"clang diagnostic ignored \"-Wshadow\"") constexpr RawPropsPropNameLength \
len = sizeof(s) - 1; \
constexpr RawPropsPropNameHash hash = folly::hash::fnv32_buf(s, len); \
hash; \
_Pragma("clang diagnostic pop") \
})

@asklar
Copy link
Contributor Author

asklar commented Jun 28, 2022

Cc @JoshuaGross

@lyahdav
Copy link
Contributor

lyahdav commented Jun 29, 2022

Looks like it should be wrapped with #if __clang__. Example:

@lyahdav
Copy link
Contributor

lyahdav commented Jun 29, 2022

@asklar do you know if in React Native Windows we'll get a warning or error if we had this code as-is without the pragma? The issue with Clang was that this code could introduce variables len and hash which could shadow variables with the same name in an outer scope. If React Native Windows has MSVC configured to produce an error for this situation we'll have to add the MSVC pragma equivalent. If so, do you know what that is?

@asklar
Copy link
Contributor Author

asklar commented Jun 29, 2022

if we remove the pragma, I imagine msvc might produce a warning if the right warning level flag is set, perhaps @chiaramooney can try it.
is there a reason why we need the extra variable? why not just say:

#define CONSTEXPR_RAW_PROPS_KEY_HASH(s)    (folly::hash::fnv32_buf(s, sizeof(s) - 1))

is the problem that folly's fnv32_buf functions aren't constexpr? take a look at the PR I made a reference to originally and see if that helps, that does everything in constexpr without any funky macros

@JoshuaGross
Copy link
Contributor

@asklar I should be able to change the macro into a consteval function to enforce its evaluation at compile-time. Let me know if there are any concerns with doing that for MSVC. It looks like you're using consteval in https://github.com/microsoft/react-native-windows/pull/9841/files as well (I had not seen this PR previously) so maybe that's an acceptable solution here; I'll give it a shot.

@asklar
Copy link
Contributor Author

asklar commented Jun 29, 2022

thanks @JoshuaGross for taking a look! Yeah I'm using a macro to do consteval for cpp20 and constexpr otherwise; we don't yet use cpp20, so this would downgrade to constexpr for us.

@JoshuaGross
Copy link
Contributor

Yeah we're not on C++20 yet either, so I'll have to find something that works with just constexpr. I'll play around a little bit. If y'all get to it faster, let me know if MSVC is fine with just removing the pragmas.

@JoshuaGross
Copy link
Contributor

@asklar What version of C++ are you on? Can I assume at least C++17?

@asklar
Copy link
Contributor Author

asklar commented Jun 29, 2022

yes we're on cpp17

@JoshuaGross
Copy link
Contributor

JoshuaGross commented Jun 29, 2022

I have a local diff we can try out. @asklar want to see if this works for you?

// We need to use clang pragmas inside of a macro below,
// so we need to pull out the "if" statement here.
#if __clang__
#define CLANG_PRAGMA(s) _Pragma(s)
#else
#define CLANG_PRAGMA(s)
#endif

// Get hash at compile-time. sizeof(str) - 1 == strlen
#define CONSTEXPR_RAW_PROPS_KEY_HASH(s)                   \
  ({                                                      \
    CLANG_PRAGMA("clang diagnostic push")                 \
    CLANG_PRAGMA("clang diagnostic ignored \"-Wshadow\"") \
    constexpr RawPropsPropNameHash hash =                 \
        folly::hash::fnv32_buf(s, sizeof(s) - 1);         \
    hash;                                                 \
    CLANG_PRAGMA("clang diagnostic pop")                  \
  })

I'll have more commentary if/when I land the actual diff. I'm still trying to avoid doing this the "proper" way without macros because it results in 10x as much code and is IMO a lot less readable, though that's highly subjective. If this compiles on MSVC let's do this; if not, is there a scoped way to ignore shadowing warnings in MSVC?

@JoshuaGross
Copy link
Contributor

d1d11c7

@JoshuaGross
Copy link
Contributor

@asklar please reopen if this is still an issue on your end

@chiaramooney
Copy link
Contributor

@JoshuaGross Error still present following attempt to integrate 7/4 nightly build. cc @asklar

@lyahdav
Copy link
Contributor

lyahdav commented Jul 7, 2022

@chiaramooney can you confirm it's coming from the same place that @JoshuaGross modified in d1d11c7? If so, can you see if somehow __clang__ is defined in MSVC builds?

@chiaramooney
Copy link
Contributor

Yes same place. @asklar Off the top of your head do you know if clang is defined in MSVC builds, otherwise I can investigate?

@asklar
Copy link
Contributor Author

asklar commented Jul 11, 2022

__clang__ is not defined for MSVC:
image

@asklar
Copy link
Contributor Author

asklar commented Jul 11, 2022

Looks like I don't have permissions to reopen, @JoshuaGross mind reopening this?

@lyahdav
Copy link
Contributor

lyahdav commented Jul 11, 2022

__clang__ is not defined for MSVC: image

@asklar so if __clang__ is not defined, I'm confused how it's running code under #if __clang__. Can we get a link to the full build output and can we confirm that the RNW build included d1d11c7? Maybe it's coming from another file that needs a similar fix?

@lyahdav lyahdav reopened this Jul 11, 2022
@chiaramooney
Copy link
Contributor

@asklar
Copy link
Contributor Author

asklar commented Jul 14, 2022

it looks like the syntax case ({something}): is not valid for MSVC:
https://godbolt.org/z/P4qh7rKrf

@asklar
Copy link
Contributor Author

asklar commented Jul 14, 2022

ok, looks like that syntax is a language extension in GCC (and clang implements it too) but it is not standard C++:

https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html

@JoshuaGross could we write this in a way that is portable? maybe move the "statement expression" inside of a #define instead of just the pragma

@asklar
Copy link
Contributor Author

asklar commented Jul 14, 2022

an alternative approach is to use an immediate lambda instead of a statement expression:

case [&]{ /* ... */ return something; }(): /* ... */

@lyahdav
Copy link
Contributor

lyahdav commented Jul 18, 2022

FYI @JoshuaGross is OOO until next week. If anyone from the MSFT side wants to put up a PR with a fix sooner, I can find someone on our side to review

@asklar
Copy link
Contributor Author

asklar commented Jul 19, 2022

@chiaramooney can you apply the change and send a PR to here?

@chiaramooney
Copy link
Contributor

Trying

#define CONSTEXPR_RAW_PROPS_KEY_HASH(s)                   \
  []{                                                     \
    CLANG_PRAGMA("clang diagnostic push")                 \
    CLANG_PRAGMA("clang diagnostic ignored \"-Wshadow\"") \
    return folly::hash::fnv32_buf(s, sizeof(s) - 1);      \
    CLANG_PRAGMA("clang diagnostic pop")                  \
    }()

still results in the same syntax errors as case ({something}): @rozele might be looking into it to see what's wrong

@JoshuaGross
Copy link
Contributor

@asklar @chiaramooney I'm back from leave but not sure when I'll be able to prioritize this. The only hard requirement/goal from my end is that these blocks continue to be compile-time evaluated on iOS and Android; it would be nice if that were the case for all platforms, but there might not be a portable way of doing it. Can one of you iterate on this until it compiles for MSVC? And then we can make sure the solution is acceptable for iOS/Android as well. I don't normally compile using MSVC so I'd prefer not to drive the solution.

@chiaramooney
Copy link
Contributor

Alright I believe we have a fix. Both BaseTextProps.cpp and PropsMacros.h need edits. New versions of files can be found here:
https://github.com/microsoft/react-native-windows/blob/daf914bbb2d7ad7bc20cdac022818d0b65b3306b/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/text/BaseTextProps.cpp

https://github.com/microsoft/react-native-windows/blob/daf914bbb2d7ad7bc20cdac022818d0b65b3306b/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/core/PropsMacros.h

These changes use the approach of replacing all ({something}) syntax with lambda expressions in both the GET_FIELD_VALUE and CONSTEXPR_RAW_PROPS_KEY_HASH(s) macros and adding a semicolon to the end of the GET_FIELD_VALUE macro. @JoshuaGross @lyahdav

@chiaramooney
Copy link
Contributor

@JoshuaGross @lyahdav If you have a moment to validate that the changes also work on your end. I can put out a PR.

@lyahdav
Copy link
Contributor

lyahdav commented Jul 27, 2022

@chiaramooney I'd say just put out a PR on this repo for it, and then we'll see if builds successfully in our CI.

@kelset
Copy link
Contributor

kelset commented Aug 2, 2022

@chiaramooney I noticed that your PR landed - do you need this in 0.70?

@lyahdav
Copy link
Contributor

lyahdav commented Aug 2, 2022

The PR was unlanded. Looks like it caused some regression. I'm awaiting some clarification internally on the status.

@lyahdav
Copy link
Contributor

lyahdav commented Aug 2, 2022

Looks like a fix for the regression is landing. The fix should work on MSVC, but we'll need someone from the MSFT side to verify. You can monitor for commits touching BaseTextProps.cpp to see when it's landed.

@kelset
Copy link
Contributor

kelset commented Aug 3, 2022

ok so let's postpone this to the next RC - we'll do RC2 without this, and you all can let me know if this will need to be in RC3

@asklar
Copy link
Contributor Author

asklar commented Aug 3, 2022

This issue is blocking ingestion into RNW, so if we can get this sorted out sooner than later (in rc1) that'd be great.

@asklar
Copy link
Contributor Author

asklar commented Aug 3, 2022

@lyahdav can you reopen this issue if it still needs to be [re-]merged?

@lyahdav
Copy link
Contributor

lyahdav commented Aug 4, 2022

Looks like the fix has landed: a142a78. @rshest didn't test this on MSVC but it should work in theory. If there's an issue you can let us know here.

roryabraham pushed a commit to Expensify/react-native that referenced this issue Aug 17, 2022
Summary:
Fix macro errors for Windows. Current syntax breaks the build of the React Common project on Windows because the ({...}) syntax is not supported; must be replaced with lambda expressions.

Resolves facebook#34090

## Changelog

<!-- Help reviewers and the release process by writing your own changelog entry. For an example, see:
https://reactnative.dev/contributing/changelogs-in-pull-requests
-->

[General] [Fixed] - Fix macro errors for Windows.

lyahdav JoshuaGross

Pull Request resolved: facebook#34299

Test Plan: Build on react-native-windows repo. Tested in RNW app.

Reviewed By: javache

Differential Revision: D38272966

Pulled By: NickGerleman

fbshipit-source-id: e76eac11cde173ef49465d01d793c593017f2ab7
roryabraham pushed a commit to Expensify/react-native that referenced this issue Aug 17, 2022
Summary:
Fix macro errors for Windows. Current syntax breaks the build of the React Common project on Windows because the ({...}) syntax is not supported; must be replaced with lambda expressions.

Resolves facebook#34090

## Changelog

<!-- Help reviewers and the release process by writing your own changelog entry. For an example, see:
https://reactnative.dev/contributing/changelogs-in-pull-requests
-->

[General] [Fixed] - Fix macro errors for Windows.

lyahdav JoshuaGross

Pull Request resolved: facebook#34299

Test Plan: Build on react-native-windows repo. Tested in RNW app.

Reviewed By: javache

Differential Revision: D38272966

Pulled By: NickGerleman

fbshipit-source-id: e76eac11cde173ef49465d01d793c593017f2ab7
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Needs: React Native Team Attention p: Microsoft Partner: Microsoft Partner Tech: React Native Core Issue related to the Core of React Native
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants