Skip to content

Commit 2a0514c

Browse files
richmckeevercopybara-github
authored andcommitted
Add an error hook mechanism in TIv2.
This allows external logic to fix type inference errors as they are encountered, to support various use cases, such as: - Translating VAST to DSLX in a type-naive fashion and then using type inference to direct the insertion of casts. - Optimistically stripping unnecessary casts/annotations and then finding out which ones are actually necessary. - Continuing past the first error to find more problems. PiperOrigin-RevId: 811482637
1 parent 5e543c3 commit 2a0514c

19 files changed

+636
-120
lines changed

xls/dslx/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,7 @@ cc_library(
517517
"//xls/dslx/ir_convert:convert_options",
518518
"//xls/dslx/type_system:type_info",
519519
"//xls/dslx/type_system:typecheck_module",
520+
"//xls/dslx/type_system_v2:type_inference_error_handler",
520521
"//xls/dslx/type_system_v2:typecheck_module_v2",
521522
"@com_google_absl//absl/cleanup",
522523
"@com_google_absl//absl/log:check",

xls/dslx/parse_and_typecheck.cc

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include "xls/dslx/ir_convert/convert_options.h"
3939
#include "xls/dslx/type_system/type_info.h"
4040
#include "xls/dslx/type_system/typecheck_module.h"
41+
#include "xls/dslx/type_system_v2/type_inference_error_handler.h"
4142
#include "xls/dslx/type_system_v2/typecheck_module_v2.h"
4243
#include "xls/dslx/warning_collector.h"
4344

@@ -47,7 +48,7 @@ absl::StatusOr<TypecheckedModule> ParseAndTypecheck(
4748
std::string_view text, std::string_view path, std::string_view module_name,
4849
ImportData* import_data, std::vector<CommentData>* comments,
4950
std::optional<TypeInferenceVersion> force_version,
50-
const ConvertOptions& options) {
51+
const ConvertOptions& options, TypeInferenceErrorHandler error_handler) {
5152
XLS_RET_CHECK(import_data != nullptr);
5253

5354
FileTable& file_table = import_data->file_table();
@@ -66,7 +67,8 @@ absl::StatusOr<TypecheckedModule> ParseAndTypecheck(
6667
import_data->file_table(), comments));
6768

6869
XLS_RETURN_IF_ERROR(module->SetConfiguredValues(options.configured_values));
69-
return TypecheckModule(std::move(module), path, import_data, force_version);
70+
return TypecheckModule(std::move(module), path, import_data, force_version,
71+
error_handler);
7072
}
7173

