Skip to content

Commit 65f66cb

Browse files
cdlearycopybara-github
authored andcommitted
[DSLX:type_system] Resolve invocation callee using ref/def chain.
This also adds an appropriate check that the callee is a function. Previously we would check that the function existed at module scope but get confounded by the local shadow, causing an ICE. Found via coverage-guided fuzzing. PiperOrigin-RevId: 597961474
1 parent aa74093 commit 65f66cb

File tree

3 files changed

+51
-7
lines changed

3 files changed

+51
-7
lines changed

xls/dslx/frontend/ast.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -850,6 +850,10 @@ class NameRef : public Expr {
850850
return IsBuiltin() ? nullptr
851851
: std::get<const NameDef*>(name_def())->definer();
852852
}
853+
AstNode* GetDefiner() {
854+
const auto* self = this;
855+
return const_cast<AstNode*>(self->GetDefiner());
856+
}
853857

854858
template <typename T>
855859
bool DefinerIs() {

xls/dslx/type_system/deduce.cc

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "xls/dslx/type_system/deduce.h"
1616

1717
#include <algorithm>
18+
#include <cstddef>
1819
#include <cstdint>
1920
#include <functional>
2021
#include <iterator>
@@ -2923,9 +2924,17 @@ static absl::StatusOr<TypeAndParametricEnv> DeduceInstantiation(
29232924
// top.
29242925
XLS_ASSIGN_OR_RETURN(std::unique_ptr<ConcreteType> callee_type,
29252926
ctx->Deduce(invocation->callee()));
2926-
return TypeAndParametricEnv{down_cast<FunctionType*>(callee_type.get())
2927-
->return_type()
2928-
.CloneToUnique(),
2927+
FunctionType* callee_fn_type = dynamic_cast<FunctionType*>(callee_type.get());
2928+
2929+
// Callee must be a function.
2930+
if (callee_fn_type == nullptr) {
2931+
return TypeInferenceErrorStatus(
2932+
invocation->callee()->span(), callee_type.get(),
2933+
absl::StrFormat("Invocation callee `%s` is not a function",
2934+
invocation->callee()->ToString()));
2935+
}
2936+
2937+
return TypeAndParametricEnv{callee_fn_type->return_type().CloneToUnique(),
29292938
{}};
29302939
}
29312940

@@ -3121,17 +3130,22 @@ absl::StatusOr<std::unique_ptr<ConcreteType>> DeduceInvocation(
31213130
auto resolve_fn = [](const Instantiation* node,
31223131
DeduceCtx* ctx) -> absl::StatusOr<Function*> {
31233132
Expr* callee = node->callee();
3133+
31243134
Function* fn;
31253135
if (auto* colon_ref = dynamic_cast<ColonRef*>(callee);
31263136
colon_ref != nullptr) {
31273137
XLS_ASSIGN_OR_RETURN(fn,
31283138
ResolveColonRefToFnForInvocation(colon_ref, ctx));
31293139
} else if (auto* name_ref = dynamic_cast<NameRef*>(callee);
31303140
name_ref != nullptr) {
3131-
const std::string& callee_name = name_ref->identifier();
3132-
XLS_ASSIGN_OR_RETURN(fn,
3133-
GetMemberOrTypeInferenceError<Function>(
3134-
ctx->module(), callee_name, name_ref->span()));
3141+
AstNode* definer = name_ref->GetDefiner();
3142+
fn = dynamic_cast<Function*>(definer);
3143+
if (fn == nullptr) {
3144+
return TypeInferenceErrorStatus(
3145+
node->callee()->span(), nullptr,
3146+
absl::StrFormat("Invocation callee `%s` is not a function",
3147+
node->callee()->ToString()));
3148+
}
31353149
} else {
31363150
return TypeInferenceErrorStatus(
31373151
node->span(), nullptr,

xls/dslx/type_system/typecheck_test.cc

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2214,5 +2214,31 @@ fn f() { fail!%2 }
22142214
"it is not being invoked")));
22152215
}
22162216

2217+
TEST(TypecheckErrorTest, InvokeATokenValueViaShadowing) {
2218+
EXPECT_THAT(
2219+
Typecheck(R"(
2220+
fn shadowed() {}
2221+
2222+
fn f(shadowed: token) {
2223+
shadowed()
2224+
}
2225+
)")
2226+
.status(),
2227+
IsPosError("TypeInferenceError",
2228+
HasSubstr("Invocation callee `shadowed` is not a function")));
2229+
}
2230+
2231+
TEST(TypecheckErrorTest, InvokeATokenValueNoShadowing) {
2232+
EXPECT_THAT(
2233+
Typecheck(R"(
2234+
fn f(tok: token) {
2235+
tok()
2236+
}
2237+
)")
2238+
.status(),
2239+
IsPosError("TypeInferenceError",
2240+
HasSubstr("Invocation callee `tok` is not a function")));
2241+
}
2242+
22172243
} // namespace
22182244
} // namespace xls::dslx

0 commit comments

Comments
 (0)