Closed fschuh closed 1 year ago
@hedayat, if you want to look at it. I may be able to look as well this weekend.
I found the issue, in short if if constexpr
isn't supported, FakeIt will generate an Assign
function for each arguments of the mocked function (from left to right) until all the parameters from the ReturnAndSet
/Set
are consumed. The generated function either contain code for assigning the parameter from ReturnAndSet
/Set
to the parameter of the mocked function, or code for throwing an exception (because generation the assignment code isn't possible, like if we tried to assign an std::string
to an int
).
This decision was taken based on if parameter A was convertible to parameter B, but it was wrong because int
is convertible to int
, but not assignable (int
is an rvalue, like 5
for example, and obviously 5 = 2
is not possible), so it generated code that wouldn't compile.
I changed the check from is_convertible
to is_assignable
and now it works, it generate the "assignment" code only if the two variables are compatible for assignment.
I'll merge the fix soon, and will release it in the 2.3.1, but be aware that your example "ReturnAndSet: output as second arg")"
still won't compile because without placeholders you're trying to assign to the first arg which isn't an output arg.
Fixed by #295 in 2.3.1.
Thanks for the fix, and sorry that I wasn't able to spend time on it.
No worries, it took me 5 months to change two lines, I understand.
:D
I found the issue, in short if
if constexpr
isn't supported, FakeIt will generate anAssign
function for each arguments of the mocked function (from left to right) until all the parameters from theReturnAndSet
/Set
are consumed. The generated function either contain code for assigning the parameter fromReturnAndSet
/Set
to the parameter of the mocked function, or code for throwing an exception (because generation the assignment code isn't possible, like if we tried to assign anstd::string
to anint
).This decision was taken based on if parameter A was convertible to parameter B, but it was wrong because
int
is convertible toint
, but not assignable (int
is an rvalue, like5
for example, and obviously5 = 2
is not possible), so it generated code that wouldn't compile.I changed the check from
is_convertible
tois_assignable
and now it works, it generate the "assignment" code only if the two variables are compatible for assignment.I'll merge the fix soon, and will release it in the 2.3.1, but be aware that your example
"ReturnAndSet: output as second arg")"
still won't compile because without placeholders you're trying to assign to the first arg which isn't an output arg.
Great, thanks for the fix. I just tried it on the dev-2.3.1 branch and can confirm it works now.
Also my bad for the test you mentioned, "ReturnAndSet: output as second arg"
, it was incorrect and indeed shouldn't compile even with the fix.
ReturnAndSet seems to only compile if all arguments in a method are outputs. The only exception seems to be if the output is the first argument, but that only compiles if a placeholder isn't used.
Here are a few sample tests (with and without placeholders) that reproduce the issue:
Using Visual Studio 2019 MSVC, and FakeIt 2.3.0.