Skip to content

Commit 40e4b6e

Browse files
committed
Auto merge of #52841 - petrochenkov:premacro, r=alexcrichton
resolve: Implement prelude search for macro paths, implement tool attributes When identifier is macro path is resolved in scopes (i.e. the first path segment - `foo` in `foo::mac!()` or `foo!()`), scopes are searched in the same order as for non-macro paths - items in modules, extern prelude, tool prelude (see later), standard library prelude, language prelude, but with some extra shadowing restrictions (names from globs and macro expansions cannot shadow names from outer scopes). See the comment in `fn resolve_lexical_macro_path_segment` for more details. "Tool prelude" currently contains two "tool modules" `rustfmt` and `clippy`, and is searched immediately after extern prelude. This makes the [possible long-term solution](https://github.com/rust-lang/rfcs/blob/master/text/2103-tool-attributes.md#long-term-solution) for tool attributes exactly equivalent to the existing extern prelude scheme, except that `--extern=my_crate` making crate names available in scope is replaced with something like `--tool=my_tool` making tool names available in scope. The `tool_attributes` feature is still unstable and `#![feature(tool_attributes)]` now implicitly enables `#![feature(use_extern_macros)]`. `use_extern_macros` is a prerequisite for `tool_attributes`, so their stabilization will happen in the same order. If `use_extern_macros` is not enabled, then tool attributes are treated as custom attributes (this is temporary, anyway). Fixes #52576 Fixes #52512 Fixes #51277 cc #52269
2 parents 40cb447 + c3e5421 commit 40e4b6e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+675
-135
lines changed

src/librustc/hir/def.rs

+6
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ pub enum Def {
4949
PrimTy(hir::PrimTy),
5050
TyParam(DefId),
5151
SelfTy(Option<DefId> /* trait */, Option<DefId> /* impl */),
52+
ToolMod, // e.g. `rustfmt` in `#[rustfmt::skip]`
5253

5354
// Value namespace
5455
Fn(DefId),
@@ -67,6 +68,7 @@ pub enum Def {
6768

6869
// Macro namespace
6970
Macro(DefId, MacroKind),
71+
NonMacroAttr, // e.g. `#[inline]` or `#[rustfmt::skip]`
7072

7173
GlobalAsm(DefId),
7274

@@ -259,6 +261,8 @@ impl Def {
259261
Def::Label(..) |
260262
Def::PrimTy(..) |
261263
Def::SelfTy(..) |
264+
Def::ToolMod |
265+
Def::NonMacroAttr |
262266
Def::Err => {
263267
bug!("attempted .def_id() on invalid def: {:?}", self)
264268
}
@@ -299,6 +303,8 @@ impl Def {
299303
Def::SelfTy(..) => "self type",
300304
Def::Macro(.., macro_kind) => macro_kind.descr(),
301305
Def::GlobalAsm(..) => "global asm",
306+
Def::ToolMod => "tool module",
307+
Def::NonMacroAttr => "non-macro attribute",
302308
Def::Err => "unresolved item",
303309
}
304310
}

src/librustc/ich/impls_hir.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1016,6 +1016,8 @@ impl_stable_hash_for!(enum hir::def::Def {
10161016
Label(node_id),
10171017
Macro(def_id, macro_kind),
10181018
GlobalAsm(def_id),
1019+
ToolMod,
1020+
NonMacroAttr,
10191021
Err
10201022
});
10211023

src/librustc_resolve/build_reduced_graph.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -629,7 +629,8 @@ impl<'a> Resolver<'a> {
629629
pub fn get_macro(&mut self, def: Def) -> Lrc<SyntaxExtension> {
630630
let def_id = match def {
631631
Def::Macro(def_id, ..) => def_id,
632-
_ => panic!("Expected Def::Macro(..)"),
632+
Def::NonMacroAttr => return Lrc::new(SyntaxExtension::NonMacroAttr),
633+
_ => panic!("Expected Def::Macro(..) or Def::NonMacroAttr"),
633634
};
634635
if let Some(ext) = self.macro_map.get(&def_id) {
635636
return ext.clone();

src/librustc_resolve/check_unused.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,7 @@ pub fn check_crate(resolver: &mut Resolver, krate: &ast::Crate) {
131131
directive.vis.get() == ty::Visibility::Public ||
132132
directive.span.is_dummy() => {
133133
if let ImportDirectiveSubclass::MacroUse = directive.subclass {
134-
if resolver.session.features_untracked().use_extern_macros &&
135-
!directive.span.is_dummy() {
134+
if resolver.use_extern_macros && !directive.span.is_dummy() {
136135
resolver.session.buffer_lint(
137136
lint::builtin::MACRO_USE_EXTERN_CRATE,
138137
directive.id,

src/librustc_resolve/lib.rs

+18-12
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,10 @@ mod check_unused;
8686
mod build_reduced_graph;
8787
mod resolve_imports;
8888

89+
fn is_known_tool(name: Name) -> bool {
90+
["clippy", "rustfmt"].contains(&&*name.as_str())
91+
}
92+
8993
/// A free importable items suggested in case of resolution failure.
9094
struct ImportSuggestion {
9195
path: Path,
@@ -200,15 +204,10 @@ fn resolve_struct_error<'sess, 'a>(resolver: &'sess Resolver,
200204
err.span_label(typaram_span, "type variable from outer function");
201205
}
202206
},
203-
Def::Mod(..) | Def::Struct(..) | Def::Union(..) | Def::Enum(..) | Def::Variant(..) |
204-
Def::Trait(..) | Def::TyAlias(..) | Def::TyForeign(..) | Def::TraitAlias(..) |
205-
Def::AssociatedTy(..) | Def::PrimTy(..) | Def::Fn(..) | Def::Const(..) |
206-
Def::Static(..) | Def::StructCtor(..) | Def::VariantCtor(..) | Def::Method(..) |
207-
Def::AssociatedConst(..) | Def::Local(..) | Def::Upvar(..) | Def::Label(..) |
208-
Def::Existential(..) | Def::AssociatedExistential(..) |
209-
Def::Macro(..) | Def::GlobalAsm(..) | Def::Err =>
207+
_ => {
210208
bug!("TypeParametersFromOuterFunction should only be used with Def::SelfTy or \
211209
Def::TyParam")
210+
}
212211
}
213212

214213
// Try to retrieve the span of the function signature and generate a new message with
@@ -1711,9 +1710,7 @@ impl<'a> Resolver<'a> {
17111710
vis: ty::Visibility::Public,
17121711
}),
17131712

1714-
// The `proc_macro` and `decl_macro` features imply `use_extern_macros`
1715-
use_extern_macros:
1716-
features.use_extern_macros || features.decl_macro,
1713+
use_extern_macros: features.use_extern_macros(),
17171714

17181715
crate_loader,
17191716
macro_names: FxHashSet(),
@@ -1846,6 +1843,7 @@ impl<'a> Resolver<'a> {
18461843
path_span: Span)
18471844
-> Option<LexicalScopeBinding<'a>> {
18481845
let record_used = record_used_id.is_some();
1846+
assert!(ns == TypeNS || ns == ValueNS);
18491847
if ns == TypeNS {
18501848
ident.span = if ident.name == keywords::SelfType.name() {
18511849
// FIXME(jseyfried) improve `Self` hygiene
@@ -1922,8 +1920,9 @@ impl<'a> Resolver<'a> {
19221920
return Some(LexicalScopeBinding::Item(binding))
19231921
}
19241922
_ if poisoned.is_some() => break,
1925-
Err(Undetermined) => return None,
1926-
Err(Determined) => {}
1923+
Err(Determined) => continue,
1924+
Err(Undetermined) =>
1925+
span_bug!(ident.span, "undetermined resolution during main resolution pass"),
19271926
}
19281927
}
19291928

@@ -1945,6 +1944,11 @@ impl<'a> Resolver<'a> {
19451944
ident.span, Mark::root()).to_name_binding(self.arenas);
19461945
return Some(LexicalScopeBinding::Item(binding));
19471946
}
1947+
if ns == TypeNS && is_known_tool(ident.name) {
1948+
let binding = (Def::ToolMod, ty::Visibility::Public,
1949+
ident.span, Mark::root()).to_name_binding(self.arenas);
1950+
return Some(LexicalScopeBinding::Item(binding));
1951+
}
19481952
if let Some(prelude) = self.prelude {
19491953
if let Ok(binding) = self.resolve_ident_in_module_unadjusted(prelude, ident, ns,
19501954
false, false, path_span) {
@@ -3505,6 +3509,8 @@ impl<'a> Resolver<'a> {
35053509
let maybe_assoc = opt_ns != Some(MacroNS) && PathSource::Type.is_expected(def);
35063510
if let Some(next_module) = binding.module() {
35073511
module = Some(next_module);
3512+
} else if def == Def::ToolMod && i + 1 != path.len() {
3513+
return PathResult::NonModule(PathResolution::new(Def::NonMacroAttr))
35083514
} else if def == Def::Err {
35093515
return PathResult::NonModule(err_path_resolution());
35103516
} else if opt_ns.is_some() && (is_last || maybe_assoc) {

0 commit comments

Comments
 (0)