Skip to content

Commit e112738

Browse files
committed
Clean up rustc_session::output::{find,validate}_crate_name
1 parent f5cd2c5 commit e112738

File tree

4 files changed

+63
-62
lines changed

4 files changed

+63
-62
lines changed

compiler/rustc_session/messages.ftl

+3-3
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ session_cannot_mix_and_match_sanitizers = `-Zsanitizer={$first}` is incompatible
88
session_cli_feature_diagnostic_help =
99
add `-Zcrate-attr="feature({$feature})"` to the command-line options to enable
1010
11-
session_crate_name_does_not_match = `--crate-name` and `#[crate_name]` are required to match, but `{$s}` != `{$name}`
11+
session_crate_name_does_not_match = `--crate-name` and `#[crate_name]` are required to match, but `{$crate_name}` != `{$attr_crate_name}`
1212
1313
session_crate_name_empty = crate name must not be empty
1414
@@ -52,8 +52,8 @@ session_instrumentation_not_supported = {$us} instrumentation is not supported f
5252
session_int_literal_too_large = integer literal is too large
5353
.note = value exceeds limit of `{$limit}`
5454
55-
session_invalid_character_in_create_name = invalid character `{$character}` in crate name: `{$crate_name}`
56-
session_invalid_character_in_create_name_help = you can either pass `--crate-name` on the command line or add `#![crate_name="…"]` to set the crate name
55+
session_invalid_character_in_crate_name = invalid character {$character} in crate name: `{$crate_name}`
56+
.help = you can either pass `--crate-name` on the command line or add `#![crate_name = "…"]` to set the crate name
5757
5858
session_invalid_float_literal_suffix = invalid suffix `{$suffix}` for float literal
5959
.label = invalid suffix `{$suffix}`

compiler/rustc_session/src/errors.rs

+5-11
Original file line numberDiff line numberDiff line change
@@ -216,8 +216,8 @@ pub(crate) struct FileWriteFail<'a> {
216216
pub(crate) struct CrateNameDoesNotMatch {
217217
#[primary_span]
218218
pub(crate) span: Span,
219-
pub(crate) s: Symbol,
220-
pub(crate) name: Symbol,
219+
pub(crate) crate_name: Symbol,
220+
pub(crate) attr_crate_name: Symbol,
221221
}
222222

223223
#[derive(Diagnostic)]
@@ -234,20 +234,14 @@ pub(crate) struct CrateNameEmpty {
234234
}
235235

236236
#[derive(Diagnostic)]
237-
#[diag(session_invalid_character_in_create_name)]
237+
#[diag(session_invalid_character_in_crate_name)]
238238
pub(crate) struct InvalidCharacterInCrateName {
239239
#[primary_span]
240240
pub(crate) span: Option<Span>,
241241
pub(crate) character: char,
242242
pub(crate) crate_name: Symbol,
243-
#[subdiagnostic]
244-
pub(crate) crate_name_help: Option<InvalidCrateNameHelp>,
245-
}
246-
247-
#[derive(Subdiagnostic)]
248-
pub(crate) enum InvalidCrateNameHelp {
249-
#[help(session_invalid_character_in_create_name_help)]
250-
AddCrateName,
243+
#[help]
244+
pub(crate) help: Option<()>,
251245
}
252246

253247
#[derive(Subdiagnostic)]

compiler/rustc_session/src/output.rs

+53-46
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use crate::Session;
1111
use crate::config::{self, CrateType, Input, OutFileName, OutputFilenames, OutputType};
1212
use crate::errors::{
1313
self, CrateNameDoesNotMatch, CrateNameEmpty, CrateNameInvalid, FileIsNotWriteable,
14-
InvalidCharacterInCrateName, InvalidCrateNameHelp,
14+
InvalidCharacterInCrateName,
1515
};
1616

1717
pub fn out_filename(
@@ -51,10 +51,13 @@ fn is_writeable(p: &Path) -> bool {
5151
}
5252
}
5353