7274
absl::StatusOr<std::unique_ptr<Module>> ParseModule(
@@ -95,8 +97,8 @@ absl::StatusOr<std::unique_ptr<Module>> ParseModuleFromFileAtPath(
9597

9698
absl::StatusOr<TypecheckedModule> TypecheckModule(
9799
std::unique_ptr<Module> module, std::string_view path,
98-
ImportData* import_data,
99-
std::optional<TypeInferenceVersion> force_version) {
100+
ImportData* import_data, std::optional<TypeInferenceVersion> force_version,
101+
TypeInferenceErrorHandler error_handler) {
100102
XLS_RET_CHECK(module.get() != nullptr);
101103
XLS_RET_CHECK(import_data != nullptr);
102104

@@ -115,7 +117,8 @@ absl::StatusOr<TypecheckedModule> TypecheckModule(
115117
using ExtendedTypecheckModuleFn =
116118
absl::StatusOr<std::unique_ptr<ModuleInfo>> (*)(
117119
std::unique_ptr<Module>, std::filesystem::path path, ImportData*,
118-
WarningCollector*, std::unique_ptr<SemanticsAnalysis>);
120+
WarningCollector*, std::unique_ptr<SemanticsAnalysis>,
121+
TypeInferenceErrorHandler);
119122
ExtendedTypecheckModuleFn version_entry_point =
120123
static_cast<ExtendedTypecheckModuleFn>(&TypecheckModule);
121124

@@ -136,7 +139,7 @@ absl::StatusOr<TypecheckedModule> TypecheckModule(
136139
XLS_ASSIGN_OR_RETURN(
137140
std::unique_ptr<ModuleInfo> module_info,
138141
version_entry_point(std::move(module), path, import_data, &warnings,
139-
std::move(semantics_analysis)));
142+
std::move(semantics_analysis), error_handler));
140143

141144
if (version_entry_point == TypecheckModuleV2) {
142145
XLS_RETURN_IF_ERROR(module_info->inference_table_converter()

xls/dslx/parse_and_typecheck.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "xls/dslx/import_data.h"
3131
#include "xls/dslx/ir_convert/convert_options.h"
3232
#include "xls/dslx/type_system/type_info.h"
33+
#include "xls/dslx/type_system_v2/type_inference_error_handler.h"
3334
#include "xls/dslx/warning_collector.h"
3435
#include "xls/dslx/warning_kind.h"
3536

@@ -70,7 +71,8 @@ absl::StatusOr<TypecheckedModule> ParseAndTypecheck(
7071
std::string_view text, std::string_view path, std::string_view module_name,
7172
ImportData* import_data, std::vector<CommentData>* comments = nullptr,
7273
std::optional<TypeInferenceVersion> force_version = std::nullopt,
73-
const ConvertOptions& options = ConvertOptions{});
74+
const ConvertOptions& options = ConvertOptions{},
75+
TypeInferenceErrorHandler error_handler = nullptr);
7476

7577
// Helper that parses and creates a new module from the given "text".
7678
//
@@ -95,7 +97,8 @@ absl::StatusOr<std::unique_ptr<Module>> ParseModuleFromFileAtPath(
9597
absl::StatusOr<TypecheckedModule> TypecheckModule(
9698
std::unique_ptr<Module> module, std::string_view path,
9799
ImportData* import_data,
98-
std::optional<TypeInferenceVersion> force_version = std::nullopt);
100+
std::optional<TypeInferenceVersion> force_version = std::nullopt,
101+
TypeInferenceErrorHandler error_handler = nullptr);
99102

100103
} // namespace xls::dslx
101104

xls/dslx/type_system/BUILD

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,7 @@ cc_library(
378378
"//xls/dslx/frontend:module",
379379
"//xls/dslx/frontend:proc",
380380
"//xls/dslx/frontend:semantics_analysis",
381+
"//xls/dslx/type_system_v2:type_inference_error_handler",
381382
"@com_google_absl//absl/log",
382383
"@com_google_absl//absl/status",
383384
"@com_google_absl//absl/status:statusor",
@@ -399,6 +400,8 @@ cc_library(
399400
"//xls/dslx:import_data",
400401
"//xls/dslx:parse_and_typecheck",
401402
"//xls/dslx:virtualizable_file_system",
403+
"//xls/dslx/ir_convert:convert_options",
404+
"//xls/dslx/type_system_v2:type_inference_error_handler",
402405
"@com_google_absl//absl/status",
403406
"@com_google_absl//absl/status:statusor",
404407
"@com_google_absl//absl/strings",

xls/dslx/type_system/typecheck_module.cc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
#include "xls/dslx/type_system/typecheck_function.h"
5050
#include "xls/dslx/type_system/typecheck_invocation.h"
5151
#include "xls/dslx/type_system/unwrap_meta_type.h"
52+
#include "xls/dslx/type_system_v2/type_inference_error_handler.h"
5253
#include "xls/dslx/warning_collector.h"
5354

5455
namespace xls::dslx {
@@ -401,7 +402,8 @@ absl::Status TypecheckModuleMember(const ModuleMember& member, Module* module,
401402
absl::StatusOr<std::unique_ptr<ModuleInfo>> TypecheckModule(
402403
std::unique_ptr<Module> module, std::filesystem::path path,
403404
ImportData* import_data, WarningCollector* warnings,
404-
std::unique_ptr<SemanticsAnalysis> /*unused*/) {
405+
std::unique_ptr<SemanticsAnalysis> /*unused*/,
406+
TypeInferenceErrorHandler /*unused*/) {
405407
XLS_ASSIGN_OR_RETURN(TypeInfo * type_info,
406408
import_data->type_info_owner().New(module.get()));
407409

xls/dslx/type_system/typecheck_module.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "xls/dslx/frontend/module.h"
2525
#include "xls/dslx/frontend/semantics_analysis.h"
2626
#include "xls/dslx/import_data.h"
27+
#include "xls/dslx/type_system_v2/type_inference_error_handler.h"
2728
#include "xls/dslx/warning_collector.h"
2829

2930
namespace xls::dslx {
@@ -43,7 +44,8 @@ namespace xls::dslx {
4344
absl::StatusOr<std::unique_ptr<ModuleInfo>> TypecheckModule(
4445
std::unique_ptr<Module> module, std::filesystem::path path,
4546
ImportData* import_data, WarningCollector* warnings,
46-
std::unique_ptr<SemanticsAnalysis> /*unused*/ = nullptr);
47+
std::unique_ptr<SemanticsAnalysis> /*unused*/ = nullptr,
48+
TypeInferenceErrorHandler /*unused*/ = nullptr);
4749

4850
// Forward decl for the internal declarations below.
4951
class DeduceCtx;

xls/dslx/type_system/typecheck_test_utils.cc

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

1717
#include <memory>
18+
#include <optional>
1819
#include <string>
1920
#include <string_view>
2021
#include <utility>
@@ -25,16 +26,18 @@
2526
#include "xls/dslx/command_line_utils.h"
2627
#include "xls/dslx/create_import_data.h"
2728
#include "xls/dslx/import_data.h"
29+
#include "xls/dslx/ir_convert/convert_options.h"
2830
#include "xls/dslx/parse_and_typecheck.h"
2931
#include "xls/dslx/type_system/type_info_to_proto.h"
32+
#include "xls/dslx/type_system_v2/type_inference_error_handler.h"
3033
#include "xls/dslx/virtualizable_file_system.h"
3134

3235
namespace xls::dslx {
3336

34-
absl::StatusOr<TypecheckResult> Typecheck(std::string_view program,
35-
std::string_view module_name,
36-
ImportData* import_data,
37-
bool add_version_attribute) {
37+
absl::StatusOr<TypecheckResult> Typecheck(
38+
std::string_view program, std::string_view module_name,
39+
ImportData* import_data, bool add_version_attribute,
40+
TypeInferenceErrorHandler error_handler) {
3841
std::unique_ptr<ImportData> owned_import_data;
3942
if (import_data == nullptr) {
4043
owned_import_data = CreateImportDataPtrForTest();
@@ -46,7 +49,8 @@ absl::StatusOr<TypecheckResult> Typecheck(std::string_view program,
4649
: std::string(program);
4750
absl::StatusOr<TypecheckedModule> tm = ParseAndTypecheck(
4851
program_with_version_attribute, absl::StrCat(module_name, ".x"),
49-
module_name, import_data);
52+
module_name, import_data, /*comments=*/nullptr,
53+
/*force_version=*/std::nullopt, ConvertOptions{}, error_handler);
5054

5155
if (!tm.ok()) {
5256
UniformContentFilesystem vfs(program_with_version_attribute);
@@ -60,6 +64,13 @@ absl::StatusOr<TypecheckResult> Typecheck(std::string_view program,
6064
return TypecheckResult{std::move(owned_import_data), std::move(*tm)};
6165
}
6266

67+
absl::StatusOr<TypecheckResult> TypecheckV2(
68+
std::string_view program, TypeInferenceErrorHandler error_handler) {
69+
return Typecheck(absl::StrCat("#![feature(type_inference_v2)]\n\n", program),
70+
/*module_name=*/"fake", /*import_data=*/nullptr,
71+
/*add_version_attribute=*/false, error_handler);
72+
}
73+
6374
absl::StatusOr<TypecheckResult> TypecheckV2(std::string_view program,
6475
std::string_view module_name,
6576
ImportData* import_data) {

xls/dslx/type_system/typecheck_test_utils.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "absl/strings/substitute.h"
2525
#include "xls/dslx/import_data.h"
2626
#include "xls/dslx/parse_and_typecheck.h"
27+
#include "xls/dslx/type_system_v2/type_inference_error_handler.h"
2728
#include "re2/re2.h"
2829

2930
namespace xls::dslx {
@@ -42,17 +43,22 @@ struct TypecheckResult {
4243
// Helper for parsing/typechecking a snippet of DSLX text.
4344
//
4445
// If `import_data` is not provided one is created for internal use.
45-
absl::StatusOr<TypecheckResult> Typecheck(std::string_view program,
46-
std::string_view module_name = "fake",
47-
ImportData* import_data = nullptr,
48-
bool add_version_attribute = true);
46+
absl::StatusOr<TypecheckResult> Typecheck(
47+
std::string_view program, std::string_view module_name = "fake",
48+
ImportData* import_data = nullptr, bool add_version_attribute = true,
49+
TypeInferenceErrorHandler error_handler = nullptr);
4950

5051
// Variant that prepends the `type_inference_v2` DSLX module attribute to
5152
// `program` to force the use of type_system_v2.
5253
absl::StatusOr<TypecheckResult> TypecheckV2(
5354
std::string_view program, std::string_view module_name = "fake",
5455
ImportData* import_data = nullptr);
5556

57+
// Variant that prepends the `type_inference_v2` DSLX module attribute to
58+
// `program` to force the use of type_system_v2.
59+
absl::StatusOr<TypecheckResult> TypecheckV2(
60+
std::string_view program, TypeInferenceErrorHandler error_handler);
61+
5662
// Verifies that a failed typecheck status message indicates a type mismatch
5763
// between the given two types in string format.
5864
MATCHER_P2(HasTypeMismatch, type1, type2, "") {

xls/dslx/type_system_v2/BUILD

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ cc_library(
129129
":type_annotation_filter",
130130
":type_annotation_resolver",
131131
":type_annotation_utils",
132+
":type_inference_error_handler",
132133
":type_system_tracer",
133134
":unify_type_annotations",
134135
":validate_concrete_type",
@@ -246,6 +247,19 @@ cc_library(
246247
],
247248
)
248249

250+
cc_library(
251+
name = "type_inference_error_handler",
252+
hdrs = ["type_inference_error_handler.h"],
253+
deps = [
254+
":inference_table",
255+
"//xls/dslx/frontend:ast",
256+
"//xls/dslx/frontend:ast_node",
257+
"//xls/dslx/type_system:type",
258+
"@com_google_absl//absl/status:statusor",
259+
"@com_google_absl//absl/types:span",
260+
],
261+
)
262+
249263
cc_library(
250264
name = "typecheck_module_v2",
251265
srcs = ["typecheck_module_v2.cc"],
@@ -255,11 +269,14 @@ cc_library(
255269
":inference_table_converter",
256270
":inference_table_converter_impl",
257271
":populate_table",
272+
":type_inference_error_handler",
258273
":type_system_tracer",
259274
"//xls/common/file:filesystem",
260275
"//xls/common/status:status_macros",
261276
"//xls/dslx:import_data",
262277
"//xls/dslx:warning_collector",
278+
"//xls/dslx/frontend:ast",
279+
"//xls/dslx/frontend:ast_node",
263280
"//xls/dslx/frontend:module",
264281
"//xls/dslx/frontend:semantics_analysis",
265282
"//xls/dslx/type_system:type_info",
@@ -269,6 +286,7 @@ cc_library(
269286
"@com_google_absl//absl/status",
270287
"@com_google_absl//absl/status:statusor",
271288
"@com_google_absl//absl/strings",
289+
"@com_google_absl//absl/types:span",
272290
],
273291
)
274292

@@ -413,6 +431,32 @@ cc_test(
413431
],
414432
)
415433

434+
cc_test(
435+
name = "typecheck_module_v2_error_handler_test",
436+
srcs = ["typecheck_module_v2_error_handler_test.cc"],
437+
deps = [
438+
":matchers",
439+
":type_annotation_utils",
440+
":type_inference_error_handler",
441+
":type_system_test_utils",
442+
"//xls/common:xls_gunit_main",
443+
"//xls/common/status:matchers",
444+
"//xls/dslx/frontend:ast",
445+
"//xls/dslx/frontend:ast_node",
446+
"//xls/dslx/frontend:pos",
447+
"//xls/dslx/type_system:typecheck_test_utils",
448+
"@com_google_absl//absl/algorithm:container",
449+
"@com_google_absl//absl/container:flat_hash_map",
450+
"@com_google_absl//absl/container:flat_hash_set",
451+
"@com_google_absl//absl/log",
452+
"@com_google_absl//absl/status",
453+
"@com_google_absl//absl/status:statusor",
454+
"@com_google_absl//absl/strings",
455+
"@com_google_absl//absl/types:span",
456+
"@googletest//:gtest",
457+
],
458+
)
459+
416460
cc_library(
417461
name = "type_system_test_utils",
418462
testonly = True,
@@ -681,6 +725,7 @@ cc_library(
681725
":simplified_type_annotation_cache",
682726
":type_annotation_filter",
683727
":type_annotation_utils",
728+
":type_inference_error_handler",
684729
":type_system_tracer",
685730
":unify_type_annotations",
686731
"//xls/common:casts",
@@ -706,6 +751,7 @@ cc_library(
706751
"@com_google_absl//absl/status",
707752
"@com_google_absl//absl/status:statusor",
708753
"@com_google_absl//absl/strings",
754+
"@com_google_absl//absl/types:span",
709755
],
710756
)
711757

0 commit comments

Comments
 (0)