Skip to content

Commit 60c8460

Browse files
committed
Auto merge of #54336 - petrochenkov:preuni, r=alexcrichton
resolve: Some refactorings in preparation for uniform paths 2.0 The main result is that in-scope resolution performed during macro expansion / import resolution is now consolidated in a single function (`fn early_resolve_ident_in_lexical_scope`), which can now be used for resolving first import segments as well when uniform paths are enabled. r? @ghost
2 parents 766e21c + 0d8e9cd commit 60c8460

File tree

14 files changed

+262
-403
lines changed

14 files changed

+262
-403
lines changed

src/Cargo.lock

+1
Original file line numberDiff line numberDiff line change
@@ -2388,6 +2388,7 @@ name = "rustc_resolve"
23882388
version = "0.0.0"
23892389
dependencies = [
23902390
"arena 0.0.0",
2391+
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
23912392
"log 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
23922393
"rustc 0.0.0",
23932394
"rustc_data_structures 0.0.0",

src/librustc/hir/def.rs

+3
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ pub enum NonMacroAttrKind {
3636
Tool,
3737
/// Single-segment custom attribute registered by a derive macro (`#[serde(default)]`).
3838
DeriveHelper,
39+
/// Single-segment custom attriubte registered by a legacy plugin (`register_attribute`).
40+
LegacyPluginHelper,
3941
/// Single-segment custom attribute not registered in any way (`#[my_attr]`).
4042
Custom,
4143
}
@@ -259,6 +261,7 @@ impl NonMacroAttrKind {
259261
NonMacroAttrKind::Builtin => "built-in attribute",
260262
NonMacroAttrKind::Tool => "tool attribute",
261263
NonMacroAttrKind::DeriveHelper => "derive helper attribute",
264+
NonMacroAttrKind::LegacyPluginHelper => "legacy plugin helper attribute",
262265
NonMacroAttrKind::Custom => "custom attribute",
263266
}
264267
}

src/librustc/ich/impls_hir.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1012,6 +1012,7 @@ impl_stable_hash_for!(enum hir::def::NonMacroAttrKind {
10121012
Builtin,
10131013
Tool,
10141014
DeriveHelper,
1015+
LegacyPluginHelper,
10151016
Custom,
10161017
});
10171018

src/librustc_resolve/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ crate-type = ["dylib"]
1010
test = false
1111

1212
[dependencies]
13+
bitflags = "1.0"
1314
log = "0.4"
1415
syntax = { path = "../libsyntax" }
1516
rustc = { path = "../librustc" }

src/librustc_resolve/lib.rs

+6-7
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
#![feature(rustc_diagnostic_macros)]
1818
#![feature(slice_sort_by_cached_key)]
1919

20+
#[macro_use]
21+
extern crate bitflags;
2022
#[macro_use]
2123
extern crate log;
2224
#[macro_use]
@@ -1012,7 +1014,8 @@ pub struct ModuleData<'a> {
10121014
normal_ancestor_id: DefId,
10131015

