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
Fix issue 10913 std.regex API regression #1532
Conversation
Weird, why is it that encapsulating the test inside an enum doesn't work? Or is the problem because is(T==Captures!R) is not always true? |
Just tried and put Captures!R instead of typeof(cap) - it works so the type (that is easy to trace) is correct. |
Hmm. The following reduced code does work:
It prints "true", "true". I'm going to try it with the actual regex code now to figure out why it's not working. |
Whoa, you will not believe this. Try replacing isReplaceFunctor with this version and it will work:
I think we should open a DMD bug for this. |
I'm destroyed :) |
Done. Strangest fix in my book |
Yeah no kidding. The fix looks good. But I think you should still file a bug against DMD for this. In theory, it should be able to infer the @safe-ty of the delegate automatically without requiring the @System. |
Would be nice but demangle is not @safe... |
But isn't that already true in your original fix? Once you have an arbitrary lambda template parameter, in theory it can contain anything, including code that formats your disk and trashes your stack. |
On second thought, should replace be marked @trusted at all? It can't be @safe if you pass an unsafe delegate into it via the alias parameter. I thought the compiler can now infer @safety attributes, so all it takes is a @safe unittest to ensure that for reasonable lambdas replace is @safe. If user code wants to pass un@safe code to replace, it's not really your problem to try to make it somehow @safe. On that note, this is one area where D is lacking: to have a way of saying "this function's safety depends on the safety of parameter X", similar to inout for const/unqual. Same goes for purity, nothrow, etc.. Sometimes I want to say "this function is pure, safe, nothrow, up to the purity/safety/nothrow-ness of delegate parameter X", but the current language has no way of expressing this. |
Actually, the latest DMD will already infer attributes for template functions, so you don't need to mark replace as @trusted at all. Here's a little test I did:
The compiler output is:
So basically, if you omit attributes, the compiler will automatically infer the best attributes for replace(). |
And I take back my comment about D being unable to express attributes based on parameters; the above inference already gives you the best possible attributes for each instantiation. But suppose you want a safeguard in your code so that future changes don't accidentally break purity, for example. It's possible to do this with today's language, though it may cause performance issues unless the compiler is sufficiently optimizing. You just wrap your code in a lambda literal that gets immediately called:
You can handle @safe and nothrow in the same way. Once Kenji's pull dlang/dmd#2483 is merged, this approach can actually become practical without fearing performance hits. |
Cool but then said isReplaceFunctor template has to be defined with whatever the current safety of replace instance is. ... Local templates can't take alias parameters.... |
I'm just guessing, but I wonder if the original problem was caused because replace is @trusted, so the compiler tried to instantiate isReplaceFunctor as @safe? Because when I tested it outside of std.regex, the compiler was able to correctly compile (my copy of) isReplaceFunctor with no problems. Maybe try taking out @trusted from replace and see if the test case compiles? |
There wasn't much of public stuff anyway... updated. |
Seems like autotester is failing to compile the new code. :-( |
Mmm is it my compiler is slightly out of date or something but it passes for me :) |
Damn it was green for a while before some wicked pull brought git master down :( |
Fix issue 10913 std.regex API regression
No idea why I can't package __traits(compiles, ...) in a trait-like template. I must be missing something ...