Skip to content

Commit

Permalink
Infer crate name after file opening
Browse files Browse the repository at this point in the history
Fixes #3129.

gcc/rust/ChangeLog:

	* rust-session-manager.cc (Session::handle_crate_name): Remove
	crate name inference
	(Session::compile_crate): Add crate name inference and error if
	inferred name is empty. Remove CompileOptions::get_instance ()
	that returned a local copy of the options. Rename
	crate_name_changed to crate_name_found to match semantics.
	(rust_crate_name_validation_test): Test inferring ".rs" name
	* rust-session-manager.h: Modify handle_crate_name definition to
	include filename.
  • Loading branch information
dylngg committed Aug 29, 2024
1 parent 2501644 commit 280d596
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 29 deletions.
60 changes: 32 additions & 28 deletions gcc/rust/rust-session-manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -396,31 +396,16 @@ Session::handle_input_files (int num_files, const char **files)

const auto &file = files[0];

if (options.crate_name.empty ())
{
auto filename = "-";
if (num_files > 0)
filename = files[0];

auto crate_name = infer_crate_name (filename);
rust_debug ("inferred crate name: %s", crate_name.c_str ());
// set the preliminary crate name here
// we will figure out the real crate name in `handle_crate_name`
options.set_crate_name (crate_name);
}

CrateNum crate_num = mappings.get_next_crate_num (options.get_crate_name ());
mappings.set_current_crate (crate_num);

rust_debug ("Attempting to parse file: %s", file);
compile_crate (file);
}

void
Session::handle_crate_name (const AST::Crate &parsed_crate)
Session::handle_crate_name (const char *filename,
const AST::Crate &parsed_crate)
{
auto &mappings = Analysis::Mappings::get ();
auto crate_name_changed = false;
auto crate_name_found = false;
auto error = Error (UNDEF_LOCATION, std::string ());

for (const auto &attr : parsed_crate.inner_attrs)
Expand All @@ -444,27 +429,45 @@ Session::handle_crate_name (const AST::Crate &parsed_crate)
continue;
}

auto options = Session::get_instance ().options;
if (options.crate_name_set_manually && (options.crate_name != msg_str))
{
rust_error_at (attr.get_locus (),
"%<-frust-crate-name%> and %<#[crate_name]%> are "
"required to match, but %qs does not match %qs",
options.crate_name.c_str (), msg_str.c_str ());
}
crate_name_changed = true;
crate_name_found = true;
options.set_crate_name (msg_str);
mappings.set_crate_name (mappings.get_current_crate (), msg_str);
}

options.crate_name_set_manually |= crate_name_changed;
if (!options.crate_name_set_manually
&& !validate_crate_name (options.crate_name, error))
options.crate_name_set_manually |= crate_name_found;
if (!options.crate_name_set_manually)
{
error.emit ();
rust_inform (linemap_position_for_column (line_table, 0),
"crate name inferred from this file");
auto crate_name = infer_crate_name (filename);
if (crate_name.empty ())
{
rust_error_at (UNDEF_LOCATION, "crate name from filename %s is empty",
filename);
return;
}

rust_debug ("inferred crate name: %s", crate_name.c_str ());
options.set_crate_name (crate_name);

if (!validate_crate_name (options.get_crate_name (), error))
{
error.emit ();
rust_inform (linemap_position_for_column (line_table, 0),
"crate name inferred from this file");
return;
}
}

if (saw_errors ())
return;

CrateNum crate_num = mappings.get_next_crate_num (options.get_crate_name ());
mappings.set_current_crate (crate_num);
}

// Parses a single file with filename filename.
Expand Down Expand Up @@ -533,7 +536,7 @@ Session::compile_crate (const char *filename)
std::unique_ptr<AST::Crate> ast_crate = parser.parse_crate ();

// handle crate name
handle_crate_name (*ast_crate.get ());
handle_crate_name (filename, *ast_crate.get ());

// dump options except lexer dump
if (options.dump_option_enabled (CompileOptions::AST_DUMP_PRETTY))
Expand Down Expand Up @@ -1384,6 +1387,7 @@ rust_crate_name_validation_test (void)
ASSERT_FALSE (Rust::validate_crate_name ("", error));

/* Tests for crate name inference */
ASSERT_EQ (Rust::infer_crate_name (".rs"), "");
ASSERT_EQ (Rust::infer_crate_name ("c.rs"), "c");
// NOTE: ... but - is allowed when in the filename
ASSERT_EQ (Rust::infer_crate_name ("a-b.rs"), "a_b");
Expand Down
2 changes: 1 addition & 1 deletion gcc/rust/rust-session-manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ struct Session
const struct cl_option_handlers *handlers);
void handle_input_files (int num_files, const char **files);
void init_options ();
void handle_crate_name (const AST::Crate &parsed_crate);
void handle_crate_name (const char *filename, const AST::Crate &parsed_crate);

/* This function saves the filename data into the session manager using the
* `move` semantics, and returns a C-style string referencing the input
Expand Down

0 comments on commit 280d596

Please sign in to comment.