54+
/// Find and [validate] the crate name.
55+
///
56+
/// [validate]: validate_crate_name
5457
pub fn find_crate_name(sess: &Session, attrs: &[ast::Attribute]) -> Symbol {
55-
let validate = |s: Symbol, span: Option<Span>| {
56-
validate_crate_name(sess, s, span);
57-
s
58+
let validate = |name, span| {
59+
validate_crate_name(sess, name, span);
60+
name
5861
};
5962

6063
// Look in attributes 100% of the time to make sure the attribute is marked
@@ -64,61 +67,65 @@ pub fn find_crate_name(sess: &Session, attrs: &[ast::Attribute]) -> Symbol {
6467
let attr_crate_name =
6568
attr::find_by_name(attrs, sym::crate_name).and_then(|at| at.value_str().map(|s| (at, s)));
6669

67-
if let Some(ref s) = sess.opts.crate_name {
68-
let s = Symbol::intern(s);
69-
if let Some((attr, name)) = attr_crate_name {
70-
if name != s {
71-
sess.dcx().emit_err(CrateNameDoesNotMatch { span: attr.span, s, name });
72-
}
70+
if let Some(crate_name) = &sess.opts.crate_name {
71+
let crate_name = Symbol::intern(crate_name);
72+
if let Some((attr, attr_crate_name)) = attr_crate_name
73+
&& attr_crate_name != crate_name
74+
{
75+
sess.dcx().emit_err(CrateNameDoesNotMatch {
76+
span: attr.span,
77+
crate_name,
78+
attr_crate_name,
79+
});
7380
}
74-
return validate(s, None);
81+
return validate(crate_name, None);
7582
}
7683

77-
if let Some((attr, s)) = attr_crate_name {
78-
return validate(s, Some(attr.span));
84+
if let Some((attr, crate_name)) = attr_crate_name {
85+
return validate(crate_name, Some(attr.span));
7986
}
80-
if let Input::File(ref path) = sess.io.input {
81-
if let Some(s) = path.file_stem().and_then(|s| s.to_str()) {
82-
if s.starts_with('-') {
83-
sess.dcx().emit_err(CrateNameInvalid { s });
84-
} else {
85-
return validate(Symbol::intern(&s.replace('-', "_")), None);
86-
}
87+
88+
if let Input::File(ref path) = sess.io.input
89+
&& let Some(s) = path.file_stem().and_then(|s| s.to_str())
90+
{
91+
if s.starts_with('-') {
92+
sess.dcx().emit_err(CrateNameInvalid { s });
93+
} else {
94+
return validate(Symbol::intern(&s.replace('-', "_")), None);
8795
}
8896
}
8997

9098
Symbol::intern("rust_out")
9199
}
92100

93-
pub fn validate_crate_name(sess: &Session, s: Symbol, sp: Option<Span>) {
94-
let mut err_count = 0;
95-
{
96-
if s.is_empty() {
97-
err_count += 1;
98-
sess.dcx().emit_err(CrateNameEmpty { span: sp });
99-
}
100-
for c in s.as_str().chars() {
101-
if c.is_alphanumeric() {
102-
continue;
103-
}
104-
if c == '_' {
105-
continue;
106-
}
107-
err_count += 1;
108-
sess.dcx().emit_err(InvalidCharacterInCrateName {
109-
span: sp,
110-
character: c,
111-
crate_name: s,
112-
crate_name_help: if sp.is_none() {
113-
Some(InvalidCrateNameHelp::AddCrateName)
114-
} else {
115-
None
116-
},
117-
});
101+
/// Validate the given crate name.
102+
///
103+
/// Note that this validation is more permissive than identifier parsing. It considers
104+
/// non-empty sequences of alphanumeric and underscore characters to be valid crate names.
105+
/// Most notably, it accepts names starting with a numeric character like `0`!
106+
///
107+
/// Furthermore, this shouldn't be taken as the canonical crate name validator.
108+
/// Other places may use a more restrictive grammar (e.g., identifier or ASCII identifier).
109+
pub fn validate_crate_name(sess: &Session, crate_name: Symbol, span: Option<Span>) {
110+
let mut result = Ok(());
111+
112+
if crate_name.is_empty() {
113+
result = Err(sess.dcx().emit_err(CrateNameEmpty { span }));
114+
}
115+
116+
for c in crate_name.as_str().chars() {
117+
if c.is_alphanumeric() || c == '_' {
118+
continue;
118119
}
120+
result = Err(sess.dcx().emit_err(InvalidCharacterInCrateName {
121+
span,
122+
character: c,
123+
crate_name,
124+
help: span.is_none().then_some(()),
125+
}));
119126
}
120127

121-
if err_count > 0 {
128+
if result.is_err() {
122129
FatalError.raise();
123130
}
124131
}
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
error: invalid character `'$'` in crate name: `need_crate_arg_ignore_tidy$x`
1+
error: invalid character '$' in crate name: `need_crate_arg_ignore_tidy$x`
22
|
3-
= help: you can either pass `--crate-name` on the command line or add `#![crate_name="…"]` to set the crate name
3+
= help: you can either pass `--crate-name` on the command line or add `#![crate_name = "…"]` to set the crate name
44

55
error: aborting due to 1 previous error
66

0 commit comments

Comments
 (0)