diff --git a/src/librustc/hir/map/definitions.rs b/src/librustc/hir/map/definitions.rs index c85cee7366055..fa4bf1511b874 100644 --- a/src/librustc/hir/map/definitions.rs +++ b/src/librustc/hir/map/definitions.rs @@ -287,6 +287,31 @@ impl DefPath { s } + /// Return filename friendly string of the DefPah with the + /// crate-prefix. + pub fn to_string_friendly(&self, crate_imported_name: F) -> String + where F: FnOnce(CrateNum) -> Symbol + { + let crate_name_str = crate_imported_name(self.krate).as_str(); + let mut s = String::with_capacity(crate_name_str.len() + self.data.len() * 16); + + write!(s, "::{}", crate_name_str).unwrap(); + + for component in &self.data { + if component.disambiguator == 0 { + write!(s, "::{}", component.data.as_interned_str()).unwrap(); + } else { + write!(s, + "{}[{}]", + component.data.as_interned_str(), + component.disambiguator) + .unwrap(); + } + } + + s + } + /// Return filename friendly string of the DefPah without /// the crate-prefix. This method is useful if you don't have /// a TyCtxt available. diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 619262abb0bf5..18fc3538537d2 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -37,7 +37,7 @@ use syntax::parse; use syntax::parse::ParseSess; use syntax::{ast, source_map}; use syntax::feature_gate::AttributeType; -use syntax_pos::{MultiSpan, Span}; +use syntax_pos::{MultiSpan, Span, symbol::Symbol}; use util::profiling::SelfProfiler; use rustc_target::spec::PanicStrategy; @@ -164,6 +164,10 @@ pub struct Session { /// Cap lint level specified by a driver specifically. pub driver_lint_caps: FxHashMap, + + /// All the crate names specified with `--extern`, and the builtin ones. + /// Starting with the Rust 2018 edition, absolute paths resolve in this set. + pub extern_prelude: FxHashSet, } pub struct PerfStats { @@ -1109,6 +1113,17 @@ pub fn build_session_( }; let working_dir = file_path_mapping.map_prefix(working_dir); + let mut extern_prelude: FxHashSet = + sopts.externs.iter().map(|kv| Symbol::intern(kv.0)).collect(); + + // HACK(eddyb) this ignores the `no_{core,std}` attributes. + // FIXME(eddyb) warn (somewhere) if core/std is used with `no_{core,std}`. + // if !attr::contains_name(&krate.attrs, "no_core") { + // if !attr::contains_name(&krate.attrs, "no_std") { + extern_prelude.insert(Symbol::intern("core")); + extern_prelude.insert(Symbol::intern("std")); + extern_prelude.insert(Symbol::intern("meta")); + let sess = Session { target: target_cfg, host, @@ -1183,6 +1198,7 @@ pub fn build_session_( has_global_allocator: Once::new(), has_panic_handler: Once::new(), driver_lint_caps: FxHashMap(), + extern_prelude, }; validate_commandline_args_with_session_available(&sess); diff --git a/src/librustc/ty/query/on_disk_cache.rs b/src/librustc/ty/query/on_disk_cache.rs index 0e4d2f1f64730..296602e21bad7 100644 --- a/src/librustc/ty/query/on_disk_cache.rs +++ b/src/librustc/ty/query/on_disk_cache.rs @@ -606,6 +606,7 @@ impl<'a, 'tcx, 'x> SpecializedDecoder for CacheDecoder<'a, ' alloc_decoding_session.decode_alloc_id(self) } } + impl<'a, 'tcx, 'x> SpecializedDecoder for CacheDecoder<'a, 'tcx, 'x> { fn specialized_decode(&mut self) -> Result { let tag: u8 = Decodable::decode(self)?; diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 6eef2397f9c6e..fa2debf2c0dc7 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -256,6 +256,7 @@ impl<'a> CrateLoader<'a> { let cmeta = cstore::CrateMetadata { name: crate_root.name, + imported_name: ident, extern_crate: Lock::new(None), def_path_table: Lrc::new(def_path_table), trait_impls, diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs index aad632f89180d..ec48a4a4c6997 100644 --- a/src/librustc_metadata/cstore.rs +++ b/src/librustc_metadata/cstore.rs @@ -53,8 +53,13 @@ pub struct ImportedSourceFile { } pub struct CrateMetadata { + /// Original name of the crate. pub name: Symbol, + /// Name of the crate as imported. I.e. if imported with + /// `extern crate foo as bar;` this will be `bar`. + pub imported_name: Symbol, + /// Information about the extern crate that caused this crate to /// be loaded. If this is `None`, then the crate was injected /// (e.g., by the allocator) diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index 4382a3c12c961..4bea8558ffe27 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -441,8 +441,7 @@ impl cstore::CStore { let data = self.get_crate_data(id.krate); if let Some(ref proc_macros) = data.proc_macros { return LoadedMacro::ProcMacro(proc_macros[id.index.to_proc_macro_index()].1.clone()); - } else if data.name == "proc_macro" && - self.get_crate_data(id.krate).item_name(id.index) == "quote" { + } else if data.name == "proc_macro" && data.item_name(id.index) == "quote" { use syntax::ext::base::SyntaxExtension; use syntax_ext::proc_macro_impl::BangProcMacro; @@ -454,8 +453,9 @@ impl cstore::CStore { return LoadedMacro::ProcMacro(Lrc::new(ext)); } - let (name, def) = data.get_macro(id.index); - let source_name = FileName::Macros(name.to_string()); + let def = data.get_macro(id.index); + let macro_full_name = data.def_path(id.index).to_string_friendly(|_| data.imported_name); + let source_name = FileName::Macros(macro_full_name); let source_file = sess.parse_sess.source_map().new_source_file(source_name, def.body); let local_span = Span::new(source_file.start_pos, source_file.end_pos, NO_EXPANSION); diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 43b03cb863c74..044d23270aa06 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -1101,10 +1101,10 @@ impl<'a, 'tcx> CrateMetadata { } } - pub fn get_macro(&self, id: DefIndex) -> (InternedString, MacroDef) { + pub fn get_macro(&self, id: DefIndex) -> MacroDef { let entry = self.entry(id); match entry.kind { - EntryKind::MacroDef(macro_def) => (self.item_name(id), macro_def.decode(self)), + EntryKind::MacroDef(macro_def) => macro_def.decode(self), _ => bug!(), } } diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 168603d4179a7..e393aa9921845 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1350,7 +1350,6 @@ pub struct Resolver<'a, 'b: 'a> { graph_root: Module<'a>, prelude: Option>, - extern_prelude: FxHashSet, /// n.b. This is used only for better diagnostics, not name resolution itself. has_self: FxHashSet, @@ -1663,17 +1662,6 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { DefCollector::new(&mut definitions, Mark::root()) .collect_root(crate_name, session.local_crate_disambiguator()); - let mut extern_prelude: FxHashSet = - session.opts.externs.iter().map(|kv| Symbol::intern(kv.0)).collect(); - - // HACK(eddyb) this ignore the `no_{core,std}` attributes. - // FIXME(eddyb) warn (elsewhere) if core/std is used with `no_{core,std}`. - // if !attr::contains_name(&krate.attrs, "no_core") { - // if !attr::contains_name(&krate.attrs, "no_std") { - extern_prelude.insert(Symbol::intern("core")); - extern_prelude.insert(Symbol::intern("std")); - extern_prelude.insert(Symbol::intern("meta")); - let mut invocations = FxHashMap(); invocations.insert(Mark::root(), arenas.alloc_invocation_data(InvocationData::root(graph_root))); @@ -1692,7 +1680,6 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { // AST. graph_root, prelude: None, - extern_prelude, has_self: FxHashSet(), field_names: FxHashMap(), @@ -1963,7 +1950,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { if !module.no_implicit_prelude { // `record_used` means that we don't try to load crates during speculative resolution - if record_used && ns == TypeNS && self.extern_prelude.contains(&ident.name) { + if record_used && ns == TypeNS && self.session.extern_prelude.contains(&ident.name) { let crate_id = self.crate_loader.process_path_extern(ident.name, ident.span); let crate_root = self.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX }); self.populate_module_if_necessary(&crate_root); @@ -3950,7 +3937,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { } else { // Items from the prelude if !module.no_implicit_prelude { - names.extend(self.extern_prelude.iter().cloned()); + names.extend(self.session.extern_prelude.iter().cloned()); if let Some(prelude) = self.prelude { add_module_candidates(prelude, &mut names); } @@ -4396,8 +4383,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { ); if self.session.rust_2018() { - let extern_prelude_names = self.extern_prelude.clone(); - for &name in extern_prelude_names.iter() { + for &name in &self.session.extern_prelude { let ident = Ident::with_empty_ctxt(name); match self.crate_loader.maybe_process_path_extern(name, ident.span) { Some(crate_id) => { diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 35d96b9302b43..b320ef032f258 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -575,6 +575,13 @@ impl<'a, 'cl> Resolver<'a, 'cl> { // 5. Standard library prelude (de-facto closed, controlled). // 6. Language prelude (closed, controlled). // (Macro NS) + // 0. Derive helpers (open, not controlled). All ambiguities with other names + // are currently reported as errors. They should be higher in priority than preludes + // and probably even names in modules according to the "general principles" above. They + // also should be subject to restricted shadowing because are effectively produced by + // derives (you need to resolve the derive first to add helpers into scope), but they + // should be available before the derive is expanded for compatibility. + // It's mess in general, so we are being conservative for now. // 1. Names in modules (both normal `mod`ules and blocks), loop through hygienic parents // (open, not controlled). // 2. `macro_use` prelude (open, the open part is from macro expansions, not controlled). @@ -583,13 +590,6 @@ impl<'a, 'cl> Resolver<'a, 'cl> { // 2b. Standard library prelude is currently implemented as `macro-use` (closed, controlled) // 3. Language prelude: builtin macros (closed, controlled, except for legacy plugins). // 4. Language prelude: builtin attributes (closed, controlled). - // N (unordered). Derive helpers (open, not controlled). All ambiguities with other names - // are currently reported as errors. They should be higher in priority than preludes - // and maybe even names in modules according to the "general principles" above. They - // also should be subject to restricted shadowing because are effectively produced by - // derives (you need to resolve the derive first to add helpers into scope), but they - // should be available before the derive is expanded for compatibility. - // It's mess in general, so we are being conservative for now. assert!(ns == TypeNS || ns == MacroNS); assert!(force || !record_used); // `record_used` implies `force` @@ -621,7 +621,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { } // Go through all the scopes and try to resolve the name. - let mut where_to_resolve = WhereToResolve::Module(parent_scope.module); + let mut where_to_resolve = WhereToResolve::DeriveHelpers; let mut use_prelude = !parent_scope.module.no_implicit_prelude; loop { let result = match where_to_resolve { @@ -681,7 +681,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { result } WhereToResolve::ExternPrelude => { - if use_prelude && self.extern_prelude.contains(&ident.name) { + if use_prelude && self.session.extern_prelude.contains(&ident.name) { let crate_id = self.crate_loader.process_path_extern(ident.name, ident.span); let crate_root = @@ -751,8 +751,8 @@ impl<'a, 'cl> Resolver<'a, 'cl> { } WhereToResolve::MacroUsePrelude => WhereToResolve::BuiltinMacros, WhereToResolve::BuiltinMacros => WhereToResolve::BuiltinAttrs, - WhereToResolve::BuiltinAttrs => WhereToResolve::DeriveHelpers, - WhereToResolve::DeriveHelpers => break, // nowhere else to search + WhereToResolve::BuiltinAttrs => break, // nowhere else to search + WhereToResolve::DeriveHelpers => WhereToResolve::Module(parent_scope.module), WhereToResolve::ExternPrelude => WhereToResolve::ToolPrelude, WhereToResolve::ToolPrelude => WhereToResolve::StdLibPrelude, WhereToResolve::StdLibPrelude => WhereToResolve::BuiltinTypes, diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index dc4a76db69266..e689e6d70fdf4 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -199,7 +199,7 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { if !( ns == TypeNS && !ident.is_path_segment_keyword() && - self.extern_prelude.contains(&ident.name) + self.session.extern_prelude.contains(&ident.name) ) { // ... unless the crate name is not in the `extern_prelude`. return binding; @@ -218,7 +218,7 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { } else if ns == TypeNS && !ident.is_path_segment_keyword() && - self.extern_prelude.contains(&ident.name) + self.session.extern_prelude.contains(&ident.name) { let crate_id = self.crate_loader.process_path_extern(ident.name, ident.span); @@ -735,7 +735,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { let uniform_paths_feature = self.session.features_untracked().uniform_paths; for ((span, _, ns), results) in uniform_paths_canaries { let name = results.name; - let external_crate = if ns == TypeNS && self.extern_prelude.contains(&name) { + let external_crate = if ns == TypeNS && self.session.extern_prelude.contains(&name) { let crate_id = self.crate_loader.process_path_extern(name, span); Some(Def::Mod(DefId { krate: crate_id, index: CRATE_DEF_INDEX })) diff --git a/src/librustc_typeck/check_unused.rs b/src/librustc_typeck/check_unused.rs index 5967bd1ba3eea..4b3f08a10ff5e 100644 --- a/src/librustc_typeck/check_unused.rs +++ b/src/librustc_typeck/check_unused.rs @@ -130,15 +130,13 @@ fn unused_crates_lint<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>) { }); for extern_crate in &crates_to_lint { - assert!(extern_crate.def_id.is_local()); + let id = tcx.hir.as_local_node_id(extern_crate.def_id).unwrap(); + let item = tcx.hir.expect_item(id); // If the crate is fully unused, we suggest removing it altogether. // We do this in any edition. if extern_crate.warn_if_unused { if let Some(&span) = unused_extern_crates.get(&extern_crate.def_id) { - assert_eq!(extern_crate.def_id.krate, LOCAL_CRATE); - let hir_id = tcx.hir.definitions().def_index_to_hir_id(extern_crate.def_id.index); - let id = tcx.hir.hir_to_node_id(hir_id); let msg = "unused extern crate"; tcx.struct_span_lint_node(lint, id, span, msg) .span_suggestion_short_with_applicability( @@ -157,6 +155,13 @@ fn unused_crates_lint<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>) { continue; } + // If the extern crate isn't in the extern prelude, + // there is no way it can be written as an `use`. + let orig_name = extern_crate.orig_name.unwrap_or(item.name); + if !tcx.sess.extern_prelude.contains(&orig_name) { + continue; + } + // If the extern crate has any attributes, they may have funky // semantics we can't faithfully represent using `use` (most // notably `#[macro_use]`). Ignore it. @@ -165,9 +170,6 @@ fn unused_crates_lint<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>) { } // Otherwise, we can convert it into a `use` of some kind. - let hir_id = tcx.hir.definitions().def_index_to_hir_id(extern_crate.def_id.index); - let id = tcx.hir.hir_to_node_id(hir_id); - let item = tcx.hir.expect_item(id); let msg = "`extern crate` is not idiomatic in the new edition"; let help = format!( "convert it to a `{}`", diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs index 63b70b1224840..bc4b7385d8aff 100644 --- a/src/libsyntax/config.rs +++ b/src/libsyntax/config.rs @@ -89,6 +89,7 @@ impl<'a> StripUnconfigured<'a> { parser.expect(&token::Comma)?; let lo = parser.span.lo(); let (path, tokens) = parser.parse_meta_item_unrestricted()?; + parser.eat(&token::Comma); // Optional trailing comma parser.expect(&token::CloseDelim(token::Paren))?; Ok((cfg, path, tokens, parser.prev_span.with_lo(lo))) }) { diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs index bd70344b01812..67fd847a2ae91 100644 --- a/src/libsyntax_pos/lib.rs +++ b/src/libsyntax_pos/lib.rs @@ -87,7 +87,7 @@ scoped_thread_local!(pub static GLOBALS: Globals); #[derive(Debug, Eq, PartialEq, Clone, Ord, PartialOrd, Hash, RustcDecodable, RustcEncodable)] pub enum FileName { Real(PathBuf), - /// e.g. "std" macros + /// A macro. This includes the full name of the macro, so that there are no clashes. Macros(String), /// call to `quote!` QuoteExpansion, diff --git a/src/test/compile-fail-fulldeps/proc-macro/proc-macro-attributes.rs b/src/test/compile-fail-fulldeps/proc-macro/proc-macro-attributes.rs index 83bbb7c13c43f..d0aed8b162486 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/proc-macro-attributes.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/proc-macro-attributes.rs @@ -11,13 +11,11 @@ // aux-build:derive-b.rs // ignore-stage1 -#![allow(warnings)] - #[macro_use] extern crate derive_b; -#[B] //~ ERROR `B` is a derive mode -#[C] +#[B] +#[C] //~ ERROR attribute `C` is currently unknown to the compiler #[B(D)] #[B(E = "foo")] #[B(arbitrary tokens)] diff --git a/src/test/ui-fulldeps/custom-derive/auxiliary/plugin.rs b/src/test/ui-fulldeps/custom-derive/auxiliary/plugin.rs index 7be909c3c9e87..124bc05b7a348 100644 --- a/src/test/ui-fulldeps/custom-derive/auxiliary/plugin.rs +++ b/src/test/ui-fulldeps/custom-derive/auxiliary/plugin.rs @@ -25,3 +25,13 @@ pub fn derive_foo(input: TokenStream) -> TokenStream { pub fn derive_bar(input: TokenStream) -> TokenStream { panic!("lolnope"); } + +#[proc_macro_derive(WithHelper, attributes(helper))] +pub fn with_helper(input: TokenStream) -> TokenStream { + TokenStream::new() +} + +#[proc_macro_attribute] +pub fn helper(_: TokenStream, input: TokenStream) -> TokenStream { + input +} diff --git a/src/test/ui-fulldeps/custom-derive/helper-attr-blocked-by-import-ambig.rs b/src/test/ui-fulldeps/custom-derive/helper-attr-blocked-by-import-ambig.rs new file mode 100644 index 0000000000000..b750a8bb0d932 --- /dev/null +++ b/src/test/ui-fulldeps/custom-derive/helper-attr-blocked-by-import-ambig.rs @@ -0,0 +1,13 @@ +// aux-build:plugin.rs +// ignore-stage1 + +#[macro_use(WithHelper)] +extern crate plugin; + +use plugin::helper; + +#[derive(WithHelper)] +#[helper] //~ ERROR `helper` is ambiguous +struct S; + +fn main() {} diff --git a/src/test/ui-fulldeps/custom-derive/helper-attr-blocked-by-import-ambig.stderr b/src/test/ui-fulldeps/custom-derive/helper-attr-blocked-by-import-ambig.stderr new file mode 100644 index 0000000000000..059629c0b62d5 --- /dev/null +++ b/src/test/ui-fulldeps/custom-derive/helper-attr-blocked-by-import-ambig.stderr @@ -0,0 +1,20 @@ +error[E0659]: `helper` is ambiguous + --> $DIR/helper-attr-blocked-by-import-ambig.rs:10:3 + | +LL | #[helper] //~ ERROR `helper` is ambiguous + | ^^^^^^ ambiguous name + | +note: `helper` could refer to the name defined here + --> $DIR/helper-attr-blocked-by-import-ambig.rs:9:10 + | +LL | #[derive(WithHelper)] + | ^^^^^^^^^^ +note: `helper` could also refer to the name imported here + --> $DIR/helper-attr-blocked-by-import-ambig.rs:7:5 + | +LL | use plugin::helper; + | ^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0659`. diff --git a/src/test/ui-fulldeps/custom-derive/helper-attr-blocked-by-import.rs b/src/test/ui-fulldeps/custom-derive/helper-attr-blocked-by-import.rs new file mode 100644 index 0000000000000..03b774f6c6400 --- /dev/null +++ b/src/test/ui-fulldeps/custom-derive/helper-attr-blocked-by-import.rs @@ -0,0 +1,29 @@ +// compile-pass +// aux-build:plugin.rs +// ignore-stage1 + +#[macro_use(WithHelper)] +extern crate plugin; + +use self::one::*; +use self::two::*; + +mod helper {} + +mod one { + use helper; + + #[derive(WithHelper)] + #[helper] + struct One; +} + +mod two { + use helper; + + #[derive(WithHelper)] + #[helper] + struct Two; +} + +fn main() {} diff --git a/src/test/ui-fulldeps/proc-macro/derive-helper-shadowing.stderr b/src/test/ui-fulldeps/proc-macro/derive-helper-shadowing.stderr index cdfecb3d10146..e0aeae4ba6c54 100644 --- a/src/test/ui-fulldeps/proc-macro/derive-helper-shadowing.stderr +++ b/src/test/ui-fulldeps/proc-macro/derive-helper-shadowing.stderr @@ -4,17 +4,16 @@ error[E0659]: `my_attr` is ambiguous LL | #[my_attr] //~ ERROR `my_attr` is ambiguous | ^^^^^^^ ambiguous name | -note: `my_attr` could refer to the name imported here - --> $DIR/derive-helper-shadowing.rs:4:5 - | -LL | use derive_helper_shadowing::*; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: `my_attr` could also refer to the name defined here +note: `my_attr` could refer to the name defined here --> $DIR/derive-helper-shadowing.rs:7:10 | LL | #[derive(MyTrait)] | ^^^^^^^ - = note: consider adding an explicit import of `my_attr` to disambiguate +note: `my_attr` could also refer to the name imported here + --> $DIR/derive-helper-shadowing.rs:4:5 + | +LL | use derive_helper_shadowing::*; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui-fulldeps/unnecessary-extern-crate.rs b/src/test/ui-fulldeps/unnecessary-extern-crate.rs index df723ddf590c4..1cdc9229d078c 100644 --- a/src/test/ui-fulldeps/unnecessary-extern-crate.rs +++ b/src/test/ui-fulldeps/unnecessary-extern-crate.rs @@ -20,33 +20,23 @@ extern crate alloc as x; //~^ ERROR unused extern crate //~| HELP remove +extern crate proc_macro; + #[macro_use] extern crate test; pub extern crate test as y; -//~^ ERROR `extern crate` is not idiomatic in the new edition -//~| HELP convert it to a `pub use` pub extern crate libc; -//~^ ERROR `extern crate` is not idiomatic in the new edition -//~| HELP convert it to a `pub use` pub(crate) extern crate libc as a; -//~^ ERROR `extern crate` is not idiomatic in the new edition -//~| HELP convert it to a `pub(crate) use` crate extern crate libc as b; -//~^ ERROR `extern crate` is not idiomatic in the new edition -//~| HELP convert it to a `crate use` mod foo { pub(in crate::foo) extern crate libc as c; - //~^ ERROR `extern crate` is not idiomatic in the new edition - //~| HELP convert it to a `pub(in crate::foo) use` pub(super) extern crate libc as d; - //~^ ERROR `extern crate` is not idiomatic in the new edition - //~| HELP convert it to a `pub(super) use` extern crate alloc; //~^ ERROR unused extern crate @@ -57,12 +47,8 @@ mod foo { //~| HELP remove pub extern crate test; - //~^ ERROR `extern crate` is not idiomatic in the new edition - //~| HELP convert it pub extern crate test as y; - //~^ ERROR `extern crate` is not idiomatic in the new edition - //~| HELP convert it mod bar { extern crate alloc; @@ -74,8 +60,6 @@ mod foo { //~| HELP remove pub(in crate::foo::bar) extern crate libc as e; - //~^ ERROR `extern crate` is not idiomatic in the new edition - //~| HELP convert it to a `pub(in crate::foo::bar) use` fn dummy() { unsafe { @@ -96,4 +80,6 @@ mod foo { fn main() { unsafe { a::getpid(); } unsafe { b::getpid(); } + + proc_macro::TokenStream::new(); } diff --git a/src/test/ui-fulldeps/unnecessary-extern-crate.stderr b/src/test/ui-fulldeps/unnecessary-extern-crate.stderr index a4307112157b0..58ec5901585d4 100644 --- a/src/test/ui-fulldeps/unnecessary-extern-crate.stderr +++ b/src/test/ui-fulldeps/unnecessary-extern-crate.stderr @@ -16,83 +16,29 @@ error: unused extern crate LL | extern crate alloc as x; | ^^^^^^^^^^^^^^^^^^^^^^^^ help: remove it -error: `extern crate` is not idiomatic in the new edition - --> $DIR/unnecessary-extern-crate.rs:26:1 - | -LL | pub extern crate test as y; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `pub use` - -error: `extern crate` is not idiomatic in the new edition - --> $DIR/unnecessary-extern-crate.rs:30:1 - | -LL | pub extern crate libc; - | ^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `pub use` - -error: `extern crate` is not idiomatic in the new edition - --> $DIR/unnecessary-extern-crate.rs:34:1 - | -LL | pub(crate) extern crate libc as a; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `pub(crate) use` - -error: `extern crate` is not idiomatic in the new edition - --> $DIR/unnecessary-extern-crate.rs:38:1 - | -LL | crate extern crate libc as b; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `crate use` - -error: `extern crate` is not idiomatic in the new edition - --> $DIR/unnecessary-extern-crate.rs:43:5 - | -LL | pub(in crate::foo) extern crate libc as c; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `pub(in crate::foo) use` - -error: `extern crate` is not idiomatic in the new edition - --> $DIR/unnecessary-extern-crate.rs:47:5 - | -LL | pub(super) extern crate libc as d; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `pub(super) use` - error: unused extern crate - --> $DIR/unnecessary-extern-crate.rs:51:5 + --> $DIR/unnecessary-extern-crate.rs:41:5 | LL | extern crate alloc; | ^^^^^^^^^^^^^^^^^^^ help: remove it error: unused extern crate - --> $DIR/unnecessary-extern-crate.rs:55:5 + --> $DIR/unnecessary-extern-crate.rs:45:5 | LL | extern crate alloc as x; | ^^^^^^^^^^^^^^^^^^^^^^^^ help: remove it -error: `extern crate` is not idiomatic in the new edition - --> $DIR/unnecessary-extern-crate.rs:59:5 - | -LL | pub extern crate test; - | ^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `pub use` - -error: `extern crate` is not idiomatic in the new edition - --> $DIR/unnecessary-extern-crate.rs:63:5 - | -LL | pub extern crate test as y; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `pub use` - error: unused extern crate - --> $DIR/unnecessary-extern-crate.rs:68:9 + --> $DIR/unnecessary-extern-crate.rs:54:9 | LL | extern crate alloc; | ^^^^^^^^^^^^^^^^^^^ help: remove it error: unused extern crate - --> $DIR/unnecessary-extern-crate.rs:72:9 + --> $DIR/unnecessary-extern-crate.rs:58:9 | LL | extern crate alloc as x; | ^^^^^^^^^^^^^^^^^^^^^^^^ help: remove it -error: `extern crate` is not idiomatic in the new edition - --> $DIR/unnecessary-extern-crate.rs:76:9 - | -LL | pub(in crate::foo::bar) extern crate libc as e; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `pub(in crate::foo::bar) use` - -error: aborting due to 15 previous errors +error: aborting due to 6 previous errors diff --git a/src/test/ui/cfg-attr-trailing-comma.rs b/src/test/ui/cfg-attr-trailing-comma.rs new file mode 100644 index 0000000000000..21e00544ca00b --- /dev/null +++ b/src/test/ui/cfg-attr-trailing-comma.rs @@ -0,0 +1,13 @@ +// compile-flags: --cfg TRUE + +#[cfg_attr(TRUE, inline,)] // OK +fn f() {} + +#[cfg_attr(FALSE, inline,)] // OK +fn g() {} + +#[cfg_attr(TRUE, inline,,)] //~ ERROR expected `)`, found `,` +fn h() {} + +#[cfg_attr(FALSE, inline,,)] //~ ERROR expected `)`, found `,` +fn i() {} diff --git a/src/test/ui/cfg-attr-trailing-comma.stderr b/src/test/ui/cfg-attr-trailing-comma.stderr new file mode 100644 index 0000000000000..76a470417e9ed --- /dev/null +++ b/src/test/ui/cfg-attr-trailing-comma.stderr @@ -0,0 +1,14 @@ +error: expected `)`, found `,` + --> $DIR/cfg-attr-trailing-comma.rs:9:25 + | +LL | #[cfg_attr(TRUE, inline,,)] //~ ERROR expected `)`, found `,` + | ^ expected `)` + +error: expected `)`, found `,` + --> $DIR/cfg-attr-trailing-comma.rs:12:26 + | +LL | #[cfg_attr(FALSE, inline,,)] //~ ERROR expected `)`, found `,` + | ^ expected `)` + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/editions/edition-keywords-2018-2015-parsing.stderr b/src/test/ui/editions/edition-keywords-2018-2015-parsing.stderr index 02e7d5b7cd01c..5955410aa106b 100644 --- a/src/test/ui/editions/edition-keywords-2018-2015-parsing.stderr +++ b/src/test/ui/editions/edition-keywords-2018-2015-parsing.stderr @@ -23,7 +23,7 @@ LL | r#async = consumes_async_raw!(async); //~ ERROR no rules expected the t | ^^^^^ error: expected one of `move`, `|`, or `||`, found `` - --> :1:22 + --> <::edition_kw_macro_2015::passes_ident macros>:1:22 | LL | ( $ i : ident ) => ( $ i ) | ^^^ expected one of `move`, `|`, or `||` here diff --git a/src/test/ui/editions/edition-keywords-2018-2018-parsing.stderr b/src/test/ui/editions/edition-keywords-2018-2018-parsing.stderr index 435e395c2910e..6ea736828f907 100644 --- a/src/test/ui/editions/edition-keywords-2018-2018-parsing.stderr +++ b/src/test/ui/editions/edition-keywords-2018-2018-parsing.stderr @@ -23,7 +23,7 @@ LL | r#async = consumes_async_raw!(async); //~ ERROR no rules expected the t | ^^^^^ error: expected one of `move`, `|`, or `||`, found `` - --> :1:22 + --> <::edition_kw_macro_2018::passes_ident macros>:1:22 | LL | ( $ i : ident ) => ( $ i ) | ^^^ expected one of `move`, `|`, or `||` here diff --git a/src/test/ui/imports/local-modularized-tricky-fail-1.stderr b/src/test/ui/imports/local-modularized-tricky-fail-1.stderr index cce1fd30f1d6d..9c475451ce32f 100644 --- a/src/test/ui/imports/local-modularized-tricky-fail-1.stderr +++ b/src/test/ui/imports/local-modularized-tricky-fail-1.stderr @@ -60,7 +60,7 @@ LL | define_panic!(); = note: macro-expanded macros do not shadow error[E0659]: `panic` is ambiguous - --> :1:13 + --> <::std::macros::panic macros>:1:13 | LL | ( ) => ( { panic ! ( "explicit panic" ) } ) ; ( $ msg : expr ) => ( | ^^^^^ ambiguous name diff --git a/src/test/ui/macro_backtrace/main.stderr b/src/test/ui/macro_backtrace/main.stderr index 10eabca63538d..8cecef508a2b2 100644 --- a/src/test/ui/macro_backtrace/main.stderr +++ b/src/test/ui/macro_backtrace/main.stderr @@ -22,7 +22,7 @@ LL | | } LL | ping!(); | -------- in this macro invocation | - ::: :1:1 + ::: <::ping::ping macros>:1:1 | LL | ( ) => { pong ! ( ) ; } | ------------------------- @@ -42,7 +42,7 @@ LL | | } LL | deep!(); | -------- in this macro invocation (#1) | - ::: :1:1 + ::: <::ping::deep macros>:1:1 | LL | ( ) => { foo ! ( ) ; } | ------------------------ @@ -50,7 +50,7 @@ LL | ( ) => { foo ! ( ) ; } | | in this macro invocation (#2) | in this expansion of `deep!` (#1) | - ::: :1:1 + ::: <::ping::foo macros>:1:1 | LL | ( ) => { bar ! ( ) ; } | ------------------------ @@ -58,7 +58,7 @@ LL | ( ) => { bar ! ( ) ; } | | in this macro invocation (#3) | in this expansion of `foo!` (#2) | - ::: :1:1 + ::: <::ping::bar macros>:1:1 | LL | ( ) => { ping ! ( ) ; } | ------------------------- @@ -66,7 +66,7 @@ LL | ( ) => { ping ! ( ) ; } | | in this macro invocation (#4) | in this expansion of `bar!` (#3) | - ::: :1:1 + ::: <::ping::ping macros>:1:1 | LL | ( ) => { pong ! ( ) ; } | ------------------------- diff --git a/src/test/ui/rust-2018/remove-extern-crate.fixed b/src/test/ui/rust-2018/remove-extern-crate.fixed index cdae815b200d5..34c7266b637cb 100644 --- a/src/test/ui/rust-2018/remove-extern-crate.fixed +++ b/src/test/ui/rust-2018/remove-extern-crate.fixed @@ -14,6 +14,7 @@ // aux-build:remove-extern-crate.rs // compile-flags:--extern remove_extern_crate +#![feature(alloc)] #![warn(rust_2018_idioms)] @@ -22,11 +23,16 @@ use remove_extern_crate; #[macro_use] extern crate remove_extern_crate as something_else; +// Shouldn't suggest changing to `use`, as the `alloc` +// crate is not in the extern prelude - see #54381. +extern crate alloc; + fn main() { another_name::mem::drop(3); another::foo(); remove_extern_crate::foo!(); bar!(); + alloc::vec![5]; } mod another { diff --git a/src/test/ui/rust-2018/remove-extern-crate.rs b/src/test/ui/rust-2018/remove-extern-crate.rs index 4984da802c05b..570bbb02f7218 100644 --- a/src/test/ui/rust-2018/remove-extern-crate.rs +++ b/src/test/ui/rust-2018/remove-extern-crate.rs @@ -14,6 +14,7 @@ // aux-build:remove-extern-crate.rs // compile-flags:--extern remove_extern_crate +#![feature(alloc)] #![warn(rust_2018_idioms)] extern crate core; @@ -22,11 +23,16 @@ use remove_extern_crate; #[macro_use] extern crate remove_extern_crate as something_else; +// Shouldn't suggest changing to `use`, as the `alloc` +// crate is not in the extern prelude - see #54381. +extern crate alloc; + fn main() { another_name::mem::drop(3); another::foo(); remove_extern_crate::foo!(); bar!(); + alloc::vec![5]; } mod another { diff --git a/src/test/ui/rust-2018/remove-extern-crate.stderr b/src/test/ui/rust-2018/remove-extern-crate.stderr index 064a853625f74..847ba5f3544b2 100644 --- a/src/test/ui/rust-2018/remove-extern-crate.stderr +++ b/src/test/ui/rust-2018/remove-extern-crate.stderr @@ -1,24 +1,24 @@ warning: unused extern crate - --> $DIR/remove-extern-crate.rs:19:1 + --> $DIR/remove-extern-crate.rs:20:1 | LL | extern crate core; | ^^^^^^^^^^^^^^^^^^ help: remove it | note: lint level defined here - --> $DIR/remove-extern-crate.rs:17:9 + --> $DIR/remove-extern-crate.rs:18:9 | LL | #![warn(rust_2018_idioms)] | ^^^^^^^^^^^^^^^^ = note: #[warn(unused_extern_crates)] implied by #[warn(rust_2018_idioms)] warning: `extern crate` is not idiomatic in the new edition - --> $DIR/remove-extern-crate.rs:20:1 + --> $DIR/remove-extern-crate.rs:21:1 | LL | extern crate core as another_name; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `use` warning: `extern crate` is not idiomatic in the new edition - --> $DIR/remove-extern-crate.rs:33:5 + --> $DIR/remove-extern-crate.rs:39:5 | LL | extern crate core; | ^^^^^^^^^^^^^^^^^^ help: convert it to a `use`