diff options
66 files changed, 1170 insertions, 1271 deletions
diff --git a/src/librustc/hir/def.rs b/src/librustc/hir/def.rs index 131a910bebb..db568dbf9fb 100644 --- a/src/librustc/hir/def.rs +++ b/src/librustc/hir/def.rs @@ -398,4 +398,12 @@ impl<Id> Res<Id> { Res::Err => Res::Err, } } + + pub fn macro_kind(self) -> Option<MacroKind> { + match self { + Res::Def(DefKind::Macro(kind), _) => Some(kind), + Res::NonMacroAttr(..) => Some(MacroKind::Attr), + _ => None, + } + } } diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 16fd8cccc89..45549800712 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -3,11 +3,11 @@ //! Here we build the "reduced graph": the graph of the module tree without //! any imports resolved. -use crate::macros::{InvocationData, ParentScope, LegacyScope}; +use crate::macros::{InvocationData, LegacyScope}; use crate::resolve_imports::ImportDirective; use crate::resolve_imports::ImportDirectiveSubclass::{self, GlobImport, SingleImport}; use crate::{Module, ModuleData, ModuleKind, NameBinding, NameBindingKind, Segment, ToNameBinding}; -use crate::{ModuleOrUniformRoot, PerNS, Resolver, ResolverArenas, ExternPreludeEntry}; +use crate::{ModuleOrUniformRoot, ParentScope, PerNS, Resolver, ResolverArenas, ExternPreludeEntry}; use crate::Namespace::{self, TypeNS, ValueNS, MacroNS}; use crate::{resolve_error, resolve_struct_error, ResolutionError, Determinacy}; diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index e93a2315ca3..90a4107f773 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -2,21 +2,84 @@ use std::cmp::Reverse; use errors::{Applicability, DiagnosticBuilder, DiagnosticId}; use log::debug; -use rustc::hir::def::{self, DefKind, CtorKind, Namespace::*}; +use rustc::hir::def::{self, DefKind, CtorKind, NonMacroAttrKind}; +use rustc::hir::def::Namespace::{self, *}; use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId}; +use rustc::hir::PrimTy; use rustc::session::{Session, config::nightly_options}; -use syntax::ast::{self, Expr, ExprKind, Ident}; +use rustc::ty::{self, DefIdTree}; +use rustc::util::nodemap::FxHashSet; +use syntax::ast::{self, Expr, ExprKind, Ident, NodeId, Path, Ty, TyKind}; use syntax::ext::base::MacroKind; +use syntax::feature_gate::BUILTIN_ATTRIBUTES; use syntax::symbol::{Symbol, kw}; +use syntax::util::lev_distance::find_best_match_for_name; use syntax_pos::{BytePos, Span}; +use crate::resolve_imports::{ImportDirective, ImportDirectiveSubclass, ImportResolver}; +use crate::{is_self_type, is_self_value, path_names_to_string, KNOWN_TOOLS}; +use crate::{CrateLint, LegacyScope, Module, ModuleKind, ModuleOrUniformRoot}; +use crate::{PathResult, PathSource, ParentScope, Resolver, RibKind, Scope, ScopeSet, Segment}; + type Res = def::Res<ast::NodeId>; -use crate::macros::ParentScope; -use crate::resolve_imports::{ImportDirective, ImportDirectiveSubclass, ImportResolver}; -use crate::{import_candidate_to_enum_paths, is_self_type, is_self_value, path_names_to_string}; -use crate::{AssocSuggestion, CrateLint, ImportSuggestion, ModuleOrUniformRoot, PathResult, - PathSource, Resolver, Segment, Suggestion}; +/// A vector of spans and replacements, a message and applicability. +crate type Suggestion = (Vec<(Span, String)>, String, Applicability); + +/// A field or associated item from self type suggested in case of resolution failure. +enum AssocSuggestion { + Field, + MethodWithSelf, + AssocItem, +} + +struct TypoSuggestion { + candidate: Symbol, + + /// The kind of the binding ("crate", "module", etc.) + kind: &'static str, + + /// An appropriate article to refer to the binding ("a", "an", etc.) + article: &'static str, +} + +impl TypoSuggestion { + fn from_res(candidate: Symbol, res: Res) -> TypoSuggestion { + TypoSuggestion { candidate, kind: res.descr(), article: res.article() } + } +} + +/// A free importable items suggested in case of resolution failure. +crate struct ImportSuggestion { + did: Option<DefId>, + pub path: Path, +} + +fn add_typo_suggestion( + err: &mut DiagnosticBuilder<'_>, suggestion: Option<TypoSuggestion>, span: Span +) -> bool { + if let Some(suggestion) = suggestion { + let msg = format!("{} {} with a similar name exists", suggestion.article, suggestion.kind); + err.span_suggestion( + span, &msg, suggestion.candidate.to_string(), Applicability::MaybeIncorrect + ); + return true; + } + false +} + +fn add_module_candidates( + module: Module<'_>, names: &mut Vec<TypoSuggestion>, filter_fn: &impl Fn(Res) -> bool +) { + for (&(ident, _), resolution) in module.resolutions.borrow().iter() { + if let Some(binding) = resolution.borrow().binding { + let res = binding.res(); + if filter_fn(res) { + names.push(TypoSuggestion::from_res(ident.name, res)); + } + } + } +} impl<'a> Resolver<'a> { /// Handles error reporting for `smart_resolve_path_fragment` function. @@ -204,24 +267,10 @@ impl<'a> Resolver<'a> { } } - let mut levenshtein_worked = false; - // Try Levenshtein algorithm. - let suggestion = self.lookup_typo_candidate(path, ns, is_expected, span); - if let Some(suggestion) = suggestion { - let msg = format!( - "{} {} with a similar name exists", - suggestion.article, suggestion.kind - ); - err.span_suggestion( - ident_span, - &msg, - suggestion.candidate.to_string(), - Applicability::MaybeIncorrect, - ); - - levenshtein_worked = true; - } + let levenshtein_worked = add_typo_suggestion( + &mut err, self.lookup_typo_candidate(path, ns, is_expected, span), ident_span + ); // Try context-dependent help if relaxed lookup didn't work. if let Some(res) = res { @@ -365,7 +414,7 @@ impl<'a> Resolver<'a> { }; match (res, source) { - (Res::Def(DefKind::Macro(..), _), _) => { + (Res::Def(DefKind::Macro(MacroKind::Bang), _), _) => { err.span_suggestion( span, "use `!` to invoke the macro", @@ -439,6 +488,513 @@ impl<'a> Resolver<'a> { } true } + + fn lookup_assoc_candidate<FilterFn>(&mut self, + ident: Ident, + ns: Namespace, + filter_fn: FilterFn) + -> Option<AssocSuggestion> + where FilterFn: Fn(Res) -> bool + { + fn extract_node_id(t: &Ty) -> Option<NodeId> { + match t.node { + TyKind::Path(None, _) => Some(t.id), + TyKind::Rptr(_, ref mut_ty) => extract_node_id(&mut_ty.ty), + // This doesn't handle the remaining `Ty` variants as they are not + // that commonly the self_type, it might be interesting to provide + // support for those in future. + _ => None, + } + } + + // Fields are generally expected in the same contexts as locals. + if filter_fn(Res::Local(ast::DUMMY_NODE_ID)) { + if let Some(node_id) = self.current_self_type.as_ref().and_then(extract_node_id) { + // Look for a field with the same name in the current self_type. + if let Some(resolution) = self.partial_res_map.get(&node_id) { + match resolution.base_res() { + Res::Def(DefKind::Struct, did) | Res::Def(DefKind::Union, did) + if resolution.unresolved_segments() == 0 => { + if let Some(field_names) = self.field_names.get(&did) { + if field_names.iter().any(|&field_name| ident.name == field_name) { + return Some(AssocSuggestion::Field); + } + } + } + _ => {} + } + } + } + } + + for assoc_type_ident in &self.current_trait_assoc_types { + if *assoc_type_ident == ident { + return Some(AssocSuggestion::AssocItem); + } + } + + // Look for associated items in the current trait. + if let Some((module, _)) = self.current_trait_ref { + if let Ok(binding) = self.resolve_ident_in_module( + ModuleOrUniformRoot::Module(module), + ident, + ns, + None, + false, + module.span, + ) { + let res = binding.res(); + if filter_fn(res) { + return Some(if self.has_self.contains(&res.def_id()) { + AssocSuggestion::MethodWithSelf + } else { + AssocSuggestion::AssocItem + }); + } + } + } + + None + } + + /// Lookup typo candidate in scope for a macro or import. + fn early_lookup_typo_candidate( + &mut self, + scope_set: ScopeSet, + parent_scope: &ParentScope<'a>, + ident: Ident, + filter_fn: &impl Fn(Res) -> bool, + ) -> Option<TypoSuggestion> { + let mut suggestions = Vec::new(); + self.visit_scopes(scope_set, parent_scope, ident, |this, scope, _| { + match scope { + Scope::DeriveHelpers => { + let res = Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper); + if filter_fn(res) { + for derive in &parent_scope.derives { + let parent_scope = ParentScope { derives: Vec::new(), ..*parent_scope }; + if let Ok((Some(ext), _)) = this.resolve_macro_path( + derive, Some(MacroKind::Derive), &parent_scope, false, false + ) { + suggestions.extend(ext.helper_attrs.iter().map(|name| { + TypoSuggestion::from_res(*name, res) + })); + } + } + } + } + Scope::MacroRules(legacy_scope) => { + if let LegacyScope::Binding(legacy_binding) = legacy_scope { + let res = legacy_binding.binding.res(); + if filter_fn(res) { + suggestions.push( + TypoSuggestion::from_res(legacy_binding.ident.name, res) + ) + } + } + } + Scope::CrateRoot => { + let root_ident = Ident::new(kw::PathRoot, ident.span); + let root_module = this.resolve_crate_root(root_ident); + add_module_candidates(root_module, &mut suggestions, filter_fn); + } + Scope::Module(module) => { + add_module_candidates(module, &mut suggestions, filter_fn); + } + Scope::MacroUsePrelude => { + suggestions.extend(this.macro_use_prelude.iter().filter_map(|(name, binding)| { + let res = binding.res(); + if filter_fn(res) { + Some(TypoSuggestion::from_res(*name, res)) + } else { + None + } + })); + } + Scope::BuiltinMacros => { + suggestions.extend(this.builtin_macros.iter().filter_map(|(name, binding)| { + let res = binding.res(); + if filter_fn(res) { + Some(TypoSuggestion::from_res(*name, res)) + } else { + None + } + })); + } + Scope::BuiltinAttrs => { + let res = Res::NonMacroAttr(NonMacroAttrKind::Builtin); + if filter_fn(res) { + suggestions.extend(BUILTIN_ATTRIBUTES.iter().map(|(name, ..)| { + TypoSuggestion::from_res(*name, res) + })); + } + } + Scope::LegacyPluginHelpers => { + let res = Res::NonMacroAttr(NonMacroAttrKind::LegacyPluginHelper); + if filter_fn(res) { + let plugin_attributes = this.session.plugin_attributes.borrow(); + suggestions.extend(plugin_attributes.iter().map(|(name, _)| { + TypoSuggestion::from_res(*name, res) + })); + } + } + Scope::ExternPrelude => { + suggestions.extend(this.extern_prelude.iter().filter_map(|(ident, _)| { + let res = Res::Def(DefKind::Mod, DefId::local(CRATE_DEF_INDEX)); + if filter_fn(res) { + Some(TypoSuggestion::from_res(ident.name, res)) + } else { + None + } + })); + } + Scope::ToolPrelude => { + let res = Res::NonMacroAttr(NonMacroAttrKind::Tool); + suggestions.extend(KNOWN_TOOLS.iter().map(|name| { + TypoSuggestion::from_res(*name, res) + })); + } + Scope::StdLibPrelude => { + if let Some(prelude) = this.prelude { + add_module_candidates(prelude, &mut suggestions, filter_fn); + } + } + Scope::BuiltinTypes => { + let primitive_types = &this.primitive_type_table.primitive_types; + suggestions.extend( + primitive_types.iter().flat_map(|(name, prim_ty)| { + let res = Res::PrimTy(*prim_ty); + if filter_fn(res) { + Some(TypoSuggestion::from_res(*name, res)) + } else { + None + } + }) + ) + } + } + + None::<()> + }); + + // Make sure error reporting is deterministic. + suggestions.sort_by_cached_key(|suggestion| suggestion.candidate.as_str()); + + match find_best_match_for_name( + suggestions.iter().map(|suggestion| &suggestion.candidate), + &ident.as_str(), + None, + ) { + Some(found) if found != ident.name => suggestions + .into_iter() + .find(|suggestion| suggestion.candidate == found), + _ => None, + } + } + + fn lookup_typo_candidate( + &mut self, + path: &[Segment], + ns: Namespace, + filter_fn: &impl Fn(Res) -> bool, + span: Span, + ) -> Option<TypoSuggestion> { + let mut names = Vec::new(); + if path.len() == 1 { + // Search in lexical scope. + // Walk backwards up the ribs in scope and collect candidates. + for rib in self.ribs[ns].iter().rev() { + // Locals and type parameters + for (ident, &res) in &rib.bindings { + if filter_fn(res) { + names.push(TypoSuggestion::from_res(ident.name, res)); + } + } + // Items in scope + if let RibKind::ModuleRibKind(module) = rib.kind { + // Items from this module + add_module_candidates(module, &mut names, &filter_fn); + + if let ModuleKind::Block(..) = module.kind { + // We can see through blocks + } else { + // Items from the prelude + if !module.no_implicit_prelude { + names.extend(self.extern_prelude.clone().iter().flat_map(|(ident, _)| { + self.crate_loader + .maybe_process_path_extern(ident.name, ident.span) + .and_then(|crate_id| { + let crate_mod = Res::Def( + DefKind::Mod, + DefId { + krate: crate_id, + index: CRATE_DEF_INDEX, + }, + ); + + if filter_fn(crate_mod) { + Some(TypoSuggestion { + candidate: ident.name, + article: "a", + kind: "crate", + }) + } else { + None + } + }) + })); + + if let Some(prelude) = self.prelude { + add_module_candidates(prelude, &mut names, &filter_fn); + } + } + break; + } + } + } + // Add primitive types to the mix + if filter_fn(Res::PrimTy(PrimTy::Bool)) { + names.extend( + self.primitive_type_table.primitive_types.iter().map(|(name, prim_ty)| { + TypoSuggestion::from_res(*name, Res::PrimTy(*prim_ty)) + }) + ) + } + } else { + // Search in module. + let mod_path = &path[..path.len() - 1]; + if let PathResult::Module(module) = self.resolve_path_without_parent_scope( + mod_path, Some(TypeNS), false, span, CrateLint::No + ) { + if let ModuleOrUniformRoot::Module(module) = module { + add_module_candidates(module, &mut names, &filter_fn); + } + } + } + + let name = path[path.len() - 1].ident.name; + // Make sure error reporting is deterministic. + names.sort_by_cached_key(|suggestion| suggestion.candidate.as_str()); + + match find_best_match_for_name( + names.iter().map(|suggestion| &suggestion.candidate), + &name.as_str(), + None, + ) { + Some(found) if found != name => names + .into_iter() + .find(|suggestion| suggestion.candidate == found), + _ => None, + } + } + + fn lookup_import_candidates_from_module<FilterFn>(&mut self, + lookup_ident: Ident, + namespace: Namespace, + start_module: Module<'a>, + crate_name: Ident, + filter_fn: FilterFn) + -> Vec<ImportSuggestion> + where FilterFn: Fn(Res) -> bool + { + let mut candidates = Vec::new(); + let mut seen_modules = FxHashSet::default(); + let not_local_module = crate_name.name != kw::Crate; + let mut worklist = vec![(start_module, Vec::<ast::PathSegment>::new(), not_local_module)]; + + while let Some((in_module, + path_segments, + in_module_is_extern)) = worklist.pop() { + self.populate_module_if_necessary(in_module); + + // We have to visit module children in deterministic order to avoid + // instabilities in reported imports (#43552). + in_module.for_each_child_stable(|ident, ns, name_binding| { + // avoid imports entirely + if name_binding.is_import() && !name_binding.is_extern_crate() { return; } + // avoid non-importable candidates as well + if !name_binding.is_importable() { return; } + + // collect results based on the filter function + if ident.name == lookup_ident.name && ns == namespace { + let res = name_binding.res(); + if filter_fn(res) { + // create the path + let mut segms = path_segments.clone(); + if lookup_ident.span.rust_2018() { + // crate-local absolute paths start with `crate::` in edition 2018 + // FIXME: may also be stabilized for Rust 2015 (Issues #45477, #44660) + segms.insert( + 0, ast::PathSegment::from_ident(crate_name) + ); + } + + segms.push(ast::PathSegment::from_ident(ident)); + let path = Path { + span: name_binding.span, + segments: segms, + }; + // the entity is accessible in the following cases: + // 1. if it's defined in the same crate, it's always + // accessible (since private entities can be made public) + // 2. if it's defined in another crate, it's accessible + // only if both the module is public and the entity is + // declared as public (due to pruning, we don't explore + // outside crate private modules => no need to check this) + if !in_module_is_extern || name_binding.vis == ty::Visibility::Public { + let did = match res { + Res::Def(DefKind::Ctor(..), did) => self.parent(did), + _ => res.opt_def_id(), + }; + candidates.push(ImportSuggestion { did, path }); + } + } + } + + // collect submodules to explore + if let Some(module) = name_binding.module() { + // form the path + let mut path_segments = path_segments.clone(); + path_segments.push(ast::PathSegment::from_ident(ident)); + + let is_extern_crate_that_also_appears_in_prelude = + name_binding.is_extern_crate() && + lookup_ident.span.rust_2018(); + + let is_visible_to_user = + !in_module_is_extern || name_binding.vis == ty::Visibility::Public; + + if !is_extern_crate_that_also_appears_in_prelude && is_visible_to_user { + // add the module to the lookup + let is_extern = in_module_is_extern || name_binding.is_extern_crate(); + if seen_modules.insert(module.def_id().unwrap()) { + worklist.push((module, path_segments, is_extern)); + } + } + } + }) + } + + candidates + } + + /// When name resolution fails, this method can be used to look up candidate + /// entities with the expected name. It allows filtering them using the + /// supplied predicate (which should be used to only accept the types of + /// definitions expected, e.g., traits). The lookup spans across all crates. + /// + /// N.B., the method does not look into imports, but this is not a problem, + /// since we report the definitions (thus, the de-aliased imports). + crate fn lookup_import_candidates<FilterFn>( + &mut self, lookup_ident: Ident, namespace: Namespace, filter_fn: FilterFn + ) -> Vec<ImportSuggestion> + where FilterFn: Fn(Res) -> bool + { + let mut suggestions = self.lookup_import_candidates_from_module( + lookup_ident, namespace, self.graph_root, Ident::with_empty_ctxt(kw::Crate), &filter_fn + ); + + if lookup_ident.span.rust_2018() { + let extern_prelude_names = self.extern_prelude.clone(); + for (ident, _) in extern_prelude_names.into_iter() { + if let Some(crate_id) = self.crate_loader.maybe_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); + + suggestions.extend(self.lookup_import_candidates_from_module( + lookup_ident, namespace, crate_root, ident, &filter_fn)); + } + } + } + + suggestions + } + + fn find_module(&mut self, def_id: DefId) -> Option<(Module<'a>, ImportSuggestion)> { + let mut result = None; + let mut seen_modules = FxHashSet::default(); + let mut worklist = vec![(self.graph_root, Vec::new())]; + + while let Some((in_module, path_segments)) = worklist.pop() { + // abort if the module is already found + if result.is_some() { break; } + + self.populate_module_if_necessary(in_module); + + in_module.for_each_child_stable(|ident, _, name_binding| { + // abort if the module is already found or if name_binding is private external + if result.is_some() || !name_binding.vis.is_visible_locally() { + return + } + if let Some(module) = name_binding.module() { + // form the path + let mut path_segments = path_segments.clone(); + path_segments.push(ast::PathSegment::from_ident(ident)); + let module_def_id = module.def_id().unwrap(); + if module_def_id == def_id { + let path = Path { + span: name_binding.span, + segments: path_segments, + }; + result = Some((module, ImportSuggestion { did: Some(def_id), path })); + } else { + // add the module to the lookup + if seen_modules.insert(module_def_id) { + worklist.push((module, path_segments)); + } + } + } + }); + } + + result + } + + fn collect_enum_variants(&mut self, def_id: DefId) -> Option<Vec<Path>> { + self.find_module(def_id).map(|(enum_module, enum_import_suggestion)| { + self.populate_module_if_necessary(enum_module); + + let mut variants = Vec::new(); + enum_module.for_each_child_stable(|ident, _, name_binding| { + if let Res::Def(DefKind::Variant, _) = name_binding.res() { + let mut segms = enum_import_suggestion.path.segments.clone(); + segms.push(ast::PathSegment::from_ident(ident)); + variants.push(Path { + span: name_binding.span, + segments: segms, + }); + } + }); + variants + }) + } + + crate fn unresolved_macro_suggestions( + &mut self, + err: &mut DiagnosticBuilder<'a>, + macro_kind: MacroKind, + parent_scope: &ParentScope<'a>, + ident: Ident, + ) { + let is_expected = &|res: Res| res.macro_kind() == Some(macro_kind); + let suggestion = self.early_lookup_typo_candidate( + ScopeSet::Macro(macro_kind), &parent_scope, ident, is_expected + ); + add_typo_suggestion(err, suggestion, ident.span); + + if macro_kind == MacroKind::Derive && + (ident.as_str() == "Send" || ident.as_str() == "Sync") { + let msg = format!("unsafe traits like `{}` should be implemented explicitly", ident); + err.span_note(ident.span, &msg); + } + if self.macro_names.contains(&ident.modern()) { + err.help("have you added the `#[macro_use]` on the module/import?"); + } + } } impl<'a, 'b> ImportResolver<'a, 'b> { @@ -871,3 +1427,70 @@ fn find_span_immediately_after_crate_name( (next_left_bracket == after_second_colon, from_second_colon) } + +/// Gets the stringified path for an enum from an `ImportSuggestion` for an enum variant. +fn import_candidate_to_enum_paths(suggestion: &ImportSuggestion) -> (String, String) { + let variant_path = &suggestion.path; + let variant_path_string = path_names_to_string(variant_path); + + let path_len = suggestion.path.segments.len(); + let enum_path = ast::Path { + span: suggestion.path.span, + segments: suggestion.path.segments[0..path_len - 1].to_vec(), + }; + let enum_path_string = path_names_to_string(&enum_path); + + (variant_path_string, enum_path_string) +} + +/// When an entity with a given name is not available in scope, we search for +/// entities with that name in all crates. This method allows outputting the +/// results of this search in a programmer-friendly way +crate fn show_candidates( + err: &mut DiagnosticBuilder<'_>, + // This is `None` if all placement locations are inside expansions + span: Option<Span>, + candidates: &[ImportSuggestion], + better: bool, + found_use: bool, +) { + // we want consistent results across executions, but candidates are produced + // by iterating through a hash map, so make sure they are ordered: + let mut path_strings: Vec<_> = + candidates.into_iter().map(|c| path_names_to_string(&c.path)).collect(); + path_strings.sort(); + + let better = if better { "better " } else { "" }; + let msg_diff = match path_strings.len() { + 1 => " is found in another module, you can import it", + _ => "s are found in other modules, you can import them", + }; + let msg = format!("possible {}candidate{} into scope", better, msg_diff); + + if let Some(span) = span { + for candidate in &mut path_strings { + // produce an additional newline to separate the new use statement + // from the directly following item. + let additional_newline = if found_use { + "" + } else { + "\n" + }; + *candidate = format!("use {};\n{}", candidate, additional_newline); + } + + err.span_suggestions( + span, + &msg, + path_strings.into_iter(), + Applicability::Unspecified, + ); + } else { + let mut msg = msg; + msg.push(':'); + for candidate in path_strings { + msg.push('\n'); + msg.push_str(&candidate); + } + } +} diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index f867fb20785..ba8cfdcf535 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -31,7 +31,7 @@ use rustc::hir::def::{ use rustc::hir::def::Namespace::*; use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, DefId}; use rustc::hir::{TraitCandidate, TraitMap, GlobMap}; -use rustc::ty::{self, DefIdTree}; +use rustc::ty; use rustc::util::nodemap::{NodeMap, NodeSet, FxHashMap, FxHashSet, DefIdMap}; use rustc::{bug, span_bug}; @@ -69,9 +69,10 @@ use rustc_data_structures::ptr_key::PtrKey; use rustc_data_structures::sync::Lrc; use smallvec::SmallVec; +use diagnostics::{Suggestion, ImportSuggestion}; use diagnostics::{find_span_of_binding_until_next_binding, extend_span_to_previous_binding}; use resolve_imports::{ImportDirective, ImportDirectiveSubclass, NameResolution, ImportResolver}; -use macros::{InvocationData, LegacyBinding, ParentScope}; +use macros::{InvocationData, LegacyBinding, LegacyScope}; type Res = def::Res<NodeId>; @@ -84,9 +85,7 @@ mod check_unused; mod build_reduced_graph; mod resolve_imports; -fn is_known_tool(name: Name) -> bool { - ["clippy", "rustfmt"].contains(&&*name.as_str()) -} +const KNOWN_TOOLS: &[Name] = &[sym::clippy, sym::rustfmt]; enum Weak { Yes, @@ -105,6 +104,29 @@ impl Determinacy { } } +/// A specific scope in which a name can be looked up. +/// This enum is currently used only for early resolution (imports and macros), +/// but not for late resolution yet. +#[derive(Clone, Copy)] +enum Scope<'a> { + DeriveHelpers, + MacroRules(LegacyScope<'a>), + CrateRoot, + Module(Module<'a>), + MacroUsePrelude, + BuiltinMacros, + BuiltinAttrs, + LegacyPluginHelpers, + ExternPrelude, + ToolPrelude, + StdLibPrelude, + BuiltinTypes, +} + +/// Names from different contexts may want to visit different subsets of all specific scopes +/// with different restrictions when looking up the resolution. +/// This enum is currently used only for early resolution (imports and macros), +/// but not for late resolution yet. enum ScopeSet { Import(Namespace), AbsolutePath(Namespace), @@ -112,17 +134,16 @@ enum ScopeSet { Module, } -/// A free importable items suggested in case of resolution failure. -struct ImportSuggestion { - did: Option<DefId>, - path: Path, -} - -/// A field or associated item from self type suggested in case of resolution failure. -enum AssocSuggestion { - Field, - MethodWithSelf, - AssocItem, +/// Everything you need to know about a name's location to resolve it. +/// Serves as a starting point for the scope visitor. +/// This struct is currently used only for early resolution (imports and macros), +/// but not for late resolution yet. +#[derive(Clone, Debug)] +pub struct ParentScope<'a> { + module: Module<'a>, + expansion: Mark, + legacy: LegacyScope<'a>, + derives: Vec<ast::Path>, } #[derive(Eq)] @@ -132,16 +153,6 @@ struct BindingError { target: BTreeSet<Span>, } -struct TypoSuggestion { - candidate: Symbol, - - /// The kind of the binding ("crate", "module", etc.) - kind: &'static str, - - /// An appropriate article to refer to the binding ("a", "an", etc.) - article: &'static str, -} - impl PartialOrd for BindingError { fn partial_cmp(&self, other: &BindingError) -> Option<cmp::Ordering> { Some(self.cmp(other)) @@ -160,9 +171,6 @@ impl Ord for BindingError { } } -/// A vector of spans and replacements, a message and applicability. -type Suggestion = (Vec<(Span, String)>, String, Applicability); - enum ResolutionError<'a> { /// Error E0401: can't use type or const parameters from outer function. GenericParamsFromOuterFunction(Res), @@ -1488,11 +1496,7 @@ impl<'a> NameBinding<'a> { } fn macro_kind(&self) -> Option<MacroKind> { - match self.res() { - Res::Def(DefKind::Macro(kind), _) => Some(kind), - Res::NonMacroAttr(..) => Some(MacroKind::Attr), - _ => None, - } + self.res().macro_kind() } fn descr(&self) -> &'static str { @@ -2134,6 +2138,149 @@ impl<'a> Resolver<'a> { } } + /// A generic scope visitor. + /// Visits scopes in order to resolve some identifier in them or perform other actions. + /// If the callback returns `Some` result, we stop visiting scopes and return it. + fn visit_scopes<T>( + &mut self, + scope_set: ScopeSet, + parent_scope: &ParentScope<'a>, + ident: Ident, + mut visitor: impl FnMut(&mut Self, Scope<'a>, Ident) -> Option<T>, + ) -> Option<T> { + // General principles: + // 1. Not controlled (user-defined) names should have higher priority than controlled names + // built into the language or standard library. This way we can add new names into the + // language or standard library without breaking user code. + // 2. "Closed set" below means new names cannot appear after the current resolution attempt. + // Places to search (in order of decreasing priority): + // (Type NS) + // 1. FIXME: Ribs (type parameters), there's no necessary infrastructure yet + // (open set, not controlled). + // 2. Names in modules (both normal `mod`ules and blocks), loop through hygienic parents + // (open, not controlled). + // 3. Extern prelude (open, the open part is from macro expansions, not controlled). + // 4. Tool modules (closed, controlled right now, but not in the future). + // 5. Standard library prelude (de-facto closed, controlled). + // 6. Language prelude (closed, controlled). + // (Value NS) + // 1. FIXME: Ribs (local variables), there's no necessary infrastructure yet + // (open set, not controlled). + // 2. Names in modules (both normal `mod`ules and blocks), loop through hygienic parents + // (open, not controlled). + // 3. Standard library prelude (de-facto closed, controlled). + // (Macro NS) + // 1-3. 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-3. `macro_rules` (open, not controlled), loop through legacy scopes. Have higher + // priority than prelude macros, but create ambiguities with macros in modules. + // 1-3. Names in modules (both normal `mod`ules and blocks), loop through hygienic parents + // (open, not controlled). Have higher priority than prelude macros, but create + // ambiguities with `macro_rules`. + // 4. `macro_use` prelude (open, the open part is from macro expansions, not controlled). + // 4a. User-defined prelude from macro-use + // (open, the open part is from macro expansions, not controlled). + // 4b. Standard library prelude is currently implemented as `macro-use` (closed, controlled) + // 5. Language prelude: builtin macros (closed, controlled, except for legacy plugins). + // 6. Language prelude: builtin attributes (closed, controlled). + // 4-6. Legacy plugin helpers (open, not controlled). Similar to derive helpers, + // but introduced by legacy plugins using `register_attribute`. Priority is somewhere + // in prelude, not sure where exactly (creates ambiguities with any other prelude names). + + let rust_2015 = ident.span.rust_2015(); + let (ns, is_absolute_path) = match scope_set { + ScopeSet::Import(ns) => (ns, false), + ScopeSet::AbsolutePath(ns) => (ns, true), + ScopeSet::Macro(_) => (MacroNS, false), + ScopeSet::Module => (TypeNS, false), + }; + let mut scope = match ns { + _ if is_absolute_path => Scope::CrateRoot, + TypeNS | ValueNS => Scope::Module(parent_scope.module), + MacroNS => Scope::DeriveHelpers, + }; + let mut ident = ident.modern(); + let mut use_prelude = !parent_scope.module.no_implicit_prelude; + + loop { + let visit = match scope { + Scope::DeriveHelpers => true, + Scope::MacroRules(..) => true, + Scope::CrateRoot => true, + Scope::Module(..) => true, + Scope::MacroUsePrelude => use_prelude || rust_2015, + Scope::BuiltinMacros => true, + Scope::BuiltinAttrs => true, + Scope::LegacyPluginHelpers => use_prelude || rust_2015, + Scope::ExternPrelude => use_prelude || is_absolute_path, + Scope::ToolPrelude => use_prelude, + Scope::StdLibPrelude => use_prelude, + Scope::BuiltinTypes => true, + }; + + if visit { + if let break_result @ Some(..) = visitor(self, scope, ident) { + return break_result; + } + } + + scope = match scope { + Scope::DeriveHelpers => + Scope::MacroRules(parent_scope.legacy), + Scope::MacroRules(legacy_scope) => match legacy_scope { + LegacyScope::Binding(binding) => Scope::MacroRules( + binding.parent_legacy_scope + ), + LegacyScope::Invocation(invoc) => Scope::MacroRules( + invoc.output_legacy_scope.get().unwrap_or(invoc.parent_legacy_scope) + ), + LegacyScope::Empty => Scope::Module(parent_scope.module), + } + Scope::CrateRoot => match ns { + TypeNS => { + ident.span.adjust(Mark::root()); + Scope::ExternPrelude + } + ValueNS | MacroNS => break, + } + Scope::Module(module) => { + use_prelude = !module.no_implicit_prelude; + match self.hygienic_lexical_parent(module, &mut ident.span) { + Some(parent_module) => Scope::Module(parent_module), + None => { + ident.span.adjust(Mark::root()); + match ns { + TypeNS => Scope::ExternPrelude, + ValueNS => Scope::StdLibPrelude, + MacroNS => Scope::MacroUsePrelude, + } + } + } + } + Scope::MacroUsePrelude => Scope::StdLibPrelude, + Scope::BuiltinMacros => Scope::BuiltinAttrs, + Scope::BuiltinAttrs => Scope::LegacyPluginHelpers, + Scope::LegacyPluginHelpers => break, // nowhere else to search + Scope::ExternPrelude if is_absolute_path => break, + Scope::ExternPrelude => Scope::ToolPrelude, + Scope::ToolPrelude => Scope::StdLibPrelude, + Scope::StdLibPrelude => match ns { + TypeNS => Scope::BuiltinTypes, + ValueNS => break, // nowhere else to search + MacroNS => Scope::BuiltinMacros, + } + Scope::BuiltinTypes => break, // nowhere else to search + }; + } + + None + } + /// This resolves the identifier `ident` in the namespace `ns` in the current lexical scope. /// More specifically, we proceed up the hierarchy of scopes and return the binding for /// `ident` in the first scope that defines it (or None if no scopes define it). @@ -2258,7 +2405,7 @@ impl<'a> Resolver<'a> { return Some(LexicalScopeBinding::Item(binding)); } } - if ns == TypeNS && is_known_tool(ident.name) { + if ns == TypeNS && KNOWN_TOOLS.contains(&ident.name) { let binding = (Res::ToolMod, ty::Visibility::Public, DUMMY_SP, Mark::root()).to_name_binding(self.arenas); return Some(LexicalScopeBinding::Item(binding)); @@ -3517,9 +3664,7 @@ impl<'a> Resolver<'a> { crate_lint: CrateLint, ) -> Option<PartialRes> { let mut fin_res = None; - // FIXME: can't resolve paths in macro namespace yet, macros are - // processed by the little special hack below. - for (i, ns) in [primary_ns, TypeNS, ValueNS, /*MacroNS*/].iter().cloned().enumerate() { + for (i, ns) in [primary_ns, TypeNS, ValueNS].iter().cloned().enumerate() { if i == 0 || ns != primary_ns { match self.resolve_qpath(id, qself, path, ns, span, global_by_default, crate_lint) { // If defer_to_typeck, then resolution > no resolution, @@ -3528,21 +3673,23 @@ impl<'a> Resolver<'a> { defer_to_typeck => return Some(partial_res), partial_res => if fin_res.is_none() { fin_res = partial_res }, - }; + } } } - if primary_ns != MacroNS && - (self.macro_names.contains(&path[0].ident.modern()) || - self.builtin_macros.get(&path[0].ident.name).cloned() - .and_then(NameBinding::macro_kind) == Some(MacroKind::Bang) || - self.macro_use_prelude.get(&path[0].ident.name).cloned() - .and_then(NameBinding::macro_kind) == Some(MacroKind::Bang)) { - // Return some dummy definition, it's enough for error reporting. - return Some(PartialRes::new(Res::Def( - DefKind::Macro(MacroKind::Bang), - DefId::local(CRATE_DEF_INDEX), - ))); + + // `MacroNS` + assert!(primary_ns != MacroNS); + if qself.is_none() { + let path_seg = |seg: &Segment| ast::PathSegment::from_ident(seg.ident); + let path = Path { segments: path.iter().map(path_seg).collect(), span }; + let parent_scope = + ParentScope { module: self.current_module, ..self.dummy_parent_scope() }; + if let Ok((_, res)) = + self.resolve_macro_path(&path, None, &parent_scope, false, false) { + return Some(PartialRes::new(res)); + } } + fin_res } @@ -4124,195 +4271,6 @@ impl<'a> Resolver<'a> { res } - fn lookup_assoc_candidate<FilterFn: Fn(Res) -> bool>( - &mut self, - ident: Ident, - ns: Namespace, - filter_fn: FilterFn, - ) -> Option<AssocSuggestion> { - fn extract_node_id(t: &Ty) -> Option<NodeId> { - match t.node { - TyKind::Path(None, _) => Some(t.id), - TyKind::Rptr(_, ref mut_ty) => extract_node_id(&mut_ty.ty), - // This doesn't handle the remaining `Ty` variants as they are not - // that commonly the self_type, it might be interesting to provide - // support for those in future. - _ => None, - } - } - - // Fields are generally expected in the same contexts as locals. - if filter_fn(Res::Local(ast::DUMMY_NODE_ID)) { - if let Some(node_id) = self.current_self_type.as_ref().and_then(extract_node_id) { - // Look for a field with the same name in the current self_type. - if let Some(resolution) = self.partial_res_map.get(&node_id) { - match resolution.base_res() { - Res::Def(DefKind::Struct, did) | Res::Def(DefKind::Union, did) - if resolution.unresolved_segments() == 0 => { - if let Some(field_names) = self.field_names.get(&did) { - if field_names.iter().any(|&field_name| ident.name == field_name) { - return Some(AssocSuggestion::Field); - } - } - } - _ => {} - } - } - } - } - - for assoc_type_ident in &self.current_trait_assoc_types { - if *assoc_type_ident == ident { - return Some(AssocSuggestion::AssocItem); - } - } - - // Look for associated items in the current trait. - if let Some((module, _)) = self.current_trait_ref { - if let Ok(binding) = self.resolve_ident_in_module( - ModuleOrUniformRoot::Module(module), - ident, - ns, - None, - false, - module.span, - ) { - let res = binding.res(); - if filter_fn(res) { - debug!("extract_node_id res not filtered"); - return Some(if self.has_self.contains(&res.def_id()) { - AssocSuggestion::MethodWithSelf - } else { - AssocSuggestion::AssocItem - }); - } - } - } - - None - } - - fn lookup_typo_candidate<FilterFn>( - &mut self, - path: &[Segment], - ns: Namespace, - filter_fn: FilterFn, - span: Span, - ) -> Option<TypoSuggestion> - where - FilterFn: Fn(Res) -> bool, - { - let add_module_candidates = |module: Module<'_>, names: &mut Vec<TypoSuggestion>| { - for (&(ident, _), resolution) in module.resolutions.borrow().iter() { - if let Some(binding) = resolution.borrow().binding { - if filter_fn(binding.res()) { - names.push(TypoSuggestion { - candidate: ident.name, - article: binding.res().article(), - kind: binding.res().descr(), - }); - } - } - } - }; - - let mut names = Vec::new(); - if path.len() == 1 { - // Search in lexical scope. - // Walk backwards up the ribs in scope and collect candidates. - for rib in self.ribs[ns].iter().rev() { - // Locals and type parameters - for (ident, &res) in &rib.bindings { - if filter_fn(res) { - names.push(TypoSuggestion { - candidate: ident.name, - article: res.article(), - kind: res.descr(), - }); - } - } - // Items in scope - if let ModuleRibKind(module) = rib.kind { - // Items from this module - add_module_candidates(module, &mut names); - - if let ModuleKind::Block(..) = module.kind { - // We can see through blocks - } else { - // Items from the prelude - if !module.no_implicit_prelude { - names.extend(self.extern_prelude.clone().iter().flat_map(|(ident, _)| { - self.crate_loader - .maybe_process_path_extern(ident.name, ident.span) - .and_then(|crate_id| { - let crate_mod = Res::Def( - DefKind::Mod, - DefId { - krate: crate_id, - index: CRATE_DEF_INDEX, - }, - ); - - if filter_fn(crate_mod) { - Some(TypoSuggestion { - candidate: ident.name, - article: "a", - kind: "crate", - }) - } else { - None - } - }) - })); - - if let Some(prelude) = self.prelude { - add_module_candidates(prelude, &mut names); - } - } - break; - } - } - } - // Add primitive types to the mix - if filter_fn(Res::PrimTy(Bool)) { - names.extend( - self.primitive_type_table.primitive_types.iter().map(|(name, _)| { - TypoSuggestion { - candidate: *name, - article: "a", - kind: "primitive type", - } - }) - ) - } - } else { - // Search in module. - let mod_path = &path[..path.len() - 1]; - if let PathResult::Module(module) = self.resolve_path_without_parent_scope( - mod_path, Some(TypeNS), false, span, CrateLint::No - ) { - if let ModuleOrUniformRoot::Module(module) = module { - add_module_candidates(module, &mut names); - } - } - } - - let name = path[path.len() - 1].ident.name; - // Make sure error reporting is deterministic. - names.sort_by_cached_key(|suggestion| suggestion.candidate.as_str()); - - match find_best_match_for_name( - names.iter().map(|suggestion| &suggestion.candidate), - &name.as_str(), - None, - ) { - Some(found) if found != name => names - .into_iter() - .find(|suggestion| suggestion.candidate == found), - _ => None, - } - } - fn with_resolved_label<F>(&mut self, label: Option<Label>, id: NodeId, f: F) where F: FnOnce(&mut Resolver<'_>) { @@ -4606,193 +4564,6 @@ impl<'a> Resolver<'a> { import_ids } - fn lookup_import_candidates_from_module<FilterFn>(&mut self, - lookup_ident: Ident, - namespace: Namespace, - start_module: &'a ModuleData<'a>, - crate_name: Ident, - filter_fn: FilterFn) - -> Vec<ImportSuggestion> - where FilterFn: Fn(Res) -> bool - { - let mut candidates = Vec::new(); - let mut seen_modules = FxHashSet::default(); - let not_local_module = crate_name.name != kw::Crate; - let mut worklist = vec![(start_module, Vec::<ast::PathSegment>::new(), not_local_module)]; - - while let Some((in_module, - path_segments, - in_module_is_extern)) = worklist.pop() { - self.populate_module_if_necessary(in_module); - - // We have to visit module children in deterministic order to avoid - // instabilities in reported imports (#43552). - in_module.for_each_child_stable(|ident, ns, name_binding| { - // avoid imports entirely - if name_binding.is_import() && !name_binding.is_extern_crate() { return; } - // avoid non-importable candidates as well - if !name_binding.is_importable() { return; } - - // collect results based on the filter function - if ident.name == lookup_ident.name && ns == namespace { - let res = name_binding.res(); - if filter_fn(res) { - // create the path - let mut segms = path_segments.clone(); - if lookup_ident.span.rust_2018() { - // crate-local absolute paths start with `crate::` in edition 2018 - // FIXME: may also be stabilized for Rust 2015 (Issues #45477, #44660) - segms.insert( - 0, ast::PathSegment::from_ident(crate_name) - ); - } - - segms.push(ast::PathSegment::from_ident(ident)); - let path = Path { - span: name_binding.span, - segments: segms, - }; - // the entity is accessible in the following cases: - // 1. if it's defined in the same crate, it's always - // accessible (since private entities can be made public) - // 2. if it's defined in another crate, it's accessible - // only if both the module is public and the entity is - // declared as public (due to pruning, we don't explore - // outside crate private modules => no need to check this) - if !in_module_is_extern || name_binding.vis == ty::Visibility::Public { - let did = match res { - Res::Def(DefKind::Ctor(..), did) => self.parent(did), - _ => res.opt_def_id(), - }; - candidates.push(ImportSuggestion { did, path }); - } - } - } - - // collect submodules to explore - if let Some(module) = name_binding.module() { - // form the path - let mut path_segments = path_segments.clone(); - path_segments.push(ast::PathSegment::from_ident(ident)); - - let is_extern_crate_that_also_appears_in_prelude = - name_binding.is_extern_crate() && - lookup_ident.span.rust_2018(); - - let is_visible_to_user = - !in_module_is_extern || name_binding.vis == ty::Visibility::Public; - - if !is_extern_crate_that_also_appears_in_prelude && is_visible_to_user { - // add the module to the lookup - let is_extern = in_module_is_extern || name_binding.is_extern_crate(); - if seen_modules.insert(module.def_id().unwrap()) { - worklist.push((module, path_segments, is_extern)); - } - } - } - }) - } - - candidates - } - - /// When name resolution fails, this method can be used to look up candidate - /// entities with the expected name. It allows filtering them using the - /// supplied predicate (which should be used to only accept the types of - /// definitions expected, e.g., traits). The lookup spans across all crates. - /// - /// N.B., the method does not look into imports, but this is not a problem, - /// since we report the definitions (thus, the de-aliased imports). - fn lookup_import_candidates<FilterFn>(&mut self, - lookup_ident: Ident, - namespace: Namespace, - filter_fn: FilterFn) - -> Vec<ImportSuggestion> - where FilterFn: Fn(Res) -> bool - { - let mut suggestions = self.lookup_import_candidates_from_module( - lookup_ident, namespace, self.graph_root, Ident::with_empty_ctxt(kw::Crate), &filter_fn - ); - - if lookup_ident.span.rust_2018() { - let extern_prelude_names = self.extern_prelude.clone(); - for (ident, _) in extern_prelude_names.into_iter() { - if let Some(crate_id) = self.crate_loader.maybe_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); - - suggestions.extend(self.lookup_import_candidates_from_module( - lookup_ident, namespace, crate_root, ident, &filter_fn)); - } - } - } - - suggestions - } - - fn find_module(&mut self, def_id: DefId) -> Option<(Module<'a>, ImportSuggestion)> { - let mut result = None; - let mut seen_modules = FxHashSet::default(); - let mut worklist = vec![(self.graph_root, Vec::new())]; - - while let Some((in_module, path_segments)) = worklist.pop() { - // abort if the module is already found - if result.is_some() { break; } - - self.populate_module_if_necessary(in_module); - - in_module.for_each_child_stable(|ident, _, name_binding| { - // abort if the module is already found or if name_binding is private external - if result.is_some() || !name_binding.vis.is_visible_locally() { - return - } - if let Some(module) = name_binding.module() { - // form the path - let mut path_segments = path_segments.clone(); - path_segments.push(ast::PathSegment::from_ident(ident)); - let module_def_id = module.def_id().unwrap(); - if module_def_id == def_id { - let path = Path { - span: name_binding.span, - segments: path_segments, - }; - result = Some((module, ImportSuggestion { did: Some(def_id), path })); - } else { - // add the module to the lookup - if seen_modules.insert(module_def_id) { - worklist.push((module, path_segments)); - } - } - } - }); - } - - result - } - - fn collect_enum_variants(&mut self, def_id: DefId) -> Option<Vec<Path>> { - self.find_module(def_id).map(|(enum_module, enum_import_suggestion)| { - self.populate_module_if_necessary(enum_module); - - let mut variants = Vec::new(); - enum_module.for_each_child_stable(|ident, _, name_binding| { - if let Res::Def(DefKind::Variant, _) = name_binding.res() { - let mut segms = enum_import_suggestion.path.segments.clone(); - segms.push(ast::PathSegment::from_ident(ident)); - variants.push(Path { - span: name_binding.span, - segments: segms, - }); - } - }); - variants - }) - } - fn record_partial_res(&mut self, node_id: NodeId, resolution: PartialRes) { debug!("(recording res) recording {:?} for {}", resolution, node_id); if let Some(prev_res) = self.partial_res_map.insert(node_id, resolution) { @@ -5010,7 +4781,7 @@ impl<'a> Resolver<'a> { for UseError { mut err, candidates, node_id, better } in self.use_injections.drain(..) { let (span, found_use) = UsePlacementFinder::check(krate, node_id); if !candidates.is_empty() { - show_candidates(&mut err, span, &candidates, better, found_use); + diagnostics::show_candidates(&mut err, span, &candidates, better, found_use); } err.emit(); } @@ -5326,72 +5097,6 @@ fn path_names_to_string(path: &Path) -> String { .collect::<Vec<_>>()) } -/// Gets the stringified path for an enum from an `ImportSuggestion` for an enum variant. -fn import_candidate_to_enum_paths(suggestion: &ImportSuggestion) -> (String, String) { - let variant_path = &suggestion.path; - let variant_path_string = path_names_to_string(variant_path); - - let path_len = suggestion.path.segments.len(); - let enum_path = ast::Path { - span: suggestion.path.span, - segments: suggestion.path.segments[0..path_len - 1].to_vec(), - }; - let enum_path_string = path_names_to_string(&enum_path); - - (variant_path_string, enum_path_string) -} - -/// When an entity with a given name is not available in scope, we search for -/// entities with that name in all crates. This method allows outputting the -/// results of this search in a programmer-friendly way -fn show_candidates(err: &mut DiagnosticBuilder<'_>, - // This is `None` if all placement locations are inside expansions - span: Option<Span>, - candidates: &[ImportSuggestion], - better: bool, - found_use: bool) { - - // we want consistent results across executions, but candidates are produced - // by iterating through a hash map, so make sure they are ordered: - let mut path_strings: Vec<_> = - candidates.into_iter().map(|c| path_names_to_string(&c.path)).collect(); - path_strings.sort(); - - let better = if better { "better " } else { "" }; - let msg_diff = match path_strings.len() { - 1 => " is found in another module, you can import it", - _ => "s are found in other modules, you can import them", - }; - let msg = format!("possible {}candidate{} into scope", better, msg_diff); - - if let Some(span) = span { - for candidate in &mut path_strings { - // produce an additional newline to separate the new use statement - // from the directly following item. - let additional_newline = if found_use { - "" - } else { - "\n" - }; - *candidate = format!("use {};\n{}", candidate, additional_newline); - } - - err.span_suggestions( - span, - &msg, - path_strings.into_iter(), - Applicability::Unspecified, - ); - } else { - let mut msg = msg; - msg.push(':'); - for candidate in path_strings { - msg.push('\n'); - msg.push_str(&candidate); - } - } -} - /// A somewhat inefficient routine to obtain the name of a module. fn module_to_string(module: Module<'_>) -> Option<String> { let mut names = Vec::new(); diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index fc1becfe309..34e85e1cf10 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -1,7 +1,7 @@ use crate::{AmbiguityError, AmbiguityKind, AmbiguityErrorMisc, Determinacy}; -use crate::{CrateLint, Resolver, ResolutionError, ScopeSet, Weak}; +use crate::{CrateLint, Resolver, ResolutionError, Scope, ScopeSet, ParentScope, Weak}; use crate::{Module, ModuleKind, NameBinding, NameBindingKind, PathResult, Segment, ToNameBinding}; -use crate::{is_known_tool, resolve_error}; +use crate::{resolve_error, KNOWN_TOOLS}; use crate::ModuleOrUniformRoot; use crate::Namespace::*; use crate::build_reduced_graph::{BuildReducedGraphVisitor, IsMacroExport}; @@ -13,18 +13,15 @@ use rustc::middle::stability; use rustc::{ty, lint, span_bug}; use syntax::ast::{self, Ident, ItemKind}; use syntax::attr::{self, StabilityLevel}; -use syntax::errors::DiagnosticBuilder; use syntax::ext::base::{self, Indeterminate}; use syntax::ext::base::{MacroKind, SyntaxExtension}; use syntax::ext::expand::{AstFragment, Invocation, InvocationKind}; use syntax::ext::hygiene::{self, Mark, ExpnInfo, ExpnKind}; use syntax::ext::tt::macro_rules; -use syntax::feature_gate::{feature_err, emit_feature_err, is_builtin_attr_name}; -use syntax::feature_gate::{AttributeGate, GateIssue, Stability, BUILTIN_ATTRIBUTES}; +use syntax::feature_gate::{emit_feature_err, is_builtin_attr_name}; +use syntax::feature_gate::GateIssue; use syntax::symbol::{Symbol, kw, sym}; -use syntax::util::lev_distance::find_best_match_for_name; use syntax_pos::{Span, DUMMY_SP}; -use errors::Applicability; use std::cell::Cell; use std::{mem, ptr}; @@ -60,10 +57,10 @@ impl<'a> InvocationData<'a> { /// Not modularized, can shadow previous legacy bindings, etc. #[derive(Debug)] pub struct LegacyBinding<'a> { - binding: &'a NameBinding<'a>, + crate binding: &'a NameBinding<'a>, /// Legacy scope into which the `macro_rules` item was planted. - parent_legacy_scope: LegacyScope<'a>, - ident: Ident, + crate parent_legacy_scope: LegacyScope<'a>, + crate ident: Ident, } /// The scope introduced by a `macro_rules!` macro. @@ -82,15 +79,6 @@ pub enum LegacyScope<'a> { Invocation(&'a InvocationData<'a>), } -/// Everything you need to resolve a macro or import path. -#[derive(Clone, Debug)] -pub struct ParentScope<'a> { - crate module: Module<'a>, - crate expansion: Mark, - crate legacy: LegacyScope<'a>, - crate derives: Vec<ast::Path>, -} - // Macro namespace is separated into two sub-namespaces, one for bang macros and // one for attribute-like macros (attributes, derives). // We ignore resolutions from one sub-namespace when searching names in scope for another. @@ -232,7 +220,7 @@ impl<'a> base::Resolver for Resolver<'a> { }; let parent_scope = self.invoc_parent_scope(invoc_id, derives_in_scope); - let (ext, res) = self.smart_resolve_macro_path(path, kind, &parent_scope, true, force)?; + let (ext, res) = self.smart_resolve_macro_path(path, kind, &parent_scope, force)?; let span = invoc.span(); invoc.expansion_data.mark.set_expn_info(ext.expn_info(span, fast_print_path(path))); @@ -281,10 +269,10 @@ impl<'a> Resolver<'a> { path: &ast::Path, kind: MacroKind, parent_scope: &ParentScope<'a>, - trace: bool, force: bool, ) -> Result<(Lrc<SyntaxExtension>, Res), Indeterminate> { - let (ext, res) = match self.resolve_macro_path(path, kind, parent_scope, trace, force) { + let (ext, res) = match self.resolve_macro_path(path, Some(kind), parent_scope, + true, force) { Ok((Some(ext), res)) => (ext, res), // Use dummy syntax extensions for unresolved macros for better recovery. Ok((None, res)) => (self.dummy_ext(kind), res), @@ -324,23 +312,7 @@ impl<'a> Resolver<'a> { } } } - Res::NonMacroAttr(attr_kind) => { - if attr_kind == NonMacroAttrKind::Custom { - assert!(path.segments.len() == 1); - if !features.custom_attribute { - let msg = format!("The attribute `{}` is currently unknown to the \ - compiler and may have meaning added to it in the \ - future", path); - self.report_unknown_attribute( - path.span, - &path.segments[0].ident.as_str(), - &msg, - sym::custom_attribute, - ); - } - } - } - Res::Err => {} + Res::NonMacroAttr(..) | Res::Err => {} _ => panic!("expected `DefKind::Macro` or `Res::NonMacroAttr`"), }; @@ -359,64 +331,10 @@ impl<'a> Resolver<'a> { }) } - fn report_unknown_attribute(&self, span: Span, name: &str, msg: &str, feature: Symbol) { - let mut err = feature_err( - &self.session.parse_sess, - feature, - span, - GateIssue::Language, - &msg, - ); - - let features = self.session.features_untracked(); - - let attr_candidates = BUILTIN_ATTRIBUTES - .iter() - .filter_map(|&(name, _, _, ref gate)| { - if name.as_str().starts_with("rustc_") && !features.rustc_attrs { - return None; - } - - match gate { - AttributeGate::Gated(Stability::Unstable, ..) - if self.session.opts.unstable_features.is_nightly_build() => - { - Some(name) - } - AttributeGate::Gated(Stability::Deprecated(..), ..) => Some(name), - AttributeGate::Ungated => Some(name), - _ => None, - } - }) - .chain( - // Add built-in macro attributes as well. - self.builtin_macros.iter().filter_map(|(name, binding)| { - match binding.macro_kind() { - Some(MacroKind::Attr) => Some(*name), - _ => None, - } - }), - ) - .collect::<Vec<_>>(); - - let lev_suggestion = find_best_match_for_name(attr_candidates.iter(), &name, None); - - if let Some(suggestion) = lev_suggestion { - err.span_suggestion( - span, - "a built-in attribute with a similar name exists", - suggestion.to_string(), - Applicability::MaybeIncorrect, - ); - } - - err.emit(); - } - pub fn resolve_macro_path( &mut self, path: &ast::Path, - kind: MacroKind, + kind: Option<MacroKind>, parent_scope: &ParentScope<'a>, trace: bool, force: bool, @@ -425,7 +343,7 @@ impl<'a> Resolver<'a> { let mut path = Segment::from_path(path); // Possibly apply the macro helper hack - if kind == MacroKind::Bang && path.len() == 1 && + if kind == Some(MacroKind::Bang) && path.len() == 1 && path[0].ident.span.ctxt().outer_expn_info() .map_or(false, |info| info.local_inner_macros) { let root = Ident::new(kw::DollarCrate, path[0].ident.span); @@ -446,6 +364,7 @@ impl<'a> Resolver<'a> { }; if trace { + let kind = kind.expect("macro kind must be specified if tracing is enabled"); parent_scope.module.multi_segment_macro_resolutions.borrow_mut() .push((path, path_span, kind, parent_scope.clone(), res.ok())); } @@ -453,14 +372,17 @@ impl<'a> Resolver<'a> { self.prohibit_imported_non_macro_attrs(None, res.ok(), path_span); res } else { + // Macro without a specific kind restriction is equvalent to a macro import. + let scope_set = kind.map_or(ScopeSet::Import(MacroNS), ScopeSet::Macro); let binding = self.early_resolve_ident_in_lexical_scope( - path[0].ident, ScopeSet::Macro(kind), parent_scope, false, force, path_span + path[0].ident, scope_set, parent_scope, false, force, path_span ); if let Err(Determinacy::Undetermined) = binding { return Err(Determinacy::Undetermined); } if trace { + let kind = kind.expect("macro kind must be specified if tracing is enabled"); parent_scope.module.single_segment_macro_resolutions.borrow_mut() .push((path[0].ident, kind, parent_scope.clone(), binding.ok())); } @@ -487,65 +409,6 @@ impl<'a> Resolver<'a> { force: bool, path_span: Span, ) -> Result<&'a NameBinding<'a>, Determinacy> { - // General principles: - // 1. Not controlled (user-defined) names should have higher priority than controlled names - // built into the language or standard library. This way we can add new names into the - // language or standard library without breaking user code. - // 2. "Closed set" below means new names cannot appear after the current resolution attempt. - // Places to search (in order of decreasing priority): - // (Type NS) - // 1. FIXME: Ribs (type parameters), there's no necessary infrastructure yet - // (open set, not controlled). - // 2. Names in modules (both normal `mod`ules and blocks), loop through hygienic parents - // (open, not controlled). - // 3. Extern prelude (closed, not controlled). - // 4. Tool modules (closed, controlled right now, but not in the future). - // 5. Standard library prelude (de-facto closed, controlled). - // 6. Language prelude (closed, controlled). - // (Value NS) - // 1. FIXME: Ribs (local variables), there's no necessary infrastructure yet - // (open set, not controlled). - // 2. Names in modules (both normal `mod`ules and blocks), loop through hygienic parents - // (open, not controlled). - // 3. Standard library prelude (de-facto closed, controlled). - // (Macro NS) - // 1-3. 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-3. `macro_rules` (open, not controlled), loop through legacy scopes. Have higher - // priority than prelude macros, but create ambiguities with macros in modules. - // 1-3. Names in modules (both normal `mod`ules and blocks), loop through hygienic parents - // (open, not controlled). Have higher priority than prelude macros, but create - // ambiguities with `macro_rules`. - // 4. `macro_use` prelude (open, the open part is from macro expansions, not controlled). - // 4a. User-defined prelude from macro-use - // (open, the open part is from macro expansions, not controlled). - // 4b. Standard library prelude is currently implemented as `macro-use` (closed, controlled) - // 5. Language prelude: builtin macros (closed, controlled, except for legacy plugins). - // 6. Language prelude: builtin attributes (closed, controlled). - // 4-6. Legacy plugin helpers (open, not controlled). Similar to derive helpers, - // but introduced by legacy plugins using `register_attribute`. Priority is somewhere - // in prelude, not sure where exactly (creates ambiguities with any other prelude names). - - enum WhereToResolve<'a> { - DeriveHelpers, - MacroRules(LegacyScope<'a>), - CrateRoot, - Module(Module<'a>), - MacroUsePrelude, - BuiltinMacros, - BuiltinAttrs, - LegacyPluginHelpers, - ExternPrelude, - ToolPrelude, - StdLibPrelude, - BuiltinTypes, - } - bitflags::bitflags! { struct Flags: u8 { const MACRO_RULES = 1 << 0; @@ -558,13 +421,19 @@ impl<'a> Resolver<'a> { } assert!(force || !record_used); // `record_used` implies `force` - let mut ident = orig_ident.modern(); // Make sure `self`, `super` etc produce an error when passed to here. - if ident.is_path_segment_keyword() { + if orig_ident.is_path_segment_keyword() { return Err(Determinacy::Determined); } + let (ns, macro_kind, is_import) = match scope_set { + ScopeSet::Import(ns) => (ns, None, true), + ScopeSet::AbsolutePath(ns) => (ns, None, false), + ScopeSet::Macro(macro_kind) => (MacroNS, Some(macro_kind), false), + ScopeSet::Module => (TypeNS, None, false), + }; + // This is *the* result, resolution from the scope closest to the resolved identifier. // However, sometimes this result is "weak" because it comes from a glob import or // a macro expansion, and in this case it cannot shadow names from outer scopes, e.g. @@ -577,34 +446,22 @@ impl<'a> Resolver<'a> { // So we have to save the innermost solution and continue searching in outer scopes // to detect potential ambiguities. let mut innermost_result: Option<(&NameBinding<'_>, Flags)> = None; + let mut determinacy = Determinacy::Determined; // Go through all the scopes and try to resolve the name. - let rust_2015 = orig_ident.span.rust_2015(); - let (ns, macro_kind, is_import, is_absolute_path) = match scope_set { - ScopeSet::Import(ns) => (ns, None, true, false), - ScopeSet::AbsolutePath(ns) => (ns, None, false, true), - ScopeSet::Macro(macro_kind) => (MacroNS, Some(macro_kind), false, false), - ScopeSet::Module => (TypeNS, None, false, false), - }; - let mut where_to_resolve = match ns { - _ if is_absolute_path => WhereToResolve::CrateRoot, - TypeNS | ValueNS => WhereToResolve::Module(parent_scope.module), - MacroNS => WhereToResolve::DeriveHelpers, - }; - let mut use_prelude = !parent_scope.module.no_implicit_prelude; - let mut determinacy = Determinacy::Determined; - loop { - let result = match where_to_resolve { - WhereToResolve::DeriveHelpers => { + let break_result = + self.visit_scopes(scope_set, parent_scope, orig_ident, |this, scope, ident| { + let result = match scope { + Scope::DeriveHelpers => { let mut result = Err(Determinacy::Determined); for derive in &parent_scope.derives { let parent_scope = ParentScope { derives: Vec::new(), ..*parent_scope }; - match self.resolve_macro_path(derive, MacroKind::Derive, + match this.resolve_macro_path(derive, Some(MacroKind::Derive), &parent_scope, true, force) { Ok((Some(ext), _)) => if ext.helper_attrs.contains(&ident.name) { let binding = (Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper), ty::Visibility::Public, derive.span, Mark::root()) - .to_name_binding(self.arenas); + .to_name_binding(this.arenas); result = Ok((binding, Flags::empty())); break; } @@ -615,19 +472,19 @@ impl<'a> Resolver<'a> { } result } - WhereToResolve::MacroRules(legacy_scope) => match legacy_scope { + Scope::MacroRules(legacy_scope) => match legacy_scope { LegacyScope::Binding(legacy_binding) if ident == legacy_binding.ident => Ok((legacy_binding.binding, Flags::MACRO_RULES)), LegacyScope::Invocation(invoc) if invoc.output_legacy_scope.get().is_none() => Err(Determinacy::Undetermined), _ => Err(Determinacy::Determined), } - WhereToResolve::CrateRoot => { - let root_ident = Ident::new(kw::PathRoot, orig_ident.span); - let root_module = self.resolve_crate_root(root_ident); - let binding = self.resolve_ident_in_module_ext( + Scope::CrateRoot => { + let root_ident = Ident::new(kw::PathRoot, ident.span); + let root_module = this.resolve_crate_root(root_ident); + let binding = this.resolve_ident_in_module_ext( ModuleOrUniformRoot::Module(root_module), - orig_ident, + ident, ns, None, record_used, @@ -636,15 +493,15 @@ impl<'a> Resolver<'a> { match binding { Ok(binding) => Ok((binding, Flags::MODULE | Flags::MISC_SUGGEST_CRATE)), Err((Determinacy::Undetermined, Weak::No)) => - return Err(Determinacy::determined(force)), + return Some(Err(Determinacy::determined(force))), Err((Determinacy::Undetermined, Weak::Yes)) => Err(Determinacy::Undetermined), Err((Determinacy::Determined, _)) => Err(Determinacy::Determined), } } - WhereToResolve::Module(module) => { - let orig_current_module = mem::replace(&mut self.current_module, module); - let binding = self.resolve_ident_in_module_unadjusted_ext( + Scope::Module(module) => { + let orig_current_module = mem::replace(&mut this.current_module, module); + let binding = this.resolve_ident_in_module_unadjusted_ext( ModuleOrUniformRoot::Module(module), ident, ns, @@ -653,10 +510,10 @@ impl<'a> Resolver<'a> { record_used, path_span, ); - self.current_module = orig_current_module; + this.current_module = orig_current_module; match binding { Ok(binding) => { - let misc_flags = if ptr::eq(module, self.graph_root) { + let misc_flags = if ptr::eq(module, this.graph_root) { Flags::MISC_SUGGEST_CRATE } else if module.is_normal() { Flags::MISC_SUGGEST_SELF @@ -666,107 +523,82 @@ impl<'a> Resolver<'a> { Ok((binding, Flags::MODULE | misc_flags)) } Err((Determinacy::Undetermined, Weak::No)) => - return Err(Determinacy::determined(force)), + return Some(Err(Determinacy::determined(force))), Err((Determinacy::Undetermined, Weak::Yes)) => Err(Determinacy::Undetermined), Err((Determinacy::Determined, _)) => Err(Determinacy::Determined), } } - WhereToResolve::MacroUsePrelude => { - if use_prelude || rust_2015 { - match self.macro_use_prelude.get(&ident.name).cloned() { - Some(binding) => - Ok((binding, Flags::PRELUDE | Flags::MISC_FROM_PRELUDE)), - None => Err(Determinacy::determined( - self.graph_root.unresolved_invocations.borrow().is_empty() - )) - } - } else { - Err(Determinacy::Determined) - } - } - WhereToResolve::BuiltinMacros => { - match self.builtin_macros.get(&ident.name).cloned() { - Some(binding) => Ok((binding, Flags::PRELUDE)), - None => Err(Determinacy::Determined), - } - } - WhereToResolve::BuiltinAttrs => { - if is_builtin_attr_name(ident.name) { - let binding = (Res::NonMacroAttr(NonMacroAttrKind::Builtin), - ty::Visibility::Public, DUMMY_SP, Mark::root()) - .to_name_binding(self.arenas); - Ok((binding, Flags::PRELUDE)) - } else { - Err(Determinacy::Determined) - } + Scope::MacroUsePrelude => match this.macro_use_prelude.get(&ident.name).cloned() { + Some(binding) => Ok((binding, Flags::PRELUDE | Flags::MISC_FROM_PRELUDE)), + None => Err(Determinacy::determined( + this.graph_root.unresolved_invocations.borrow().is_empty() + )) + } + Scope::BuiltinMacros => match this.builtin_macros.get(&ident.name).cloned() { + Some(binding) => Ok((binding, Flags::PRELUDE)), + None => Err(Determinacy::Determined), + } + Scope::BuiltinAttrs => if is_builtin_attr_name(ident.name) { + let binding = (Res::NonMacroAttr(NonMacroAttrKind::Builtin), + ty::Visibility::Public, DUMMY_SP, Mark::root()) + .to_name_binding(this.arenas); + Ok((binding, Flags::PRELUDE)) + } else { + Err(Determinacy::Determined) } - WhereToResolve::LegacyPluginHelpers => { - if (use_prelude || rust_2015) && - self.session.plugin_attributes.borrow().iter() + Scope::LegacyPluginHelpers => if this.session.plugin_attributes.borrow().iter() .any(|(name, _)| ident.name == *name) { - let binding = (Res::NonMacroAttr(NonMacroAttrKind::LegacyPluginHelper), - ty::Visibility::Public, DUMMY_SP, Mark::root()) - .to_name_binding(self.arenas); - Ok((binding, Flags::PRELUDE)) - } else { - Err(Determinacy::Determined) - } - } - WhereToResolve::ExternPrelude => { - if use_prelude || is_absolute_path { - match self.extern_prelude_get(ident, !record_used) { - Some(binding) => Ok((binding, Flags::PRELUDE)), - None => Err(Determinacy::determined( - self.graph_root.unresolved_invocations.borrow().is_empty() - )), - } - } else { - Err(Determinacy::Determined) - } - } - WhereToResolve::ToolPrelude => { - if use_prelude && is_known_tool(ident.name) { - let binding = (Res::ToolMod, ty::Visibility::Public, - DUMMY_SP, Mark::root()).to_name_binding(self.arenas); - Ok((binding, Flags::PRELUDE)) - } else { - Err(Determinacy::Determined) - } + let binding = (Res::NonMacroAttr(NonMacroAttrKind::LegacyPluginHelper), + ty::Visibility::Public, DUMMY_SP, Mark::root()) + .to_name_binding(this.arenas); + Ok((binding, Flags::PRELUDE)) + } else { + Err(Determinacy::Determined) + } + Scope::ExternPrelude => match this.extern_prelude_get(ident, !record_used) { + Some(binding) => Ok((binding, Flags::PRELUDE)), + None => Err(Determinacy::determined( + this.graph_root.unresolved_invocations.borrow().is_empty() + )), + } + Scope::ToolPrelude => if KNOWN_TOOLS.contains(&ident.name) { + let binding = (Res::ToolMod, ty::Visibility::Public, DUMMY_SP, Mark::root()) + .to_name_binding(this.arenas); + Ok((binding, Flags::PRELUDE)) + } else { + Err(Determinacy::Determined) } - WhereToResolve::StdLibPrelude => { + Scope::StdLibPrelude => { let mut result = Err(Determinacy::Determined); - if use_prelude { - if let Some(prelude) = self.prelude { - if let Ok(binding) = self.resolve_ident_in_module_unadjusted( - ModuleOrUniformRoot::Module(prelude), - ident, - ns, - false, - path_span, - ) { - result = Ok((binding, Flags::PRELUDE | Flags::MISC_FROM_PRELUDE)); - } + if let Some(prelude) = this.prelude { + if let Ok(binding) = this.resolve_ident_in_module_unadjusted( + ModuleOrUniformRoot::Module(prelude), + ident, + ns, + false, + path_span, + ) { + result = Ok((binding, Flags::PRELUDE | Flags::MISC_FROM_PRELUDE)); } } result } - WhereToResolve::BuiltinTypes => { - match self.primitive_type_table.primitive_types.get(&ident.name).cloned() { - Some(prim_ty) => { - let binding = (Res::PrimTy(prim_ty), ty::Visibility::Public, - DUMMY_SP, Mark::root()).to_name_binding(self.arenas); - Ok((binding, Flags::PRELUDE)) - } - None => Err(Determinacy::Determined) + Scope::BuiltinTypes => match this.primitive_type_table.primitive_types + .get(&ident.name).cloned() { + Some(prim_ty) => { + let binding = (Res::PrimTy(prim_ty), ty::Visibility::Public, + DUMMY_SP, Mark::root()).to_name_binding(this.arenas); + Ok((binding, Flags::PRELUDE)) } + None => Err(Determinacy::Determined) } }; match result { Ok((binding, flags)) if sub_namespace_match(binding.macro_kind(), macro_kind) => { if !record_used { - return Ok(binding); + return Some(Ok(binding)); } if let Some((innermost_binding, innermost_flags)) = innermost_result { @@ -791,11 +623,11 @@ impl<'a> Resolver<'a> { Some(AmbiguityKind::LegacyHelperVsPrelude) } else if innermost_flags.contains(Flags::MACRO_RULES) && flags.contains(Flags::MODULE) && - !self.disambiguate_legacy_vs_modern(innermost_binding, + !this.disambiguate_legacy_vs_modern(innermost_binding, binding) || flags.contains(Flags::MACRO_RULES) && innermost_flags.contains(Flags::MODULE) && - !self.disambiguate_legacy_vs_modern(binding, + !this.disambiguate_legacy_vs_modern(binding, innermost_binding) { Some(AmbiguityKind::LegacyVsModern) } else if innermost_binding.is_glob_import() { @@ -816,7 +648,7 @@ impl<'a> Resolver<'a> { } else { AmbiguityErrorMisc::None }; - self.ambiguity_errors.push(AmbiguityError { + this.ambiguity_errors.push(AmbiguityError { kind, ident: orig_ident, b1: innermost_binding, @@ -824,7 +656,7 @@ impl<'a> Resolver<'a> { misc1: misc(innermost_flags), misc2: misc(flags), }); - return Ok(innermost_binding); + return Some(Ok(innermost_binding)); } } } else { @@ -836,55 +668,11 @@ impl<'a> Resolver<'a> { Err(Determinacy::Undetermined) => determinacy = Determinacy::Undetermined } - where_to_resolve = match where_to_resolve { - WhereToResolve::DeriveHelpers => - WhereToResolve::MacroRules(parent_scope.legacy), - WhereToResolve::MacroRules(legacy_scope) => match legacy_scope { - LegacyScope::Binding(binding) => WhereToResolve::MacroRules( - binding.parent_legacy_scope - ), - LegacyScope::Invocation(invoc) => WhereToResolve::MacroRules( - invoc.output_legacy_scope.get().unwrap_or(invoc.parent_legacy_scope) - ), - LegacyScope::Empty => WhereToResolve::Module(parent_scope.module), - } - WhereToResolve::CrateRoot => match ns { - TypeNS => { - ident.span.adjust(Mark::root()); - WhereToResolve::ExternPrelude - } - ValueNS | MacroNS => break, - } - WhereToResolve::Module(module) => { - match self.hygienic_lexical_parent(module, &mut ident.span) { - Some(parent_module) => WhereToResolve::Module(parent_module), - None => { - ident.span.adjust(Mark::root()); - use_prelude = !module.no_implicit_prelude; - match ns { - TypeNS => WhereToResolve::ExternPrelude, - ValueNS => WhereToResolve::StdLibPrelude, - MacroNS => WhereToResolve::MacroUsePrelude, - } - } - } - } - WhereToResolve::MacroUsePrelude => WhereToResolve::StdLibPrelude, - WhereToResolve::BuiltinMacros => WhereToResolve::BuiltinAttrs, - WhereToResolve::BuiltinAttrs => WhereToResolve::LegacyPluginHelpers, - WhereToResolve::LegacyPluginHelpers => break, // nowhere else to search - WhereToResolve::ExternPrelude if is_absolute_path => break, - WhereToResolve::ExternPrelude => WhereToResolve::ToolPrelude, - WhereToResolve::ToolPrelude => WhereToResolve::StdLibPrelude, - WhereToResolve::StdLibPrelude => match ns { - TypeNS => WhereToResolve::BuiltinTypes, - ValueNS => break, // nowhere else to search - MacroNS => WhereToResolve::BuiltinMacros, - } - WhereToResolve::BuiltinTypes => break, // nowhere else to search - }; + None + }); - continue; + if let Some(break_result) = break_result { + return break_result; } // The first found solution was the only one, return it. @@ -893,13 +681,14 @@ impl<'a> Resolver<'a> { } let determinacy = Determinacy::determined(determinacy == Determinacy::Determined || force); - if determinacy == Determinacy::Determined && macro_kind == Some(MacroKind::Attr) { + if determinacy == Determinacy::Determined && macro_kind == Some(MacroKind::Attr) && + self.session.features_untracked().custom_attribute { // For single-segment attributes interpret determinate "no resolution" as a custom // attribute. (Lexical resolution implies the first segment and attr kind should imply // the last segment, so we are certainly working with a single-segment attribute here.) assert!(ns == MacroNS); let binding = (Res::NonMacroAttr(NonMacroAttrKind::Custom), - ty::Visibility::Public, ident.span, Mark::root()) + ty::Visibility::Public, orig_ident.span, Mark::root()) .to_name_binding(self.arenas); Ok(binding) } else { @@ -992,7 +781,7 @@ impl<'a> Resolver<'a> { let msg = format!("cannot find {} `{}{}` in this scope", kind.descr(), ident, bang); let mut err = self.session.struct_span_err(ident.span, &msg); - self.suggest_macro_name(ident.name, kind, &mut err, ident.span); + self.unresolved_macro_suggestions(&mut err, kind, &parent_scope, ident); err.emit(); } } @@ -1042,64 +831,6 @@ impl<'a> Resolver<'a> { } } - fn suggest_macro_name(&mut self, name: Symbol, kind: MacroKind, - err: &mut DiagnosticBuilder<'a>, span: Span) { - if kind == MacroKind::Derive && (name.as_str() == "Send" || name.as_str() == "Sync") { - let msg = format!("unsafe traits like `{}` should be implemented explicitly", name); - err.span_note(span, &msg); - return; - } - - // First check if this is a locally-defined bang macro. - let suggestion = if let MacroKind::Bang = kind { - find_best_match_for_name( - self.macro_names.iter().map(|ident| &ident.name), &name.as_str(), None) - } else { - None - // Then check global macros. - }.or_else(|| { - let names = self.builtin_macros.iter().chain(self.macro_use_prelude.iter()) - .filter_map(|(name, binding)| { - if binding.macro_kind() == Some(kind) { Some(name) } else { None } - }); - find_best_match_for_name(names, &name.as_str(), None) - // Then check modules. - }).or_else(|| { - let is_macro = |res| { - if let Res::Def(DefKind::Macro(def_kind), _) = res { - def_kind == kind - } else { - false - } - }; - let ident = Ident::new(name, span); - self.lookup_typo_candidate(&[Segment::from_ident(ident)], MacroNS, is_macro, span) - .map(|suggestion| suggestion.candidate) - }); - - if let Some(suggestion) = suggestion { - if suggestion != name { - if let MacroKind::Bang = kind { - err.span_suggestion( - span, - "you could try the macro", - suggestion.to_string(), - Applicability::MaybeIncorrect - ); - } else { - err.span_suggestion( - span, - "try", - suggestion.to_string(), - Applicability::MaybeIncorrect - ); - } - } else { - err.help("have you added the `#[macro_use]` on the module/import?"); - } - } - } - crate fn check_reserved_macro_name(&mut self, ident: Ident, res: Res) { // Reserve some names that are not quite covered by the general check // performed on `Resolver::builtin_attrs`. diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 5edfe923e68..14622fd9f91 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -1,15 +1,15 @@ use ImportDirectiveSubclass::*; use crate::{AmbiguityError, AmbiguityKind, AmbiguityErrorMisc}; -use crate::{CrateLint, Module, ModuleOrUniformRoot, PerNS, ScopeSet, Weak}; +use crate::{CrateLint, Module, ModuleOrUniformRoot, PerNS, ScopeSet, ParentScope, Weak}; use crate::Determinacy::{self, *}; use crate::Namespace::{self, TypeNS, MacroNS}; use crate::{NameBinding, NameBindingKind, ToNameBinding, PathResult, PrivacyError}; use crate::{Resolver, Segment}; use crate::{names_to_string, module_to_string}; -use crate::{resolve_error, ResolutionError, Suggestion}; +use crate::{resolve_error, ResolutionError}; use crate::ModuleKind; -use crate::macros::ParentScope; +use crate::diagnostics::Suggestion; use errors::Applicability; diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index c527ed02bc0..04de3374d05 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -6,6 +6,7 @@ use rustc::lint as lint; use rustc::ty; use syntax; use syntax::ast::{self, Ident}; +use syntax::ext::base::SyntaxExtensionKind; use syntax::feature_gate::UnstableFeatures; use syntax::symbol::Symbol; use syntax_pos::DUMMY_SP; @@ -425,12 +426,10 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> { /// Resolves a string as a macro. fn macro_resolve(cx: &DocContext<'_>, path_str: &str) -> Option<Res> { - use syntax::ext::base::{MacroKind, SyntaxExtensionKind}; - let segment = ast::PathSegment::from_ident(Ident::from_str(path_str)); - let path = ast::Path { segments: vec![segment], span: DUMMY_SP }; + let path = ast::Path::from_ident(Ident::from_str(path_str)); cx.enter_resolver(|resolver| { if let Ok((Some(ext), res)) = resolver.resolve_macro_path( - &path, MacroKind::Bang, &resolver.dummy_parent_scope(), false, false + &path, None, &resolver.dummy_parent_scope(), false, false ) { if let SyntaxExtensionKind::LegacyBang { .. } = ext.kind { return Some(res.map_id(|_| panic!("unexpected id"))); diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index 8da3e6c19d5..f23ed7371c6 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -604,6 +604,7 @@ symbols! { rustc_then_this_would_need, rustc_variance, rustdoc, + rustfmt, rust_eh_personality, rust_eh_unwind_resume, rust_oom, diff --git a/src/test/ui/attributes/obsolete-attr.rs b/src/test/ui/attributes/obsolete-attr.rs index 89e2ad2669c..8759344e6f8 100644 --- a/src/test/ui/attributes/obsolete-attr.rs +++ b/src/test/ui/attributes/obsolete-attr.rs @@ -1,7 +1,9 @@ // Obsolete attributes fall back to feature gated custom attributes. -#[ab_isize="stdcall"] extern {} //~ ERROR attribute `ab_isize` is currently unknown +#[ab_isize="stdcall"] extern {} +//~^ ERROR cannot find attribute macro `ab_isize` in this scope -#[fixed_stack_segment] fn f() {} //~ ERROR attribute `fixed_stack_segment` is currently unknown +#[fixed_stack_segment] fn f() {} +//~^ ERROR cannot find attribute macro `fixed_stack_segment` in this scope fn main() {} diff --git a/src/test/ui/attributes/obsolete-attr.stderr b/src/test/ui/attributes/obsolete-attr.stderr index 6021700dfbb..9c6909f65f3 100644 --- a/src/test/ui/attributes/obsolete-attr.stderr +++ b/src/test/ui/attributes/obsolete-attr.stderr @@ -1,21 +1,14 @@ -error[E0658]: The attribute `fixed_stack_segment` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/obsolete-attr.rs:5:3 +error: cannot find attribute macro `fixed_stack_segment` in this scope + --> $DIR/obsolete-attr.rs:6:3 | LL | #[fixed_stack_segment] fn f() {} | ^^^^^^^^^^^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable -error[E0658]: The attribute `ab_isize` is currently unknown to the compiler and may have meaning added to it in the future +error: cannot find attribute macro `ab_isize` in this scope --> $DIR/obsolete-attr.rs:3:3 | LL | #[ab_isize="stdcall"] extern {} | ^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/attributes/unknown-attr.rs b/src/test/ui/attributes/unknown-attr.rs index e2a4f3226d5..140a1fc3f93 100644 --- a/src/test/ui/attributes/unknown-attr.rs +++ b/src/test/ui/attributes/unknown-attr.rs @@ -2,8 +2,11 @@ #![feature(custom_inner_attributes)] -#![mutable_doc] //~ ERROR attribute `mutable_doc` is currently unknown +#![mutable_doc] +//~^ ERROR cannot find attribute macro `mutable_doc` in this scope -#[dance] mod a {} //~ ERROR attribute `dance` is currently unknown +#[dance] mod a {} +//~^ ERROR cannot find attribute macro `dance` in this scope -#[dance] fn main() {} //~ ERROR attribute `dance` is currently unknown +#[dance] fn main() {} +//~^ ERROR cannot find attribute macro `dance` in this scope diff --git a/src/test/ui/attributes/unknown-attr.stderr b/src/test/ui/attributes/unknown-attr.stderr index b46db566293..4d463874d66 100644 --- a/src/test/ui/attributes/unknown-attr.stderr +++ b/src/test/ui/attributes/unknown-attr.stderr @@ -1,30 +1,20 @@ -error[E0658]: The attribute `mutable_doc` is currently unknown to the compiler and may have meaning added to it in the future +error: cannot find attribute macro `mutable_doc` in this scope --> $DIR/unknown-attr.rs:5:4 | LL | #![mutable_doc] | ^^^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable -error[E0658]: The attribute `dance` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/unknown-attr.rs:7:3 +error: cannot find attribute macro `dance` in this scope + --> $DIR/unknown-attr.rs:8:3 | LL | #[dance] mod a {} | ^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable -error[E0658]: The attribute `dance` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/unknown-attr.rs:9:3 +error: cannot find attribute macro `dance` in this scope + --> $DIR/unknown-attr.rs:11:3 | LL | #[dance] fn main() {} | ^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.rs b/src/test/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.rs index 1ed2ddcda44..22dbac76670 100644 --- a/src/test/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.rs +++ b/src/test/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.rs @@ -1,6 +1,7 @@ macro_rules! foo { () => { - #[cfg_attr(all(), unknown)] //~ ERROR `unknown` is currently unknown + #[cfg_attr(all(), unknown)] + //~^ ERROR cannot find attribute macro `unknown` in this scope fn foo() {} } } diff --git a/src/test/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.stderr b/src/test/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.stderr index cf4d0fc5ad0..c7c52a2923a 100644 --- a/src/test/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.stderr +++ b/src/test/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.stderr @@ -1,4 +1,4 @@ -error[E0658]: The attribute `unknown` is currently unknown to the compiler and may have meaning added to it in the future +error: cannot find attribute macro `unknown` in this scope --> $DIR/cfg-attr-unknown-attribute-macro-expansion.rs:3:27 | LL | #[cfg_attr(all(), unknown)] @@ -6,10 +6,6 @@ LL | #[cfg_attr(all(), unknown)] ... LL | foo!(); | ------- in this macro invocation - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable error: aborting due to previous error -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/custom_attribute.rs b/src/test/ui/custom_attribute.rs index 9cb43ab07ad..13c873c3b7e 100644 --- a/src/test/ui/custom_attribute.rs +++ b/src/test/ui/custom_attribute.rs @@ -1,9 +1,9 @@ #![feature(stmt_expr_attributes)] -#[foo] //~ ERROR The attribute `foo` +#[foo] //~ ERROR cannot find attribute macro `foo` in this scope fn main() { - #[foo] //~ ERROR The attribute `foo` + #[foo] //~ ERROR cannot find attribute macro `foo` in this scope let x = (); - #[foo] //~ ERROR The attribute `foo` + #[foo] //~ ERROR cannot find attribute macro `foo` in this scope x } diff --git a/src/test/ui/custom_attribute.stderr b/src/test/ui/custom_attribute.stderr index 84c4e33e55a..b4f9f3f49b2 100644 --- a/src/test/ui/custom_attribute.stderr +++ b/src/test/ui/custom_attribute.stderr @@ -1,30 +1,20 @@ -error[E0658]: The attribute `foo` is currently unknown to the compiler and may have meaning added to it in the future +error: cannot find attribute macro `foo` in this scope --> $DIR/custom_attribute.rs:3:3 | LL | #[foo] | ^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable -error[E0658]: The attribute `foo` is currently unknown to the compiler and may have meaning added to it in the future +error: cannot find attribute macro `foo` in this scope --> $DIR/custom_attribute.rs:5:7 | LL | #[foo] | ^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable -error[E0658]: The attribute `foo` is currently unknown to the compiler and may have meaning added to it in the future +error: cannot find attribute macro `foo` in this scope --> $DIR/custom_attribute.rs:7:7 | LL | #[foo] | ^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/derives/deriving-meta-unknown-trait.stderr b/src/test/ui/derives/deriving-meta-unknown-trait.stderr index cf0173dfad5..1b8e689c753 100644 --- a/src/test/ui/derives/deriving-meta-unknown-trait.stderr +++ b/src/test/ui/derives/deriving-meta-unknown-trait.stderr @@ -2,7 +2,7 @@ error: cannot find derive macro `Eqr` in this scope --> $DIR/deriving-meta-unknown-trait.rs:1:10 | LL | #[derive(Eqr)] - | ^^^ help: try: `Eq` + | ^^^ help: a derive macro with a similar name exists: `Eq` error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-custom_attribute.rs b/src/test/ui/feature-gates/feature-gate-custom_attribute.rs index f31c9d5afc4..d34936b42a6 100644 --- a/src/test/ui/feature-gates/feature-gate-custom_attribute.rs +++ b/src/test/ui/feature-gates/feature-gate-custom_attribute.rs @@ -1,23 +1,18 @@ // Check that literals in attributes parse just fine. +#[fake_attr] //~ ERROR cannot find attribute macro `fake_attr` in this scope +#[fake_attr(100)] //~ ERROR cannot find attribute macro `fake_attr` in this scope +#[fake_attr(1, 2, 3)] //~ ERROR cannot find attribute macro `fake_attr` in this scope +#[fake_attr("hello")] //~ ERROR cannot find attribute macro `fake_attr` in this scope +#[fake_attr(name = "hello")] //~ ERROR cannot find attribute macro `fake_attr` in this scope +#[fake_attr(1, "hi", key = 12, true, false)] //~ ERROR cannot find attribute macro `fake_attr` in th +#[fake_attr(key = "hello", val = 10)] //~ ERROR cannot find attribute macro `fake_attr` in this scop +#[fake_attr(key("hello"), val(10))] //~ ERROR cannot find attribute macro `fake_attr` in this scope +#[fake_attr(enabled = true, disabled = false)] //~ ERROR cannot find attribute macro `fake_attr` in +#[fake_attr(true)] //~ ERROR cannot find attribute macro `fake_attr` in this scope +#[fake_attr(pi = 3.14159)] //~ ERROR cannot find attribute macro `fake_attr` in this scope +#[fake_attr(b"hi")] //~ ERROR cannot find attribute macro `fake_attr` in this scope +#[fake_doc(r"doc")] //~ ERROR cannot find attribute macro `fake_doc` in this scope +struct Q {} -#![allow(dead_code)] -#![allow(unused_variables)] - -#[fake_attr] //~ ERROR attribute `fake_attr` is currently unknown -#[fake_attr(100)] //~ ERROR attribute `fake_attr` is currently unknown -#[fake_attr(1, 2, 3)] //~ ERROR attribute `fake_attr` is currently unknown -#[fake_attr("hello")] //~ ERROR attribute `fake_attr` is currently unknown -#[fake_attr(name = "hello")] //~ ERROR attribute `fake_attr` is currently unknown -#[fake_attr(1, "hi", key = 12, true, false)] //~ ERROR attribute `fake_attr` is currently unknown -#[fake_attr(key = "hello", val = 10)] //~ ERROR attribute `fake_attr` is currently unknown -#[fake_attr(key("hello"), val(10))] //~ ERROR attribute `fake_attr` is currently unknown -#[fake_attr(enabled = true, disabled = false)] //~ ERROR attribute `fake_attr` is currently unknown -#[fake_attr(true)] //~ ERROR attribute `fake_attr` is currently unknown -#[fake_attr(pi = 3.14159)] //~ ERROR attribute `fake_attr` is currently unknown -#[fake_attr(b"hi")] //~ ERROR attribute `fake_attr` is currently unknown -#[fake_doc(r"doc")] //~ ERROR attribute `fake_doc` is currently unknown -struct Q { } - - -fn main() { } +fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-custom_attribute.stderr b/src/test/ui/feature-gates/feature-gate-custom_attribute.stderr index 12175feadd6..efdc2d1cd31 100644 --- a/src/test/ui/feature-gates/feature-gate-custom_attribute.stderr +++ b/src/test/ui/feature-gates/feature-gate-custom_attribute.stderr @@ -1,120 +1,80 @@ -error[E0658]: The attribute `fake_attr` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/feature-gate-custom_attribute.rs:7:3 +error: cannot find attribute macro `fake_attr` in this scope + --> $DIR/feature-gate-custom_attribute.rs:3:3 | LL | #[fake_attr] | ^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable -error[E0658]: The attribute `fake_attr` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/feature-gate-custom_attribute.rs:8:3 +error: cannot find attribute macro `fake_attr` in this scope + --> $DIR/feature-gate-custom_attribute.rs:4:3 | LL | #[fake_attr(100)] | ^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable -error[E0658]: The attribute `fake_attr` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/feature-gate-custom_attribute.rs:9:3 +error: cannot find attribute macro `fake_attr` in this scope + --> $DIR/feature-gate-custom_attribute.rs:5:3 | LL | #[fake_attr(1, 2, 3)] | ^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable -error[E0658]: The attribute `fake_attr` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/feature-gate-custom_attribute.rs:10:3 +error: cannot find attribute macro `fake_attr` in this scope + --> $DIR/feature-gate-custom_attribute.rs:6:3 | LL | #[fake_attr("hello")] | ^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable -error[E0658]: The attribute `fake_attr` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/feature-gate-custom_attribute.rs:11:3 +error: cannot find attribute macro `fake_attr` in this scope + --> $DIR/feature-gate-custom_attribute.rs:7:3 | LL | #[fake_attr(name = "hello")] | ^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable -error[E0658]: The attribute `fake_attr` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/feature-gate-custom_attribute.rs:12:3 +error: cannot find attribute macro `fake_attr` in this scope + --> $DIR/feature-gate-custom_attribute.rs:8:3 | LL | #[fake_attr(1, "hi", key = 12, true, false)] | ^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable -error[E0658]: The attribute `fake_attr` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/feature-gate-custom_attribute.rs:13:3 +error: cannot find attribute macro `fake_attr` in this scope + --> $DIR/feature-gate-custom_attribute.rs:9:3 | LL | #[fake_attr(key = "hello", val = 10)] | ^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable -error[E0658]: The attribute `fake_attr` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/feature-gate-custom_attribute.rs:14:3 +error: cannot find attribute macro `fake_attr` in this scope + --> $DIR/feature-gate-custom_attribute.rs:10:3 | LL | #[fake_attr(key("hello"), val(10))] | ^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable -error[E0658]: The attribute `fake_attr` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/feature-gate-custom_attribute.rs:15:3 +error: cannot find attribute macro `fake_attr` in this scope + --> $DIR/feature-gate-custom_attribute.rs:11:3 | LL | #[fake_attr(enabled = true, disabled = false)] | ^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable -error[E0658]: The attribute `fake_attr` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/feature-gate-custom_attribute.rs:16:3 +error: cannot find attribute macro `fake_attr` in this scope + --> $DIR/feature-gate-custom_attribute.rs:12:3 | LL | #[fake_attr(true)] | ^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable -error[E0658]: The attribute `fake_attr` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/feature-gate-custom_attribute.rs:17:3 +error: cannot find attribute macro `fake_attr` in this scope + --> $DIR/feature-gate-custom_attribute.rs:13:3 | LL | #[fake_attr(pi = 3.14159)] | ^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable -error[E0658]: The attribute `fake_attr` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/feature-gate-custom_attribute.rs:18:3 +error: cannot find attribute macro `fake_attr` in this scope + --> $DIR/feature-gate-custom_attribute.rs:14:3 | LL | #[fake_attr(b"hi")] | ^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable -error[E0658]: The attribute `fake_doc` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/feature-gate-custom_attribute.rs:19:3 +error: cannot find attribute macro `fake_doc` in this scope + --> $DIR/feature-gate-custom_attribute.rs:15:3 | LL | #[fake_doc(r"doc")] | ^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable error: aborting due to 13 previous errors -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gates/feature-gate-rustc-attrs.rs b/src/test/ui/feature-gates/feature-gate-rustc-attrs.rs index 9ce2fb58ab0..13983726c78 100644 --- a/src/test/ui/feature-gates/feature-gate-rustc-attrs.rs +++ b/src/test/ui/feature-gates/feature-gate-rustc-attrs.rs @@ -19,5 +19,5 @@ fn g() {} //~^ ERROR used by the test suite #[rustc_unknown] //~^ ERROR attributes starting with `rustc` are reserved for use by the `rustc` compiler -//~| ERROR attribute `rustc_unknown` is currently unknown +//~| ERROR cannot find attribute macro `rustc_unknown` in this scope fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-rustc-attrs.stderr b/src/test/ui/feature-gates/feature-gate-rustc-attrs.stderr index 7c5aa5381e8..23cf936ee83 100644 --- a/src/test/ui/feature-gates/feature-gate-rustc-attrs.stderr +++ b/src/test/ui/feature-gates/feature-gate-rustc-attrs.stderr @@ -37,14 +37,11 @@ LL | #[rustc_unknown] = note: for more information, see https://github.com/rust-lang/rust/issues/29642 = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable -error[E0658]: The attribute `rustc_unknown` is currently unknown to the compiler and may have meaning added to it in the future +error: cannot find attribute macro `rustc_unknown` in this scope --> $DIR/feature-gate-rustc-attrs.rs:20:3 | LL | #[rustc_unknown] | ^^^^^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable error[E0658]: used by the test suite --> $DIR/feature-gate-rustc-attrs.rs:18:1 diff --git a/src/test/ui/hygiene/no_implicit_prelude-2018.stderr b/src/test/ui/hygiene/no_implicit_prelude-2018.stderr index e7ae7afa02a..0fdb18d967a 100644 --- a/src/test/ui/hygiene/no_implicit_prelude-2018.stderr +++ b/src/test/ui/hygiene/no_implicit_prelude-2018.stderr @@ -3,8 +3,6 @@ error: cannot find macro `print!` in this scope | LL | print!(); | ^^^^^ - | - = help: have you added the `#[macro_use]` on the module/import? error: aborting due to previous error diff --git a/src/test/ui/hygiene/no_implicit_prelude.stderr b/src/test/ui/hygiene/no_implicit_prelude.stderr index 737b375ed89..a89176fe690 100644 --- a/src/test/ui/hygiene/no_implicit_prelude.stderr +++ b/src/test/ui/hygiene/no_implicit_prelude.stderr @@ -13,7 +13,6 @@ error: cannot find macro `panic!` in this scope LL | assert_eq!(0, 0); | ^^^^^^^^^^^^^^^^^ | - = help: have you added the `#[macro_use]` on the module/import? = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) error[E0599]: no method named `clone` found for type `()` in the current scope diff --git a/src/test/ui/hygiene/rustc-macro-transparency.rs b/src/test/ui/hygiene/rustc-macro-transparency.rs index a0a3d411d28..5f36993af2f 100644 --- a/src/test/ui/hygiene/rustc-macro-transparency.rs +++ b/src/test/ui/hygiene/rustc-macro-transparency.rs @@ -26,6 +26,6 @@ fn main() { Opaque; //~ ERROR cannot find value `Opaque` in this scope transparent; // OK - semitransparent; //~ ERROR cannot find value `semitransparent` in this scope - opaque; //~ ERROR cannot find value `opaque` in this scope + semitransparent; //~ ERROR expected value, found macro `semitransparent` + opaque; //~ ERROR expected value, found macro `opaque` } diff --git a/src/test/ui/hygiene/rustc-macro-transparency.stderr b/src/test/ui/hygiene/rustc-macro-transparency.stderr index 2a9df221e2c..5eacfdf8dee 100644 --- a/src/test/ui/hygiene/rustc-macro-transparency.stderr +++ b/src/test/ui/hygiene/rustc-macro-transparency.stderr @@ -4,18 +4,19 @@ error[E0425]: cannot find value `Opaque` in this scope LL | Opaque; | ^^^^^^ help: a local variable with a similar name exists: `opaque` -error[E0425]: cannot find value `semitransparent` in this scope +error[E0423]: expected value, found macro `semitransparent` --> $DIR/rustc-macro-transparency.rs:29:5 | LL | semitransparent; - | ^^^^^^^^^^^^^^^ not found in this scope + | ^^^^^^^^^^^^^^^ help: use `!` to invoke the macro: `semitransparent!` -error[E0425]: cannot find value `opaque` in this scope +error[E0423]: expected value, found macro `opaque` --> $DIR/rustc-macro-transparency.rs:30:5 | LL | opaque; - | ^^^^^^ not found in this scope + | ^^^^^^ help: use `!` to invoke the macro: `opaque!` error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0425`. +Some errors have detailed explanations: E0423, E0425. +For more information about an error, try `rustc --explain E0423`. diff --git a/src/test/ui/impl-trait/universal_wrong_bounds.rs b/src/test/ui/impl-trait/universal_wrong_bounds.rs index 56a13ea257e..2182506c7b7 100644 --- a/src/test/ui/impl-trait/universal_wrong_bounds.rs +++ b/src/test/ui/impl-trait/universal_wrong_bounds.rs @@ -6,9 +6,8 @@ fn foo(f: impl Display + Clone) -> String { wants_clone(f); } -fn wants_debug(g: impl Debug) { } //~ ERROR cannot find -fn wants_display(g: impl Debug) { } //~ ERROR cannot find +fn wants_debug(g: impl Debug) { } //~ ERROR expected trait, found derive macro `Debug` +fn wants_display(g: impl Debug) { } //~ ERROR expected trait, found derive macro `Debug` fn wants_clone(g: impl Clone) { } -fn main() { -} +fn main() {} diff --git a/src/test/ui/impl-trait/universal_wrong_bounds.stderr b/src/test/ui/impl-trait/universal_wrong_bounds.stderr index 1fd3ebff62a..f530792955b 100644 --- a/src/test/ui/impl-trait/universal_wrong_bounds.stderr +++ b/src/test/ui/impl-trait/universal_wrong_bounds.stderr @@ -1,23 +1,23 @@ -error[E0405]: cannot find trait `Debug` in this scope +error[E0404]: expected trait, found derive macro `Debug` --> $DIR/universal_wrong_bounds.rs:9:24 | LL | fn wants_debug(g: impl Debug) { } - | ^^^^^ not found in this scope -help: possible candidate is found in another module, you can import it into scope + | ^^^^^ not a trait +help: possible better candidate is found in another module, you can import it into scope | LL | use std::fmt::Debug; | -error[E0405]: cannot find trait `Debug` in this scope +error[E0404]: expected trait, found derive macro `Debug` --> $DIR/universal_wrong_bounds.rs:10:26 | LL | fn wants_display(g: impl Debug) { } - | ^^^^^ not found in this scope -help: possible candidate is found in another module, you can import it into scope + | ^^^^^ not a trait +help: possible better candidate is found in another module, you can import it into scope | LL | use std::fmt::Debug; | error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0405`. +For more information about this error, try `rustc --explain E0404`. diff --git a/src/test/ui/issues/issue-32655.rs b/src/test/ui/issues/issue-32655.rs index 4634179d4e1..fad7bf55cf4 100644 --- a/src/test/ui/issues/issue-32655.rs +++ b/src/test/ui/issues/issue-32655.rs @@ -1,9 +1,6 @@ -#![allow(dead_code)] -#![feature(rustc_attrs)] - macro_rules! foo ( () => ( - #[derive_Clone] //~ ERROR attribute `derive_Clone` is currently unknown + #[derive_Clone] //~ ERROR cannot find attribute macro `derive_Clone` in this scope struct T; ); ); @@ -15,7 +12,7 @@ macro_rules! bar ( foo!(); bar!( - #[derive_Clone] //~ ERROR attribute `derive_Clone` is currently unknown + #[derive_Clone] //~ ERROR cannot find attribute macro `derive_Clone` in this scope struct S; ); diff --git a/src/test/ui/issues/issue-32655.stderr b/src/test/ui/issues/issue-32655.stderr index 43bb4105c8d..e13bed0fbfd 100644 --- a/src/test/ui/issues/issue-32655.stderr +++ b/src/test/ui/issues/issue-32655.stderr @@ -1,24 +1,17 @@ -error[E0658]: The attribute `derive_Clone` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/issue-32655.rs:6:11 +error: cannot find attribute macro `derive_Clone` in this scope + --> $DIR/issue-32655.rs:3:11 | LL | #[derive_Clone] | ^^^^^^^^^^^^ ... LL | foo!(); | ------- in this macro invocation - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable -error[E0658]: The attribute `derive_Clone` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/issue-32655.rs:18:7 +error: cannot find attribute macro `derive_Clone` in this scope + --> $DIR/issue-32655.rs:15:7 | LL | #[derive_Clone] | ^^^^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/issues/issue-37534.rs b/src/test/ui/issues/issue-37534.rs index 9386b4516a3..1e67e9a8158 100644 --- a/src/test/ui/issues/issue-37534.rs +++ b/src/test/ui/issues/issue-37534.rs @@ -1,5 +1,5 @@ struct Foo<T: ?Hash> { } -//~^ ERROR cannot find trait `Hash` in this scope +//~^ ERROR expected trait, found derive macro `Hash` //~^^ ERROR parameter `T` is never used //~^^^ WARN default bound relaxed for a type parameter, but this does nothing diff --git a/src/test/ui/issues/issue-37534.stderr b/src/test/ui/issues/issue-37534.stderr index 741e93561bc..3a0ab32dcc6 100644 --- a/src/test/ui/issues/issue-37534.stderr +++ b/src/test/ui/issues/issue-37534.stderr @@ -1,9 +1,9 @@ -error[E0405]: cannot find trait `Hash` in this scope +error[E0404]: expected trait, found derive macro `Hash` --> $DIR/issue-37534.rs:1:16 | LL | struct Foo<T: ?Hash> { } - | ^^^^ not found in this scope -help: possible candidate is found in another module, you can import it into scope + | ^^^^ not a trait +help: possible better candidate is found in another module, you can import it into scope | LL | use std::hash::Hash; | @@ -24,5 +24,5 @@ LL | struct Foo<T: ?Hash> { } error: aborting due to 2 previous errors -Some errors have detailed explanations: E0392, E0405. +Some errors have detailed explanations: E0392, E0404. For more information about an error, try `rustc --explain E0392`. diff --git a/src/test/ui/issues/issue-49074.rs b/src/test/ui/issues/issue-49074.rs index ad66e421c6b..38074d5b05c 100644 --- a/src/test/ui/issues/issue-49074.rs +++ b/src/test/ui/issues/issue-49074.rs @@ -1,7 +1,7 @@ // Check that unknown attribute error is shown even if there are unresolved macros. #[marco_use] // typo -//~^ ERROR The attribute `marco_use` is currently unknown to the compiler +//~^ ERROR cannot find attribute macro `marco_use` in this scope mod foo { macro_rules! bar { () => (); diff --git a/src/test/ui/issues/issue-49074.stderr b/src/test/ui/issues/issue-49074.stderr index 3ab876dbf42..c557255ab50 100644 --- a/src/test/ui/issues/issue-49074.stderr +++ b/src/test/ui/issues/issue-49074.stderr @@ -1,11 +1,8 @@ -error[E0658]: The attribute `marco_use` is currently unknown to the compiler and may have meaning added to it in the future +error: cannot find attribute macro `marco_use` in this scope --> $DIR/issue-49074.rs:3:3 | LL | #[marco_use] // typo | ^^^^^^^^^ help: a built-in attribute with a similar name exists: `macro_use` - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable error: cannot find macro `bar!` in this scope --> $DIR/issue-49074.rs:12:4 @@ -17,4 +14,3 @@ LL | bar!(); error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/macros/macro-name-typo.stderr b/src/test/ui/macros/macro-name-typo.stderr index a8930f243f8..967f4f3c4ac 100644 --- a/src/test/ui/macros/macro-name-typo.stderr +++ b/src/test/ui/macros/macro-name-typo.stderr @@ -2,7 +2,7 @@ error: cannot find macro `printlx!` in this scope --> $DIR/macro-name-typo.rs:2:5 | LL | printlx!("oh noes!"); - | ^^^^^^^ help: you could try the macro: `println` + | ^^^^^^^ help: a macro with a similar name exists: `println` error: aborting due to previous error diff --git a/src/test/ui/macros/macro-path-prelude-fail-3.stderr b/src/test/ui/macros/macro-path-prelude-fail-3.stderr index 7eeddb88547..96b8a24cff2 100644 --- a/src/test/ui/macros/macro-path-prelude-fail-3.stderr +++ b/src/test/ui/macros/macro-path-prelude-fail-3.stderr @@ -2,7 +2,7 @@ error: cannot find macro `inline!` in this scope --> $DIR/macro-path-prelude-fail-3.rs:2:5 | LL | inline!(); - | ^^^^^^ help: you could try the macro: `line` + | ^^^^^^ help: a macro with a similar name exists: `line` error: aborting due to previous error diff --git a/src/test/ui/macros/macro-reexport-removed.rs b/src/test/ui/macros/macro-reexport-removed.rs index fb33794a5ca..b69a1fa4df0 100644 --- a/src/test/ui/macros/macro-reexport-removed.rs +++ b/src/test/ui/macros/macro-reexport-removed.rs @@ -2,7 +2,7 @@ #![feature(macro_reexport)] //~ ERROR feature has been removed -#[macro_reexport(macro_one)] //~ ERROR attribute `macro_reexport` is currently unknown +#[macro_reexport(macro_one)] //~ ERROR cannot find attribute macro `macro_reexport` in this scope extern crate two_macros; fn main() {} diff --git a/src/test/ui/macros/macro-reexport-removed.stderr b/src/test/ui/macros/macro-reexport-removed.stderr index 44233d7b7dd..25778fba68f 100644 --- a/src/test/ui/macros/macro-reexport-removed.stderr +++ b/src/test/ui/macros/macro-reexport-removed.stderr @@ -10,16 +10,12 @@ note: subsumed by `pub use` LL | #![feature(macro_reexport)] | ^^^^^^^^^^^^^^ -error[E0658]: The attribute `macro_reexport` is currently unknown to the compiler and may have meaning added to it in the future +error: cannot find attribute macro `macro_reexport` in this scope --> $DIR/macro-reexport-removed.rs:5:3 | LL | #[macro_reexport(macro_one)] | ^^^^^^^^^^^^^^ help: a built-in attribute with a similar name exists: `macro_export` - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable error: aborting due to 2 previous errors -Some errors have detailed explanations: E0557, E0658. -For more information about an error, try `rustc --explain E0557`. +For more information about this error, try `rustc --explain E0557`. diff --git a/src/test/ui/macros/macro-use-wrong-name.stderr b/src/test/ui/macros/macro-use-wrong-name.stderr index d178d4e4a60..28f727d6a58 100644 --- a/src/test/ui/macros/macro-use-wrong-name.stderr +++ b/src/test/ui/macros/macro-use-wrong-name.stderr @@ -2,7 +2,7 @@ error: cannot find macro `macro_two!` in this scope --> $DIR/macro-use-wrong-name.rs:7:5 | LL | macro_two!(); - | ^^^^^^^^^ help: you could try the macro: `macro_one` + | ^^^^^^^^^ help: a macro with a similar name exists: `macro_one` error: aborting due to previous error diff --git a/src/test/ui/macros/macro_undefined.stderr b/src/test/ui/macros/macro_undefined.stderr index b516f91c67d..9239b2a51e6 100644 --- a/src/test/ui/macros/macro_undefined.stderr +++ b/src/test/ui/macros/macro_undefined.stderr @@ -2,7 +2,7 @@ error: cannot find macro `k!` in this scope --> $DIR/macro_undefined.rs:11:5 | LL | k!(); - | ^ help: you could try the macro: `kl` + | ^ help: a macro with a similar name exists: `kl` error: aborting due to previous error diff --git a/src/test/ui/no-implicit-prelude-nested.rs b/src/test/ui/no-implicit-prelude-nested.rs index fae52c0edc1..c314967da4f 100644 --- a/src/test/ui/no-implicit-prelude-nested.rs +++ b/src/test/ui/no-implicit-prelude-nested.rs @@ -9,7 +9,7 @@ mod foo { mod baz { struct Test; impl Add for Test {} //~ ERROR cannot find trait `Add` in this scope - impl Clone for Test {} //~ ERROR cannot find trait `Clone` in this scope + impl Clone for Test {} //~ ERROR expected trait, found derive macro `Clone` impl Iterator for Test {} //~ ERROR cannot find trait `Iterator` in this scope impl ToString for Test {} //~ ERROR cannot find trait `ToString` in this scope impl Writer for Test {} //~ ERROR cannot find trait `Writer` in this scope @@ -21,7 +21,7 @@ mod foo { struct Test; impl Add for Test {} //~ ERROR cannot find trait `Add` in this scope - impl Clone for Test {} //~ ERROR cannot find trait `Clone` in this scope + impl Clone for Test {} //~ ERROR expected trait, found derive macro `Clone` impl Iterator for Test {} //~ ERROR cannot find trait `Iterator` in this scope impl ToString for Test {} //~ ERROR cannot find trait `ToString` in this scope impl Writer for Test {} //~ ERROR cannot find trait `Writer` in this scope @@ -36,7 +36,7 @@ fn qux() { mod qux_inner { struct Test; impl Add for Test {} //~ ERROR cannot find trait `Add` in this scope - impl Clone for Test {} //~ ERROR cannot find trait `Clone` in this scope + impl Clone for Test {} //~ ERROR expected trait, found derive macro `Clone` impl Iterator for Test {} //~ ERROR cannot find trait `Iterator` in this scope impl ToString for Test {} //~ ERROR cannot find trait `ToString` in this scope impl Writer for Test {} //~ ERROR cannot find trait `Writer` in this scope diff --git a/src/test/ui/no-implicit-prelude-nested.stderr b/src/test/ui/no-implicit-prelude-nested.stderr index 79b9396d41c..8d695e45da4 100644 --- a/src/test/ui/no-implicit-prelude-nested.stderr +++ b/src/test/ui/no-implicit-prelude-nested.stderr @@ -8,12 +8,12 @@ help: possible candidate is found in another module, you can import it into scop LL | use std::ops::Add; | -error[E0405]: cannot find trait `Clone` in this scope +error[E0404]: expected trait, found derive macro `Clone` --> $DIR/no-implicit-prelude-nested.rs:12:14 | LL | impl Clone for Test {} - | ^^^^^ not found in this scope -help: possible candidates are found in other modules, you can import them into scope + | ^^^^^ not a trait +help: possible better candidates are found in other modules, you can import them into scope | LL | use std::clone::Clone; | @@ -72,12 +72,12 @@ help: possible candidate is found in another module, you can import it into scop LL | use std::ops::Add; | -error[E0405]: cannot find trait `Clone` in this scope +error[E0404]: expected trait, found derive macro `Clone` --> $DIR/no-implicit-prelude-nested.rs:24:10 | LL | impl Clone for Test {} - | ^^^^^ not found in this scope -help: possible candidates are found in other modules, you can import them into scope + | ^^^^^ not a trait +help: possible better candidates are found in other modules, you can import them into scope | LL | use std::clone::Clone; | @@ -136,12 +136,12 @@ help: possible candidate is found in another module, you can import it into scop LL | use std::ops::Add; | -error[E0405]: cannot find trait `Clone` in this scope +error[E0404]: expected trait, found derive macro `Clone` --> $DIR/no-implicit-prelude-nested.rs:39:14 | LL | impl Clone for Test {} - | ^^^^^ not found in this scope -help: possible candidates are found in other modules, you can import them into scope + | ^^^^^ not a trait +help: possible better candidates are found in other modules, you can import them into scope | LL | use std::clone::Clone; | @@ -192,5 +192,5 @@ LL | use std::prelude::v1::drop; error: aborting due to 18 previous errors -Some errors have detailed explanations: E0405, E0425. -For more information about an error, try `rustc --explain E0405`. +Some errors have detailed explanations: E0404, E0405, E0425. +For more information about an error, try `rustc --explain E0404`. diff --git a/src/test/ui/no-implicit-prelude.rs b/src/test/ui/no-implicit-prelude.rs index e2074bbb8c8..4b0ca4d524e 100644 --- a/src/test/ui/no-implicit-prelude.rs +++ b/src/test/ui/no-implicit-prelude.rs @@ -8,7 +8,7 @@ struct Test; impl Add for Test {} //~ ERROR cannot find trait `Add` in this scope -impl Clone for Test {} //~ ERROR cannot find trait `Clone` in this scope +impl Clone for Test {} //~ ERROR expected trait, found derive macro `Clone` impl Iterator for Test {} //~ ERROR cannot find trait `Iterator` in this scope impl ToString for Test {} //~ ERROR cannot find trait `ToString` in this scope impl Writer for Test {} //~ ERROR cannot find trait `Writer` in this scope diff --git a/src/test/ui/no-implicit-prelude.stderr b/src/test/ui/no-implicit-prelude.stderr index eac1fcb7b67..6ae889df602 100644 --- a/src/test/ui/no-implicit-prelude.stderr +++ b/src/test/ui/no-implicit-prelude.stderr @@ -8,12 +8,12 @@ help: possible candidate is found in another module, you can import it into scop LL | use std::ops::Add; | -error[E0405]: cannot find trait `Clone` in this scope +error[E0404]: expected trait, found derive macro `Clone` --> $DIR/no-implicit-prelude.rs:11:6 | LL | impl Clone for Test {} - | ^^^^^ not found in this scope -help: possible candidates are found in other modules, you can import them into scope + | ^^^^^ not a trait +help: possible better candidates are found in other modules, you can import them into scope | LL | use std::clone::Clone; | @@ -64,5 +64,5 @@ LL | use std::prelude::v1::drop; error: aborting due to 6 previous errors -Some errors have detailed explanations: E0405, E0425. -For more information about an error, try `rustc --explain E0405`. +Some errors have detailed explanations: E0404, E0405, E0425. +For more information about an error, try `rustc --explain E0404`. diff --git a/src/test/ui/proc-macro/derive-helper-shadowing.rs b/src/test/ui/proc-macro/derive-helper-shadowing.rs index cdc0d6da946..59ba1390e13 100644 --- a/src/test/ui/proc-macro/derive-helper-shadowing.rs +++ b/src/test/ui/proc-macro/derive-helper-shadowing.rs @@ -19,7 +19,7 @@ struct S { struct U; mod inner { - #[empty_helper] //~ ERROR attribute `empty_helper` is currently unknown + #[empty_helper] //~ ERROR cannot find attribute macro `empty_helper` in this scope struct V; } diff --git a/src/test/ui/proc-macro/derive-helper-shadowing.stderr b/src/test/ui/proc-macro/derive-helper-shadowing.stderr index 984ea4fb8ad..149f6eef443 100644 --- a/src/test/ui/proc-macro/derive-helper-shadowing.stderr +++ b/src/test/ui/proc-macro/derive-helper-shadowing.stderr @@ -1,11 +1,8 @@ -error[E0658]: The attribute `empty_helper` is currently unknown to the compiler and may have meaning added to it in the future +error: cannot find attribute macro `empty_helper` in this scope --> $DIR/derive-helper-shadowing.rs:22:15 | LL | #[empty_helper] | ^^^^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable error[E0659]: `empty_helper` is ambiguous (derive helper attribute vs any other name) --> $DIR/derive-helper-shadowing.rs:8:3 @@ -27,5 +24,4 @@ LL | use test_macros::empty_attr as empty_helper; error: aborting due to 2 previous errors -Some errors have detailed explanations: E0658, E0659. -For more information about an error, try `rustc --explain E0658`. +For more information about this error, try `rustc --explain E0659`. diff --git a/src/test/ui/proc-macro/derive-still-gated.rs b/src/test/ui/proc-macro/derive-still-gated.rs index d895d26f267..4e6f9b07220 100644 --- a/src/test/ui/proc-macro/derive-still-gated.rs +++ b/src/test/ui/proc-macro/derive-still-gated.rs @@ -3,7 +3,7 @@ #[macro_use] extern crate test_macros; -#[derive_Empty] //~ ERROR attribute `derive_Empty` is currently unknown +#[derive_Empty] //~ ERROR cannot find attribute macro `derive_Empty` in this scope struct A; fn main() {} diff --git a/src/test/ui/proc-macro/derive-still-gated.stderr b/src/test/ui/proc-macro/derive-still-gated.stderr index a6c0ce6260a..4df1715db94 100644 --- a/src/test/ui/proc-macro/derive-still-gated.stderr +++ b/src/test/ui/proc-macro/derive-still-gated.stderr @@ -1,12 +1,8 @@ -error[E0658]: The attribute `derive_Empty` is currently unknown to the compiler and may have meaning added to it in the future +error: cannot find attribute macro `derive_Empty` in this scope --> $DIR/derive-still-gated.rs:6:3 | LL | #[derive_Empty] | ^^^^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable error: aborting due to previous error -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/proc-macro/expand-to-unstable-2.rs b/src/test/ui/proc-macro/expand-to-unstable-2.rs index 437ae930934..da7c89fdd46 100644 --- a/src/test/ui/proc-macro/expand-to-unstable-2.rs +++ b/src/test/ui/proc-macro/expand-to-unstable-2.rs @@ -1,11 +1,12 @@ // aux-build:derive-unstable-2.rs +#![feature(custom_attribute)] + #[macro_use] extern crate derive_unstable_2; #[derive(Unstable)] //~^ ERROR attributes starting with `rustc` are reserved for use by the `rustc` compiler -//~| ERROR attribute `rustc_foo` is currently unknown to the compiler struct A; diff --git a/src/test/ui/proc-macro/expand-to-unstable-2.stderr b/src/test/ui/proc-macro/expand-to-unstable-2.stderr index 3a729846d78..01e6a4a8ab9 100644 --- a/src/test/ui/proc-macro/expand-to-unstable-2.stderr +++ b/src/test/ui/proc-macro/expand-to-unstable-2.stderr @@ -1,5 +1,5 @@ error[E0658]: attributes starting with `rustc` are reserved for use by the `rustc` compiler - --> $DIR/expand-to-unstable-2.rs:6:10 + --> $DIR/expand-to-unstable-2.rs:8:10 | LL | #[derive(Unstable)] | ^^^^^^^^ @@ -7,15 +7,6 @@ LL | #[derive(Unstable)] = note: for more information, see https://github.com/rust-lang/rust/issues/29642 = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable -error[E0658]: The attribute `rustc_foo` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/expand-to-unstable-2.rs:6:10 - | -LL | #[derive(Unstable)] - | ^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable - -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/proc-macro/issue-41211.rs b/src/test/ui/proc-macro/issue-41211.rs index ee9246e1c9b..491b89b2f55 100644 --- a/src/test/ui/proc-macro/issue-41211.rs +++ b/src/test/ui/proc-macro/issue-41211.rs @@ -3,11 +3,11 @@ // FIXME: https://github.com/rust-lang/rust/issues/41430 // This is a temporary regression test for the ICE reported in #41211 +#![feature(custom_attribute)] #![feature(custom_inner_attributes)] #![identity_attr] -//~^ ERROR attribute `identity_attr` is currently unknown to the compiler -//~| ERROR inconsistent resolution for a macro: first custom attribute, then attribute macro +//~^ ERROR inconsistent resolution for a macro: first custom attribute, then attribute macro extern crate test_macros; use test_macros::identity_attr; diff --git a/src/test/ui/proc-macro/issue-41211.stderr b/src/test/ui/proc-macro/issue-41211.stderr index b5c08587e19..f01cba0c930 100644 --- a/src/test/ui/proc-macro/issue-41211.stderr +++ b/src/test/ui/proc-macro/issue-41211.stderr @@ -1,18 +1,8 @@ -error[E0658]: The attribute `identity_attr` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/issue-41211.rs:8:4 - | -LL | #![identity_attr] - | ^^^^^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable - error: inconsistent resolution for a macro: first custom attribute, then attribute macro - --> $DIR/issue-41211.rs:8:4 + --> $DIR/issue-41211.rs:9:4 | LL | #![identity_attr] | ^^^^^^^^^^^^^ -error: aborting due to 2 previous errors +error: aborting due to previous error -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/proc-macro/macro-namespace-reserved-2.rs b/src/test/ui/proc-macro/macro-namespace-reserved-2.rs index 7a9e472c6c3..8a26df9e76a 100644 --- a/src/test/ui/proc-macro/macro-namespace-reserved-2.rs +++ b/src/test/ui/proc-macro/macro-namespace-reserved-2.rs @@ -35,7 +35,7 @@ fn check_bang3() { //~| ERROR expected macro, found derive macro `crate::MyTrait` } -#[my_macro] //~ ERROR attribute `my_macro` is currently unknown +#[my_macro] //~ ERROR cannot find attribute macro `my_macro` in this scope #[crate::my_macro] //~ ERROR can't use a procedural macro from the same crate that defines it //~| ERROR expected attribute, found macro `crate::my_macro` fn check_attr1() {} diff --git a/src/test/ui/proc-macro/macro-namespace-reserved-2.stderr b/src/test/ui/proc-macro/macro-namespace-reserved-2.stderr index 8a5e346c2b5..e6017dc4d11 100644 --- a/src/test/ui/proc-macro/macro-namespace-reserved-2.stderr +++ b/src/test/ui/proc-macro/macro-namespace-reserved-2.stderr @@ -76,15 +76,6 @@ error: can't use a procedural macro from the same crate that defines it LL | #[derive(MyTrait)] | ^^^^^^^ -error[E0658]: The attribute `my_macro` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/macro-namespace-reserved-2.rs:38:3 - | -LL | #[my_macro] - | ^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable - error: can't use a procedural macro from the same crate that defines it --> $DIR/macro-namespace-reserved-2.rs:39:3 | @@ -97,6 +88,12 @@ error: expected attribute, found macro `crate::my_macro` LL | #[crate::my_macro] | ^^^^^^^^^^^^^^^ not an attribute +error: cannot find attribute macro `my_macro` in this scope + --> $DIR/macro-namespace-reserved-2.rs:38:3 + | +LL | #[my_macro] + | ^^^^^^^^ + error: cannot find derive macro `my_macro` in this scope --> $DIR/macro-namespace-reserved-2.rs:48:10 | @@ -117,4 +114,3 @@ LL | MyTrait!(); error: aborting due to 19 previous errors -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/proc-macro/proc-macro-attributes.rs b/src/test/ui/proc-macro/proc-macro-attributes.rs index 062053453ee..04215226c6d 100644 --- a/src/test/ui/proc-macro/proc-macro-attributes.rs +++ b/src/test/ui/proc-macro/proc-macro-attributes.rs @@ -4,7 +4,7 @@ extern crate derive_b; #[B] //~ ERROR `B` is ambiguous -#[C] //~ ERROR attribute `C` is currently unknown to the compiler +#[C] //~ ERROR cannot find attribute macro `C` in this scope #[B(D)] //~ ERROR `B` is ambiguous #[B(E = "foo")] //~ ERROR `B` is ambiguous #[B(arbitrary tokens)] //~ ERROR `B` is ambiguous diff --git a/src/test/ui/proc-macro/proc-macro-attributes.stderr b/src/test/ui/proc-macro/proc-macro-attributes.stderr index 02dfce1a735..b068c6bc83b 100644 --- a/src/test/ui/proc-macro/proc-macro-attributes.stderr +++ b/src/test/ui/proc-macro/proc-macro-attributes.stderr @@ -1,11 +1,8 @@ -error[E0658]: The attribute `C` is currently unknown to the compiler and may have meaning added to it in the future +error: cannot find attribute macro `C` in this scope --> $DIR/proc-macro-attributes.rs:7:3 | LL | #[C] - | ^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable + | ^ help: a derive helper attribute with a similar name exists: `B` error[E0659]: `B` is ambiguous (derive helper attribute vs any other name) --> $DIR/proc-macro-attributes.rs:6:3 @@ -77,5 +74,4 @@ LL | #[macro_use] error: aborting due to 5 previous errors -Some errors have detailed explanations: E0658, E0659. -For more information about an error, try `rustc --explain E0658`. +For more information about this error, try `rustc --explain E0659`. diff --git a/src/test/ui/proc-macro/resolve-error.rs b/src/test/ui/proc-macro/resolve-error.rs index 1298c08df84..0a7861aba6e 100644 --- a/src/test/ui/proc-macro/resolve-error.rs +++ b/src/test/ui/proc-macro/resolve-error.rs @@ -24,11 +24,11 @@ macro_rules! attr_proc_mac { struct Foo; // Interpreted as a feature gated custom attribute -#[attr_proc_macra] //~ ERROR attribute `attr_proc_macra` is currently unknown +#[attr_proc_macra] //~ ERROR cannot find attribute macro `attr_proc_macra` in this scope struct Bar; // Interpreted as a feature gated custom attribute -#[FooWithLongNan] //~ ERROR attribute `FooWithLongNan` is currently unknown +#[FooWithLongNan] //~ ERROR cannot find attribute macro `FooWithLongNan` in this scope struct Asdf; #[derive(Dlone)] diff --git a/src/test/ui/proc-macro/resolve-error.stderr b/src/test/ui/proc-macro/resolve-error.stderr index 02cf7cdb964..3c9b2baacbd 100644 --- a/src/test/ui/proc-macro/resolve-error.stderr +++ b/src/test/ui/proc-macro/resolve-error.stderr @@ -1,38 +1,32 @@ -error[E0658]: The attribute `attr_proc_macra` is currently unknown to the compiler and may have meaning added to it in the future +error: cannot find derive macro `FooWithLongNan` in this scope + --> $DIR/resolve-error.rs:22:10 + | +LL | #[derive(FooWithLongNan)] + | ^^^^^^^^^^^^^^ help: a derive macro with a similar name exists: `FooWithLongName` + +error: cannot find attribute macro `attr_proc_macra` in this scope --> $DIR/resolve-error.rs:27:3 | LL | #[attr_proc_macra] - | ^^^^^^^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable + | ^^^^^^^^^^^^^^^ help: an attribute macro with a similar name exists: `attr_proc_macro` -error[E0658]: The attribute `FooWithLongNan` is currently unknown to the compiler and may have meaning added to it in the future +error: cannot find attribute macro `FooWithLongNan` in this scope --> $DIR/resolve-error.rs:31:3 | LL | #[FooWithLongNan] | ^^^^^^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable - -error: cannot find derive macro `FooWithLongNan` in this scope - --> $DIR/resolve-error.rs:22:10 - | -LL | #[derive(FooWithLongNan)] - | ^^^^^^^^^^^^^^ help: try: `FooWithLongName` error: cannot find derive macro `Dlone` in this scope --> $DIR/resolve-error.rs:34:10 | LL | #[derive(Dlone)] - | ^^^^^ help: try: `Clone` + | ^^^^^ help: a derive macro with a similar name exists: `Clone` error: cannot find derive macro `Dlona` in this scope --> $DIR/resolve-error.rs:38:10 | LL | #[derive(Dlona)] - | ^^^^^ help: try: `Clona` + | ^^^^^ help: a derive macro with a similar name exists: `Clona` error: cannot find derive macro `attr_proc_macra` in this scope --> $DIR/resolve-error.rs:42:10 @@ -44,13 +38,13 @@ error: cannot find macro `FooWithLongNama!` in this scope --> $DIR/resolve-error.rs:47:5 | LL | FooWithLongNama!(); - | ^^^^^^^^^^^^^^^ help: you could try the macro: `FooWithLongNam` + | ^^^^^^^^^^^^^^^ help: a macro with a similar name exists: `FooWithLongNam` error: cannot find macro `attr_proc_macra!` in this scope --> $DIR/resolve-error.rs:50:5 | LL | attr_proc_macra!(); - | ^^^^^^^^^^^^^^^ help: you could try the macro: `attr_proc_mac` + | ^^^^^^^^^^^^^^^ help: a macro with a similar name exists: `attr_proc_mac` error: cannot find macro `Dlona!` in this scope --> $DIR/resolve-error.rs:53:5 @@ -62,8 +56,7 @@ error: cannot find macro `bang_proc_macrp!` in this scope --> $DIR/resolve-error.rs:56:5 | LL | bang_proc_macrp!(); - | ^^^^^^^^^^^^^^^ help: you could try the macro: `bang_proc_macro` + | ^^^^^^^^^^^^^^^ help: a macro with a similar name exists: `bang_proc_macro` error: aborting due to 10 previous errors -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/reserved/reserved-attr-on-macro.rs b/src/test/ui/reserved/reserved-attr-on-macro.rs index cb535362266..fddb991da82 100644 --- a/src/test/ui/reserved/reserved-attr-on-macro.rs +++ b/src/test/ui/reserved/reserved-attr-on-macro.rs @@ -1,5 +1,5 @@ #[rustc_attribute_should_be_reserved] -//~^ ERROR attribute `rustc_attribute_should_be_reserved` is currently unknown +//~^ ERROR cannot find attribute macro `rustc_attribute_should_be_reserved` in this scope //~| ERROR attributes starting with `rustc` are reserved for use by the `rustc` compiler macro_rules! foo { diff --git a/src/test/ui/reserved/reserved-attr-on-macro.stderr b/src/test/ui/reserved/reserved-attr-on-macro.stderr index cbd111b47bf..d4b97d290ea 100644 --- a/src/test/ui/reserved/reserved-attr-on-macro.stderr +++ b/src/test/ui/reserved/reserved-attr-on-macro.stderr @@ -7,14 +7,11 @@ LL | #[rustc_attribute_should_be_reserved] = note: for more information, see https://github.com/rust-lang/rust/issues/29642 = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable -error[E0658]: The attribute `rustc_attribute_should_be_reserved` is currently unknown to the compiler and may have meaning added to it in the future +error: cannot find attribute macro `rustc_attribute_should_be_reserved` in this scope --> $DIR/reserved-attr-on-macro.rs:1:3 | LL | #[rustc_attribute_should_be_reserved] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable error: cannot determine resolution for the macro `foo` --> $DIR/reserved-attr-on-macro.rs:10:5 diff --git a/src/test/ui/resolve/levenshtein.stderr b/src/test/ui/resolve/levenshtein.stderr index 7af2cdf7b57..2e3c0f5448e 100644 --- a/src/test/ui/resolve/levenshtein.stderr +++ b/src/test/ui/resolve/levenshtein.stderr @@ -2,7 +2,7 @@ error[E0412]: cannot find type `esize` in this scope --> $DIR/levenshtein.rs:5:11 | LL | fn foo(c: esize) {} // Misspelled primitive type name. - | ^^^^^ help: a primitive type with a similar name exists: `isize` + | ^^^^^ help: a builtin type with a similar name exists: `isize` error[E0412]: cannot find type `Baz` in this scope --> $DIR/levenshtein.rs:10:10 diff --git a/src/test/ui/span/issue-36530.rs b/src/test/ui/span/issue-36530.rs index e11be9e17f2..14b2c8644e0 100644 --- a/src/test/ui/span/issue-36530.rs +++ b/src/test/ui/span/issue-36530.rs @@ -1,9 +1,10 @@ // gate-test-custom_inner_attributes -#[foo] //~ ERROR is currently unknown to the compiler +#![feature(custom_attribute)] + +#[foo] mod foo { - #![foo] //~ ERROR is currently unknown to the compiler - //~| ERROR non-builtin inner attributes are unstable + #![foo] //~ ERROR non-builtin inner attributes are unstable } fn main() {} diff --git a/src/test/ui/span/issue-36530.stderr b/src/test/ui/span/issue-36530.stderr index 65f03e756a2..c6b7895e65a 100644 --- a/src/test/ui/span/issue-36530.stderr +++ b/src/test/ui/span/issue-36530.stderr @@ -1,14 +1,5 @@ -error[E0658]: The attribute `foo` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/issue-36530.rs:3:3 - | -LL | #[foo] - | ^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable - error[E0658]: non-builtin inner attributes are unstable - --> $DIR/issue-36530.rs:5:5 + --> $DIR/issue-36530.rs:7:5 | LL | #![foo] | ^^^^^^^ @@ -16,15 +7,6 @@ LL | #![foo] = note: for more information, see https://github.com/rust-lang/rust/issues/54726 = help: add `#![feature(custom_inner_attributes)]` to the crate attributes to enable -error[E0658]: The attribute `foo` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/issue-36530.rs:5:8 - | -LL | #![foo] - | ^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable - -error: aborting due to 3 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/suggestions/attribute-typos.rs b/src/test/ui/suggestions/attribute-typos.rs index 0e10131ce8d..74f63f2b0ed 100644 --- a/src/test/ui/suggestions/attribute-typos.rs +++ b/src/test/ui/suggestions/attribute-typos.rs @@ -1,11 +1,11 @@ -#[deprcated] //~ ERROR attribute `deprcated` is currently unknown +#[deprcated] //~ ERROR cannot find attribute macro `deprcated` in this scope fn foo() {} -#[tests] //~ ERROR attribute `tests` is currently unknown to the compiler +#[tests] //~ ERROR cannot find attribute macro `tests` in this scope fn bar() {} #[rustc_err] -//~^ ERROR attribute `rustc_err` is currently unknown +//~^ ERROR cannot find attribute macro `rustc_err` in this scope //~| ERROR attributes starting with `rustc` are reserved for use by the `rustc` compiler fn main() {} diff --git a/src/test/ui/suggestions/attribute-typos.stderr b/src/test/ui/suggestions/attribute-typos.stderr index 7c28e882728..6b2f591b9e7 100644 --- a/src/test/ui/suggestions/attribute-typos.stderr +++ b/src/test/ui/suggestions/attribute-typos.stderr @@ -7,32 +7,23 @@ LL | #[rustc_err] = note: for more information, see https://github.com/rust-lang/rust/issues/29642 = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable -error[E0658]: The attribute `rustc_err` is currently unknown to the compiler and may have meaning added to it in the future +error: cannot find attribute macro `rustc_err` in this scope --> $DIR/attribute-typos.rs:7:3 | LL | #[rustc_err] - | ^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable + | ^^^^^^^^^ help: a built-in attribute with a similar name exists: `rustc_error` -error[E0658]: The attribute `tests` is currently unknown to the compiler and may have meaning added to it in the future +error: cannot find attribute macro `tests` in this scope --> $DIR/attribute-typos.rs:4:3 | LL | #[tests] - | ^^^^^ help: a built-in attribute with a similar name exists: `test` - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable + | ^^^^^ help: an attribute macro with a similar name exists: `test` -error[E0658]: The attribute `deprcated` is currently unknown to the compiler and may have meaning added to it in the future +error: cannot find attribute macro `deprcated` in this scope --> $DIR/attribute-typos.rs:1:3 | LL | #[deprcated] | ^^^^^^^^^ help: a built-in attribute with a similar name exists: `deprecated` - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable error: aborting due to 4 previous errors diff --git a/src/test/ui/tool-attributes/tool-attributes-misplaced-1.rs b/src/test/ui/tool-attributes/tool-attributes-misplaced-1.rs index ce902b7e7d2..8c62b34bd9e 100644 --- a/src/test/ui/tool-attributes/tool-attributes-misplaced-1.rs +++ b/src/test/ui/tool-attributes/tool-attributes-misplaced-1.rs @@ -5,7 +5,7 @@ type B = rustfmt::skip; //~ ERROR expected type, found tool attribute `rustfmt:: struct S; // Interpreted as a feature gated custom attribute -#[rustfmt] //~ ERROR attribute `rustfmt` is currently unknown +#[rustfmt] //~ ERROR cannot find attribute macro `rustfmt` in this scope fn check() {} #[rustfmt::skip] // OK diff --git a/src/test/ui/tool-attributes/tool-attributes-misplaced-1.stderr b/src/test/ui/tool-attributes/tool-attributes-misplaced-1.stderr index 32c9a1e8b6e..33581a17082 100644 --- a/src/test/ui/tool-attributes/tool-attributes-misplaced-1.stderr +++ b/src/test/ui/tool-attributes/tool-attributes-misplaced-1.stderr @@ -1,18 +1,15 @@ -error[E0658]: The attribute `rustfmt` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/tool-attributes-misplaced-1.rs:8:3 - | -LL | #[rustfmt] - | ^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable - error: cannot find derive macro `rustfmt` in this scope --> $DIR/tool-attributes-misplaced-1.rs:4:10 | LL | #[derive(rustfmt)] | ^^^^^^^ +error: cannot find attribute macro `rustfmt` in this scope + --> $DIR/tool-attributes-misplaced-1.rs:8:3 + | +LL | #[rustfmt] + | ^^^^^^^ + error: cannot find macro `rustfmt!` in this scope --> $DIR/tool-attributes-misplaced-1.rs:14:5 | @@ -45,5 +42,4 @@ LL | rustfmt::skip; error: aborting due to 7 previous errors -Some errors have detailed explanations: E0423, E0658. -For more information about an error, try `rustc --explain E0423`. +For more information about this error, try `rustc --explain E0423`. |