10141016
resolutions: RefCell<FxHashMap<(Ident, Namespace), &'a RefCell<NameResolution<'a>>>>,
1015-
legacy_macro_resolutions: RefCell<Vec<(Ident, MacroKind, ParentScope<'a>, Option<Def>)>>,
1017+
legacy_macro_resolutions: RefCell<Vec<(Ident, MacroKind, ParentScope<'a>,
1018+
Option<&'a NameBinding<'a>>)>>,
10161019
macro_resolutions: RefCell<Vec<(Box<[Ident]>, Span)>>,
10171020
builtin_attrs: RefCell<Vec<(Ident, ParentScope<'a>)>>,
10181021

@@ -1210,10 +1213,6 @@ impl<'a> NameBinding<'a> {
12101213
}
12111214
}
12121215

1213-
fn get_macro<'b: 'a>(&self, resolver: &mut Resolver<'a, 'b>) -> Lrc<SyntaxExtension> {
1214-
resolver.get_macro(self.def_ignoring_ambiguity())
1215-
}
1216-
12171216
// We sometimes need to treat variants as `pub` for backwards compatibility
12181217
fn pseudo_vis(&self) -> ty::Visibility {
12191218
if self.is_variant() && self.def().def_id().is_local() {
@@ -3664,8 +3663,8 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
36643663
self.resolve_ident_in_module(module, ident, ns, record_used, path_span)
36653664
} else if opt_ns == Some(MacroNS) {
36663665
assert!(ns == TypeNS);
3667-
self.resolve_lexical_macro_path_segment(ident, ns, None, parent_scope, record_used,
3668-
record_used, path_span).map(|(b, _)| b)
3666+
self.early_resolve_ident_in_lexical_scope(ident, ns, None, parent_scope,
3667+
record_used, record_used, path_span)
36693668
} else {
36703669
let record_used_id =
36713670
if record_used { crate_lint.node_id().or(Some(CRATE_NODE_ID)) } else { None };

src/librustc_resolve/macros.rs

+197-278
Large diffs are not rendered by default.

src/librustc_resolve/resolve_imports.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,7 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
334334
// expansion. With restricted shadowing names from globs and macro expansions cannot
335335
// shadow names from outer scopes, so we can freely fallback from module search to search
336336
// in outer scopes. To continue search in outer scopes we have to lie a bit and return
337-
// `Determined` to `resolve_lexical_macro_path_segment` even if the correct answer
337+
// `Determined` to `early_resolve_ident_in_lexical_scope` even if the correct answer
338338
// for in-module resolution could be `Undetermined`.
339339
if restricted_shadowing {
340340
return Err(Determined);

src/libsyntax/ext/expand.rs

+30-43
Original file line numberDiff line numberDiff line change
@@ -220,14 +220,6 @@ pub struct Invocation {
220220
pub expansion_data: ExpansionData,
221221
}
222222

223-
// Needed for feature-gating attributes used after derives or together with test/bench
224-
#[derive(Clone, Copy, PartialEq)]
225-
pub enum TogetherWith {
226-
None,
227-
Derive,
228-
TestBench,
229-
}
230-
231223
pub enum InvocationKind {
232224
Bang {
233225
mac: ast::Mac,
@@ -238,7 +230,8 @@ pub enum InvocationKind {
238230
attr: Option<ast::Attribute>,
239231
traits: Vec<Path>,
240232
item: Annotatable,
241-
together_with: TogetherWith,
233+
// We temporarily report errors for attribute macros placed after derives
234+
after_derive: bool,
242235
},
243236
Derive {
244237
path: Path,
@@ -1084,19 +1077,17 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
10841077
traits: Vec<Path>,
10851078
item: Annotatable,
10861079
kind: AstFragmentKind,
1087-
together_with: TogetherWith)
1080+
after_derive: bool)
10881081
-> AstFragment {
1089-
self.collect(kind, InvocationKind::Attr { attr, traits, item, together_with })
1082+
self.collect(kind, InvocationKind::Attr { attr, traits, item, after_derive })
10901083
}
10911084

1092-
fn find_attr_invoc(&self, attrs: &mut Vec<ast::Attribute>, together_with: &mut TogetherWith)
1085+
fn find_attr_invoc(&self, attrs: &mut Vec<ast::Attribute>, after_derive: &mut bool)
10931086
-> Option<ast::Attribute> {
10941087
let attr = attrs.iter()
10951088
.position(|a| {
10961089
if a.path == "derive" {
1097-
*together_with = TogetherWith::Derive
1098-
} else if a.path == "rustc_test_marker2" {
1099-
*together_with = TogetherWith::TestBench
1090+
*after_derive = true;
11001091
}
11011092
!attr::is_known(a) && !is_builtin_attr(a)
11021093
})
@@ -1109,19 +1100,15 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
11091100
"non-builtin inner attributes are unstable");
11101101
}
11111102
}
1112-
if together_with == &TogetherWith::None &&
1113-
attrs.iter().any(|a| a.path == "rustc_test_marker2") {
1114-
*together_with = TogetherWith::TestBench;
1115-
}
11161103
attr
11171104
}
11181105

11191106
/// If `item` is an attr invocation, remove and return the macro attribute and derive traits.
11201107
fn classify_item<T>(&mut self, mut item: T)
1121-
-> (Option<ast::Attribute>, Vec<Path>, T, TogetherWith)
1108+
-> (Option<ast::Attribute>, Vec<Path>, T, /* after_derive */ bool)
11221109
where T: HasAttrs,
11231110
{
1124-
let (mut attr, mut traits, mut together_with) = (None, Vec::new(), TogetherWith::None);
1111+
let (mut attr, mut traits, mut after_derive) = (None, Vec::new(), false);
11251112

11261113
item = item.map_attrs(|mut attrs| {
11271114
if let Some(legacy_attr_invoc) = self.cx.resolver.find_legacy_attr_invoc(&mut attrs,
@@ -1130,20 +1117,20 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
11301117
return attrs;
11311118
}
11321119

1133-
attr = self.find_attr_invoc(&mut attrs, &mut together_with);
1120+
attr = self.find_attr_invoc(&mut attrs, &mut after_derive);
11341121
traits = collect_derives(&mut self.cx, &mut attrs);
11351122
attrs
11361123
});
11371124

1138-
(attr, traits, item, together_with)
1125+
(attr, traits, item, after_derive)
11391126
}
11401127

11411128
/// Alternative of `classify_item()` that ignores `#[derive]` so invocations fallthrough
11421129
/// to the unused-attributes lint (making it an error on statements and expressions
11431130
/// is a breaking change)
11441131
fn classify_nonitem<T: HasAttrs>(&mut self, mut item: T)
1145-
-> (Option<ast::Attribute>, T, TogetherWith) {
1146-
let (mut attr, mut together_with) = (None, TogetherWith::None);
1132+
-> (Option<ast::Attribute>, T, /* after_derive */ bool) {
1133+
let (mut attr, mut after_derive) = (None, false);
11471134

11481135
item = item.map_attrs(|mut attrs| {
11491136
if let Some(legacy_attr_invoc) = self.cx.resolver.find_legacy_attr_invoc(&mut attrs,
@@ -1152,11 +1139,11 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
11521139
return attrs;
11531140
}
11541141

1155-
attr = self.find_attr_invoc(&mut attrs, &mut together_with);
1142+
attr = self.find_attr_invoc(&mut attrs, &mut after_derive);
11561143
attrs
11571144
});
11581145

1159-
(attr, item, together_with)
1146+
(attr, item, after_derive)
11601147
}
11611148

11621149
fn configure<T: HasAttrs>(&mut self, node: T) -> Option<T> {
@@ -1195,7 +1182,7 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
11951182
expr.node = self.cfg.configure_expr_kind(expr.node);
11961183

11971184
// ignore derives so they remain unused
1198-
let (attr, expr, together_with) = self.classify_nonitem(expr);
1185+
let (attr, expr, after_derive) = self.classify_nonitem(expr);
11991186

12001187
if attr.is_some() {
12011188
// collect the invoc regardless of whether or not attributes are permitted here
@@ -1204,7 +1191,7 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
12041191

12051192
// AstFragmentKind::Expr requires the macro to emit an expression
12061193
return self.collect_attr(attr, vec![], Annotatable::Expr(P(expr)),
1207-
AstFragmentKind::Expr, together_with).make_expr();
1194+
AstFragmentKind::Expr, after_derive).make_expr();
12081195
}
12091196

12101197
if let ast::ExprKind::Mac(mac) = expr.node {
@@ -1220,13 +1207,13 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
12201207
expr.node = self.cfg.configure_expr_kind(expr.node);
12211208

12221209
// ignore derives so they remain unused
1223-
let (attr, expr, together_with) = self.classify_nonitem(expr);
1210+
let (attr, expr, after_derive) = self.classify_nonitem(expr);
12241211

12251212
if attr.is_some() {
12261213
attr.as_ref().map(|a| self.cfg.maybe_emit_expr_attr_err(a));
12271214

12281215
return self.collect_attr(attr, vec![], Annotatable::Expr(P(expr)),
1229-
AstFragmentKind::OptExpr, together_with).make_opt_expr();
1216+
AstFragmentKind::OptExpr, after_derive).make_opt_expr();
12301217
}
12311218

12321219
if let ast::ExprKind::Mac(mac) = expr.node {
@@ -1258,18 +1245,18 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
12581245

12591246
// we'll expand attributes on expressions separately
12601247
if !stmt.is_expr() {
1261-
let (attr, derives, stmt_, together_with) = if stmt.is_item() {
1248+
let (attr, derives, stmt_, after_derive) = if stmt.is_item() {
12621249
self.classify_item(stmt)
12631250
} else {
12641251
// ignore derives on non-item statements so it falls through
12651252
// to the unused-attributes lint
1266-
let (attr, stmt, together_with) = self.classify_nonitem(stmt);
1267-
(attr, vec![], stmt, together_with)
1253+
let (attr, stmt, after_derive) = self.classify_nonitem(stmt);
1254+
(attr, vec![], stmt, after_derive)
12681255
};
12691256

12701257
if attr.is_some() || !derives.is_empty() {
12711258
return self.collect_attr(attr, derives, Annotatable::Stmt(P(stmt_)),
1272-
AstFragmentKind::Stmts, together_with).make_stmts();
1259+
AstFragmentKind::Stmts, after_derive).make_stmts();
12731260
}
12741261

12751262
stmt = stmt_;
@@ -1311,10 +1298,10 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
13111298
fn fold_item(&mut self, item: P<ast::Item>) -> SmallVec<[P<ast::Item>; 1]> {
13121299
let item = configure!(self, item);
13131300

1314-
let (attr, traits, item, together_with) = self.classify_item(item);
1301+
let (attr, traits, item, after_derive) = self.classify_item(item);
13151302
if attr.is_some() || !traits.is_empty() {
13161303
return self.collect_attr(attr, traits, Annotatable::Item(item),
1317-
AstFragmentKind::Items, together_with).make_items();
1304+
AstFragmentKind::Items, after_derive).make_items();
13181305
}
13191306

13201307
match item.node {
@@ -1386,10 +1373,10 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
13861373
fn fold_trait_item(&mut self, item: ast::TraitItem) -> SmallVec<[ast::TraitItem; 1]> {
13871374
let item = configure!(self, item);
13881375

1389-
let (attr, traits, item, together_with) = self.classify_item(item);
1376+
let (attr, traits, item, after_derive) = self.classify_item(item);
13901377
if attr.is_some() || !traits.is_empty() {
13911378
return self.collect_attr(attr, traits, Annotatable::TraitItem(P(item)),
1392-
AstFragmentKind::TraitItems, together_with).make_trait_items()
1379+
AstFragmentKind::TraitItems, after_derive).make_trait_items()
13931380
}
13941381

13951382
match item.node {
@@ -1405,10 +1392,10 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
14051392
fn fold_impl_item(&mut self, item: ast::ImplItem) -> SmallVec<[ast::ImplItem; 1]> {
14061393
let item = configure!(self, item);
14071394

1408-
let (attr, traits, item, together_with) = self.classify_item(item);
1395+
let (attr, traits, item, after_derive) = self.classify_item(item);
14091396
if attr.is_some() || !traits.is_empty() {
14101397
return self.collect_attr(attr, traits, Annotatable::ImplItem(P(item)),
1411-
AstFragmentKind::ImplItems, together_with).make_impl_items();
1398+
AstFragmentKind::ImplItems, after_derive).make_impl_items();
14121399
}
14131400

14141401
match item.node {
@@ -1440,11 +1427,11 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
14401427
fn fold_foreign_item(&mut self, foreign_item: ast::ForeignItem)
14411428
-> SmallVec<[ast::ForeignItem; 1]>
14421429
{
1443-
let (attr, traits, foreign_item, together_with) = self.classify_item(foreign_item);
1430+
let (attr, traits, foreign_item, after_derive) = self.classify_item(foreign_item);
14441431

14451432
if attr.is_some() || !traits.is_empty() {
14461433
return self.collect_attr(attr, traits, Annotatable::ForeignItem(P(foreign_item)),
1447-
AstFragmentKind::ForeignItems, together_with)
1434+
AstFragmentKind::ForeignItems, after_derive)
14481435
.make_foreign_items();
14491436
}
14501437

src/libsyntax/feature_gate.rs

-4
Original file line numberDiff line numberDiff line change
@@ -995,10 +995,6 @@ pub const BUILTIN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeG
995995
"the `#[rustc_test_marker]` attribute \
996996
is used internally to track tests",
997997
cfg_fn!(rustc_attrs))),
998-
("rustc_test_marker2", Normal, Gated(Stability::Unstable,
999-
"rustc_attrs",
1000-
"temporarily used by rustc to report some errors",
1001-
cfg_fn!(rustc_attrs))),
1002998
("rustc_transparent_macro", Whitelisted, Gated(Stability::Unstable,
1003999
"rustc_attrs",
10041000
"used internally for testing macro hygiene",

src/libsyntax_ext/test.rs

+1-7
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ pub fn expand_test_or_bench(
4949
// If we're not in test configuration, remove the annotated item
5050
if !cx.ecfg.should_test { return vec![]; }
5151

52-
let mut item =
52+
let item =
5353
if let Annotatable::Item(i) = item { i }
5454
else {
5555
cx.parse_sess.span_diagnostic.span_fatal(item.span(),
@@ -192,12 +192,6 @@ pub fn expand_test_or_bench(
192192

193193
debug!("Synthetic test item:\n{}\n", pprust::item_to_string(&test_const));
194194

195-
// Temporarily add another marker to the original item for error reporting
196-
let marker2 = cx.attribute(
197-
attr_sp, cx.meta_word(attr_sp, Symbol::intern("rustc_test_marker2"))
198-
);
199-
item.attrs.push(marker2);
200-
201195
vec![
202196
// Access to libtest under a gensymed name
203197
Annotatable::Item(test_extern),

src/test/run-pass-fulldeps/macro-crate.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@
1919
#[macro_use] #[no_link]
2020
extern crate macro_crate_test;
2121

22-
#[derive(PartialEq, Clone, Debug)]
2322
#[rustc_into_multi_foo]
23+
#[derive(PartialEq, Clone, Debug)]
2424
fn foo() -> AnotherFakeTypeThatHadBetterGoAway {}
2525

2626
// Check that the `#[into_multi_foo]`-generated `foo2` is configured away
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
11
// aux-build:attr_proc_macro.rs
2-
// compile-flags:--test
32

4-
#![feature(test)]
5-
6-
extern crate test;
73
extern crate attr_proc_macro;
84
use attr_proc_macro::*;
95

@@ -15,18 +11,4 @@ struct Before;
1511
#[attr_proc_macro] //~ ERROR macro attributes must be placed before `#[derive]`
1612
struct After;
1713

18-
#[attr_proc_macro] //~ ERROR macro attributes cannot be used together with `#[test]` or `#[bench]`
19-
#[test]
20-
fn test_before() {}
21-
22-
#[test]
23-
#[attr_proc_macro] //~ ERROR macro attributes cannot be used together with `#[test]` or `#[bench]`
24-
fn test_after() {}
25-
26-
#[attr_proc_macro] //~ ERROR macro attributes cannot be used together with `#[test]` or `#[bench]`
27-
#[bench]
28-
fn bench_before(b: &mut test::Bencher) {}
29-
30-
#[bench]
31-
#[attr_proc_macro] //~ ERROR macro attributes cannot be used together with `#[test]` or `#[bench]`
32-
fn bench_after(b: &mut test::Bencher) {}
14+
fn main() {}

0 commit comments

Comments
 (0)