mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 22:02:23 +01:00
Also document why these are expected on `CARBON_KIND`. In
`kind_switch_test.cpp`, drop the `str` variable.
My recollection of the original discussion of `CARBON_KIND` is that it
should always have braces due to the risk of confusion for statement
interpretation, similar to a typical `if`/`else` but more subtle due to
the macro.
For example:
```
case CARBON_KIND(int n):
str << "int = " << n;
return str.TakeStr();
```
is equivalent to:
```
case CARBON_KIND(int n): {
str << "int = " << n;
}
return str.TakeStr();
```
This happens to work in context because `str` isn't scoped, but a
trivial refactoring to move `RawStringOstream str;` the first statement
of the `case` would probably have non-obvious results. For example:
```
case CARBON_KIND(int n):
RawStringOstream str; // Valid name shadowing, destructed without use.
str << "int = " << n; // Name lookup error on `n`.
return str.TakeStr();
```
55 lines
1.3 KiB
C++
55 lines
1.3 KiB
C++
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
|
// Exceptions. See /LICENSE for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
|
|
#include "toolchain/base/kind_switch.h"
|
|
|
|
#include <gtest/gtest.h>
|
|
|
|
#include <string>
|
|
#include <variant>
|
|
|
|
#include "common/raw_string_ostream.h"
|
|
|
|
namespace Carbon {
|
|
namespace {
|
|
|
|
TEST(KindSwitch, Variant) {
|
|
auto f = [](std::variant<int, float, char> v) -> std::string {
|
|
CARBON_KIND_SWITCH(v) {
|
|
case CARBON_KIND(int n): {
|
|
return llvm::formatv("int = {0}", n);
|
|
}
|
|
case CARBON_KIND(float f): {
|
|
return llvm::formatv("float = {0}", f);
|
|
}
|
|
case CARBON_KIND(char c): {
|
|
return llvm::formatv("char = {0}", c);
|
|
}
|
|
}
|
|
};
|
|
|
|
EXPECT_EQ(f(int{1}), "int = 1");
|
|
EXPECT_EQ(f(float{2}), "float = 2.00");
|
|
EXPECT_EQ(f(char{'h'}), "char = h");
|
|
}
|
|
|
|
TEST(KindSwitch, VariantUnusedValue) {
|
|
auto f = [](std::variant<int, float> v) -> std::string {
|
|
CARBON_KIND_SWITCH(v) {
|
|
case CARBON_KIND(int n): {
|
|
return llvm::formatv("int = {0}", n);
|
|
}
|
|
case CARBON_KIND(float _):
|
|
// The float value is not used, we see that using `_` works.
|
|
return "float";
|
|
}
|
|
};
|
|
|
|
EXPECT_EQ(f(int{1}), "int = 1");
|
|
EXPECT_EQ(f(float{2}), "float");
|
|
}
|
|
|
|
} // namespace
|
|
} // namespace Carbon
|