diff --git a/Cargo.lock b/Cargo.lock index 7337901bc3a59..412a4e5a2b3d7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4236,6 +4236,7 @@ dependencies = [ "rustc_fluent_macro", "rustc_fs_util", "rustc_hir", + "rustc_lexer", "rustc_lint_defs", "rustc_macros", "rustc_serialize", diff --git a/compiler/rustc_session/Cargo.toml b/compiler/rustc_session/Cargo.toml index e26d25d9a4123..5b91d75a2c974 100644 --- a/compiler/rustc_session/Cargo.toml +++ b/compiler/rustc_session/Cargo.toml @@ -19,6 +19,7 @@ rustc_span = { path = "../rustc_span" } rustc_fs_util = { path = "../rustc_fs_util" } rustc_ast = { path = "../rustc_ast" } rustc_lint_defs = { path = "../rustc_lint_defs" } +rustc_lexer = { path = "../rustc_lexer" } smallvec = "1.8.1" termize = "0.1.1" diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index f00472f181d8e..eee9ac54b3a16 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -2451,6 +2451,19 @@ pub fn parse_externs( Some((opts, name)) => (Some(opts), name.to_string()), }; + if !rustc_lexer::is_ident(&name) { + let mut error = handler.early_struct_error(format!( + "crate name `{name}` passed to `--extern` is not a valid identifier" + )); + let adjusted_name = name.replace("-", "_"); + if rustc_lexer::is_ident(&adjusted_name) { + error.help(format!( + "consider replacing the dashes with underscores: `{adjusted_name}`" + )); + } + error.emit(); + } + let path = path.map(|p| CanonicalizedPath::new(p)); let entry = externs.entry(name.to_owned()); diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 086ce4e69646a..889d7e730108f 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -1710,6 +1710,15 @@ impl EarlyErrorHandler { self.handler.struct_fatal(msg).emit() } + #[allow(rustc::untranslatable_diagnostic)] + #[allow(rustc::diagnostic_outside_of_impl)] + pub(crate) fn early_struct_error( + &self, + msg: impl Into, + ) -> DiagnosticBuilder<'_, !> { + self.handler.struct_fatal(msg) + } + #[allow(rustc::untranslatable_diagnostic)] #[allow(rustc::diagnostic_outside_of_impl)] pub fn early_warn(&self, msg: impl Into) { diff --git a/tests/ui/extern-flag/invalid-crate-name-dashed.rs b/tests/ui/extern-flag/invalid-crate-name-dashed.rs new file mode 100644 index 0000000000000..bb1f4b0a4dfd4 --- /dev/null +++ b/tests/ui/extern-flag/invalid-crate-name-dashed.rs @@ -0,0 +1,7 @@ +// compile-flags: --extern=my-awesome-library=libawesome.rlib +// error-pattern: crate name `my-awesome-library` passed to `--extern` is not a valid identifier +// error-pattern: consider replacing the dashes with underscores: `my_awesome_library` + +pub use my_awesome_library::*; + +fn main() {} diff --git a/tests/ui/extern-flag/invalid-crate-name-dashed.stderr b/tests/ui/extern-flag/invalid-crate-name-dashed.stderr new file mode 100644 index 0000000000000..00deaf332ea5d --- /dev/null +++ b/tests/ui/extern-flag/invalid-crate-name-dashed.stderr @@ -0,0 +1,4 @@ +error: crate name `my-awesome-library` passed to `--extern` is not a valid identifier + | + = help: consider replacing the dashes with underscores: `my_awesome_library` + diff --git a/tests/ui/extern-flag/invalid-crate-name.rs b/tests/ui/extern-flag/invalid-crate-name.rs new file mode 100644 index 0000000000000..8be3f1a32ce90 --- /dev/null +++ b/tests/ui/extern-flag/invalid-crate-name.rs @@ -0,0 +1,4 @@ +// compile-flags: --extern=?#1%$ +// error-pattern: crate name `?#1%$` passed to `--extern` is not a valid identifier + +fn main() {} diff --git a/tests/ui/extern-flag/invalid-crate-name.stderr b/tests/ui/extern-flag/invalid-crate-name.stderr new file mode 100644 index 0000000000000..798b88c5fdadb --- /dev/null +++ b/tests/ui/extern-flag/invalid-crate-name.stderr @@ -0,0 +1,2 @@ +error: crate name `?#1%$` passed to `--extern` is not a valid identifier + diff --git a/tests/ui/rust-2018/trait-import-suggestions.rs b/tests/ui/rust-2018/trait-import-suggestions.rs index 9c67c3f4b4b2e..900b3d09334d0 100644 --- a/tests/ui/rust-2018/trait-import-suggestions.rs +++ b/tests/ui/rust-2018/trait-import-suggestions.rs @@ -1,6 +1,6 @@ // edition:2018 // aux-build:trait-import-suggestions.rs -// compile-flags:--extern trait-import-suggestions +// compile-flags:--extern trait_import_suggestions mod foo { mod foobar {