-
Notifications
You must be signed in to change notification settings - Fork 252
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
[BUG] operator is
should be constrained or answered statically
#492
Comments
See also P2392's §2.1.2, §4.1.8. A: It's a better spelling for a chain of `if constexpr` `else`.Given a resolution for this issue,
|
|
It's not OK, it's necessary.
|
All compilers agree that this can be made to work if I just add |
I agree that constexpr is necessary for the pure type matching. This also becomes critical if inspect is used in the context of a template parameter. Did you create a test file where all common cases are evaluated? |
The one in the OP works,
|
But not to the point necessary to optimize |
It should still be possible Have Then, we can optimize If the chosen |
This is how it should look: https://cpp2.godbolt.org/z/s17G457aP.
|
I would guess it is the wrong forward declaration of
The requirement is missing. This makes the compiler think that there is an alternative definition which leads to the linker error. On a quick check, I could not find if the requires clause can be defined in a forward declaration. |
Oh, right. That's #323 (comment). |
Also support interpolation and "as std::string" for ints and bools (and remove uses of `std::boolalpha`, use `as std::string` or interpolation instead)
This is actually necessary since an |
I will take a look on your cases and will check if they are fixed or might be fixed in #701 |
It certainly is an improvement. |
Title:
operator is
should be constrained or answered statically.Description:
operator is
should be non-viable given a type-unsafe input.This is to implement P2392's §4.2.
It's also to correctly resolve #433,
as split off from #491:
Comments moved from #491.
The case of this PR is:
P2392 doesn't say what should happen in this case.
If one extracted the wording from the design, it would be UB by omission
IIUC what P1371 says, then it would similarly be UB by omission:
It also links to
https://github.com/solodon4/Mach7,
https://github.com/mpark/patterns, and
https://github.com/jbandela/simple_match.
But this corner case doesn't seem to be mentioned in their README.
Originally posted by @JohelEGP in #491 (comment)
How about this instead?
For a dependent
inspect
,when the is-as-expression-target of an alternative is well-formed,
the corresponding statement should also be well-formed.
So we move
from a runtime-checked contract
to a compile-time assertion.
Originally posted by @JohelEGP in #491 (comment)
Actually,
the proposals are clear that when there's a match,
execution continues at the corresponding statement.
The proposals are also clear in that
an ill-formed condition means the whole branch is a discarded statement.
So it falls out from the existing rules
that a well-formed condition implies the corresponding statement is also instantiated.
The actual bug is
that the validity check happens for the statement
and not at the condition (and thus for the whole branch).
Another bug is that an
is
-expression is always be well-formed,resulting in always-
false
when the equivalent withoutis
would be ill-formed.There is an example at P2392 §3.4.3
that mixes conditions that don't work for all intended types.
It can demonstrate the issue.
Here is a reduction: https://cpp2.godbolt.org/z/c5rsjP6a7.
Notice how
s is (in(1, 2))
is well-formed.It should be ill-formed outside a dependent
inspect
.As the condition of the alternative of a dependent
inspect
,it should make the alternative discarded.
Originally posted by @JohelEGP in #491 (comment)
Consider this degenerate case:
inspect
of 100 alternatives:is _
.Because a condition is always well-formed,
an always-
false
condition for a given input type isn't optimized out.Given an input
std::string
,the first 99 conditions are necessarily evaluated sequentially,
even though they're all always-
false
.Originally posted by @JohelEGP in #491 (comment)
Let's take the same
inspect
again.For the given conditions,
the
operator is
overloads ofstd::variant<std::string, i32>
should be well-formed and necessarily runtime-evaluated.
The same for
std::variant<std::monostate>
should be ill-formed.So
std::variant::operator is
should only workat runtime and when the query can be forwarded to one of its variant alternatives.
Nothing changes the fact that if the condition is well-formed, the statement should be instantiated.
Originally posted by @JohelEGP in #491 (comment)
Once
operator is
is constrained or answered statically,it becomes necessary to fix
inspect
to omit alternatives whose conditions are non-viable.
It also becomes possible
to omit alternatives whose conditions always-
false
.Note that there's a distinction between an
operator is
that is constrained and answered statically.A constrained
operator is
has preconditions on the input type.There are other contexts where we might want the semantics of an
inspect
's alternative's condition.Minimal reproducer (https://cpp2.godbolt.org/z/87hjsccYd):
Commands:
cppfront -clean-cpp1 main.cpp2 clang++17 -std=c++23 -stdlib=libc++ -lc++abi -pedantic-errors -Wall -Wextra -Wconversion -I . main.cpp
Expected result:
f(s)
: An error when instantiating:(x) -> _ = { return "a string"; }()
.f(1)
: Alternative withis std::string
to be statically elided.s is (in(1, 2))
: An error, just likein(1, 2)(s)
.Actual result and error:
f(s)
: Unconditionally returnsstd::string()
because the matched alternative's statement is ill-formed.f(1)
: Unconditionally evaluatesis std::string
that will always befalse
.s is (in(1, 2))
: Unconditionally results infalse
, even thoughin(1, 2)(s)
is ill-formed.Cpp2 lowered to Cpp1.
Output.
The text was updated successfully, but these errors were encountered: