Auto merge of #53471 - petrochenkov:biattr2, r=oli-obk

resolve: Some macro resolution refactoring

Work towards completing https://github.com/rust-lang/rust/pull/50911#issuecomment-411605393

The last commit also fixes https://github.com/rust-lang/rust/issues/53269 by not using `def_id()` on `Def::Err` and also fixes https://github.com/rust-lang/rust/issues/53512.
This commit is contained in:
bors 2018-08-21 20:33:31 +00:00
commit d0d81b7fc1
25 changed files with 426 additions and 391 deletions

View File

@ -80,7 +80,7 @@ use std::mem::replace;
use rustc_data_structures::sync::Lrc;
use resolve_imports::{ImportDirective, ImportDirectiveSubclass, NameResolution, ImportResolver};
use macros::{InvocationData, LegacyBinding, MacroBinding};
use macros::{InvocationData, LegacyBinding};
// NB: This module needs to be declared first so diagnostics are
// registered before they are used.
@ -1399,7 +1399,7 @@ pub struct Resolver<'a, 'b: 'a> {
proc_mac_errors: Vec<macros::ProcMacError>,
/// crate-local macro expanded `macro_export` referred to by a module-relative path
macro_expanded_macro_export_errors: BTreeSet<(Span, Span)>,
/// macro-expanded `macro_rules` shadowing existing macros
disallowed_shadowing: Vec<&'a LegacyBinding<'a>>,
arenas: &'a ResolverArenas<'a>,
@ -3529,7 +3529,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
} else if opt_ns == Some(MacroNS) {
assert!(ns == TypeNS);
self.resolve_lexical_macro_path_segment(ident, ns, record_used, record_used,
false, path_span).map(MacroBinding::binding)
false, path_span).map(|(b, _)| b)
} else {
let record_used_id =
if record_used { crate_lint.node_id().or(Some(CRATE_NODE_ID)) } else { None };
@ -4431,6 +4431,42 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
vis.is_accessible_from(module.normal_ancestor_id, self)
}
fn report_ambiguity_error(
&self, name: Name, span: Span, _lexical: bool,
def1: Def, is_import1: bool, is_glob1: bool, from_expansion1: bool, span1: Span,
def2: Def, is_import2: bool, _is_glob2: bool, _from_expansion2: bool, span2: Span,
) {
let participle = |is_import: bool| if is_import { "imported" } else { "defined" };
let msg1 = format!("`{}` could refer to the name {} here", name, participle(is_import1));
let msg2 =
format!("`{}` could also refer to the name {} here", name, participle(is_import2));
let note = if from_expansion1 {
Some(if let Def::Macro(..) = def1 {
format!("macro-expanded {} do not shadow",
if is_import1 { "macro imports" } else { "macros" })
} else {
format!("macro-expanded {} do not shadow when used in a macro invocation path",
if is_import1 { "imports" } else { "items" })
})
} else if is_glob1 {
Some(format!("consider adding an explicit import of `{}` to disambiguate", name))
} else {
None
};
let mut err = struct_span_err!(self.session, span, E0659, "`{}` is ambiguous", name);
err.span_note(span1, &msg1);
match def2 {
Def::Macro(..) if span2.is_dummy() =>
err.note(&format!("`{}` is also a builtin macro", name)),
_ => err.span_note(span2, &msg2),
};
if let Some(note) = note {
err.note(&note);
}
err.emit();
}
fn report_errors(&mut self, krate: &Crate) {
self.report_shadowing_errors();
self.report_with_use_injections(krate);
@ -4446,30 +4482,15 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
}
for &AmbiguityError { span, name, b1, b2, lexical } in &self.ambiguity_errors {
if !reported_spans.insert(span) { continue }
let participle = |binding: &NameBinding| {
if binding.is_import() { "imported" } else { "defined" }
};
let msg1 = format!("`{}` could refer to the name {} here", name, participle(b1));
let msg2 = format!("`{}` could also refer to the name {} here", name, participle(b2));
let note = if b1.expansion == Mark::root() || !lexical && b1.is_glob_import() {
format!("consider adding an explicit import of `{}` to disambiguate", name)
} else if let Def::Macro(..) = b1.def() {
format!("macro-expanded {} do not shadow",
if b1.is_import() { "macro imports" } else { "macros" })
} else {
format!("macro-expanded {} do not shadow when used in a macro invocation path",
if b1.is_import() { "imports" } else { "items" })
};
let mut err = struct_span_err!(self.session, span, E0659, "`{}` is ambiguous", name);
err.span_note(b1.span, &msg1);
match b2.def() {
Def::Macro(..) if b2.span.is_dummy() =>
err.note(&format!("`{}` is also a builtin macro", name)),
_ => err.span_note(b2.span, &msg2),
};
err.note(&note).emit();
if reported_spans.insert(span) {
self.report_ambiguity_error(
name, span, lexical,
b1.def(), b1.is_import(), b1.is_glob_import(),
b1.expansion != Mark::root(), b1.span,
b2.def(), b2.is_import(), b2.is_glob_import(),
b2.expansion != Mark::root(), b2.span,
);
}
}
for &PrivacyError(span, name, binding) in &self.privacy_errors {

View File

@ -43,6 +43,9 @@ use std::cell::Cell;
use std::mem;
use rustc_data_structures::sync::Lrc;
crate struct FromPrelude(bool);
crate struct FromExpansion(bool);
#[derive(Clone)]
pub struct InvocationData<'a> {
pub module: Cell<Module<'a>>,
@ -80,6 +83,12 @@ pub struct LegacyBinding<'a> {
pub span: Span,
}
impl<'a> LegacyBinding<'a> {
fn def(&self) -> Def {
Def::Macro(self.def_id, MacroKind::Bang)
}
}
pub struct ProcMacError {
crate_name: Symbol,
name: Symbol,
@ -88,37 +97,6 @@ pub struct ProcMacError {
warn_msg: &'static str,
}
#[derive(Copy, Clone)]
pub enum MacroBinding<'a> {
Legacy(&'a LegacyBinding<'a>),
Global(&'a NameBinding<'a>),
Modern(&'a NameBinding<'a>),
}
impl<'a> MacroBinding<'a> {
pub fn span(self) -> Span {
match self {
MacroBinding::Legacy(binding) => binding.span,
MacroBinding::Global(binding) | MacroBinding::Modern(binding) => binding.span,
}
}
pub fn binding(self) -> &'a NameBinding<'a> {
match self {
MacroBinding::Global(binding) | MacroBinding::Modern(binding) => binding,
MacroBinding::Legacy(_) => panic!("unexpected MacroBinding::Legacy"),
}
}
pub fn def_ignoring_ambiguity(self) -> Def {
match self {
MacroBinding::Legacy(binding) => Def::Macro(binding.def_id, MacroKind::Bang),
MacroBinding::Global(binding) | MacroBinding::Modern(binding) =>
binding.def_ignoring_ambiguity(),
}
}
}
impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> {
fn next_node_id(&mut self) -> ast::NodeId {
self.session.next_node_id()
@ -319,94 +297,38 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> {
None
}
fn resolve_invoc(&mut self, invoc: &Invocation, scope: Mark, force: bool)
-> Result<Option<Lrc<SyntaxExtension>>, Determinacy> {
let def = match invoc.kind {
InvocationKind::Attr { attr: None, .. } => return Ok(None),
_ => self.resolve_invoc_to_def(invoc, scope, force)?,
fn resolve_macro_invocation(&mut self, invoc: &Invocation, scope: Mark, force: bool)
-> Result<Option<Lrc<SyntaxExtension>>, Determinacy> {
let (path, kind, derives_in_scope) = match invoc.kind {
InvocationKind::Attr { attr: None, .. } =>
return Ok(None),
InvocationKind::Attr { attr: Some(ref attr), ref traits, .. } =>
(&attr.path, MacroKind::Attr, &traits[..]),
InvocationKind::Bang { ref mac, .. } =>
(&mac.node.path, MacroKind::Bang, &[][..]),
InvocationKind::Derive { ref path, .. } =>
(path, MacroKind::Derive, &[][..]),
};
if let Def::Macro(_, MacroKind::ProcMacroStub) = def {
self.report_proc_macro_stub(invoc.span());
return Err(Determinacy::Determined);
} else if let Def::NonMacroAttr(attr_kind) = def {
// Note that not only attributes, but anything in macro namespace can result in a
// `Def::NonMacroAttr` definition (e.g. `inline!()`), so we must report the error
// below for these cases.
let is_attr_invoc =
if let InvocationKind::Attr { .. } = invoc.kind { true } else { false };
let path = invoc.path().expect("no path for non-macro attr");
match attr_kind {
NonMacroAttrKind::Tool | NonMacroAttrKind::DeriveHelper |
NonMacroAttrKind::Custom if is_attr_invoc => {
let features = self.session.features_untracked();
if attr_kind == NonMacroAttrKind::Tool &&
!features.tool_attributes {
feature_err(&self.session.parse_sess, "tool_attributes",
invoc.span(), GateIssue::Language,
"tool attributes are unstable").emit();
}
if attr_kind == NonMacroAttrKind::Custom {
assert!(path.segments.len() == 1);
let name = path.segments[0].ident.name.as_str();
if name.starts_with("rustc_") {
if !features.rustc_attrs {
let msg = "unless otherwise specified, attributes with the prefix \
`rustc_` are reserved for internal compiler diagnostics";
feature_err(&self.session.parse_sess, "rustc_attrs", invoc.span(),
GateIssue::Language, &msg).emit();
}
} else if name.starts_with("derive_") {
if !features.custom_derive {
feature_err(&self.session.parse_sess, "custom_derive", invoc.span(),
GateIssue::Language, EXPLAIN_DERIVE_UNDERSCORE).emit();
}
} else 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);
feature_err(&self.session.parse_sess, "custom_attribute", invoc.span(),
GateIssue::Language, &msg).emit();
}
}
return Ok(Some(Lrc::new(SyntaxExtension::NonMacroAttr {
mark_used: attr_kind == NonMacroAttrKind::Tool,
})));
}
_ => {
self.report_non_macro_attr(path.span, def);
return Err(Determinacy::Determined);
}
}
let (def, ext) = self.resolve_macro_to_def(path, kind, scope, derives_in_scope, force)?;
if let Def::Macro(def_id, _) = def {
self.macro_defs.insert(invoc.expansion_data.mark, def_id);
let normal_module_def_id =
self.macro_def_scope(invoc.expansion_data.mark).normal_ancestor_id;
self.definitions.add_parent_module_of_macro_def(invoc.expansion_data.mark,
normal_module_def_id);
invoc.expansion_data.mark.set_default_transparency(ext.default_transparency());
invoc.expansion_data.mark.set_is_builtin(def_id.krate == BUILTIN_MACROS_CRATE);
}
let def_id = def.def_id();
self.macro_defs.insert(invoc.expansion_data.mark, def_id);
let normal_module_def_id =
self.macro_def_scope(invoc.expansion_data.mark).normal_ancestor_id;
self.definitions.add_parent_module_of_macro_def(invoc.expansion_data.mark,
normal_module_def_id);
self.unused_macros.remove(&def_id);
let ext = self.get_macro(def);
invoc.expansion_data.mark.set_default_transparency(ext.default_transparency());
invoc.expansion_data.mark.set_is_builtin(def_id.krate == BUILTIN_MACROS_CRATE);
Ok(Some(ext))
}
fn resolve_macro(&mut self, scope: Mark, path: &ast::Path, kind: MacroKind, force: bool)
-> Result<Lrc<SyntaxExtension>, Determinacy> {
self.resolve_macro_to_def(scope, path, kind, force).and_then(|def| {
if let Def::Macro(_, MacroKind::ProcMacroStub) = def {
self.report_proc_macro_stub(path.span);
return Err(Determinacy::Determined);
} else if let Def::NonMacroAttr(..) = def {
self.report_non_macro_attr(path.span, def);
return Err(Determinacy::Determined);
}
self.unused_macros.remove(&def.def_id());
Ok(self.get_macro(def))
})
fn resolve_macro_path(&mut self, path: &ast::Path, kind: MacroKind, scope: Mark,
derives_in_scope: &[ast::Path], force: bool)
-> Result<Lrc<SyntaxExtension>, Determinacy> {
Ok(self.resolve_macro_to_def(path, kind, scope, derives_in_scope, force)?.1)
}
fn check_unused_macros(&self) {
@ -428,95 +350,91 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> {
}
impl<'a, 'cl> Resolver<'a, 'cl> {
fn report_proc_macro_stub(&self, span: Span) {
self.session.span_err(span,
"can't use a procedural macro from the same crate that defines it");
}
fn resolve_macro_to_def(&mut self, path: &ast::Path, kind: MacroKind, scope: Mark,
derives_in_scope: &[ast::Path], force: bool)
-> Result<(Def, Lrc<SyntaxExtension>), Determinacy> {
let def = self.resolve_macro_to_def_inner(path, kind, scope, derives_in_scope, force);
fn report_non_macro_attr(&self, span: Span, def: Def) {
self.session.span_err(span, &format!("expected a macro, found {}", def.kind_name()));
}
fn resolve_invoc_to_def(&mut self, invoc: &Invocation, scope: Mark, force: bool)
-> Result<Def, Determinacy> {
let (attr, traits) = match invoc.kind {
InvocationKind::Attr { ref attr, ref traits, .. } => (attr, traits),
InvocationKind::Bang { ref mac, .. } => {
return self.resolve_macro_to_def(scope, &mac.node.path, MacroKind::Bang, force);
}
InvocationKind::Derive { ref path, .. } => {
return self.resolve_macro_to_def(scope, path, MacroKind::Derive, force);
}
};
let path = attr.as_ref().unwrap().path.clone();
let def = self.resolve_macro_to_def(scope, &path, MacroKind::Attr, force);
if let Ok(Def::NonMacroAttr(NonMacroAttrKind::Custom)) = def {} else {
return def;
}
// At this point we've found that the `attr` is determinately unresolved and thus can be
// interpreted as a custom attribute. Normally custom attributes are feature gated, but
// it may be a custom attribute whitelisted by a derive macro and they do not require
// a feature gate.
//
// So here we look through all of the derive annotations in scope and try to resolve them.
// If they themselves successfully resolve *and* one of the resolved derive macros
// whitelists this attribute's name, then this is a registered attribute and we can convert
// it from a "generic custom attrite" into a "known derive helper attribute".
enum ConvertToDeriveHelper { Yes, No, DontKnow }
let mut convert_to_derive_helper = ConvertToDeriveHelper::No;
let attr_name = path.segments[0].ident.name;
for path in traits {
match self.resolve_macro(scope, path, MacroKind::Derive, force) {
Ok(ext) => if let SyntaxExtension::ProcMacroDerive(_, ref inert_attrs, _) = *ext {
if inert_attrs.contains(&attr_name) {
convert_to_derive_helper = ConvertToDeriveHelper::Yes;
break
}
},
Err(Determinacy::Undetermined) =>
convert_to_derive_helper = ConvertToDeriveHelper::DontKnow,
Err(Determinacy::Determined) => {}
}
}
match convert_to_derive_helper {
ConvertToDeriveHelper::Yes => Ok(Def::NonMacroAttr(NonMacroAttrKind::DeriveHelper)),
ConvertToDeriveHelper::No => def,
ConvertToDeriveHelper::DontKnow => Err(Determinacy::determined(force)),
}
}
fn resolve_macro_to_def(&mut self, scope: Mark, path: &ast::Path, kind: MacroKind, force: bool)
-> Result<Def, Determinacy> {
let def = self.resolve_macro_to_def_inner(scope, path, kind, force);
// Report errors and enforce feature gates for the resolved macro.
if def != Err(Determinacy::Undetermined) {
// Do not report duplicated errors on every undetermined resolution.
path.segments.iter().find(|segment| segment.args.is_some()).map(|segment| {
self.session.span_err(segment.args.as_ref().unwrap().span(),
"generic arguments in macro path");
});
}
if kind != MacroKind::Bang && path.segments.len() > 1 &&
def != Ok(Def::NonMacroAttr(NonMacroAttrKind::Tool)) {
if !self.session.features_untracked().proc_macro_path_invoc {
emit_feature_err(
&self.session.parse_sess,
"proc_macro_path_invoc",
path.span,
GateIssue::Language,
"paths of length greater than one in macro invocations are \
currently unstable",
);
for segment in &path.segments {
if let Some(args) = &segment.args {
self.session.span_err(args.span(), "generic arguments in macro path");
}
}
}
def
let def = def?;
if path.segments.len() > 1 {
if kind != MacroKind::Bang {
if def != Def::NonMacroAttr(NonMacroAttrKind::Tool) &&
!self.session.features_untracked().proc_macro_path_invoc {
let msg = format!("non-ident {} paths are unstable", kind.descr());
emit_feature_err(&self.session.parse_sess, "proc_macro_path_invoc",
path.span, GateIssue::Language, &msg);
}
}
}
match def {
Def::Macro(def_id, macro_kind) => {
self.unused_macros.remove(&def_id);
if macro_kind == MacroKind::ProcMacroStub {
let msg = "can't use a procedural macro from the same crate that defines it";
self.session.span_err(path.span, msg);
return Err(Determinacy::Determined);
}
}
Def::NonMacroAttr(attr_kind) => {
if kind == MacroKind::Attr {
let features = self.session.features_untracked();
if attr_kind == NonMacroAttrKind::Tool && !features.tool_attributes {
feature_err(&self.session.parse_sess, "tool_attributes", path.span,
GateIssue::Language, "tool attributes are unstable").emit();
}
if attr_kind == NonMacroAttrKind::Custom {
assert!(path.segments.len() == 1);
let name = path.segments[0].ident.name.as_str();
if name.starts_with("rustc_") {
if !features.rustc_attrs {
let msg = "unless otherwise specified, attributes with the prefix \
`rustc_` are reserved for internal compiler diagnostics";
feature_err(&self.session.parse_sess, "rustc_attrs", path.span,
GateIssue::Language, &msg).emit();
}
} else if name.starts_with("derive_") {
if !features.custom_derive {
feature_err(&self.session.parse_sess, "custom_derive", path.span,
GateIssue::Language, EXPLAIN_DERIVE_UNDERSCORE).emit();
}
} else 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);
feature_err(&self.session.parse_sess, "custom_attribute", path.span,
GateIssue::Language, &msg).emit();
}
}
} else {
// Not only attributes, but anything in macro namespace can result in
// `Def::NonMacroAttr` definition (e.g. `inline!()`), so we must report
// an error for those cases.
let msg = format!("expected a macro, found {}", def.kind_name());
self.session.span_err(path.span, &msg);
return Err(Determinacy::Determined);
}
}
_ => panic!("expected `Def::Macro` or `Def::NonMacroAttr`"),
}
Ok((def, self.get_macro(def)))
}
pub fn resolve_macro_to_def_inner(&mut self, scope: Mark, path: &ast::Path,
kind: MacroKind, force: bool)
-> Result<Def, Determinacy> {
pub fn resolve_macro_to_def_inner(&mut self, path: &ast::Path, kind: MacroKind, scope: Mark,
derives_in_scope: &[ast::Path], force: bool)
-> Result<Def, Determinacy> {
let ast::Path { ref segments, span } = *path;
let mut path: Vec<_> = segments.iter().map(|seg| seg.ident).collect();
let invocation = self.invocations[&scope];
@ -558,12 +476,12 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
}
let legacy_resolution = self.resolve_legacy_scope(&invocation.legacy_scope, path[0], false);
let result = if let Some(MacroBinding::Legacy(binding)) = legacy_resolution {
Ok(Def::Macro(binding.def_id, MacroKind::Bang))
let result = if let Some((legacy_binding, _)) = legacy_resolution {
Ok(legacy_binding.def())
} else {
match self.resolve_lexical_macro_path_segment(path[0], MacroNS, false, force,
kind == MacroKind::Attr, span) {
Ok(binding) => Ok(binding.binding().def_ignoring_ambiguity()),
Ok((binding, _)) => Ok(binding.def_ignoring_ambiguity()),
Err(Determinacy::Undetermined) => return Err(Determinacy::Undetermined),
Err(Determinacy::Determined) => {
self.found_unresolved_macro = true;
@ -575,21 +493,56 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
self.current_module.nearest_item_scope().legacy_macro_resolutions.borrow_mut()
.push((scope, path[0], kind, result.ok()));
result
if let Ok(Def::NonMacroAttr(NonMacroAttrKind::Custom)) = result {} else {
return result;
}
// At this point we've found that the `attr` is determinately unresolved and thus can be
// interpreted as a custom attribute. Normally custom attributes are feature gated, but
// it may be a custom attribute whitelisted by a derive macro and they do not require
// a feature gate.
//
// So here we look through all of the derive annotations in scope and try to resolve them.
// If they themselves successfully resolve *and* one of the resolved derive macros
// whitelists this attribute's name, then this is a registered attribute and we can convert
// it from a "generic custom attrite" into a "known derive helper attribute".
assert!(kind == MacroKind::Attr);
enum ConvertToDeriveHelper { Yes, No, DontKnow }
let mut convert_to_derive_helper = ConvertToDeriveHelper::No;
for derive in derives_in_scope {
match self.resolve_macro_path(derive, MacroKind::Derive, scope, &[], force) {
Ok(ext) => if let SyntaxExtension::ProcMacroDerive(_, ref inert_attrs, _) = *ext {
if inert_attrs.contains(&path[0].name) {
convert_to_derive_helper = ConvertToDeriveHelper::Yes;
break
}
},
Err(Determinacy::Undetermined) =>
convert_to_derive_helper = ConvertToDeriveHelper::DontKnow,
Err(Determinacy::Determined) => {}
}
}
match convert_to_derive_helper {
ConvertToDeriveHelper::Yes => Ok(Def::NonMacroAttr(NonMacroAttrKind::DeriveHelper)),
ConvertToDeriveHelper::No => result,
ConvertToDeriveHelper::DontKnow => Err(Determinacy::determined(force)),
}
}
// Resolve the initial segment of a non-global macro path
// (e.g. `foo` in `foo::bar!(); or `foo!();`).
// This is a variation of `fn resolve_ident_in_lexical_scope` that can be run during
// expansion and import resolution (perhaps they can be merged in the future).
pub fn resolve_lexical_macro_path_segment(&mut self,
mut ident: Ident,
ns: Namespace,
record_used: bool,
force: bool,
is_attr: bool,
path_span: Span)
-> Result<MacroBinding<'a>, Determinacy> {
crate fn resolve_lexical_macro_path_segment(
&mut self,
mut ident: Ident,
ns: Namespace,
record_used: bool,
force: bool,
is_attr: bool,
path_span: Span
) -> Result<(&'a NameBinding<'a>, FromPrelude), 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
@ -629,7 +582,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
// m::mac!();
// }
// This includes names from globs and from macro expansions.
let mut potentially_ambiguous_result: Option<MacroBinding> = None;
let mut potentially_ambiguous_result: Option<(&NameBinding, FromPrelude)> = None;
enum WhereToResolve<'a> {
Module(Module<'a>),
@ -657,11 +610,11 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
path_span,
);
self.current_module = orig_current_module;
binding.map(MacroBinding::Modern)
binding.map(|binding| (binding, FromPrelude(false)))
}
WhereToResolve::MacroPrelude => {
match self.macro_prelude.get(&ident.name).cloned() {
Some(binding) => Ok(MacroBinding::Global(binding)),
Some(binding) => Ok((binding, FromPrelude(true))),
None => Err(Determinacy::Determined),
}
}
@ -673,7 +626,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
let binding = (Def::NonMacroAttr(NonMacroAttrKind::Builtin),
ty::Visibility::Public, ident.span, Mark::root())
.to_name_binding(self.arenas);
Ok(MacroBinding::Global(binding))
Ok((binding, FromPrelude(true)))
} else {
Err(Determinacy::Determined)
}
@ -696,7 +649,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
let binding = (crate_root, ty::Visibility::Public,
ident.span, Mark::root()).to_name_binding(self.arenas);
Ok(MacroBinding::Global(binding))
Ok((binding, FromPrelude(true)))
} else {
Err(Determinacy::Determined)
}
@ -705,7 +658,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
if use_prelude && is_known_tool(ident.name) {
let binding = (Def::ToolMod, ty::Visibility::Public,
ident.span, Mark::root()).to_name_binding(self.arenas);
Ok(MacroBinding::Global(binding))
Ok((binding, FromPrelude(true)))
} else {
Err(Determinacy::Determined)
}
@ -722,7 +675,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
false,
path_span,
) {
result = Ok(MacroBinding::Global(binding));
result = Ok((binding, FromPrelude(true)));
}
}
}
@ -733,7 +686,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
self.primitive_type_table.primitive_types.get(&ident.name).cloned() {
let binding = (Def::PrimTy(prim_ty), ty::Visibility::Public,
ident.span, Mark::root()).to_name_binding(self.arenas);
Ok(MacroBinding::Global(binding))
Ok((binding, FromPrelude(true)))
} else {
Err(Determinacy::Determined)
}
@ -772,18 +725,16 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
return Ok(result);
}
let binding = result.binding();
// Found a solution that is ambiguous with a previously found solution.
// Push an ambiguity error for later reporting and
// return something for better recovery.
if let Some(previous_result) = potentially_ambiguous_result {
if binding.def() != previous_result.binding().def() {
if result.0.def() != previous_result.0.def() {
self.ambiguity_errors.push(AmbiguityError {
span: path_span,
name: ident.name,
b1: previous_result.binding(),
b2: binding,
b1: previous_result.0,
b2: result.0,
lexical: true,
});
return Ok(previous_result);
@ -793,7 +744,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
// Found a solution that's not an ambiguity yet, but is "suspicious" and
// can participate in ambiguities later on.
// Remember it and go search for other solutions in outer scopes.
if binding.is_glob_import() || binding.expansion != Mark::root() {
if result.0.is_glob_import() || result.0.expansion != Mark::root() {
potentially_ambiguous_result = Some(result);
continue_search!();
@ -823,20 +774,19 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
let binding = (Def::NonMacroAttr(NonMacroAttrKind::Custom),
ty::Visibility::Public, ident.span, Mark::root())
.to_name_binding(self.arenas);
Ok(MacroBinding::Global(binding))
Ok((binding, FromPrelude(true)))
} else {
Err(determinacy)
}
}
pub fn resolve_legacy_scope(&mut self,
mut scope: &'a Cell<LegacyScope<'a>>,
ident: Ident,
record_used: bool)
-> Option<MacroBinding<'a>> {
crate fn resolve_legacy_scope(&mut self,
mut scope: &'a Cell<LegacyScope<'a>>,
ident: Ident,
record_used: bool)
-> Option<(&'a LegacyBinding<'a>, FromExpansion)> {
let ident = ident.modern();
let mut relative_depth: u32 = 0;
let mut binding = None;
loop {
match scope.get() {
LegacyScope::Empty => break,
@ -861,23 +811,14 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
if record_used && relative_depth > 0 {
self.disallowed_shadowing.push(potential_binding);
}
binding = Some(potential_binding);
break
return Some((potential_binding, FromExpansion(relative_depth > 0)));
}
scope = &potential_binding.parent;
}
};
}
let binding = if let Some(binding) = binding {
MacroBinding::Legacy(binding)
} else if let Some(binding) = self.macro_prelude.get(&ident.name).cloned() {
MacroBinding::Global(binding)
} else {
return None;
};
Some(binding)
None
}
pub fn finalize_current_module_macro_resolutions(&mut self) {
@ -899,10 +840,10 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
let resolution = self.resolve_lexical_macro_path_segment(ident, MacroNS, true, true,
kind == MacroKind::Attr, span);
let check_consistency = |this: &Self, binding: MacroBinding| {
let check_consistency = |this: &Self, new_def: Def| {
if let Some(def) = def {
if this.ambiguity_errors.is_empty() && this.disallowed_shadowing.is_empty() &&
binding.def_ignoring_ambiguity() != def {
new_def != def && new_def != Def::Err {
// Make sure compilation does not succeed if preferred macro resolution
// has changed after the macro had been expanded. In theory all such
// situations should be reported as ambiguity errors, so this is span-bug.
@ -921,17 +862,6 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
};
match (legacy_resolution, resolution) {
(Some(MacroBinding::Legacy(legacy_binding)), Ok(MacroBinding::Modern(binding))) => {
if legacy_binding.def_id != binding.def_ignoring_ambiguity().def_id() {
let msg1 = format!("`{}` could refer to the macro defined here", ident);
let msg2 =
format!("`{}` could also refer to the macro imported here", ident);
self.session.struct_span_err(span, &format!("`{}` is ambiguous", ident))
.span_note(legacy_binding.span, &msg1)
.span_note(binding.span, &msg2)
.emit();
}
},
(None, Err(_)) => {
assert!(def.is_none());
let bang = if kind == MacroKind::Bang { "!" } else { "" };
@ -941,26 +871,34 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
self.suggest_macro_name(&ident.as_str(), kind, &mut err, span);
err.emit();
},
(Some(MacroBinding::Modern(_)), _) | (_, Ok(MacroBinding::Legacy(_))) => {
span_bug!(span, "impossible macro resolution result");
(Some((legacy_binding, FromExpansion(from_expansion))),
Ok((binding, FromPrelude(false)))) |
(Some((legacy_binding, FromExpansion(from_expansion @ true))),
Ok((binding, FromPrelude(true)))) => {
if legacy_binding.def() != binding.def_ignoring_ambiguity() {
self.report_ambiguity_error(
ident.name, span, true,
legacy_binding.def(), false, false,
from_expansion, legacy_binding.span,
binding.def(), binding.is_import(), binding.is_glob_import(),
binding.expansion != Mark::root(), binding.span,
);
}
},
// OK, non-macro-expanded legacy wins over macro prelude even if defs are different
(Some((legacy_binding, FromExpansion(false))), Ok((_, FromPrelude(true)))) |
// OK, unambiguous resolution
(Some((legacy_binding, _)), Err(_)) => {
check_consistency(self, legacy_binding.def());
}
// OK, unambiguous resolution
(Some(binding), Err(_)) | (None, Ok(binding)) |
// OK, legacy wins over global even if their definitions are different
(Some(binding @ MacroBinding::Legacy(_)), Ok(MacroBinding::Global(_))) |
// OK, modern wins over global even if their definitions are different
(Some(MacroBinding::Global(_)), Ok(binding @ MacroBinding::Modern(_))) => {
check_consistency(self, binding);
}
(Some(MacroBinding::Global(binding1)), Ok(MacroBinding::Global(binding2))) => {
if binding1.def() != binding2.def() {
span_bug!(span, "mismatch between same global macro resolutions");
(None, Ok((binding, FromPrelude(from_prelude)))) => {
check_consistency(self, binding.def_ignoring_ambiguity());
if from_prelude {
self.record_use(ident, MacroNS, binding, span);
self.err_if_macro_use_proc_macro(ident.name, span, binding);
}
check_consistency(self, MacroBinding::Global(binding1));
self.record_use(ident, MacroNS, binding1, span);
self.err_if_macro_use_proc_macro(ident.name, span, binding1);
},
}
};
}
}
@ -1082,7 +1020,11 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
/// Error if `ext` is a Macros 1.1 procedural macro being imported by `#[macro_use]`
fn err_if_macro_use_proc_macro(&mut self, name: Name, use_span: Span,
binding: &NameBinding<'a>) {
let krate = binding.def().def_id().krate;
let krate = match binding.def() {
Def::NonMacroAttr(..) | Def::Err => return,
Def::Macro(def_id, _) => def_id.krate,
_ => unreachable!(),
};
// Plugin-based syntax extensions are exempt from this check
if krate == BUILTIN_MACROS_CRATE { return; }

View File

@ -403,9 +403,7 @@ fn macro_resolve(cx: &DocContext, path_str: &str) -> Option<Def> {
let path = ast::Path { segments: vec![segment], span: DUMMY_SP };
let mut resolver = cx.resolver.borrow_mut();
let mark = Mark::root();
let res = resolver
.resolve_macro_to_def_inner(mark, &path, MacroKind::Bang, false);
if let Ok(def) = res {
if let Ok(def) = resolver.resolve_macro_to_def_inner(&path, MacroKind::Bang, mark, &[], false) {
if let SyntaxExtension::DeclMacro { .. } = *resolver.get_macro(def) {
return Some(def);
}

View File

@ -727,10 +727,12 @@ pub trait Resolver {
fn find_legacy_attr_invoc(&mut self, attrs: &mut Vec<Attribute>, allow_derive: bool)
-> Option<Attribute>;
fn resolve_invoc(&mut self, invoc: &Invocation, scope: Mark, force: bool)
-> Result<Option<Lrc<SyntaxExtension>>, Determinacy>;
fn resolve_macro(&mut self, scope: Mark, path: &ast::Path, kind: MacroKind, force: bool)
-> Result<Lrc<SyntaxExtension>, Determinacy>;
fn resolve_macro_invocation(&mut self, invoc: &Invocation, scope: Mark, force: bool)
-> Result<Option<Lrc<SyntaxExtension>>, Determinacy>;
fn resolve_macro_path(&mut self, path: &ast::Path, kind: MacroKind, scope: Mark,
derives_in_scope: &[ast::Path], force: bool)
-> Result<Lrc<SyntaxExtension>, Determinacy>;
fn check_unused_macros(&self);
}
@ -761,12 +763,13 @@ impl Resolver for DummyResolver {
fn resolve_imports(&mut self) {}
fn find_legacy_attr_invoc(&mut self, _attrs: &mut Vec<Attribute>, _allow_derive: bool)
-> Option<Attribute> { None }
fn resolve_invoc(&mut self, _invoc: &Invocation, _scope: Mark, _force: bool)
-> Result<Option<Lrc<SyntaxExtension>>, Determinacy> {
fn resolve_macro_invocation(&mut self, _invoc: &Invocation, _scope: Mark, _force: bool)
-> Result<Option<Lrc<SyntaxExtension>>, Determinacy> {
Err(Determinacy::Determined)
}
fn resolve_macro(&mut self, _scope: Mark, _path: &ast::Path, _kind: MacroKind,
_force: bool) -> Result<Lrc<SyntaxExtension>, Determinacy> {
fn resolve_macro_path(&mut self, _path: &ast::Path, _kind: MacroKind, _scope: Mark,
_derives_in_scope: &[ast::Path], _force: bool)
-> Result<Lrc<SyntaxExtension>, Determinacy> {
Err(Determinacy::Determined)
}
fn check_unused_macros(&self) {}

View File

@ -243,15 +243,6 @@ impl Invocation {
InvocationKind::Derive { ref path, .. } => path.span,
}
}
pub fn path(&self) -> Option<&Path> {
match self.kind {
InvocationKind::Bang { ref mac, .. } => Some(&mac.node.path),
InvocationKind::Attr { attr: Some(ref attr), .. } => Some(&attr.path),
InvocationKind::Attr { attr: None, .. } => None,
InvocationKind::Derive { ref path, .. } => Some(path),
}
}
}
pub struct MacroExpander<'a, 'b:'a> {
@ -343,7 +334,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
let scope =
if self.monotonic { invoc.expansion_data.mark } else { orig_expansion_data.mark };
let ext = match self.cx.resolver.resolve_invoc(&invoc, scope, force) {
let ext = match self.cx.resolver.resolve_macro_invocation(&invoc, scope, force) {
Ok(ext) => Some(ext),
Err(Determinacy::Determined) => None,
Err(Determinacy::Undetermined) => {
@ -393,8 +384,8 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
for path in &traits {
let mark = Mark::fresh(self.cx.current_expansion.mark);
derives.push(mark);
let item = match self.cx.resolver.resolve_macro(
Mark::root(), path, MacroKind::Derive, false) {
let item = match self.cx.resolver.resolve_macro_path(
path, MacroKind::Derive, Mark::root(), &[], false) {
Ok(ext) => match *ext {
BuiltinDerive(..) => item_with_markers.clone(),
_ => item.clone(),

View File

@ -22,7 +22,7 @@ extern crate proc_macro_gates as foo;
use foo::*;
#[foo::a] //~ ERROR: paths of length greater than one
#[foo::a] //~ ERROR: non-ident attribute macro paths are unstable
fn _test() {}
fn _test_inner() {

View File

@ -2,37 +2,37 @@ error: can't use a procedural macro from the same crate that defines it
--> $DIR/macro-namespace-reserved-2.rs:34:5
|
LL | my_macro!(); //~ ERROR can't use a procedural macro from the same crate that defines it
| ^^^^^^^^^^^^
| ^^^^^^^^
error: can't use a procedural macro from the same crate that defines it
--> $DIR/macro-namespace-reserved-2.rs:37:5
|
LL | my_macro_attr!(); //~ ERROR can't use a procedural macro from the same crate that defines it
| ^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^
error: can't use a procedural macro from the same crate that defines it
--> $DIR/macro-namespace-reserved-2.rs:40:5
|
LL | MyTrait!(); //~ ERROR can't use a procedural macro from the same crate that defines it
| ^^^^^^^^^^^
| ^^^^^^^
error: can't use a procedural macro from the same crate that defines it
--> $DIR/macro-namespace-reserved-2.rs:43:1
--> $DIR/macro-namespace-reserved-2.rs:43:3
|
LL | #[my_macro] //~ ERROR can't use a procedural macro from the same crate that defines it
| ^^^^^^^^^^^
| ^^^^^^^^
error: can't use a procedural macro from the same crate that defines it
--> $DIR/macro-namespace-reserved-2.rs:45:1
--> $DIR/macro-namespace-reserved-2.rs:45:3
|
LL | #[my_macro_attr] //~ ERROR can't use a procedural macro from the same crate that defines it
| ^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^
error: can't use a procedural macro from the same crate that defines it
--> $DIR/macro-namespace-reserved-2.rs:47:1
--> $DIR/macro-namespace-reserved-2.rs:47:3
|
LL | #[MyTrait] //~ ERROR can't use a procedural macro from the same crate that defines it
| ^^^^^^^^^^
| ^^^^^^^
error: can't use a procedural macro from the same crate that defines it
--> $DIR/macro-namespace-reserved-2.rs:50:10

View File

@ -2,7 +2,7 @@ error[E0658]: The attribute `unknown` is currently unknown to the compiler and m
--> $DIR/cfg-attr-unknown-attribute-macro-expansion.rs:13:27
|
LL | #[cfg_attr(all(), unknown)] //~ ERROR `unknown` is currently unknown
| ^^^^^^^^
| ^^^^^^^
...
LL | foo!();
| ------- in this macro invocation

View File

@ -1,24 +1,24 @@
error[E0658]: The attribute `foo` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642)
--> $DIR/custom_attribute.rs:13:1
--> $DIR/custom_attribute.rs:13:3
|
LL | #[foo] //~ ERROR The attribute `foo`
| ^^^^^^
| ^^^
|
= 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 (see issue #29642)
--> $DIR/custom_attribute.rs:15:5
--> $DIR/custom_attribute.rs:15:7
|
LL | #[foo] //~ ERROR The attribute `foo`
| ^^^^^^
| ^^^
|
= 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 (see issue #29642)
--> $DIR/custom_attribute.rs:17:5
--> $DIR/custom_attribute.rs:17:7
|
LL | #[foo] //~ ERROR The attribute `foo`
| ^^^^^^
| ^^^
|
= help: add #![feature(custom_attribute)] to the crate attributes to enable

View File

@ -1,104 +1,104 @@
error[E0658]: The attribute `fake_attr` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642)
--> $DIR/feature-gate-custom_attribute.rs:17:1
--> $DIR/feature-gate-custom_attribute.rs:17:3
|
LL | #[fake_attr] //~ ERROR attribute `fake_attr` is currently unknown
| ^^^^^^^^^^^^
| ^^^^^^^^^
|
= 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 (see issue #29642)
--> $DIR/feature-gate-custom_attribute.rs:18:1
--> $DIR/feature-gate-custom_attribute.rs:18:3
|
LL | #[fake_attr(100)] //~ ERROR attribute `fake_attr` is currently unknown
| ^^^^^^^^^^^^^^^^^
| ^^^^^^^^^
|
= 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 (see issue #29642)
--> $DIR/feature-gate-custom_attribute.rs:19:1
--> $DIR/feature-gate-custom_attribute.rs:19:3
|
LL | #[fake_attr(1, 2, 3)] //~ ERROR attribute `fake_attr` is currently unknown
| ^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^
|
= 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 (see issue #29642)
--> $DIR/feature-gate-custom_attribute.rs:20:1
--> $DIR/feature-gate-custom_attribute.rs:20:3
|
LL | #[fake_attr("hello")] //~ ERROR attribute `fake_attr` is currently unknown
| ^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^
|
= 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 (see issue #29642)
--> $DIR/feature-gate-custom_attribute.rs:21:1
--> $DIR/feature-gate-custom_attribute.rs:21:3
|
LL | #[fake_attr(name = "hello")] //~ ERROR attribute `fake_attr` is currently unknown
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^
|
= 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 (see issue #29642)
--> $DIR/feature-gate-custom_attribute.rs:22:1
--> $DIR/feature-gate-custom_attribute.rs:22:3
|
LL | #[fake_attr(1, "hi", key = 12, true, false)] //~ ERROR attribute `fake_attr` is currently unknown
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^
|
= 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 (see issue #29642)
--> $DIR/feature-gate-custom_attribute.rs:23:1
--> $DIR/feature-gate-custom_attribute.rs:23:3
|
LL | #[fake_attr(key = "hello", val = 10)] //~ ERROR attribute `fake_attr` is currently unknown
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^
|
= 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 (see issue #29642)
--> $DIR/feature-gate-custom_attribute.rs:24:1
--> $DIR/feature-gate-custom_attribute.rs:24:3
|
LL | #[fake_attr(key("hello"), val(10))] //~ ERROR attribute `fake_attr` is currently unknown
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^
|
= 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 (see issue #29642)
--> $DIR/feature-gate-custom_attribute.rs:25:1
--> $DIR/feature-gate-custom_attribute.rs:25:3
|
LL | #[fake_attr(enabled = true, disabled = false)] //~ ERROR attribute `fake_attr` is currently unknown
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^
|
= 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 (see issue #29642)
--> $DIR/feature-gate-custom_attribute.rs:26:1
--> $DIR/feature-gate-custom_attribute.rs:26:3
|
LL | #[fake_attr(true)] //~ ERROR attribute `fake_attr` is currently unknown
| ^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^
|
= 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 (see issue #29642)
--> $DIR/feature-gate-custom_attribute.rs:27:1
--> $DIR/feature-gate-custom_attribute.rs:27:3
|
LL | #[fake_attr(pi = 3.14159)] //~ ERROR attribute `fake_attr` is currently unknown
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^
|
= 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 (see issue #29642)
--> $DIR/feature-gate-custom_attribute.rs:28:1
--> $DIR/feature-gate-custom_attribute.rs:28:3
|
LL | #[fake_attr(b"hi")] //~ ERROR attribute `fake_attr` is currently unknown
| ^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^
|
= 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 (see issue #29642)
--> $DIR/feature-gate-custom_attribute.rs:29:1
--> $DIR/feature-gate-custom_attribute.rs:29:3
|
LL | #[fake_doc(r"doc")] //~ ERROR attribute `fake_doc` is currently unknown
| ^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^
|
= help: add #![feature(custom_attribute)] to the crate attributes to enable

View File

@ -1,8 +1,8 @@
error[E0658]: attributes of the form `#[derive_*]` are reserved for the compiler (see issue #29644)
--> $DIR/feature-gate-custom_derive.rs:11:1
--> $DIR/feature-gate-custom_derive.rs:11:3
|
LL | #[derive_Clone]
| ^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^
|
= help: add #![feature(custom_derive)] to the crate attributes to enable

View File

@ -1,8 +1,8 @@
error[E0658]: unless otherwise specified, attributes with the prefix `rustc_` are reserved for internal compiler diagnostics (see issue #29642)
--> $DIR/feature-gate-rustc-attrs.rs:15:1
--> $DIR/feature-gate-rustc-attrs.rs:15:3
|
LL | #[rustc_foo]
| ^^^^^^^^^^^^
| ^^^^^^^^^
|
= help: add #![feature(rustc_attrs)] to the crate attributes to enable

View File

@ -1,8 +1,8 @@
error[E0658]: tool attributes are unstable (see issue #44690)
--> $DIR/feature-gate-tool_attributes.rs:12:5
--> $DIR/feature-gate-tool_attributes.rs:12:7
|
LL | #[rustfmt::skip] //~ ERROR tool attributes are unstable
| ^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^
|
= help: add #![feature(tool_attributes)] to the crate attributes to enable

View File

@ -0,0 +1,21 @@
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// Ambiguity between a `macro_rules` macro and a non-existent import recovered as `Def::Err`
macro_rules! mac { () => () }
mod m {
use nonexistent_module::mac; //~ ERROR unresolved import `nonexistent_module`
mac!(); //~ ERROR `mac` is ambiguous
}
fn main() {}

View File

@ -0,0 +1,27 @@
error[E0432]: unresolved import `nonexistent_module`
--> $DIR/issue-53269.rs:16:9
|
LL | use nonexistent_module::mac; //~ ERROR unresolved import `nonexistent_module`
| ^^^^^^^^^^^^^^^^^^ Maybe a missing `extern crate nonexistent_module;`?
error[E0659]: `mac` is ambiguous
--> $DIR/issue-53269.rs:18:5
|
LL | mac!(); //~ ERROR `mac` is ambiguous
| ^^^
|
note: `mac` could refer to the name defined here
--> $DIR/issue-53269.rs:13:1
|
LL | macro_rules! mac { () => () }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: `mac` could also refer to the name imported here
--> $DIR/issue-53269.rs:16:9
|
LL | use nonexistent_module::mac; //~ ERROR unresolved import `nonexistent_module`
| ^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 2 previous errors
Some errors occurred: E0432, E0659.
For more information about an error, try `rustc --explain E0432`.

View File

@ -0,0 +1,17 @@
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// Macro from prelude is shadowed by non-existent import recovered as `Def::Err`.
use std::assert; //~ ERROR unresolved import `std::assert`
fn main() {
assert!(true);
}

View File

@ -0,0 +1,9 @@
error[E0432]: unresolved import `std::assert`
--> $DIR/issue-53512.rs:13:5
|
LL | use std::assert; //~ ERROR unresolved import `std::assert`
| ^^^^^^^^^^^ no `assert` in the root
error: aborting due to previous error
For more information about this error, try `rustc --explain E0432`.

View File

@ -1,15 +1,15 @@
error: `m` is ambiguous
error[E0659]: `m` is ambiguous
--> $DIR/macros.rs:48:5
|
LL | m!(); //~ ERROR ambiguous
| ^
|
note: `m` could refer to the macro defined here
note: `m` could refer to the name defined here
--> $DIR/macros.rs:46:5
|
LL | macro_rules! m { () => {} }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: `m` could also refer to the macro imported here
note: `m` could also refer to the name imported here
--> $DIR/macros.rs:47:9
|
LL | use two_macros::m;

View File

@ -37,10 +37,10 @@ mod m4 {
mod m5 {
macro_rules! m { () => {
macro_rules! panic { () => {} } //~ ERROR `panic` is already in scope
macro_rules! panic { () => {} }
} }
m!();
panic!();
panic!(); //~ ERROR `panic` is ambiguous
}
#[macro_use(n)]

View File

@ -1,13 +1,19 @@
error: `panic` is already in scope
error[E0659]: `panic` is ambiguous
--> $DIR/shadow_builtin_macros.rs:43:5
|
LL | panic!(); //~ ERROR `panic` is ambiguous
| ^^^^^
|
note: `panic` could refer to the name defined here
--> $DIR/shadow_builtin_macros.rs:40:9
|
LL | macro_rules! panic { () => {} } //~ ERROR `panic` is already in scope
LL | macro_rules! panic { () => {} }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | } }
LL | m!();
| ----- in this macro invocation
|
= note: macro-expanded `macro_rules!`s may not shadow existing macros (see RFC 1560)
= note: `panic` is also a builtin macro
= note: macro-expanded macros do not shadow
error[E0659]: `panic` is ambiguous
--> $DIR/shadow_builtin_macros.rs:25:14

View File

@ -1,8 +1,8 @@
error[E0658]: attributes of the form `#[derive_*]` are reserved for the compiler (see issue #29644)
--> $DIR/issue-32655.rs:16:9
--> $DIR/issue-32655.rs:16:11
|
LL | #[derive_Clone] //~ ERROR attributes of the form
| ^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^
...
LL | foo!();
| ------- in this macro invocation
@ -10,10 +10,10 @@ LL | foo!();
= help: add #![feature(custom_derive)] to the crate attributes to enable
error[E0658]: attributes of the form `#[derive_*]` are reserved for the compiler (see issue #29644)
--> $DIR/issue-32655.rs:28:5
--> $DIR/issue-32655.rs:28:7
|
LL | #[derive_Clone] //~ ERROR attributes of the form
| ^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^
|
= help: add #![feature(custom_derive)] to the crate attributes to enable

View File

@ -1,8 +1,8 @@
error[E0658]: The attribute `marco_use` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642)
--> $DIR/issue-49074.rs:13:1
--> $DIR/issue-49074.rs:13:3
|
LL | #[marco_use] // typo
| ^^^^^^^^^^^^
| ^^^^^^^^^
|
= help: add #![feature(custom_attribute)] to the crate attributes to enable

View File

@ -11,10 +11,10 @@ LL | #![feature(macro_reexport)] //~ ERROR feature has been removed
| ^^^^^^^^^^^^^^
error[E0658]: The attribute `macro_reexport` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642)
--> $DIR/macro-reexport-removed.rs:15:1
--> $DIR/macro-reexport-removed.rs:15:3
|
LL | #[macro_reexport(macro_one)] //~ ERROR attribute `macro_reexport` is currently unknown
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^
|
= help: add #![feature(custom_attribute)] to the crate attributes to enable

View File

@ -1,8 +1,8 @@
error[E0658]: unless otherwise specified, attributes with the prefix `rustc_` are reserved for internal compiler diagnostics (see issue #29642)
--> $DIR/reserved-attr-on-macro.rs:11:1
--> $DIR/reserved-attr-on-macro.rs:11:3
|
LL | #[rustc_attribute_should_be_reserved] //~ ERROR attributes with the prefix `rustc_` are reserved
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: add #![feature(rustc_attrs)] to the crate attributes to enable

View File

@ -1,16 +1,16 @@
error[E0658]: The attribute `foo` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642)
--> $DIR/issue-36530.rs:11:1
--> $DIR/issue-36530.rs:11:3
|
LL | #[foo] //~ ERROR is currently unknown to the compiler
| ^^^^^^
| ^^^
|
= 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 (see issue #29642)
--> $DIR/issue-36530.rs:13:5
--> $DIR/issue-36530.rs:13:8
|
LL | #![foo] //~ ERROR is currently unknown to the compiler
| ^^^^^^^
| ^^^
|
= help: add #![feature(custom_attribute)] to the crate attributes to enable