Description
See thread starting at #550 (comment):
There is another case that #506 doesn't yet cover (https://cpp2.godbolt.org/z/hzYxv5rn6):
type_declaration: @struct type = { require: (this) = { } } require_fn: type == std::function<void(bool, std::string_view)>; array2: (inout t: type_declaration) = { require: require_fn = :(args...) t&$*.require(args...); _ = require; } main: () = { }
main.cpp2:6:91: error: variable 'require' cannot be implicitly captured in a lambda with no capture-default specified 6 | require_fn require {[_0 = (&t)](auto const& ...args) mutable -> auto { return CPP2_UFCS(require, (*cpp2::assert_not_null(_0)), args...); }}; | ^ main.cpp2:6:14: note: 'require' declared here 6 | require_fn require {[_0 = (&t)](auto const& ...args) mutable -> auto { return CPP2_UFCS(require, (*cpp2::assert_not_null(_0)), args...); }}; | ^
require
has typerequire_fn
, so it isn't that its type is deduced.
But it still tries to userequire
without capturing it.
Name lookup finds an object, so it doesn't try a free function, and the object must be captured.
If we're in a context that would need to capture the name, we should not use the UFCS macro.
In the context of a member function, this would happen to work due to #281.
require: require_fn = :(args...) t&$*.require(args...);
For this kind of code, in GitHub,
there are precisely 7 uses with the identifiersize
that would break if they were rewritten to Cpp2 and compiled with cppfront:
https://github.com/search?q=lang%3AC%2B%2B+content%3A%2F+size+%3D+%5C%5B.*%5C.size%5C%28%5C%29%3B%2F+NOT+is%3Afork&type=code.