mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-04 22:02:52 +01:00
Introduce FindIfOrNull() FindIfOrNone() and Contains() (#5322)
`FindIfOrNull` returns a pointer to the element in the range if it's found, and nullptr otherwise. `FindIfOrNone` returns a copy of the element in the range if it's found, and `T::None` (for a range of elements of type `T`) otherwise. `Contains` returns a bool indicating whether the element in the range is found. These functions replace `llvm::find()` and `llvm::find_if()` when you want a single answer back instead of an iterator. This avoids the need to check against `end()`, allowing the return condition to be tested as a standard bool. We replace uses of `find()` and `find_if()` that did not require an iterator with these new helpers. Note that the return type of `FindIfOrNull` is a pointer since we can not write `optional<T&>`, which must be tested for null. If the null check is omitted, UB occurs and the resulting code may end up with an incorrect pointer (https://crbug.com/40153300) into the range (or elsewhere), rather than a null dereference. And this would be very confusing to debug. Hopefully debug builds and sanitizers keep this from being an issue we sink a bunch of time into debugging.
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
#include <optional>
|
||||
#include <utility>
|
||||
|
||||
#include "common/find.h"
|
||||
#include "toolchain/base/kind_switch.h"
|
||||
#include "toolchain/check/context.h"
|
||||
#include "toolchain/check/control_flow.h"
|
||||
@@ -90,15 +91,9 @@ static auto FindSelfPattern(Context& context,
|
||||
-> SemIR::InstId {
|
||||
auto implicit_param_patterns =
|
||||
context.inst_blocks().GetOrEmpty(implicit_param_patterns_id);
|
||||
if (const auto* i = llvm::find_if(implicit_param_patterns,
|
||||
[&](auto implicit_param_id) {
|
||||
return SemIR::IsSelfPattern(
|
||||
context.sem_ir(), implicit_param_id);
|
||||
});
|
||||
i != implicit_param_patterns.end()) {
|
||||
return *i;
|
||||
}
|
||||
return SemIR::InstId::None;
|
||||
return FindIfOrNone(implicit_param_patterns, [&](auto implicit_param_id) {
|
||||
return SemIR::IsSelfPattern(context.sem_ir(), implicit_param_id);
|
||||
});
|
||||
}
|
||||
|
||||
// Diagnoses issues with the modifiers, removing modifiers that shouldn't be
|
||||
|
||||
Reference in New Issue
Block a user