diff --git a/xls/dslx/type_system/deduce.cc b/xls/dslx/type_system/deduce.cc index 4991498589..2f1f913bcb 100644 --- a/xls/dslx/type_system/deduce.cc +++ b/xls/dslx/type_system/deduce.cc @@ -2079,14 +2079,24 @@ class DeduceVisitor : public AstNodeVisitor { return Fatal(n); } absl::Status HandleFunctionRef(const FunctionRef* n) override { - return Fatal(n); + XLS_ASSIGN_OR_RETURN(std::unique_ptr callee_type, + ctx_->Deduce(n->callee())); + if (!callee_type->IsFunction()) { + return TypeInferenceErrorStatus( + n->span(), callee_type.get(), + "Callee for function reference must be function-typed", + ctx_->file_table()); + } + result_ = std::move(callee_type); + return absl::OkStatus(); } absl::StatusOr>& result() { return result_; } private: absl::Status Fatal(const AstNode* n) { - LOG(FATAL) << "Got unhandled AST node for deduction: " << n->ToString(); + LOG(FATAL) << "DeduceVisitor got unhandled AST node for deduction: " + << n->ToString() << " node type name: " << n->GetNodeTypeName(); } DeduceCtx* ctx_; diff --git a/xls/dslx/type_system/type.cc b/xls/dslx/type_system/type.cc index c4fecb9e52..7d3daec657 100644 --- a/xls/dslx/type_system/type.cc +++ b/xls/dslx/type_system/type.cc @@ -431,6 +431,10 @@ bool Type::IsTuple() const { return dynamic_cast(this) != nullptr; } +bool Type::IsFunction() const { + return dynamic_cast(this) != nullptr; +} + const EnumType& Type::AsEnum() const { auto* s = dynamic_cast(this); CHECK(s != nullptr) << "Type is not an enum: " << *this; diff --git a/xls/dslx/type_system/type.h b/xls/dslx/type_system/type.h index 79a21473e9..01f183945a 100644 --- a/xls/dslx/type_system/type.h +++ b/xls/dslx/type_system/type.h @@ -398,6 +398,7 @@ class Type { bool IsArray() const; bool IsMeta() const; bool IsTuple() const; + bool IsFunction() const; const StructType& AsStruct() const; const ProcType& AsProc() const; diff --git a/xls/dslx/type_system/typecheck_module_test.cc b/xls/dslx/type_system/typecheck_module_test.cc index 1bef09f3c0..4d5bfa9726 100644 --- a/xls/dslx/type_system/typecheck_module_test.cc +++ b/xls/dslx/type_system/typecheck_module_test.cc @@ -3884,6 +3884,14 @@ proc t { )")); } +TEST(TypecheckErrorTest, InstantiateALiteralNumber) { + constexpr std::string_view kProgram = "fn f(x:u2) { 0<> }"; + EXPECT_THAT(Typecheck(kProgram).status(), + IsPosError("TypeInferenceError", + HasSubstr("Could not infer a type for this number, " + "please annotate a type."))); +} + TEST(TypecheckErrorTest, SignedValueToBuiltinExpectingUNViaParametric) { EXPECT_THAT(Typecheck(R"( fn p() -> u32 {