diff --git a/src/quick-lint-js/diag/diag-list.cpp b/src/quick-lint-js/diag/diag-list.cpp index a8613c0ab..132cc8207 100644 --- a/src/quick-lint-js/diag/diag-list.cpp +++ b/src/quick-lint-js/diag/diag-list.cpp @@ -23,6 +23,11 @@ static_assert(alignof(Diag_List::Node) == alignof(Diag_List::Node_Base), Diag_List::Diag_List(Memory_Resource *memory) : memory_(memory) {} +Diag_List::Diag_List(Diag_List &&other) + : memory_(other.memory_), first_(other.first_), last_(other.last_) { + other.clear(); +} + Diag_List::~Diag_List() { this->clear(); } void Diag_List::add_many(const Diag_List &other) { diff --git a/src/quick-lint-js/diag/diag-list.h b/src/quick-lint-js/diag/diag-list.h index afd2eca5e..f00e385cc 100644 --- a/src/quick-lint-js/diag/diag-list.h +++ b/src/quick-lint-js/diag/diag-list.h @@ -36,8 +36,11 @@ class Diag_List { explicit Diag_List(Memory_Resource *); - Diag_List(Diag_List &&) = delete; - Diag_List &operator=(Diag_List &&) = delete; + Diag_List(const Diag_List &) = delete; + Diag_List &operator=(const Diag_List &) = delete; + + Diag_List(Diag_List &&); + Diag_List &operator=(Diag_List &&) = delete; // TODO(strager) ~Diag_List(); diff --git a/test/test-diag-list.cpp b/test/test-diag-list.cpp index 96db2d4c6..c57ae366c 100644 --- a/test/test-diag-list.cpp +++ b/test/test-diag-list.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -189,6 +190,41 @@ TEST(Test_Diag_List, pretty_print_one_diag) { EXPECT_EQ(ss.str(), "1 diagnostic: {\n Diag_Let_With_No_Bindings,\n}"); } } + +TEST(Test_Diag_List, moving_diag_list_clears_original) { + Linked_Bump_Allocator memory("test"); + Diag_List diags_1(&memory); + Padded_String code(u8"hello"_sv); + diags_1.add(Diag_Let_With_No_Bindings{.where = span_of(code)}); + Diag_List diags_2 = std::move(diags_1); + EXPECT_EQ(diags_1.size(), 0); +} + +TEST(Test_Diag_List, moving_diag_list_keeps_single_diag) { + Linked_Bump_Allocator memory("test"); + Diag_List diags_1(&memory); + Padded_String code(u8"hello"_sv); + diags_1.add(Diag_Let_With_No_Bindings{.where = span_of(code)}); + + Diag_List diags_2 = std::move(diags_1); + EXPECT_EQ(diags_2.size(), 1); +} + +TEST(Test_Diag_List, moving_diag_list_keeps_multiple_diags) { + Linked_Bump_Allocator memory("test"); + Diag_List diags_1(&memory); + Padded_String code(u8"hello"_sv); + diags_1.add(Diag_Let_With_No_Bindings{.where = span_of(code)}); + diags_1.add(Diag_Expected_Parenthesis_Around_If_Condition{ + .where = span_of(code), + .token = u8')', + }); + + Diag_List diags_2 = std::move(diags_1); + assert_diagnostics(&code, diags_2, + {u8"Diag_Let_With_No_Bindings"_diag, + u8"Diag_Expected_Parenthesis_Around_If_Condition"_diag}); +} } }