1- use crate :: core:: { compiler , Workspace } ;
1+ use crate :: core:: { Shell , Workspace } ;
22use crate :: util:: errors:: { CargoResult , CargoResultExt } ;
33use crate :: util:: { existing_vcs_repo, FossilRepo , GitRepo , HgRepo , PijulRepo } ;
4- use crate :: util:: { paths, validate_package_name , Config } ;
4+ use crate :: util:: { paths, restricted_names , Config } ;
55use git2:: Config as GitConfig ;
66use git2:: Repository as GitRepository ;
77use serde:: de;
@@ -155,41 +155,71 @@ fn get_name<'a>(path: &'a Path, opts: &'a NewOptions) -> CargoResult<&'a str> {
155155 } )
156156}
157157
158- fn check_name ( name : & str , opts : & NewOptions ) -> CargoResult < ( ) > {
159- // If --name is already used to override, no point in suggesting it
160- // again as a fix.
161- let name_help = match opts. name {
162- Some ( _) => "" ,
163- None => "\n use --name to override crate name" ,
164- } ;
158+ fn check_name ( name : & str , name_help : & str , has_bin : bool , shell : & mut Shell ) -> CargoResult < ( ) > {
159+ restricted_names:: validate_package_name ( name, "crate name" , name_help) ?;
165160
166- // Ban keywords + test list found at
167- // https://doc.rust-lang.org/reference/keywords.html
168- let blacklist = [
169- "abstract" , "alignof" , "as" , "become" , "box" , "break" , "const" , "continue" , "crate" , "do" ,
170- "else" , "enum" , "extern" , "false" , "final" , "fn" , "for" , "if" , "impl" , "in" , "let" , "loop" ,
171- "macro" , "match" , "mod" , "move" , "mut" , "offsetof" , "override" , "priv" , "proc" , "pub" ,
172- "pure" , "ref" , "return" , "self" , "sizeof" , "static" , "struct" , "super" , "test" , "trait" ,
173- "true" , "type" , "typeof" , "unsafe" , "unsized" , "use" , "virtual" , "where" , "while" , "yield" ,
174- ] ;
175- if blacklist. contains ( & name) || ( opts. kind . is_bin ( ) && compiler:: is_bad_artifact_name ( name) ) {
161+ if restricted_names:: is_keyword ( name) {
176162 anyhow:: bail!(
177- "The name `{}` cannot be used as a crate name{}" ,
163+ "the name `{}` cannot be used as a crate name, it is a Rust keyword {}" ,
178164 name,
179165 name_help
180- )
166+ ) ;
181167 }
182-
183- if let Some ( ref c) = name. chars ( ) . next ( ) {
184- if c. is_digit ( 10 ) {
168+ if restricted_names:: is_conflicting_artifact_name ( name) {
169+ if has_bin {
185170 anyhow:: bail!(
186- "Package names starting with a digit cannot be used as a crate name{}" ,
171+ "the name `{}` cannot be used as a crate name, \
172+ it conflicts with cargo's build directory names{}",
173+ name,
187174 name_help
188- )
175+ ) ;
176+ } else {
177+ shell. warn ( format ! (
178+ "the name `{}` will not support binary \
179+ executables with that name, \
180+ it conflicts with cargo's build directory names",
181+ name
182+ ) ) ?;
189183 }
190184 }
185+ if name == "test" {
186+ anyhow:: bail!(
187+ "the name `test` cannot be used as a crate name, \
188+ it conflicts with Rust's built-in test library{}",
189+ name_help
190+ ) ;
191+ }
192+ if [ "core" , "std" , "alloc" , "proc_macro" , "proc-macro" ] . contains ( & name) {
193+ shell. warn ( format ! (
194+ "the name `{}` is part of Rust's standard library\n \
195+ It is recommended to use a different name to avoid problems.",
196+ name
197+ ) ) ?;
198+ }
199+ if restricted_names:: is_windows_reserved ( name) {
200+ if cfg ! ( windows) {
201+ anyhow:: bail!(
202+ "cannot use name `{}`, it is a reserved Windows filename{}" ,
203+ name,
204+ name_help
205+ ) ;
206+ } else {
207+ shell. warn ( format ! (
208+ "the name `{}` is a reserved Windows filename\n \
209+ This package will not work on Windows platforms.",
210+ name
211+ ) ) ?;
212+ }
213+ }
214+ if restricted_names:: is_non_ascii_name ( name) {
215+ shell. warn ( format ! (
216+ "the name `{}` contains non-ASCII characters\n \
217+ Support for non-ASCII crate names is experimental and only valid \
218+ on the nightly toolchain.",
219+ name
220+ ) ) ?;
221+ }
191222
192- validate_package_name ( name, "crate name" , name_help) ?;
193223 Ok ( ( ) )
194224}
195225
@@ -337,7 +367,7 @@ pub fn new(opts: &NewOptions, config: &Config) -> CargoResult<()> {
337367 }
338368
339369 let name = get_name ( path, opts) ?;
340- check_name ( name, opts) ?;
370+ check_name ( name, "" , opts. kind . is_bin ( ) , & mut config . shell ( ) ) ?;
341371
342372 let mkopts = MkOptions {
343373 version_control : opts. version_control ,
@@ -372,7 +402,6 @@ pub fn init(opts: &NewOptions, config: &Config) -> CargoResult<()> {
372402 }
373403
374404 let name = get_name ( path, opts) ?;
375- check_name ( name, opts) ?;
376405
377406 let mut src_paths_types = vec ! [ ] ;
378407
@@ -385,6 +414,14 @@ pub fn init(opts: &NewOptions, config: &Config) -> CargoResult<()> {
385414 // Maybe when doing `cargo init --bin` inside a library package stub,
386415 // user may mean "initialize for library, but also add binary target"
387416 }
417+ let has_bin = src_paths_types. iter ( ) . any ( |x| x. bin ) ;
418+ // If --name is already used to override, no point in suggesting it
419+ // again as a fix.
420+ let name_help = match opts. name {
421+ Some ( _) => "" ,
422+ None => "\n use --name to override crate name" ,
423+ } ;
424+ check_name ( name, name_help, has_bin, & mut config. shell ( ) ) ?;
388425
389426 let mut version_control = opts. version_control ;
390427
@@ -426,7 +463,7 @@ pub fn init(opts: &NewOptions, config: &Config) -> CargoResult<()> {
426463 version_control,
427464 path,
428465 name,
429- bin : src_paths_types . iter ( ) . any ( |x| x . bin ) ,
466+ bin : has_bin ,
430467 source_files : src_paths_types,
431468 edition : opts. edition . as_ref ( ) . map ( |s| & * * s) ,
432469 registry : opts. registry . as_ref ( ) . map ( |s| & * * s) ,
0 commit comments