Skip to content

Commit

Permalink
Merge pull request #1816 from xlsynth:cdleary/2024-12-30-use-feature-…
Browse files Browse the repository at this point in the history
…flag

PiperOrigin-RevId: 710801795
  • Loading branch information
copybara-github committed Dec 30, 2024
2 parents 4651f2e + c61964a commit 47bdc59
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 9 deletions.
4 changes: 4 additions & 0 deletions xls/dslx/fmt/ast_fmt.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2897,6 +2897,10 @@ absl::StatusOr<DocRef> Formatter::Format(const Module& n) {
pieces.push_back(arena_.MakeText("#![type_inference_version = 2]"));
pieces.push_back(arena_.hard_line());
break;
case ModuleAnnotation::kAllowUseSyntax:
pieces.push_back(arena_.MakeText("#![feature(use_syntax)]"));
pieces.push_back(arena_.hard_line());
break;
}
}
pieces.push_back(arena_.hard_line());
Expand Down
4 changes: 3 additions & 1 deletion xls/dslx/frontend/ast_cloner_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1738,7 +1738,9 @@ fn divmod() {})*";

TEST(AstClonerTest, Use) {
constexpr std::string_view kProgram =
R"(use foo::bar::{baz::{bat, qux}, ipsum};)";
R"(#![feature(use_syntax)]
use foo::bar::{baz::{bat, qux}, ipsum};)";

FileTable file_table;
XLS_ASSERT_OK_AND_ASSIGN(auto module, ParseModule(kProgram, "fake_path.x",
Expand Down
3 changes: 3 additions & 0 deletions xls/dslx/frontend/module.cc
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ std::string Module::ToString() const {
case ModuleAnnotation::kTypeInferenceVersion2:
absl::StrAppend(out, "#![type_inference_version = 2]");
break;
case ModuleAnnotation::kAllowUseSyntax:
absl::StrAppend(out, "#![feature(use_syntax)]");
break;
}
});
return absl::StrCat(header, "\n\n", body);
Expand Down
3 changes: 3 additions & 0 deletions xls/dslx/frontend/module.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ enum class ModuleAnnotation : uint8_t {
kAllowNonstandardMemberNaming,

kTypeInferenceVersion2,

// Enable "use" syntax instead of "import" for this module.
kAllowUseSyntax,
};

// Represents a syntactic module in the AST.
Expand Down
24 changes: 24 additions & 0 deletions xls/dslx/frontend/parser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,16 @@ absl::Status Parser::ParseModuleAttribute() {
Span identifier_span;
XLS_ASSIGN_OR_RETURN(std::string identifier,
PopIdentifierOrError(&identifier_span));
if (identifier == "feature") {
XLS_RETURN_IF_ERROR(DropTokenOrError(TokenKind::kOParen));
XLS_ASSIGN_OR_RETURN(std::string feature, PopIdentifierOrError());
if (feature == "use_syntax") {
module_->AddAnnotation(ModuleAnnotation::kAllowUseSyntax);
}
XLS_RETURN_IF_ERROR(DropTokenOrError(TokenKind::kCParen));
XLS_RETURN_IF_ERROR(DropTokenOrError(TokenKind::kCBrack));
return absl::OkStatus();
}
if (identifier == "type_inference_version") {
XLS_RETURN_IF_ERROR(DropTokenOrError(TokenKind::kEquals));
XLS_RETURN_IF_ERROR(ParseTypeInferenceVersionAttribute());
Expand Down Expand Up @@ -474,11 +484,25 @@ absl::StatusOr<std::unique_ptr<Module>> Parser::ParseModule(
break;
}
case Keyword::kImport: {
if (module_->annotations().contains(
ModuleAnnotation::kAllowUseSyntax)) {
return ParseErrorStatus(
peek->span(),
"`import` syntax is disabled for this module via "
"`#![feature(use_syntax)]` at module scope; use `use` instead");
}
XLS_ASSIGN_OR_RETURN(Import * import, ParseImport(*bindings));
XLS_RETURN_IF_ERROR(module_->AddTop(import, make_collision_error));
break;
}
case Keyword::kUse: {
if (!module_->annotations().contains(
ModuleAnnotation::kAllowUseSyntax)) {
return ParseErrorStatus(
peek->span(),
"`use` syntax is not enabled for this module; enable with "
"`#![feature(use_syntax)]` at module scope");
}
XLS_ASSIGN_OR_RETURN(Use * use, ParseUse(*bindings));
XLS_RETURN_IF_ERROR(module_->AddTop(use, make_collision_error));
break;
Expand Down
26 changes: 18 additions & 8 deletions xls/dslx/frontend/parser_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1666,38 +1666,48 @@ fn foo() -> bar::T<2>[3] {
}

TEST_F(ParserTest, UseOneItemFromModule) {
RoundTrip(R"(use foo::BAR;
RoundTrip(R"(#![feature(use_syntax)]
use foo::BAR;
fn main() -> u32 {
BAR
})");
}

TEST_F(ParserTest, UseTwoItemsFromModule) {
RoundTrip(R"(use foo::{BAR, BAZ};
RoundTrip(R"(#![feature(use_syntax)]
use foo::{BAR, BAZ};
fn main() -> u32 {
BAR + BAZ
})");
}

TEST_F(ParserTest, UseWithNestedLevels) {
RoundTrip(R"(use foo::{bar::{baz, qux}, quux};
RoundTrip(R"(#![feature(use_syntax)]
use foo::{bar::{baz, qux}, quux};
fn main() -> u32 {
baz + qux + quux
})");
}

TEST_F(ParserTest, UseCollidesWithImport) {
constexpr std::string_view kProgram = "use foo; import foo;";
constexpr std::string_view kProgram = R"(#![feature(use_syntax)]
use foo; import foo;
)";
absl::StatusOr<std::unique_ptr<Module>> module = Parse(kProgram);
EXPECT_THAT(
module.status(),
StatusIs(
absl::StatusCode::kInvalidArgument,
HasSubstr("Import of `foo` is shadowing an existing definition")));
StatusIs(absl::StatusCode::kInvalidArgument,
HasSubstr("`import` syntax is disabled for this module via "
"`#![feature(use_syntax)]` at module scope")));
}

TEST_F(ParserTest, UseWithPeersAtTopLevelNotAllowed) {
constexpr std::string_view kProgram = "use {foo, bar};";
constexpr std::string_view kProgram = R"(#![feature(use_syntax)]
use {foo, bar};)";
absl::StatusOr<std::unique_ptr<Module>> module = Parse(kProgram);
EXPECT_THAT(
module.status(),
Expand Down

0 comments on commit 47bdc59

Please sign in to comment.