if !status.success() {
eprintln!(
"Running `{}` failed.\nIf you're running `tidy`, \
- try again with `--bless` flag. Or, you just want to format \
+ try again with `--bless`. Or, if you just want to format \
code, run `./x.py fmt` instead.",
cmd_debug,
);
.emit();
}
+ fn check_nomangle_item_asciionly(&self, ident: Ident, item_span: Span) {
+ if ident.name.as_str().is_ascii() {
+ return;
+ }
+ let head_span = self.session.source_map().guess_head_span(item_span);
+ struct_span_err!(
+ self.session,
+ head_span,
+ E0754,
+ "`#[no_mangle]` requires ASCII identifier"
+ )
+ .emit();
+ }
+
+ fn check_mod_file_item_asciionly(&self, ident: Ident) {
+ if ident.name.as_str().is_ascii() {
+ return;
+ }
+ struct_span_err!(
+ self.session,
+ ident.span,
+ E0754,
+ "trying to load file for module `{}` with non ascii identifer name",
+ ident.name
+ )
+ .help("consider using `#[path]` attribute to specify filesystem path")
+ .emit();
+ }
+
fn deny_generic_params(&self, generics: &Generics, ident_span: Span) {
if !generics.params.is_empty() {
struct_span_err!(
self.has_proc_macro_decls = true;
}
+ if attr::contains_name(&item.attrs, sym::no_mangle) {
+ self.check_nomangle_item_asciionly(item.ident, item.span);
+ }
+
match item.kind {
ItemKind::Impl {
unsafety,
walk_list!(self, visit_attribute, &item.attrs);
return;
}
- ItemKind::Mod(_) => {
+ ItemKind::Mod(Mod { inline, .. }) => {
// Ensure that `path` attributes on modules are recorded as used (cf. issue #35584).
- attr::first_attr_value_str_by_name(&item.attrs, sym::path);
+ if !inline && !attr::contains_name(&item.attrs, sym::path) {
+ self.check_mod_file_item_asciionly(item.ident);
+ }
}
ItemKind::Union(ref vdata, _) => {
if let VariantData::Tuple(..) | VariantData::Unit(..) = vdata {
E0751: include_str!("./error_codes/E0751.md"),
E0752: include_str!("./error_codes/E0752.md"),
E0753: include_str!("./error_codes/E0753.md"),
+E0754: include_str!("./error_codes/E0754.md"),
;
// E0006, // merged with E0005
// E0008, // cannot bind by-move into a pattern guard
--- /dev/null
+An non-ascii identifier was used in an invalid context.
+
+Erroneous code example:
+
+```compile_fail,E0754
+# #![feature(non_ascii_idents)]
+
+mod řųśť;
+// ^ error!
+fn main() {}
+```
+
+```compile_fail,E0754
+# #![feature(non_ascii_idents)]
+
+#[no_mangle]
+fn řųśť() {}
+// ^ error!
+fn main() {}
+```
+
+Non-ascii can be used as module names if it is inline
+or a #\[path\] attribute is specified. For example:
+
+```
+# #![feature(non_ascii_idents)]
+
+mod řųśť {
+ const IS_GREAT: bool = true;
+}
+
+fn main() {}
+```
pub fn generate_fn_name_span(&self, span: Span) -> Option<Span> {
let prev_span = self.span_extend_to_prev_str(span, "fn", true);
- self.span_to_snippet(prev_span)
- .map(|snippet| {
- let len = snippet
- .find(|c: char| !c.is_alphanumeric() && c != '_')
- .expect("no label after fn");
- prev_span.with_hi(BytePos(prev_span.lo().0 + len as u32))
- })
- .ok()
+ if let Ok(snippet) = self.span_to_snippet(prev_span) {
+ debug!(
+ "generate_fn_name_span: span={:?}, prev_span={:?}, snippet={:?}",
+ span, prev_span, snippet
+ );
+
+ if snippet.is_empty() {
+ return None;
+ };
+
+ let len = snippet
+ .find(|c: char| !c.is_alphanumeric() && c != '_')
+ .expect("no label after fn");
+ Some(prev_span.with_hi(BytePos(prev_span.lo().0 + len as u32)))
+ } else {
+ None
+ }
}
/// Takes the span of a type parameter in a function signature and try to generate a span for
--- /dev/null
+pub trait Foo {}
--- /dev/null
+#![feature(non_ascii_idents)]
+
+mod řųśť; //~ trying to load file for
+//~^ file not found for
+
+fn main() {}
--- /dev/null
+error[E0583]: file not found for module `řųśť`
+ --> $DIR/mod_file_nonascii_forbidden.rs:3:1
+ |
+LL | mod řųśť;
+ | ^^^^^^^^^
+ |
+ = help: to create the module `řųśť`, create file "$DIR/řųśť.rs"
+
+error[E0754]: trying to load file for module `řųśť` with non ascii identifer name
+ --> $DIR/mod_file_nonascii_forbidden.rs:3:5
+ |
+LL | mod řųśť;
+ | ^^^^
+ |
+ = help: consider using `#[path]` attribute to specify filesystem path
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0583, E0754.
+For more information about an error, try `rustc --explain E0583`.
--- /dev/null
+// check-pass
+#![feature(non_ascii_idents)]
+
+#[path="auxiliary/mod_file_nonascii_with_path_allowed-aux.rs"]
+mod řųśť;
+
+fn main() {}
--- /dev/null
+// check-pass
+#![feature(non_ascii_idents)]
+
+mod řųśť {
+ const IS_GREAT: bool = true;
+}
+
+fn main() {}
--- /dev/null
+#![feature(non_ascii_idents)]
+
+#[no_mangle]
+pub fn řųśť() {} //~ `#[no_mangle]` requires ASCII identifier
+
+fn main() {}
--- /dev/null
+error[E0754]: `#[no_mangle]` requires ASCII identifier
+ --> $DIR/no_mangle_nonascii_forbidden.rs:4:1
+ |
+LL | pub fn řųśť() {}
+ | ^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0754`.