AK+Everywhere: Disallow constructing Functions from incompatible types

Previously, AK::Function would accept _any_ callable type, and try to
call it when called, first with the given set of arguments, then with
zero arguments, and if all of those failed, it would simply not call the
function and **return a value-constructed Out type**.
This lead to many, many, many hard to debug situations when someone
forgot a `const` in their lambda argument types, and many cases of
people taking zero arguments in their lambdas to ignore them.
This commit reworks the Function interface to not include any such
surprising behaviour, if your function instance is not callable with
the declared argument set of the Function, it can simply not be
assigned to that Function instance, end of story.
This commit is contained in:
Ali Mohammad Pur 2021-06-05 23:04:31 +04:30 committed by Ali Mohammad Pur
parent 104dc93220
commit 51c2c69357
Notes: sideshowbarker 2024-07-18 16:50:18 +09:00
28 changed files with 99 additions and 92 deletions

View file

@ -39,26 +39,36 @@ namespace AK {
template<typename>
class Function;
template<typename F>
inline constexpr bool IsFunctionPointer = (IsPointer<F> && IsFunction<RemovePointer<F>>);
// Not a function pointer, and not an lvalue reference.
template<typename F>
inline constexpr bool IsFunctionObject = (!IsFunctionPointer<F> && IsRvalueReference<F&&>);
template<typename Out, typename... In>
class Function<Out(In...)> {
AK_MAKE_NONCOPYABLE(Function);
public:
Function() = default;
Function(std::nullptr_t)
{
}
~Function()
{
clear(false);
}
template<typename CallableType, class = typename EnableIf<!(IsPointer<CallableType> && IsFunction<RemovePointer<CallableType>>)&&IsRvalueReference<CallableType&&>>::Type>
Function(CallableType&& callable)
template<typename CallableType>
Function(CallableType&& callable) requires((IsFunctionObject<CallableType> && IsCallableWithArguments<CallableType, In...>))
{
init_with_callable(move(callable));
init_with_callable(forward<CallableType>(callable));
}
template<typename FunctionType, class = typename EnableIf<IsPointer<FunctionType> && IsFunction<RemovePointer<FunctionType>>>::Type>
Function(FunctionType f)
template<typename FunctionType>
Function(FunctionType f) requires((IsFunctionPointer<FunctionType> && IsCallableWithArguments<RemovePointer<FunctionType>, In...>))
{
init_with_callable(move(f));
}
@ -68,6 +78,7 @@ public:
move_from(move(other));
}
// Note: Despite this method being const, a mutable lambda _may_ modify its own captures.
Out operator()(In... in) const
{
auto* wrapper = callable_wrapper();
@ -82,16 +93,16 @@ public:
explicit operator bool() const { return !!callable_wrapper(); }
template<typename CallableType, class = typename EnableIf<!(IsPointer<CallableType> && IsFunction<RemovePointer<CallableType>>)&&IsRvalueReference<CallableType&&>>::Type>
Function& operator=(CallableType&& callable)
template<typename CallableType>
Function& operator=(CallableType&& callable) requires((IsFunctionObject<CallableType> && IsCallableWithArguments<CallableType, In...>))
{
clear();
init_with_callable(move(callable));
init_with_callable(forward<CallableType>(callable));
return *this;
}
template<typename FunctionType, class = typename EnableIf<IsPointer<FunctionType> && IsFunction<RemovePointer<FunctionType>>>::Type>
Function& operator=(FunctionType f)
template<typename FunctionType>
Function& operator=(FunctionType f) requires((IsFunctionPointer<FunctionType> && IsCallableWithArguments<RemovePointer<FunctionType>, In...>))
{
clear();
if (f)
@ -118,7 +129,8 @@ private:
class CallableWrapperBase {
public:
virtual ~CallableWrapperBase() = default;
virtual Out call(In...) const = 0;
// Note: This is not const to allow storing mutable lambdas.
virtual Out call(In...) = 0;
virtual void destroy() = 0;
virtual void init_and_swap(u8*, size_t) = 0;
};
@ -134,17 +146,9 @@ private:
{
}
Out call(In... in) const final override
Out call(In... in) final override
{
if constexpr (requires { m_callable(forward<In>(in)...); }) {
return m_callable(forward<In>(in)...);
} else if constexpr (requires { m_callable(); }) {
return m_callable();
} else if constexpr (IsVoid<Out>) {
return;
} else {
return {};
}
return m_callable(forward<In>(in)...);
}
void destroy() final override
@ -208,10 +212,10 @@ private:
VERIFY(m_call_nesting_level == 0);
using WrapperType = CallableWrapper<Callable>;
if constexpr (sizeof(WrapperType) > inline_capacity) {
*bit_cast<CallableWrapperBase**>(&m_storage) = new WrapperType(move(callable));
*bit_cast<CallableWrapperBase**>(&m_storage) = new WrapperType(forward<Callable>(callable));
m_kind = FunctionKind::Outline;
} else {
new (m_storage) WrapperType(move(callable));
new (m_storage) WrapperType(forward<Callable>(callable));
m_kind = FunctionKind::Inline;
}
}

View file

@ -435,10 +435,16 @@ inline constexpr bool IsTrivial = __is_trivial(T);
template<typename T>
inline constexpr bool IsTriviallyCopyable = __is_trivially_copyable(T);
template<typename T>
auto declval() -> T;
template<typename T, typename... Args>
inline constexpr bool IsCallableWithArguments = requires(T t) { t(declval<Args>()...); };
}
using AK::Detail::AddConst;
using AK::Detail::Conditional;
using AK::Detail::CopyConst;
using AK::Detail::declval;
using AK::Detail::DependentFalse;
using AK::Detail::EnableIf;
using AK::Detail::FalseType;
@ -447,6 +453,7 @@ using AK::Detail::IndexSequence;
using AK::Detail::IntegerSequence;
using AK::Detail::IsArithmetic;
using AK::Detail::IsBaseOf;
using AK::Detail::IsCallableWithArguments;
using AK::Detail::IsClass;
using AK::Detail::IsConst;
using AK::Detail::IsEnum;

View file

@ -39,9 +39,6 @@ struct _RawPtr {
namespace AK {
template<typename T>
auto declval() -> T;
template<class T>
constexpr T&& forward(RemoveReference<T>& param)
{
@ -118,7 +115,6 @@ using RawPtr = typename Detail::_RawPtr<T>::Type;
using AK::array_size;
using AK::ceil_div;
using AK::clamp;
using AK::declval;
using AK::exchange;
using AK::forward;
using AK::max;

View file

@ -15,7 +15,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
if (!zip_file.has_value())
return 0;
zip_file->for_each_member([]() {
zip_file->for_each_member([](auto&) {
return IterationDecision::Continue;
});

View file

@ -119,9 +119,9 @@ TESTJS_GLOBAL_FUNCTION(wait_for_page_to_load, waitForPageToLoad)
break;
}
},
[&](auto) {
[&](auto&, auto) {
dbgln("Load of resource {} failed", next_page_to_load.value());
vm.throw_exception<Web::DOM::NetworkError>(global_object);
vm.throw_exception<JS::TypeError>(global_object, "Resource load failed");
});
return JS::js_undefined();

View file

@ -203,23 +203,23 @@ int main(int argc, char** argv)
load_model(open_path.value());
}));
file_menu.add_separator();
file_menu.add_action(GUI::CommonActions::make_quit_action([&] {
file_menu.add_action(GUI::CommonActions::make_quit_action([&](auto&) {
app->quit();
}));
auto& view_menu = menubar->add_menu("&View");
view_menu.add_action(GUI::CommonActions::make_fullscreen_action([&] {
view_menu.add_action(GUI::CommonActions::make_fullscreen_action([&](auto&) {
window->set_fullscreen(!window->is_fullscreen());
}));
auto& rotation_axis_menu = view_menu.add_submenu("Rotation &Axis");
auto rotation_x_action = GUI::Action::create_checkable("&X", [&widget] {
auto rotation_x_action = GUI::Action::create_checkable("&X", [&widget](auto&) {
widget.toggle_rotate_x();
});
auto rotation_y_action = GUI::Action::create_checkable("&Y", [&widget] {
auto rotation_y_action = GUI::Action::create_checkable("&Y", [&widget](auto&) {
widget.toggle_rotate_y();
});
auto rotation_z_action = GUI::Action::create_checkable("&Z", [&widget] {
auto rotation_z_action = GUI::Action::create_checkable("&Z", [&widget](auto&) {
widget.toggle_rotate_z();
});
@ -234,16 +234,16 @@ int main(int argc, char** argv)
GUI::ActionGroup rotation_speed_actions;
rotation_speed_actions.set_exclusive(true);
auto no_rotation_action = GUI::Action::create_checkable("N&o Rotation", [&widget] {
auto no_rotation_action = GUI::Action::create_checkable("N&o Rotation", [&widget](auto&) {
widget.set_rotation_speed(0.f);
});
auto slow_rotation_action = GUI::Action::create_checkable("&Slow", [&widget] {
auto slow_rotation_action = GUI::Action::create_checkable("&Slow", [&widget](auto&) {
widget.set_rotation_speed(0.5f);
});
auto normal_rotation_action = GUI::Action::create_checkable("&Normal", [&widget] {
auto normal_rotation_action = GUI::Action::create_checkable("&Normal", [&widget](auto&) {
widget.set_rotation_speed(1.f);
});
auto fast_rotation_action = GUI::Action::create_checkable("&Fast", [&widget] {
auto fast_rotation_action = GUI::Action::create_checkable("&Fast", [&widget](auto&) {
widget.set_rotation_speed(1.5f);
});

View file

@ -25,7 +25,7 @@ FontSettingsWidget::FontSettingsWidget()
update_label_with_font(*m_default_font_label, default_font);
auto& default_font_button = *find_descendant_of_type_named<GUI::Button>("default_font_button");
default_font_button.on_click = [this] {
default_font_button.on_click = [this](auto) {
auto font_picker = GUI::FontPicker::construct(window(), &m_default_font_label->font(), false);
if (font_picker->exec() == GUI::Dialog::ExecOK) {
update_label_with_font(*m_default_font_label, *font_picker->font());
@ -37,7 +37,7 @@ FontSettingsWidget::FontSettingsWidget()
update_label_with_font(*m_fixed_width_font_label, default_fixed_width_font);
auto& fixed_width_font_button = *find_descendant_of_type_named<GUI::Button>("fixed_width_font_button");
fixed_width_font_button.on_click = [this] {
fixed_width_font_button.on_click = [this](auto) {
auto font_picker = GUI::FontPicker::construct(window(), &m_fixed_width_font_label->font(), true);
if (font_picker->exec() == GUI::Dialog::ExecOK) {
update_label_with_font(*m_fixed_width_font_label, *font_picker->font());

View file

@ -61,7 +61,7 @@ int main(int argc, char** argv)
auto& ok_button = button_container.add<GUI::Button>("OK");
ok_button.set_fixed_width(75);
ok_button.on_click = [&] {
ok_button.on_click = [&](auto) {
background_settings_widget.apply_settings();
monitor_settings_widget.apply_settings();
font_settings_widget.apply_settings();
@ -70,13 +70,13 @@ int main(int argc, char** argv)
auto& cancel_button = button_container.add<GUI::Button>("Cancel");
cancel_button.set_fixed_width(75);
cancel_button.on_click = [&] {
cancel_button.on_click = [&](auto) {
app->quit();
};
auto& apply_button = button_container.add<GUI::Button>("Apply");
apply_button.set_fixed_width(75);
apply_button.on_click = [&] {
apply_button.on_click = [&](auto) {
background_settings_widget.apply_settings();
monitor_settings_widget.apply_settings();
font_settings_widget.apply_settings();

View file

@ -34,7 +34,7 @@ FileOperationProgressWidget::FileOperationProgressWidget(NonnullRefPtr<Core::Fil
auto& destination_folder_icon = *find_descendant_of_type_named<GUI::ImageWidget>("destination_folder_icon");
destination_folder_icon.load_from_file("/res/icons/32x32/filetype-folder-open.png");
button.on_click = [this] {
button.on_click = [this](auto) {
close_pipe();
window()->close();
};

View file

@ -1124,14 +1124,14 @@ int run_in_windowed_mode(RefPtr<Core::ConfigFile> config, String initial_locatio
go_to_location_action->activate();
};
tree_view.on_drop = [&](const GUI::ModelIndex& index, GUI::DropEvent& event) {
tree_view.on_drop = [&](const GUI::ModelIndex& index, const GUI::DropEvent& event) {
if (!event.mime_data().has_urls())
return;
auto& target_node = directories_model->node(index);
if (!target_node.is_directory())
return;
copy_urls_to_directory(event.mime_data().urls(), target_node.full_path());
event.accept();
const_cast<GUI::DropEvent&>(event).accept();
};
directory_view.open(initial_location);

View file

@ -92,7 +92,7 @@ static RefPtr<GUI::Window> create_font_preview_window(FontEditorWidget& editor)
auto& reload_button = textbox_button_container.add<GUI::Button>();
reload_button.set_icon(Gfx::Bitmap::load_from_file("/res/icons/16x16/reload.png"));
reload_button.set_fixed_width(22);
reload_button.on_click = [&] {
reload_button.on_click = [&](auto) {
static int i = 1;
if (i >= s_pangram_count)
i = 0;
@ -326,7 +326,7 @@ FontEditorWidget::FontEditorWidget(const String& path, RefPtr<Gfx::BitmapFont>&&
m_glyph_editor_scale_actions.add_action(*m_scale_fifteen_action);
m_glyph_editor_scale_actions.set_exclusive(true);
move_glyph_button.on_click = [&] {
move_glyph_button.on_click = [&](auto) {
if (move_glyph_button.is_checked())
m_glyph_editor_widget->set_mode(GlyphEditorWidget::Move);
else
@ -407,7 +407,7 @@ FontEditorWidget::FontEditorWidget(const String& path, RefPtr<Gfx::BitmapFont>&&
did_modify_font();
};
m_weight_combobox->on_change = [this]() {
m_weight_combobox->on_change = [this](auto&, auto&) {
m_edited_font->set_weight(GUI::name_to_weight(m_weight_combobox->text()));
did_modify_font();
};

View file

@ -197,7 +197,7 @@ NewFontDialog::NewFontDialog(GUI::Window* parent_window)
m_glyph_width_spinbox->on_change = [&](int value) {
preview_editor.set_preview_size(value, m_glyph_height_spinbox->value());
deferred_invoke([&] {
deferred_invoke([&](auto&) {
m_glyph_editor_container->set_fixed_height(1 + preview_editor.height() + preview_editor.frame_thickness() * 2);
});
};
@ -205,7 +205,7 @@ NewFontDialog::NewFontDialog(GUI::Window* parent_window)
preview_editor.set_preview_size(m_glyph_width_spinbox->value(), value);
m_mean_line_spinbox->set_max(max(value - 2, 0));
m_baseline_spinbox->set_max(max(value - 2, 0));
deferred_invoke([&] {
deferred_invoke([&](auto&) {
m_glyph_editor_container->set_fixed_height(1 + preview_editor.height() + preview_editor.frame_thickness() * 2);
});
};

View file

@ -137,11 +137,11 @@ GoToOffsetDialog::GoToOffsetDialog()
update_statusbar();
};
m_offset_type_box->on_change = [this]() {
m_offset_type_box->on_change = [this](auto&, auto&) {
update_statusbar();
};
m_offset_from_box->on_change = [this]() {
m_offset_from_box->on_change = [this](auto&, auto&) {
update_statusbar();
};

View file

@ -89,18 +89,18 @@ CSVExportDialogPage::CSVExportDialogPage(const Sheet& sheet)
m_delimiter_tab_radio->on_checked = [&](auto) { update_preview(); };
m_delimiter_space_radio->on_checked = [&](auto) { update_preview(); };
m_delimiter_other_radio->on_checked = [&](auto) { update_preview(); };
m_delimiter_other_text_box->on_change = [&](auto&) {
m_delimiter_other_text_box->on_change = [&] {
if (m_delimiter_other_radio->is_checked())
update_preview();
};
m_quote_single_radio->on_checked = [&](auto) { update_preview(); };
m_quote_double_radio->on_checked = [&](auto) { update_preview(); };
m_quote_other_radio->on_checked = [&](auto) { update_preview(); };
m_quote_other_text_box->on_change = [&](auto&) {
m_quote_other_text_box->on_change = [&] {
if (m_quote_other_radio->is_checked())
update_preview();
};
m_quote_escape_combo_box->on_change = [&](auto&) { update_preview(); };
m_quote_escape_combo_box->on_change = [&](auto&, auto&) { update_preview(); };
m_export_header_check_box->on_checked = [&](auto) { update_preview(); };
m_quote_all_fields_check_box->on_checked = [&](auto) { update_preview(); };

View file

@ -67,18 +67,18 @@ CSVImportDialogPage::CSVImportDialogPage(StringView csv)
m_delimiter_tab_radio->on_checked = [&](auto) { update_preview(); };
m_delimiter_space_radio->on_checked = [&](auto) { update_preview(); };
m_delimiter_other_radio->on_checked = [&](auto) { update_preview(); };
m_delimiter_other_text_box->on_change = [&](auto&) {
m_delimiter_other_text_box->on_change = [&] {
if (m_delimiter_other_radio->is_checked())
update_preview();
};
m_quote_single_radio->on_checked = [&](auto) { update_preview(); };
m_quote_double_radio->on_checked = [&](auto) { update_preview(); };
m_quote_other_radio->on_checked = [&](auto) { update_preview(); };
m_quote_other_text_box->on_change = [&](auto&) {
m_quote_other_text_box->on_change = [&] {
if (m_quote_other_radio->is_checked())
update_preview();
};
m_quote_escape_combo_box->on_change = [&](auto&) { update_preview(); };
m_quote_escape_combo_box->on_change = [&](auto&, auto&) { update_preview(); };
m_read_header_check_box->on_checked = [&](auto) { update_preview(); };
m_trim_leading_field_spaces_check_box->on_checked = [&](auto) { update_preview(); };
m_trim_trailing_field_spaces_check_box->on_checked = [&](auto) { update_preview(); };

View file

@ -191,8 +191,8 @@ int main(int argc, char* argv[])
GUI::Clipboard::the().set_data(text_builder.string_view().bytes(), "text/plain", move(metadata));
};
edit_menu.add_action(GUI::CommonActions::make_copy_action([&] { clipboard_action(false); }, window));
edit_menu.add_action(GUI::CommonActions::make_cut_action([&] { clipboard_action(true); }, window));
edit_menu.add_action(GUI::CommonActions::make_copy_action([&](auto&) { clipboard_action(false); }, window));
edit_menu.add_action(GUI::CommonActions::make_cut_action([&](auto&) { clipboard_action(true); }, window));
edit_menu.add_action(GUI::CommonActions::make_paste_action([&](auto&) {
ScopeGuard update_after_paste { [&] { spreadsheet_widget.update(); } };

View file

@ -76,20 +76,20 @@ MainWidget::MainWidget()
m_replace_textbox->set_placeholder("Replace");
m_match_case_checkbox = *find_descendant_of_type_named<GUI::CheckBox>("match_case_checkbox");
m_match_case_checkbox->on_checked = [this] {
m_match_case = m_match_case_checkbox->is_checked();
m_match_case_checkbox->on_checked = [this](auto is_checked) {
m_match_case = is_checked;
};
m_match_case_checkbox->set_checked(true);
m_regex_checkbox = *find_descendant_of_type_named<GUI::CheckBox>("regex_checkbox");
m_regex_checkbox->on_checked = [this] {
m_use_regex = m_regex_checkbox->is_checked();
m_regex_checkbox->on_checked = [this](auto is_checked) {
m_use_regex = is_checked;
};
m_regex_checkbox->set_checked(false);
m_wrap_around_checkbox = *find_descendant_of_type_named<GUI::CheckBox>("wrap_around_checkbox");
m_wrap_around_checkbox->on_checked = [this] {
m_should_wrap = m_wrap_around_checkbox->is_checked();
m_wrap_around_checkbox->on_checked = [this](auto is_checked) {
m_should_wrap = is_checked;
};
m_wrap_around_checkbox->set_checked(true);

View file

@ -36,7 +36,7 @@ WelcomeWidget::WelcomeWidget()
m_next_button = *find_descendant_of_type_named<GUI::Button>("next_button");
m_next_button->set_icon(Gfx::Bitmap::load_from_file("/res/icons/16x16/go-forward.png"));
m_next_button->on_click = [&]() {
m_next_button->on_click = [&](auto) {
if (!tip_frame.is_visible()) {
m_web_view->set_visible(false);
tip_frame.set_visible(true);
@ -51,7 +51,7 @@ WelcomeWidget::WelcomeWidget()
m_help_button = *find_descendant_of_type_named<GUI::Button>("help_button");
m_help_button->set_icon(Gfx::Bitmap::load_from_file("/res/icons/16x16/book-open.png"));
m_help_button->on_click = []() {
m_help_button->on_click = [](auto) {
pid_t pid;
const char* argv[] = { "Help", nullptr };
if ((errno = posix_spawn(&pid, "/bin/Help", nullptr, nullptr, const_cast<char**>(argv), environ))) {
@ -63,13 +63,13 @@ WelcomeWidget::WelcomeWidget()
};
m_new_button = *find_descendant_of_type_named<GUI::Button>("new_button");
m_new_button->on_click = [&]() {
m_new_button->on_click = [&](auto) {
m_web_view->set_visible(!m_web_view->is_visible());
tip_frame.set_visible(!tip_frame.is_visible());
};
m_close_button = *find_descendant_of_type_named<GUI::Button>("close_button");
m_close_button->on_click = []() {
m_close_button->on_click = [](auto) {
GUI::Application::the()->quit();
};

View file

@ -82,7 +82,7 @@ GalleryWidget::GalleryWidget()
m_disabled_icon_button = basics_tab.find_descendant_of_type_named<GUI::Button>("disabled_icon_button");
m_disabled_icon_button->set_icon(*m_button_icons[2]);
m_icon_button->on_click = [&]() {
m_icon_button->on_click = [&](auto) {
static size_t i;
if (i >= m_button_icons.size())
i = 0;
@ -96,7 +96,7 @@ GalleryWidget::GalleryWidget()
m_font_button = basics_tab.find_descendant_of_type_named<GUI::Button>("font_button");
m_font_button->set_icon(Gfx::Bitmap::load_from_file("/res/icons/16x16/app-font-editor.png"));
m_font_button->on_click = [&]() {
m_font_button->on_click = [&](auto) {
auto picker = GUI::FontPicker::construct(window(), &m_text_editor->font(), false);
if (picker->exec() == GUI::Dialog::ExecOK) {
m_text_editor->set_font(picker->font());
@ -106,7 +106,7 @@ GalleryWidget::GalleryWidget()
m_file_button = basics_tab.find_descendant_of_type_named<GUI::Button>("file_button");
m_file_button->set_icon(Gfx::Bitmap::load_from_file("/res/icons/16x16/open.png"));
m_file_button->on_click = [&]() {
m_file_button->on_click = [&](auto) {
Optional<String> open_path = GUI::FilePicker::get_open_filepath(window());
if (!open_path.has_value())
return;
@ -116,7 +116,7 @@ GalleryWidget::GalleryWidget()
m_input_button = basics_tab.find_descendant_of_type_named<GUI::Button>("input_button");
m_input_button->set_icon(Gfx::Bitmap::load_from_file("/res/icons/16x16/properties.png"));
m_input_button->on_click = [&]() {
m_input_button->on_click = [&](auto) {
String value;
if (GUI::InputBox::show(window(), value, "Enter input:", "Input") == GUI::InputBox::ExecOK && !value.is_empty())
m_text_editor->set_text(value);
@ -164,7 +164,7 @@ GalleryWidget::GalleryWidget()
m_msgbox_input_type = static_cast<GUI::MessageBox::InputType>(index.row());
};
m_msgbox_button->on_click = [&]() {
m_msgbox_button->on_click = [&](auto) {
GUI::MessageBox::show(window(), m_text_editor->text(), "Message", m_msgbox_type, m_msgbox_input_type);
};
@ -261,7 +261,7 @@ GalleryWidget::GalleryWidget()
m_wizard_output->set_text(String::formatted("{}{}", serenityos_ascii, wizard_ascii));
m_wizard_button->on_click = [&]() {
m_wizard_button->on_click = [&](auto) {
StringBuilder sb;
sb.append(m_wizard_output->get_text());
sb.append("\nWizard started.");

View file

@ -62,7 +62,7 @@ NewProjectDialog::NewProjectDialog(GUI::Window* parent)
m_icon_view->on_selection_change = [&]() {
update_dialog();
};
m_icon_view->on_activation = [&]() {
m_icon_view->on_activation = [&](auto&) {
if (m_input_valid)
do_create_project();
};

View file

@ -141,7 +141,7 @@ void Game::show_score_card(bool game_over)
button_container.set_layout<GUI::VerticalBoxLayout>();
auto& close_button = button_container.add<GUI::Button>("OK");
close_button.on_click = [&score_dialog] {
close_button.on_click = [&score_dialog](auto) {
score_dialog->done(GUI::Dialog::ExecOK);
};
close_button.set_min_width(70);

View file

@ -226,7 +226,7 @@ FilePicker::FilePicker(Window* parent_window, Mode mode, const StringView& filen
button.set_fixed_height(22);
button.set_checkable(true);
button.set_exclusive(true);
button.on_click = [this, path] {
button.on_click = [this, path](auto) {
set_path(path);
};
m_common_location_buttons.append({ path, button });

View file

@ -47,13 +47,13 @@ WizardDialog::WizardDialog(Window* parent_window)
m_back_button = nav_container_widget.add<Button>("< Back");
m_back_button->set_fixed_width(75);
m_back_button->on_click = [&]() {
m_back_button->on_click = [&](auto) {
pop_page();
};
m_next_button = nav_container_widget.add<Button>("Next >");
m_next_button->set_fixed_width(75);
m_next_button->on_click = [&]() {
m_next_button->on_click = [&](auto) {
VERIFY(has_pages());
if (!current_page().can_go_next())
@ -71,7 +71,7 @@ WizardDialog::WizardDialog(Window* parent_window)
m_cancel_button = nav_container_widget.add<Button>("Cancel");
m_cancel_button->set_fixed_width(75);
m_cancel_button->on_click = [&]() {
m_cancel_button->on_click = [&](auto) {
handle_cancel();
};

View file

@ -252,7 +252,7 @@ String Parser::parse_comment()
consume();
auto comment_start_offset = m_reader.offset();
m_reader.move_until([&] {
m_reader.move_until([&](auto) {
return matches_eol();
});
String str = StringView(m_reader.bytes().slice(comment_start_offset, m_reader.offset() - comment_start_offset));
@ -664,7 +664,7 @@ NonnullRefPtr<StreamObject> Parser::parse_stream(NonnullRefPtr<DictObject> dict)
auto stream_start = m_reader.offset();
while (true) {
m_reader.move_until([&] { return matches_eol(); });
m_reader.move_until([&](auto) { return matches_eol(); });
auto potential_stream_end = m_reader.offset();
consume_eol();
if (!m_reader.matches("endstream"))

View file

@ -525,7 +525,7 @@ NonnullRefPtr<HTMLCollection> Document::applets()
{
// FIXME: This should return the same HTMLCollection object every time,
// but that would cause a reference cycle since HTMLCollection refs the root.
return HTMLCollection::create(*this, [] { return false; });
return HTMLCollection::create(*this, [](auto&) { return false; });
}
// https://html.spec.whatwg.org/multipage/obsolete.html#dom-document-anchors

View file

@ -64,7 +64,7 @@ void OutOfProcessWebView::create_client()
m_client_state.client = WebContentClient::construct(*this);
m_client_state.client->on_web_content_process_crash = [this] {
deferred_invoke([this] {
deferred_invoke([this](auto&) {
handle_web_content_process_crash();
});
};

View file

@ -30,16 +30,16 @@ void TLSv12WebSocketConnectionImpl::connect(ConnectionInfo const& connection)
m_socket->on_tls_error = [this](TLS::AlertDescription) {
on_connection_error();
};
m_socket->on_tls_ready_to_read = [this] {
m_socket->on_tls_ready_to_read = [this](auto&) {
on_ready_to_read();
};
m_socket->on_tls_ready_to_write = [this] {
m_socket->on_tls_ready_to_write = [this](auto&) {
on_connected();
};
m_socket->on_tls_finished = [this] {
on_connection_error();
};
m_socket->on_tls_certificate_request = [this](auto&) {
m_socket->on_tls_certificate_request = [](auto&) {
// FIXME : Once we handle TLS certificate requests, handle it here as well.
};
bool success = m_socket->connect(connection.url().host(), connection.url().port());

View file

@ -127,7 +127,7 @@ void ClientConnection::did_error(i32 connection_id, i32 message)
void ClientConnection::did_close(i32 connection_id, u16 code, String reason, bool was_clean)
{
async_closed(connection_id, code, reason, was_clean);
deferred_invoke([this, connection_id] {
deferred_invoke([this, connection_id](auto&) {
m_connections.remove(connection_id);
});
}