Skip to content

Commit 60f7f99

Browse files
bors[bot]liushuyu
andauthored
Merge #1163
1163: rust-session-manager: handle `crate_name` attribute r=philberty a=liushuyu - rust-session-manager: handle `crate_name` attribute Fix #789 properly Co-authored-by: liushuyu <liushuyu011@gmail.com>
2 parents d69dd65 + 57725b5 commit 60f7f99

File tree

5 files changed

+83
-13
lines changed

5 files changed

+83
-13
lines changed

gcc/rust/rust-session-manager.cc

Lines changed: 60 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,10 @@ Session::handle_option (
405405
{
406406
auto error = Error (Location (), std::string ());
407407
if ((ret = validate_crate_name (arg, error)))
408-
options.set_crate_name (arg);
408+
{
409+
options.set_crate_name (arg);
410+
options.crate_name_set_manually = true;
411+
}
409412
else
410413
{
411414
rust_assert (!error.message.empty ());
@@ -553,19 +556,9 @@ Session::parse_files (int num_files, const char **files)
553556
filename = files[0];
554557

555558
auto crate_name = infer_crate_name (filename);
556-
Error error ((Location ()), std::string ());
557559
rust_debug ("inferred crate name: %s", crate_name.c_str ());
558-
if (!validate_crate_name (crate_name, error))
559-
{
560-
// fake a linemapping so that we can show the filename
561-
linemap->start_file (filename, 0);
562-
linemap->start_line (0, 1);
563-
error.emit_error ();
564-
rust_inform (linemap->get_location (0),
565-
"crate name inferred from this file");
566-
linemap->stop ();
567-
return;
568-
}
560+
// set the preliminary crate name here
561+
// we will figure out the real crate name in `handle_crate_name`
569562
options.set_crate_name (crate_name);
570563
}
571564

@@ -582,6 +575,57 @@ Session::parse_files (int num_files, const char **files)
582575
* per-file. */
583576
}
584577

578+
void
579+
Session::handle_crate_name (AST::Crate parsed_crate)
580+
{
581+
auto mappings = Analysis::Mappings::get ();
582+
auto crate_name_changed = false;
583+
auto error = Error (Location (), std::string ());
584+
585+
for (const auto &attr : parsed_crate.inner_attrs)
586+
{
587+
if (attr.get_path () != "crate_name")
588+
continue;
589+
if (!attr.has_attr_input ())
590+
{
591+
rust_error_at (attr.get_locus (),
592+
"%<crate_name%> accepts one argument");
593+
continue;
594+
}
595+
596+
auto &literal
597+
= static_cast<AST::AttrInputLiteral &> (attr.get_attr_input ());
598+
const auto &msg_str = literal.get_literal ().as_string ();
599+
if (!validate_crate_name (msg_str, error))
600+
{
601+
error.locus = attr.get_locus ();
602+
error.emit_error ();
603+
continue;
604+
}
605+
606+
auto options = Session::get_instance ().options;
607+
if (options.crate_name_set_manually && (options.crate_name != msg_str))
608+
{
609+
rust_error_at (attr.get_locus (),
610+
"%<-frust-crate-name%> and %<#[crate_name]%> are "
611+
"required to match, but %qs does not match %qs",
612+
options.crate_name.c_str (), msg_str.c_str ());
613+
}
614+
crate_name_changed = true;
615+
options.set_crate_name (msg_str);
616+
mappings->set_crate_name (mappings->get_current_crate (), msg_str);
617+
}
618+
619+
options.crate_name_set_manually |= crate_name_changed;
620+
if (!options.crate_name_set_manually
621+
&& !validate_crate_name (options.crate_name, error))
622+
{
623+
error.emit_error ();
624+
rust_inform (linemap->get_location (0),
625+
"crate name inferred from this file");
626+
}
627+
}
628+
585629
// Parses a single file with filename filename.
586630
void
587631
Session::parse_file (const char *filename)
@@ -606,6 +650,9 @@ Session::parse_file (const char *filename)
606650
auto mappings = Analysis::Mappings::get ();
607651
mappings->insert_ast_crate (&parsed_crate);
608652

653+
// handle crate name
654+
handle_crate_name (parsed_crate);
655+
609656
if (options.dump_option_enabled (CompileOptions::LEXER_DUMP))
610657
{
611658
dump_lex (parser);

gcc/rust/rust-session-manager.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ struct CompileOptions
182182
* pointer width, vendor */
183183
TargetOptions target_data;
184184
std::string crate_name;
185+
bool crate_name_set_manually = false;
185186
bool enable_test = false;
186187
bool debug_assertions = false;
187188
bool proc_macro = false;
@@ -270,6 +271,7 @@ struct Session
270271
const struct cl_option_handlers *handlers);
271272
void parse_files (int num_files, const char **files);
272273
void init_options ();
274+
void handle_crate_name (AST::Crate parsed_crate);
273275

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

gcc/rust/util/rust-hir-map.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,19 @@ class Mappings
8888
return true;
8989
}
9090

91+
// set crate name mid-compilation
92+
// don't use this if setting crate name before Session::parse_files
93+
bool set_crate_name (CrateNum crate_num, std::string name)
94+
{
95+
rust_assert (!name.empty ());
96+
auto it = crate_names.find (crate_num);
97+
if (it == crate_names.end ())
98+
return false;
99+
100+
it->second.assign (name);
101+
return true;
102+
}
103+
91104
std::string get_current_crate_name () const
92105
{
93106
std::string name;
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// { dg-additional-options "-fdump-tree-gimple" }
2+
#![crate_name = "specified_name"]
3+
// { dg-final { scan-tree-dump-times {specified_name::main} 1 gimple } }
4+
fn main() {}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// { dg-additional-options "-frust-crate=another_name" }
2+
#![crate_name = "legit_name"]
3+
// { dg-error ".-frust-crate-name. and .#.crate_name.. are required to match, but .another_name. does not match .legit_name." "" { target *-*-* } .-1 }
4+
fn main() {}

0 commit comments

Comments
 (0)