The implementation of llvm::Any had several bugs in the past (see D101972 and D108943) and still has the same bug on Windows.
C++17 has the std::any type, which can replace llvm::Any and puts the burden to implement it correctly for all possible combinations of compiler and linker options onto the standard library.
I propose to eventually switch to std::any for this reason (it also fixes the bug I see on Windows).
Unfortunately, we can’t just switch to std::any right away (I tried in D139532), because the msvc standard library until very recently had a bug that the <any> header does not compile when exceptions are disabled.
So, to not hold onto the bugs we have, but still allow us to support old compiler versions, I propose to
Make the interface of llvm::Any similar to that of std::any (as was done for llvm::Optional). The only change is in std::any_cast, which has different semantics, so I want to add llvm::std_any_cast which follows that and deprecate llvm::any_cast.
Add an implementation of llvm::Any that uses std::any internally (this is ~80 lines of code) and enable this wrapper when the compiler supports it. This will fix llvm::Any on Windows, if msvc is new enough.
Remove the deprecated llvm::any_cast, all users should use llvm::std_any_cast
Once the minimum compiler version of LLVM is new enough, use std::any without the wrapper and remove llvm::Any
Alternatively to introducing llvm::std_any_cast in step 1., we can also keep the current llvm::any_cast interface until we switch to std::any in step 4.
Looking at your change, are there that many users of llvm::any_cast that llvm::any_cast could not be rewritten to behave as std::any_cast does? Or are we expecting a lot of downstream users to be using llvm::Any as well. llvm::Optional is probably one of the most used types in the codebase, so the incremental changing and the deprecation period makes a lot of sense I think (in fact, we are still seeing daily commits changing llvm::Optional to std::optional).
I am just wondering whether llvm::Any is used often enough to warrant similar procedure, instead of just aligning its behaviour to std::any in one large change. Step 2 and 4 would remain unchanged.
The migration from llvm::Option to std::optional is proceeding incrementally and it is a great improvement for the codebase. You noticed the issue with std::any. I am afraid that the minimal requirements for compilers to build LLVM make it impossible to migrate to the STL.
You’re right that the msvc bug makes it impossible for us to migrate from llvm::Any to std::any right now.
That’s the reason I proposed these multiple steps and why I want to keep the current Any implementation until we increase the minimum requirement for msvc far enough (well, it’s more a must than a want ;)).
We can have two implementations of llvm::Any:
The current one that is buggy but supports all compiler versions
One that is a small wrapper around std::any and has less bugs, but needs a more up-to-date msvc
We can switch between these two versions based on the _MSC_VER macro.
Once we increased the minimal requirement for msvc, we can completely replace llvm::Any with std::any.
16.7 is enforced by cmake in llvm/cmake/modules/CheckCompilerVersion.cmake. So you have to abide by that. I expect people will install the latest version at the time the bot is setup and not update it unless they have good reason to.
For the subject at hand, 16.7 is the important part.