Use explicit(false) for implicit construction (#6039)

Echoing what was added in #5608, updating existing uses. Unfortunately
there's divergent behavior for operators versus constructors, so keeping
the nolint on those.
This commit is contained in:
Jon Ross-Perkins
2025-09-10 13:47:59 +00:00
committed by GitHub
parent b74fdf52de
commit 3f799bd987
20 changed files with 75 additions and 103 deletions
+1 -1
View File
@@ -122,7 +122,7 @@ class EnumBase : public Printable<DerivedT> {
// function.
//
// NOLINTNEXTLINE(google-explicit-constructor)
constexpr operator RawEnumType() const { return value_; }
explicit(false) constexpr operator RawEnumType() const { return value_; }
// Conversion to bool is deleted to prevent direct use in an `if` condition
// instead of comparing with another value.
+7 -12
View File
@@ -104,8 +104,7 @@ class [[nodiscard]] ErrorOr {
// Constructs with an error; the error must not be Error::Success().
// Implicit for easy construction on returns.
// NOLINTNEXTLINE(google-explicit-constructor)
ErrorOr(ErrorT err) : val_(std::move(err)) {}
explicit(false) ErrorOr(ErrorT err) : val_(std::move(err)) {}
// Constructs from a custom error type derived from `ErrorBase` into an
// `ErrorOr` for `Error` to facilitate returning errors transparently.
@@ -113,8 +112,7 @@ class [[nodiscard]] ErrorOr {
requires(std::same_as<ErrorT, Error> &&
std::derived_from<OtherErrorT, ErrorBase<OtherErrorT>>)
// Implicit for easy construction on returns.
// NOLINTNEXTLINE(google-explicit-constructor)
ErrorOr(OtherErrorT other_err) : val_(other_err.ToError()) {}
explicit(false) ErrorOr(OtherErrorT other_err) : val_(other_err.ToError()) {}
// Constructs with any convertible error type, necessary for return statements
// that are already converting to the `ErrorOr` wrapper.
@@ -126,21 +124,18 @@ class [[nodiscard]] ErrorOr {
requires(std::constructible_from<ErrorT, OtherErrorT> &&
std::derived_from<OtherErrorT, ErrorBase<OtherErrorT>>)
// Implicit for easy construction on returns.
// NOLINTNEXTLINE(google-explicit-constructor)
ErrorOr(OtherErrorT other_err)
explicit(false) ErrorOr(OtherErrorT other_err)
: val_(std::in_place_type<ErrorT>, std::move(other_err)) {}
// Constructs with a reference.
// Implicit for easy construction on returns.
// NOLINTNEXTLINE(google-explicit-constructor)
ErrorOr(T ref)
explicit(false) ErrorOr(T ref)
requires std::is_reference_v<T>
: val_(std::ref(ref)) {}
// Constructs with a value.
// Implicit for easy construction on returns.
// NOLINTNEXTLINE(google-explicit-constructor)
ErrorOr(T val)
explicit(false) ErrorOr(T val)
requires(!std::is_reference_v<T>)
: val_(std::move(val)) {}
@@ -224,11 +219,11 @@ class ErrorBuilder {
}
// NOLINTNEXTLINE(google-explicit-constructor): Implicit cast for returns.
operator Error() { return Error(out_->TakeStr()); }
explicit(false) operator Error() { return Error(out_->TakeStr()); }
template <typename T>
// NOLINTNEXTLINE(google-explicit-constructor): Implicit cast for returns.
operator ErrorOr<T>() {
explicit(false) operator ErrorOr<T>() {
return Error(out_->TakeStr());
}
+1
View File
@@ -95,6 +95,7 @@ class IsSuccessMatcher {
: matcher_(std::move(matcher)) {}
template <typename T, typename ErrorT>
explicit(false)
// NOLINTNEXTLINE(google-explicit-constructor): Required for matcher APIs.
operator ::testing::Matcher<const ErrorOr<T, ErrorT>&>() const {
return ::testing::Matcher<const ErrorOr<T, ErrorT>&>(
+5 -6
View File
@@ -89,8 +89,8 @@ class MapView
// type. This is always safe to do with a view. We use a template to avoid
// needing all 3 versions.
template <typename OtherKeyT, typename OtherValueT>
// NOLINTNEXTLINE(google-explicit-constructor)
MapView(MapView<OtherKeyT, OtherValueT, KeyContextT> other_view)
explicit(false)
MapView(MapView<OtherKeyT, OtherValueT, KeyContextT> other_view)
requires(SameAsOneOf<KeyT, OtherKeyT, const OtherKeyT> &&
SameAsOneOf<ValueT, OtherValueT, const OtherValueT>)
: ImplT(other_view) {}
@@ -134,8 +134,7 @@ class MapView
friend class MapView<const KeyT, const ValueT, KeyContextT>;
MapView() = default;
// NOLINTNEXTLINE(google-explicit-constructor): Implicit by design.
MapView(ImplT base) : ImplT(base) {}
explicit(false) MapView(ImplT base) : ImplT(base) {}
MapView(ssize_t size, RawHashtable::Storage* storage)
: ImplT(size, storage) {}
};
@@ -185,13 +184,13 @@ class MapBase : protected RawHashtable::BaseImpl<InputKeyT, InputValueT,
// Implicitly convertible to the relevant view type.
//
// NOLINTNEXTLINE(google-explicit-constructor): Designed to implicitly decay.
operator ViewT() const { return this->view_impl(); }
explicit(false) operator ViewT() const { return this->view_impl(); }
// We can't chain the above conversion with the conversions on `ViewT` to add
// const, so explicitly support adding const to produce a view here.
template <typename OtherKeyT, typename OtherValueT>
// NOLINTNEXTLINE(google-explicit-constructor)
operator MapView<OtherKeyT, OtherValueT, KeyContextT>() const
explicit(false) operator MapView<OtherKeyT, OtherValueT, KeyContextT>() const
requires(SameAsOneOf<OtherKeyT, KeyT, const KeyT> &&
SameAsOneOf<OtherValueT, ValueT, const ValueT>)
{
+3 -3
View File
@@ -373,8 +373,8 @@ class ViewImpl {
// Support adding `const` to either key or value type of some other view.
template <typename OtherKeyT, typename OtherValueT>
// NOLINTNEXTLINE(google-explicit-constructor)
ViewImpl(ViewImpl<OtherKeyT, OtherValueT, KeyContextT> other_view)
explicit(false)
ViewImpl(ViewImpl<OtherKeyT, OtherValueT, KeyContextT> other_view)
requires(SameAsOneOf<KeyT, OtherKeyT, const OtherKeyT> &&
SameAsOneOf<ValueT, OtherValueT, const OtherValueT>)
: alloc_size_(other_view.alloc_size_), storage_(other_view.storage_) {}
@@ -493,7 +493,7 @@ class BaseImpl {
~BaseImpl() = default;
// NOLINTNEXTLINE(google-explicit-constructor): Designed to implicitly decay.
operator ViewImplT() const { return view_impl(); }
explicit(false) operator ViewImplT() const { return view_impl(); }
auto view_impl() const -> ViewImplT { return view_impl_; }
+7 -6
View File
@@ -78,8 +78,8 @@ class SetView : RawHashtable::ViewImpl<InputKeyT, void, InputKeyContextT> {
};
// Enable implicit conversions that add `const`-ness to the key type.
// NOLINTNEXTLINE(google-explicit-constructor)
SetView(const SetView<std::remove_const_t<KeyT>, KeyContextT>& other_view)
explicit(false)
SetView(const SetView<std::remove_const_t<KeyT>, KeyContextT>& other_view)
requires(!std::same_as<KeyT, std::remove_const_t<KeyT>>)
: ImplT(other_view) {}
@@ -115,8 +115,7 @@ class SetView : RawHashtable::ViewImpl<InputKeyT, void, InputKeyContextT> {
using EntryT = typename ImplT::EntryT;
SetView() = default;
// NOLINTNEXTLINE(google-explicit-constructor): Implicit by design.
SetView(ImplT base) : ImplT(base) {}
explicit(false) SetView(ImplT base) : ImplT(base) {}
SetView(ssize_t size, RawHashtable::Storage* storage)
: ImplT(size, storage) {}
};
@@ -161,13 +160,15 @@ class SetBase
// Implicitly convertible to the relevant view type.
//
// NOLINTNEXTLINE(google-explicit-constructor): Designed to implicitly decay.
operator ViewT() const { return this->view_impl(); }
explicit(false) operator ViewT() const { return this->view_impl(); }
// We can't chain the above conversion with the conversions on `ViewT` to add
// const, so explicitly support adding const to produce a view here.
//
// NOLINTNEXTLINE(google-explicit-constructor): Designed to implicitly decay.
operator SetView<const KeyT, KeyContextT>() const { return ViewT(*this); }
explicit(false) operator SetView<const KeyT, KeyContextT>() const {
return ViewT(*this);
}
// Convenience forwarder to the view type.
template <typename LookupKeyT>
+2 -2
View File
@@ -37,11 +37,11 @@ template <typename T>
struct AnyField {
template <typename FieldT>
// NOLINTNEXTLINE(google-explicit-constructor)
operator FieldT&() const;
explicit(false) operator FieldT&() const;
template <typename FieldT>
// NOLINTNEXTLINE(google-explicit-constructor)
operator FieldT&&() const;
explicit(false) operator FieldT&&() const;
// Don't allow conversion to T itself. This ensures we don't match against a
// copy or move constructor.
+5 -6
View File
@@ -43,11 +43,10 @@ struct TemplateString {
// `enable_if` attribute to require the array to be usable as a C string with
// the expected length. This checks both for null-termination and no embedded
// `0` bytes.
//
// NOLINTNEXTLINE(google-explicit-constructor)
constexpr TemplateString(const char (&str)[N + 1]) __attribute__((
enable_if(__builtin_strlen(str) == N,
"character array is not null-terminated valid C string"))) {
explicit(false) constexpr TemplateString(const char (&str)[N + 1])
__attribute__((
enable_if(__builtin_strlen(str) == N,
"character array is not null-terminated valid C string"))) {
// Rely on Clang's constexpr `__builtin_memcpy` to minimize compile time
// overhead copying the string contents around.
__builtin_memcpy(storage_, str, N + 1);
@@ -57,7 +56,7 @@ struct TemplateString {
// storage necessary to be used as a template parameter.
//
// NOLINTNEXTLINE(google-explicit-constructor)
constexpr operator llvm::StringRef() const {
explicit(false) constexpr operator llvm::StringRef() const {
return llvm::StringRef(storage_, N);
}
+2 -2
View File
@@ -35,8 +35,8 @@ constexpr auto IsValidTemplateString(int /*unused*/) -> std::true_type {
struct AnythingAsTemplateArg {
// An implicit constructor that can accept any argument and discards it.
template <typename T>
// NOLINTNEXTLINE(google-explicit-constructor,bugprone-forwarding-reference-overload)
constexpr AnythingAsTemplateArg(T&& /*unused*/) {}
// NOLINTNEXTLINE(bugprone-forwarding-reference-overload)
explicit(false) constexpr AnythingAsTemplateArg(T&& /*unused*/) {}
};
// An overload that will be active for any template argument. Returns a false
+1 -1
View File
@@ -71,7 +71,7 @@ class TypeEnum : public Printable<TypeEnum<Types...>> {
// Implicitly convert to the raw enum type, for use in `switch`.
//
// NOLINTNEXTLINE(google-explicit-constructor)
constexpr operator RawEnumType() const { return value_; }
explicit(false) constexpr operator RawEnumType() const { return value_; }
// Conversion to bool is deleted to prevent direct use in an `if` condition
// instead of comparing with another value.
+7 -12
View File
@@ -28,8 +28,7 @@ class LocIdForDiagnostics {
template <typename LocT>
requires std::constructible_from<SemIR::LocId, LocT>
// NOLINTNEXTLINE(google-explicit-constructor)
LocIdForDiagnostics(LocT loc_id)
explicit(false) LocIdForDiagnostics(LocT loc_id)
: LocIdForDiagnostics(SemIR::LocId(loc_id), false) {}
auto loc_id() const -> SemIR::LocId { return loc_id_; }
@@ -60,8 +59,7 @@ using MakeDiagnosticBuilderFn = llvm::function_ref<auto()->DiagnosticBuilder>;
struct InstIdAsConstant {
using DiagnosticType = Diagnostics::TypeInfo<std::string>;
// NOLINTNEXTLINE(google-explicit-constructor)
InstIdAsConstant(SemIR::InstId inst_id) : inst_id(inst_id) {}
explicit(false) InstIdAsConstant(SemIR::InstId inst_id) : inst_id(inst_id) {}
SemIR::InstId inst_id;
};
@@ -80,8 +78,7 @@ struct InstIdAsConstant {
struct TypeOfInstId {
using DiagnosticType = Diagnostics::TypeInfo<std::string>;
// NOLINTNEXTLINE(google-explicit-constructor)
TypeOfInstId(SemIR::InstId inst_id) : inst_id(inst_id) {}
explicit(false) TypeOfInstId(SemIR::InstId inst_id) : inst_id(inst_id) {}
SemIR::InstId inst_id;
};
@@ -112,8 +109,7 @@ using InstIdAsType = InstIdAsConstant;
struct InstIdAsRawType {
using DiagnosticType = Diagnostics::TypeInfo<std::string>;
// NOLINTNEXTLINE(google-explicit-constructor)
InstIdAsRawType(SemIR::InstId inst_id) : inst_id(inst_id) {}
explicit(false) InstIdAsRawType(SemIR::InstId inst_id) : inst_id(inst_id) {}
SemIR::InstId inst_id;
};
@@ -127,8 +123,7 @@ struct InstIdAsRawType {
struct TypeIdAsRawType {
using DiagnosticType = Diagnostics::TypeInfo<std::string>;
// NOLINTNEXTLINE(google-explicit-constructor)
TypeIdAsRawType(SemIR::TypeId type_id) : type_id(type_id) {}
explicit(false) TypeIdAsRawType(SemIR::TypeId type_id) : type_id(type_id) {}
SemIR::TypeId type_id;
};
@@ -145,8 +140,8 @@ struct TypedInt {
struct SpecificInterfaceIdAsRawType {
using DiagnosticType = Diagnostics::TypeInfo<std::string>;
// NOLINTNEXTLINE(google-explicit-constructor)
SpecificInterfaceIdAsRawType(SemIR::SpecificInterfaceId specific_interface_id)
explicit(false) SpecificInterfaceIdAsRawType(
SemIR::SpecificInterfaceId specific_interface_id)
: specific_interface_id(specific_interface_id) {}
SemIR::SpecificInterfaceId specific_interface_id;
+1 -2
View File
@@ -65,8 +65,7 @@ class KeywordModifierSet {
// Support implicit conversion so that the difference with the member enum is
// opaque.
// NOLINTNEXTLINE(google-explicit-constructor)
constexpr KeywordModifierSet(RawEnumType set) : set_(set) {}
explicit(false) constexpr KeywordModifierSet(RawEnumType set) : set_(set) {}
// Adds entries to the set.
auto Add(KeywordModifierSet set) -> void { set_ |= set.set_; }
+2 -4
View File
@@ -18,8 +18,7 @@ namespace Carbon::Diagnostics {
// `|`, with the true case first. the example would yield standard bool
// formatting.
struct BoolAsSelect {
// NOLINTNEXTLINE(google-explicit-constructor)
BoolAsSelect(bool value) : value(value) {}
explicit(false) BoolAsSelect(bool value) : value(value) {}
bool value;
};
@@ -47,8 +46,7 @@ struct BoolAsSelect {
//
// As another example, `{0:=1:is|:are}` is a way to handle plural-based output.
struct IntAsSelect {
// NOLINTNEXTLINE(google-explicit-constructor)
IntAsSelect(int value) : value(value) {}
explicit(false) IntAsSelect(int value) : value(value) {}
int value;
};
+2 -2
View File
@@ -66,8 +66,8 @@ class [[clang::internal_linkage]] Lexer {
public:
// Consumes (and discard) a valid token to construct a result
// indicating a token has been produced. Relies on implicit conversions.
// NOLINTNEXTLINE(google-explicit-constructor)
LexResult(TokenIndex /*discarded_token*/) : LexResult(true) {}
explicit(false) LexResult(TokenIndex /*discarded_token*/)
: LexResult(true) {}
// Returns a result indicating no token was produced.
static auto NoMatch() -> LexResult { return LexResult(false); }
+1 -2
View File
@@ -64,8 +64,7 @@ class NodeCategory : public Printable<NodeCategory> {
// Support implicit conversion so that the difference with the member enum is
// opaque.
// NOLINTNEXTLINE(google-explicit-constructor)
constexpr NodeCategory(RawEnumType value) : value_(value) {}
explicit(false) constexpr NodeCategory(RawEnumType value) : value_(value) {}
// Returns true if there's a non-empty set intersection.
constexpr auto HasAnyOf(NodeCategory other) const -> bool {
+13 -16
View File
@@ -36,8 +36,7 @@ struct NodeId : public IdBase<NodeId> {
CARBON_DCHECK(index < Max, "Index out of range: {0}", index);
}
// NOLINTNEXTLINE(google-explicit-constructor)
constexpr NodeId(NoneNodeId /*none*/) : IdBase(NoneIndex) {}
explicit(false) constexpr NodeId(NoneNodeId /*none*/) : IdBase(NoneIndex) {}
};
// For looking up the type associated with a given id type.
@@ -57,8 +56,8 @@ struct NodeIdForKind : public NodeId {
return NodeIdForKind(node_id);
}
// NOLINTNEXTLINE(google-explicit-constructor)
constexpr NodeIdForKind(NoneNodeId /*none*/) : NodeId(NoneIndex) {}
explicit(false) constexpr NodeIdForKind(NoneNodeId /*none*/)
: NodeId(NoneIndex) {}
private:
// Private to prevent accidental explicit construction from an untyped
@@ -84,13 +83,13 @@ struct NodeIdInCategory : public NodeId {
// Support conversion from `NodeIdForKind<Kind>` if Kind's category
// overlaps with `Category`.
template <const NodeKind& Kind>
// NOLINTNEXTLINE(google-explicit-constructor)
NodeIdInCategory(NodeIdForKind<Kind> node_id) : NodeId(node_id) {
explicit(false) NodeIdInCategory(NodeIdForKind<Kind> node_id)
: NodeId(node_id) {
CARBON_CHECK(Kind.category().HasAnyOf(Category));
}
// NOLINTNEXTLINE(google-explicit-constructor)
constexpr NodeIdInCategory(NoneNodeId /*none*/) : NodeId(NoneIndex) {}
explicit(false) constexpr NodeIdInCategory(NoneNodeId /*none*/)
: NodeId(NoneIndex) {}
private:
// Private to prevent accidental explicit construction from an untyped
@@ -142,16 +141,14 @@ struct NodeIdOneOf : public NodeId {
template <const NodeKind& Kind>
requires(Contains<NodeIdForKind<Kind>>)
// NOLINTNEXTLINE(google-explicit-constructor)
NodeIdOneOf(NodeIdForKind<Kind> node_id) : NodeId(node_id) {}
explicit(false) NodeIdOneOf(NodeIdForKind<Kind> node_id) : NodeId(node_id) {}
template <typename OtherNodeIdOneOf>
requires(IsSubset<OtherNodeIdOneOf>)
// NOLINTNEXTLINE(google-explicit-constructor)
NodeIdOneOf(OtherNodeIdOneOf node_id) : NodeId(node_id) {}
explicit(false) NodeIdOneOf(OtherNodeIdOneOf node_id) : NodeId(node_id) {}
// NOLINTNEXTLINE(google-explicit-constructor)
constexpr NodeIdOneOf(NoneNodeId /*none*/) : NodeId(NoneIndex) {}
explicit(false) constexpr NodeIdOneOf(NoneNodeId /*none*/)
: NodeId(NoneIndex) {}
};
using AnyClassDeclId =
@@ -179,8 +176,8 @@ using AnyRuntimeBindingPatternName =
template <typename T>
struct NodeIdNot : public NodeId {
constexpr explicit NodeIdNot(NodeId node_id) : NodeId(node_id) {}
// NOLINTNEXTLINE(google-explicit-constructor)
constexpr NodeIdNot(NoneNodeId /*none*/) : NodeId(NoneIndex) {}
explicit(false) constexpr NodeIdNot(NoneNodeId /*none*/)
: NodeId(NoneIndex) {}
};
// Note that the support for extracting these types using the `Tree::Extract*`
+1 -2
View File
@@ -131,8 +131,7 @@ class PrecedenceGroup {
// We rely on implicit conversions via `int8_t` for enumerators defined in the
// implementation.
// NOLINTNEXTLINE(google-explicit-constructor)
PrecedenceGroup(int8_t level) : level_(level) {}
explicit(false) PrecedenceGroup(int8_t level) : level_(level) {}
// The precedence level.
int8_t level_;
+12 -20
View File
@@ -100,8 +100,7 @@ class AbsoluteInstId : public InstId {
// Support implicit conversion from InstId so that InstId and AbsoluteInstId
// have the same interface.
// NOLINTNEXTLINE(google-explicit-constructor)
constexpr AbsoluteInstId(InstId inst_id) : InstId(inst_id) {}
explicit(false) constexpr AbsoluteInstId(InstId inst_id) : InstId(inst_id) {}
using InstId::InstId;
};
@@ -124,8 +123,7 @@ class DestInstId : public InstId {
// Support implicit conversion from InstId so that InstId and DestInstId
// have the same interface.
// NOLINTNEXTLINE(google-explicit-constructor)
constexpr DestInstId(InstId inst_id) : InstId(inst_id) {}
explicit(false) constexpr DestInstId(InstId inst_id) : InstId(inst_id) {}
using InstId::InstId;
};
@@ -149,8 +147,7 @@ class MetaInstId : public InstId {
// Support implicit conversion from InstId so that InstId and MetaInstId
// have the same interface.
// NOLINTNEXTLINE(google-explicit-constructor)
constexpr MetaInstId(InstId inst_id) : InstId(inst_id) {}
explicit(false) constexpr MetaInstId(InstId inst_id) : InstId(inst_id) {}
using InstId::InstId;
};
@@ -698,8 +695,7 @@ constexpr InstBlockId InstBlockId::Unreachable = InstBlockId(NoneIndex - 1);
// `InstBlockId` (unlike for the singleton error `InstId`).
class InstBlockIdOrError {
public:
// NOLINTNEXTLINE(google-explicit-constructor)
InstBlockIdOrError(InstBlockId inst_block_id)
explicit(false) InstBlockIdOrError(InstBlockId inst_block_id)
: InstBlockIdOrError(inst_block_id, false) {}
static auto MakeError() -> InstBlockIdOrError {
@@ -743,8 +739,7 @@ class AbsoluteInstBlockId : public InstBlockId {
public:
// Support implicit conversion from InstBlockId so that InstBlockId and
// AbsoluteInstBlockId have the same interface.
// NOLINTNEXTLINE(google-explicit-constructor)
constexpr AbsoluteInstBlockId(InstBlockId inst_block_id)
explicit(false) constexpr AbsoluteInstBlockId(InstBlockId inst_block_id)
: InstBlockId(inst_block_id) {}
using InstBlockId::InstBlockId;
@@ -759,8 +754,7 @@ class DeclInstBlockId : public InstBlockId {
public:
// Support implicit conversion from InstBlockId so that InstBlockId and
// DeclInstBlockId have the same interface.
// NOLINTNEXTLINE(google-explicit-constructor)
constexpr DeclInstBlockId(InstBlockId inst_block_id)
explicit(false) constexpr DeclInstBlockId(InstBlockId inst_block_id)
: InstBlockId(inst_block_id) {}
using InstBlockId::InstBlockId;
@@ -774,8 +768,8 @@ class LabelId : public InstBlockId {
public:
// Support implicit conversion from InstBlockId so that InstBlockId and
// LabelId have the same interface.
// NOLINTNEXTLINE(google-explicit-constructor)
constexpr LabelId(InstBlockId inst_block_id) : InstBlockId(inst_block_id) {}
explicit(false) constexpr LabelId(InstBlockId inst_block_id)
: InstBlockId(inst_block_id) {}
using InstBlockId::InstBlockId;
};
@@ -936,19 +930,17 @@ struct LocId : public IdBase<LocId> {
using IdBase::IdBase;
// NOLINTNEXTLINE(google-explicit-constructor)
constexpr LocId(ImportIRInstId import_ir_inst_id)
explicit(false) constexpr LocId(ImportIRInstId import_ir_inst_id)
: IdBase(import_ir_inst_id.has_value()
? FirstImportIRInstId - import_ir_inst_id.index
: NoneIndex) {}
explicit constexpr LocId(InstId inst_id) : IdBase(inst_id.index) {}
// NOLINTNEXTLINE(google-explicit-constructor)
constexpr LocId(Parse::NoneNodeId /*none*/) : IdBase(NoneIndex) {}
explicit(false) constexpr LocId(Parse::NoneNodeId /*none*/)
: IdBase(NoneIndex) {}
// NOLINTNEXTLINE(google-explicit-constructor)
constexpr LocId(Parse::NodeId node_id)
explicit(false) constexpr LocId(Parse::NodeId node_id)
: IdBase(FirstNodeId - node_id.index) {}
// Forms an equivalent LocId for a desugared location. Prefer calling
+1 -2
View File
@@ -229,8 +229,7 @@ class Inst : public Printable<Inst> {
template <typename TypedInst>
requires Internal::InstLikeType<TypedInst>
// NOLINTNEXTLINE(google-explicit-constructor)
Inst(TypedInst typed_inst)
explicit(false) Inst(TypedInst typed_inst)
// kind_ is always overwritten below.
: kind_(),
type_id_(TypeId::None),
+1 -2
View File
@@ -210,8 +210,7 @@ class TypeIterator::Step {
// explicitly first).
template <typename T>
requires std::constructible_from<Any, T>
// NOLINTNEXTLINE(google-explicit-constructor)
Step(T any) : any(any) {}
explicit(false) Step(T any) : any(any) {}
Any any;
};