about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/bootstrap/format.rs2
-rw-r--r--src/librustc_ast_passes/ast_validation.rs39
-rw-r--r--src/librustc_error_codes/error_codes.rs1
-rw-r--r--src/librustc_error_codes/error_codes/E0754.md33
-rw-r--r--src/librustc_span/source_map.rs25
-rw-r--r--src/test/ui/rfc-2457/auxiliary/mod_file_nonascii_with_path_allowed-aux.rs1
-rw-r--r--src/test/ui/rfc-2457/mod_file_nonascii_forbidden.rs6
-rw-r--r--src/test/ui/rfc-2457/mod_file_nonascii_forbidden.stderr20
-rw-r--r--src/test/ui/rfc-2457/mod_file_nonascii_with_path_allowed.rs7
-rw-r--r--src/test/ui/rfc-2457/mod_inline_nonascii_allowed.rs8
-rw-r--r--src/test/ui/rfc-2457/no_mangle_nonascii_forbidden.rs6
-rw-r--r--src/test/ui/rfc-2457/no_mangle_nonascii_forbidden.stderr9
12 files changed, 146 insertions, 11 deletions
diff --git a/src/bootstrap/format.rs b/src/bootstrap/format.rs
index 6653c505bf5..390b7e96b9a 100644
--- a/src/bootstrap/format.rs
+++ b/src/bootstrap/format.rs
@@ -23,7 +23,7 @@ fn rustfmt(src: &Path, rustfmt: &Path, path: &Path, check: bool) {
     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,
         );
diff --git a/src/librustc_ast_passes/ast_validation.rs b/src/librustc_ast_passes/ast_validation.rs
index 46c415413e9..8eb125e4440 100644
--- a/src/librustc_ast_passes/ast_validation.rs
+++ b/src/librustc_ast_passes/ast_validation.rs
@@ -572,6 +572,35 @@ impl<'a> AstValidator<'a> {
             .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!(
@@ -866,6 +895,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
             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,
@@ -992,9 +1025,11 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                 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 {
diff --git a/src/librustc_error_codes/error_codes.rs b/src/librustc_error_codes/error_codes.rs
index 2399e99a309..d6863c615f6 100644
--- a/src/librustc_error_codes/error_codes.rs
+++ b/src/librustc_error_codes/error_codes.rs
@@ -436,6 +436,7 @@ E0750: include_str!("./error_codes/E0750.md"),
 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
diff --git a/src/librustc_error_codes/error_codes/E0754.md b/src/librustc_error_codes/error_codes/E0754.md
new file mode 100644
index 00000000000..abdc01ed21a
--- /dev/null
+++ b/src/librustc_error_codes/error_codes/E0754.md
@@ -0,0 +1,33 @@
+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() {}
+```
diff --git a/src/librustc_span/source_map.rs b/src/librustc_span/source_map.rs
index d27aae0d6ed..51f55417663 100644
--- a/src/librustc_span/source_map.rs
+++ b/src/librustc_span/source_map.rs
@@ -910,14 +910,23 @@ impl SourceMap {
 
     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
diff --git a/src/test/ui/rfc-2457/auxiliary/mod_file_nonascii_with_path_allowed-aux.rs b/src/test/ui/rfc-2457/auxiliary/mod_file_nonascii_with_path_allowed-aux.rs
new file mode 100644
index 00000000000..e373b64384f
--- /dev/null
+++ b/src/test/ui/rfc-2457/auxiliary/mod_file_nonascii_with_path_allowed-aux.rs
@@ -0,0 +1 @@
+pub trait Foo {}
diff --git a/src/test/ui/rfc-2457/mod_file_nonascii_forbidden.rs b/src/test/ui/rfc-2457/mod_file_nonascii_forbidden.rs
new file mode 100644
index 00000000000..efd2932f152
--- /dev/null
+++ b/src/test/ui/rfc-2457/mod_file_nonascii_forbidden.rs
@@ -0,0 +1,6 @@
+#![feature(non_ascii_idents)]
+
+mod řųśť; //~ trying to load file for
+//~^ file not found for
+
+fn main() {}
diff --git a/src/test/ui/rfc-2457/mod_file_nonascii_forbidden.stderr b/src/test/ui/rfc-2457/mod_file_nonascii_forbidden.stderr
new file mode 100644
index 00000000000..be729836f4f
--- /dev/null
+++ b/src/test/ui/rfc-2457/mod_file_nonascii_forbidden.stderr
@@ -0,0 +1,20 @@
+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`.
diff --git a/src/test/ui/rfc-2457/mod_file_nonascii_with_path_allowed.rs b/src/test/ui/rfc-2457/mod_file_nonascii_with_path_allowed.rs
new file mode 100644
index 00000000000..e9f3fba2fb0
--- /dev/null
+++ b/src/test/ui/rfc-2457/mod_file_nonascii_with_path_allowed.rs
@@ -0,0 +1,7 @@
+// check-pass
+#![feature(non_ascii_idents)]
+
+#[path="auxiliary/mod_file_nonascii_with_path_allowed-aux.rs"]
+mod řųśť;
+
+fn main() {}
diff --git a/src/test/ui/rfc-2457/mod_inline_nonascii_allowed.rs b/src/test/ui/rfc-2457/mod_inline_nonascii_allowed.rs
new file mode 100644
index 00000000000..dd27da432ba
--- /dev/null
+++ b/src/test/ui/rfc-2457/mod_inline_nonascii_allowed.rs
@@ -0,0 +1,8 @@
+// check-pass
+#![feature(non_ascii_idents)]
+
+mod řųśť {
+    const IS_GREAT: bool = true;
+}
+
+fn main() {}
diff --git a/src/test/ui/rfc-2457/no_mangle_nonascii_forbidden.rs b/src/test/ui/rfc-2457/no_mangle_nonascii_forbidden.rs
new file mode 100644
index 00000000000..a408c975716
--- /dev/null
+++ b/src/test/ui/rfc-2457/no_mangle_nonascii_forbidden.rs
@@ -0,0 +1,6 @@
+#![feature(non_ascii_idents)]
+
+#[no_mangle]
+pub fn řųśť() {}  //~ `#[no_mangle]` requires ASCII identifier
+
+fn main() {}
diff --git a/src/test/ui/rfc-2457/no_mangle_nonascii_forbidden.stderr b/src/test/ui/rfc-2457/no_mangle_nonascii_forbidden.stderr
new file mode 100644
index 00000000000..4ca83e41032
--- /dev/null
+++ b/src/test/ui/rfc-2457/no_mangle_nonascii_forbidden.stderr
@@ -0,0 +1,9 @@
+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`.