Skip to content

Commit c44e412

Browse files
Merge pull request #3756 from antmicro:proc_config_final_expr
PiperOrigin-RevId: 863236593
2 parents 76fb633 + e445448 commit c44e412

File tree

3 files changed

+149
-16
lines changed

3 files changed

+149
-16
lines changed

xls/dslx/frontend/parser.cc

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3121,16 +3121,6 @@ absl::StatusOr<Function*> Parser::ParseProcConfig(
31213121
// Implicitly nil tuple as a result.
31223122
} else {
31233123
Expr* final_expr = std::get<Expr*>(block->statements().back()->wrapped());
3124-
3125-
if (dynamic_cast<XlsTuple*>(final_expr) == nullptr) {
3126-
Span final_stmt_span =
3127-
ToAstNode(block->statements().back()->wrapped())->GetSpan().value();
3128-
return ParseErrorStatus(
3129-
final_stmt_span,
3130-
"The final expression in a Proc config must be a tuple with one "
3131-
"element for each Proc data member.");
3132-
}
3133-
31343124
VLOG(5) << "ParseProcConfig; final expr: `" << final_expr->ToString()
31353125
<< "`";
31363126
}

xls/dslx/type_system/proc_typecheck_test.cc

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -116,12 +116,10 @@ proc entry {
116116
next (state: ()) { () }
117117
}
118118
)";
119-
EXPECT_THAT(TypecheckV2(kProgram),
120-
absl_testing::StatusIs(
121-
absl::StatusCode::kInvalidArgument,
122-
testing::HasSubstr(
123-
"final expression in a Proc config must be a tuple with "
124-
"one element for each Proc data member")));
119+
EXPECT_THAT(
120+
TypecheckV2(kProgram),
121+
absl_testing::StatusIs(absl::StatusCode::kInvalidArgument,
122+
HasTypeMismatch("(chan<u32> in,)", "u32")));
125123
}
126124

127125
TEST(TypecheckTest, RecvIfDefaultValueWrongType) {

xls/dslx/type_system_v2/typecheck_module_v2_test.cc

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7416,6 +7416,151 @@ proc Proc {
74167416
HasNodeWithType("b", "chan(sN[32], dir=in)[2]"))));
74177417
}
74187418

7419+
TEST(TypecheckV2Test, ProcConfigRequireTuple) {
7420+
EXPECT_THAT(
7421+
R"(
7422+
proc Proc {
7423+
input: chan<()> in;
7424+
config(input: chan<()> in) {
7425+
(input)
7426+
}
7427+
init { () }
7428+
next(state: ()) { () }
7429+
}
7430+
7431+
)",
7432+
TypecheckFails(HasTypeMismatch("(chan<()> in,)", "chan<()> in")));
7433+
}
7434+
7435+
TEST(TypecheckV2Test, ProcConfigTooFewChannels) {
7436+
EXPECT_THAT(
7437+
R"(
7438+
proc Proc {
7439+
input: chan<()> in;
7440+
output: chan<()> out;
7441+
config(input: chan<()> in) {
7442+
(input,)
7443+
}
7444+
init { () }
7445+
next(state: ()) { () }
7446+
}
7447+
7448+
)",
7449+
TypecheckFails(HasSubstr("Cannot match a 2-element tuple to 1 values.")));
7450+
}
7451+
7452+
TEST(TypecheckV2Test, ProcConfigTooManyChannels) {
7453+
EXPECT_THAT(
7454+
R"(
7455+
proc Proc {
7456+
req: chan<()> in;
7457+
resp: chan<()> out;
7458+
config(data_in: chan<()> in) {
7459+
let (resp, req) = chan<()>("io");
7460+
(req, resp, data_in)
7461+
}
7462+
init { () }
7463+
next(state: ()) { () }
7464+
}
7465+
7466+
)",
7467+
TypecheckFails(HasSubstr("Out-of-bounds tuple index specified: 2")));
7468+
}
7469+
7470+
TEST(TypecheckV2Test, ProcConfigMismatchingChannelTypes) {
7471+
EXPECT_THAT(
7472+
R"(
7473+
proc Proc {
7474+
req: chan<()> in;
7475+
resp: chan<()> out;
7476+
data_in: chan<u32> in;
7477+
data_out: chan<u32> out;
7478+
config(data_in: chan<u32> in, data_out: chan<u32> out) {
7479+
let (resp, req) = chan<()>("io");
7480+
(data_in, data_out, req, resp)
7481+
}
7482+
init { () }
7483+
next(state: ()) { () }
7484+
}
7485+
7486+
)",
7487+
TypecheckFails(HasTypeMismatch("()", "u32")));
7488+
}
7489+
7490+
TEST(TypecheckV2Test, ProcWithBranchedFinalExpression) {
7491+
EXPECT_THAT(
7492+
R"(
7493+
const A = u32:5;
7494+
proc Proc {
7495+
input: chan<()> in;
7496+
output: chan<()> out;
7497+
config() {
7498+
const if A == u32:1 {
7499+
let (first_output, first_input) = chan<()>("first");
7500+
(first_input, first_output)
7501+
} else {
7502+
let (second_output, second_input) = chan<()>("second");
7503+
(second_input, second_output)
7504+
}
7505+
}
7506+
init { () }
7507+
next(state: ()) { () }
7508+
}
7509+
7510+
)",
7511+
TypecheckSucceeds(
7512+
AllOf(HasNodeWithType("second_input", "chan((), dir=in)"),
7513+
HasNodeWithType("second_output", "chan((), dir=out)"))));
7514+
}
7515+
7516+
TEST(TypecheckV2Test, ProcConfigBranchedChannelTypeMismatch) {
7517+
EXPECT_THAT(
7518+
R"(
7519+
const A = u32:4;
7520+
proc Proc {
7521+
input: chan<u32> in;
7522+
output: chan<u32> out;
7523+
config() {
7524+
const if A == u32:5 {
7525+
let (first_output, first_input) = chan<u32>("first");
7526+
(first_input, first_output)
7527+
} else {
7528+
let (second_output, second_input) = chan<()>("second");
7529+
(second_input, second_output)
7530+
}
7531+
}
7532+
init { () }
7533+
next(state: ()) { () }
7534+
}
7535+
7536+
)",
7537+
TypecheckFails(HasTypeMismatch("()", "u32")));
7538+
}
7539+
7540+
TEST(TypecheckV2Test, ProcConfigFailedBranchedFinalExpression) {
7541+
EXPECT_THAT(
7542+
R"(
7543+
const A = u32:5;
7544+
proc Proc {
7545+
input: chan<()> in;
7546+
output: chan<()> out;
7547+
config() {
7548+
const if A == u32:5 {
7549+
let (first_output, first_input) = chan<()>("first");
7550+
(first_input,)
7551+
} else {
7552+
let (second_output, second_input) = chan<()>("second");
7553+
(second_input, second_output)
7554+
}
7555+
}
7556+
init { () }
7557+
next(state: ()) { () }
7558+
}
7559+
7560+
)",
7561+
TypecheckFails(HasSubstr("Cannot match a 2-element tuple to 1 values.")));
7562+
}
7563+
74197564
TEST(TypecheckV2Test, ImportParametricFunctionWithDefaultExpression) {
74207565
constexpr std::string_view kImported = R"(
74217566
pub fn some_function<N: u32, M: u32 = {N + 1}>() -> uN[M] { uN[M]:0 }

0 commit comments

Comments
 (0)