From 74fb87e3a0bb88cd3bd9857bedc236bda52a8af7 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Fri, 16 Jul 2021 16:54:47 +0200 Subject: [PATCH 1/5] Stop sorting bodies by span. The definition order is already close to the span order, and only differs in corner cases. --- compiler/rustc_ast_lowering/src/lib.rs | 10 ------ compiler/rustc_hir/src/hir.rs | 6 ---- compiler/rustc_middle/src/ty/mod.rs | 10 ++---- compiler/rustc_typeck/src/check_unused.rs | 3 +- src/test/ui/asm/type-check-1.stderr | 30 ++++++++-------- src/test/ui/borrowck/issue-64453.stderr | 12 +++---- .../ui/const-generics/type_mismatch.stderr | 12 +++---- ...const-extern-fn-requires-unsafe.mir.stderr | 12 +++---- src/test/ui/consts/issue-66693.stderr | 16 ++++----- src/test/ui/issues/issue-47486.stderr | 12 +++---- .../liveness-return-last-stmt-semi.stderr | 28 +++++++-------- .../ui/proc-macro/attribute-with-error.stderr | 16 ++++----- src/test/ui/repeat_count.stderr | 12 +++---- .../impl-trait-with-missing-bounds.stderr | 34 +++++++++---------- .../ui/suggestions/suggest-ref-macro.stderr | 16 ++++----- .../union-derive-clone.mirunsafeck.stderr | 26 +++++++------- .../union-derive-clone.thirunsafeck.stderr | 26 +++++++------- 17 files changed, 130 insertions(+), 151 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index deb7e742e5cc3..196d48faf5173 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -516,7 +516,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.owners.ensure_contains_elem(CRATE_DEF_ID, || None); self.owners[CRATE_DEF_ID] = Some(hir::OwnerNode::Crate(module)); - let body_ids = body_ids(&self.bodies); let proc_macros = c.proc_macros.iter().map(|id| self.node_id_to_hir_id[*id].unwrap()).collect(); @@ -552,7 +551,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let krate = hir::Crate { owners: self.owners, bodies: self.bodies, - body_ids, trait_impls: self.trait_impls, modules: self.modules, proc_macros, @@ -2771,14 +2769,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } } -fn body_ids(bodies: &BTreeMap>) -> Vec { - // Sorting by span ensures that we get things in order within a - // file, and also puts the files in a sensible order. - let mut body_ids: Vec<_> = bodies.keys().cloned().collect(); - body_ids.sort_by_key(|b| bodies[b].value.span); - body_ids -} - /// Helper struct for delayed construction of GenericArgs. struct GenericArgsCtor<'hir> { args: SmallVec<[hir::GenericArg<'hir>; 4]>, diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index a9bd83a67c9dc..d629cb6021456 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -674,12 +674,6 @@ pub struct Crate<'hir> { pub bodies: BTreeMap>, pub trait_impls: BTreeMap>, - /// A list of the body ids written out in the order in which they - /// appear in the crate. If you're going to process all the bodies - /// in the crate, you should iterate over this list rather than the keys - /// of bodies. - pub body_ids: Vec, - /// A list of modules written out in the order in which they /// appear in the crate. This includes the main crate module. pub modules: BTreeMap, diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 8aa27d4ca53e3..cfb49b7d9b8c5 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1677,16 +1677,12 @@ impl<'tcx> TyCtxt<'tcx> { /// crate. If you would prefer to iterate over the bodies /// themselves, you can do `self.hir().krate().body_ids.iter()`. pub fn body_owners(self) -> impl Iterator + Captures<'tcx> + 'tcx { - self.hir() - .krate() - .body_ids - .iter() - .map(move |&body_id| self.hir().body_owner_def_id(body_id)) + self.hir().krate().bodies.keys().map(move |&body_id| self.hir().body_owner_def_id(body_id)) } pub fn par_body_owners(self, f: F) { - par_iter(&self.hir().krate().body_ids) - .for_each(|&body_id| f(self.hir().body_owner_def_id(body_id))); + par_iter(&self.hir().krate().bodies) + .for_each(|(&body_id, _)| f(self.hir().body_owner_def_id(body_id))); } pub fn provided_trait_methods(self, id: DefId) -> impl 'tcx + Iterator { diff --git a/compiler/rustc_typeck/src/check_unused.rs b/compiler/rustc_typeck/src/check_unused.rs index 95d3bb1172305..cb127880c62b3 100644 --- a/compiler/rustc_typeck/src/check_unused.rs +++ b/compiler/rustc_typeck/src/check_unused.rs @@ -9,8 +9,7 @@ use rustc_span::{Span, Symbol}; pub fn check_crate(tcx: TyCtxt<'_>) { let mut used_trait_imports = FxHashSet::default(); - for &body_id in tcx.hir().krate().bodies.keys() { - let item_def_id = tcx.hir().body_owner_def_id(body_id); + for item_def_id in tcx.body_owners() { let imports = tcx.used_trait_imports(item_def_id); debug!("GatherVisitor: item_def_id={:?} with imports {:#?}", item_def_id, imports); used_trait_imports.extend(imports.iter()); diff --git a/src/test/ui/asm/type-check-1.stderr b/src/test/ui/asm/type-check-1.stderr index ad981d93d514e..5edbcf4a2a7c9 100644 --- a/src/test/ui/asm/type-check-1.stderr +++ b/src/test/ui/asm/type-check-1.stderr @@ -25,6 +25,21 @@ LL | let x = 0; LL | asm!("{}", const const_bar(x)); | ^ non-constant value +error[E0308]: mismatched types + --> $DIR/type-check-1.rs:48:26 + | +LL | asm!("{}", const 0f32); + | ^^^^ expected integer, found `f32` + +error[E0308]: mismatched types + --> $DIR/type-check-1.rs:50:26 + | +LL | asm!("{}", const 0 as *mut u8); + | ^^^^^^^^^^^^ expected integer, found *-ptr + | + = note: expected type `{integer}` + found raw pointer `*mut u8` + error: invalid asm output --> $DIR/type-check-1.rs:10:29 | @@ -64,21 +79,6 @@ LL | asm!("{}", inout(reg) v[..]); = help: the trait `Sized` is not implemented for `[u64]` = note: all inline asm arguments must have a statically known size -error[E0308]: mismatched types - --> $DIR/type-check-1.rs:48:26 - | -LL | asm!("{}", const 0f32); - | ^^^^ expected integer, found `f32` - -error[E0308]: mismatched types - --> $DIR/type-check-1.rs:50:26 - | -LL | asm!("{}", const 0 as *mut u8); - | ^^^^^^^^^^^^ expected integer, found *-ptr - | - = note: expected type `{integer}` - found raw pointer `*mut u8` - error[E0308]: mismatched types --> $DIR/type-check-1.rs:60:25 | diff --git a/src/test/ui/borrowck/issue-64453.stderr b/src/test/ui/borrowck/issue-64453.stderr index 5513c3d217e2a..14e1667038965 100644 --- a/src/test/ui/borrowck/issue-64453.stderr +++ b/src/test/ui/borrowck/issue-64453.stderr @@ -1,9 +1,3 @@ -error[E0507]: cannot move out of static item `settings_dir` - --> $DIR/issue-64453.rs:14:37 - | -LL | let settings_data = from_string(settings_dir); - | ^^^^^^^^^^^^ move occurs because `settings_dir` has type `String`, which does not implement the `Copy` trait - error: `Arguments::<'a>::new_v1` is not yet stable as a const fn --> $DIR/issue-64453.rs:4:31 | @@ -21,6 +15,12 @@ LL | static settings_dir: String = format!(""); | = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info) +error[E0507]: cannot move out of static item `settings_dir` + --> $DIR/issue-64453.rs:14:37 + | +LL | let settings_data = from_string(settings_dir); + | ^^^^^^^^^^^^ move occurs because `settings_dir` has type `String`, which does not implement the `Copy` trait + error: aborting due to 3 previous errors Some errors have detailed explanations: E0015, E0507. diff --git a/src/test/ui/const-generics/type_mismatch.stderr b/src/test/ui/const-generics/type_mismatch.stderr index f5053e4c8c8d3..8d779bee265cf 100644 --- a/src/test/ui/const-generics/type_mismatch.stderr +++ b/src/test/ui/const-generics/type_mismatch.stderr @@ -4,12 +4,6 @@ error[E0308]: mismatched types LL | bar::() | ^ expected `u8`, found `usize` -error[E0308]: mismatched types - --> $DIR/type_mismatch.rs:5:31 - | -LL | fn bar() -> [u8; N] {} - | ^ expected `usize`, found `u8` - error[E0308]: mismatched types --> $DIR/type_mismatch.rs:5:26 | @@ -18,6 +12,12 @@ LL | fn bar() -> [u8; N] {} | | | implicitly returns `()` as its body has no tail or `return` expression +error[E0308]: mismatched types + --> $DIR/type_mismatch.rs:5:31 + | +LL | fn bar() -> [u8; N] {} + | ^ expected `usize`, found `u8` + error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/consts/const-extern-fn/const-extern-fn-requires-unsafe.mir.stderr b/src/test/ui/consts/const-extern-fn/const-extern-fn-requires-unsafe.mir.stderr index b643ecc0ce8d9..33014a1500cf7 100644 --- a/src/test/ui/consts/const-extern-fn/const-extern-fn-requires-unsafe.mir.stderr +++ b/src/test/ui/consts/const-extern-fn/const-extern-fn-requires-unsafe.mir.stderr @@ -1,16 +1,16 @@ error[E0133]: call to unsafe function is unsafe and requires unsafe function or block - --> $DIR/const-extern-fn-requires-unsafe.rs:11:5 + --> $DIR/const-extern-fn-requires-unsafe.rs:9:17 | -LL | foo(); - | ^^^^^ call to unsafe function +LL | let a: [u8; foo()]; + | ^^^^^ call to unsafe function | = note: consult the function's documentation for information on how to avoid undefined behavior error[E0133]: call to unsafe function is unsafe and requires unsafe function or block - --> $DIR/const-extern-fn-requires-unsafe.rs:9:17 + --> $DIR/const-extern-fn-requires-unsafe.rs:11:5 | -LL | let a: [u8; foo()]; - | ^^^^^ call to unsafe function +LL | foo(); + | ^^^^^ call to unsafe function | = note: consult the function's documentation for information on how to avoid undefined behavior diff --git a/src/test/ui/consts/issue-66693.stderr b/src/test/ui/consts/issue-66693.stderr index 50c95c89e0b79..3349e9813a809 100644 --- a/src/test/ui/consts/issue-66693.stderr +++ b/src/test/ui/consts/issue-66693.stderr @@ -1,11 +1,3 @@ -error: argument to `panic!()` in a const context must have type `&str` - --> $DIR/issue-66693.rs:13:5 - | -LL | panic!(&1); - | ^^^^^^^^^^^ - | - = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info) - error: argument to `panic!()` in a const context must have type `&str` --> $DIR/issue-66693.rs:6:15 | @@ -22,5 +14,13 @@ LL | static _FOO: () = panic!(true); | = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info) +error: argument to `panic!()` in a const context must have type `&str` + --> $DIR/issue-66693.rs:13:5 + | +LL | panic!(&1); + | ^^^^^^^^^^^ + | + = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info) + error: aborting due to 3 previous errors diff --git a/src/test/ui/issues/issue-47486.stderr b/src/test/ui/issues/issue-47486.stderr index cf95d309c6344..a029948ca3b82 100644 --- a/src/test/ui/issues/issue-47486.stderr +++ b/src/test/ui/issues/issue-47486.stderr @@ -1,15 +1,15 @@ +error[E0282]: type annotations needed + --> $DIR/issue-47486.rs:3:31 + | +LL | [0u8; std::mem::size_of::<_>()]; + | ^ cannot infer type + error[E0308]: mismatched types --> $DIR/issue-47486.rs:2:10 | LL | () < std::mem::size_of::<_>(); | ^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found `usize` -error[E0282]: type annotations needed - --> $DIR/issue-47486.rs:3:11 - | -LL | [0u8; std::mem::size_of::<_>()]; - | ^^^^^^^^^^^^^^^^^^^^^^ cannot infer type - error: aborting due to 2 previous errors Some errors have detailed explanations: E0282, E0308. diff --git a/src/test/ui/liveness/liveness-return-last-stmt-semi.stderr b/src/test/ui/liveness/liveness-return-last-stmt-semi.stderr index d08fbac0bcaab..d9dac5de6226c 100644 --- a/src/test/ui/liveness/liveness-return-last-stmt-semi.stderr +++ b/src/test/ui/liveness/liveness-return-last-stmt-semi.stderr @@ -1,17 +1,3 @@ -error[E0308]: mismatched types - --> $DIR/liveness-return-last-stmt-semi.rs:4:41 - | -LL | macro_rules! test { () => { fn foo() -> i32 { 1; } } } - | --- ^^^ - help: consider removing this semicolon - | | | - | | expected `i32`, found `()` - | implicitly returns `()` as its body has no tail or `return` expression -... -LL | test!(); - | -------- in this macro invocation - | - = note: this error originates in the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info) - error[E0308]: mismatched types --> $DIR/liveness-return-last-stmt-semi.rs:7:19 | @@ -38,6 +24,20 @@ LL | fn baz(x: u64) -> u32 { | | | implicitly returns `()` as its body has no tail or `return` expression +error[E0308]: mismatched types + --> $DIR/liveness-return-last-stmt-semi.rs:4:41 + | +LL | macro_rules! test { () => { fn foo() -> i32 { 1; } } } + | --- ^^^ - help: consider removing this semicolon + | | | + | | expected `i32`, found `()` + | implicitly returns `()` as its body has no tail or `return` expression +... +LL | test!(); + | -------- in this macro invocation + | + = note: this error originates in the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info) + error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/proc-macro/attribute-with-error.stderr b/src/test/ui/proc-macro/attribute-with-error.stderr index 7f3a7e670b9b7..127c49957c1e5 100644 --- a/src/test/ui/proc-macro/attribute-with-error.stderr +++ b/src/test/ui/proc-macro/attribute-with-error.stderr @@ -1,3 +1,11 @@ +error[E0308]: mismatched types + --> $DIR/attribute-with-error.rs:25:22 + | +LL | let a: i32 = "foo"; + | --- ^^^^^ expected `i32`, found `&str` + | | + | expected due to this + error[E0308]: mismatched types --> $DIR/attribute-with-error.rs:10:18 | @@ -14,14 +22,6 @@ LL | let b: i32 = "f'oo"; | | | expected due to this -error[E0308]: mismatched types - --> $DIR/attribute-with-error.rs:25:22 - | -LL | let a: i32 = "foo"; - | --- ^^^^^ expected `i32`, found `&str` - | | - | expected due to this - error[E0308]: mismatched types --> $DIR/attribute-with-error.rs:35:22 | diff --git a/src/test/ui/repeat_count.stderr b/src/test/ui/repeat_count.stderr index cd07e5b8935f2..c85f057203146 100644 --- a/src/test/ui/repeat_count.stderr +++ b/src/test/ui/repeat_count.stderr @@ -30,12 +30,6 @@ error[E0308]: mismatched types LL | let e = [0; "foo"]; | ^^^^^ expected `usize`, found `&str` -error[E0308]: mismatched types - --> $DIR/repeat_count.rs:31:17 - | -LL | let g = [0; G { g: () }]; - | ^^^^^^^^^^^ expected `usize`, found struct `G` - error[E0308]: mismatched types --> $DIR/repeat_count.rs:19:17 | @@ -63,6 +57,12 @@ help: change the type of the numeric literal from `u8` to `usize` LL | let f = [0; 4usize]; | ~~~~~~ +error[E0308]: mismatched types + --> $DIR/repeat_count.rs:31:17 + | +LL | let g = [0; G { g: () }]; + | ^^^^^^^^^^^ expected `usize`, found struct `G` + error: aborting due to 9 previous errors Some errors have detailed explanations: E0308, E0435. diff --git a/src/test/ui/suggestions/impl-trait-with-missing-bounds.stderr b/src/test/ui/suggestions/impl-trait-with-missing-bounds.stderr index 1cde42ff2cb01..bb7919ebb7996 100644 --- a/src/test/ui/suggestions/impl-trait-with-missing-bounds.stderr +++ b/src/test/ui/suggestions/impl-trait-with-missing-bounds.stderr @@ -1,20 +1,3 @@ -error[E0277]: `::Item` doesn't implement `Debug` - --> $DIR/impl-trait-with-missing-bounds.rs:6:13 - | -LL | qux(constraint); - | ^^^^^^^^^^ `::Item` cannot be formatted using `{:?}` because it doesn't implement `Debug` - | - = help: the trait `Debug` is not implemented for `::Item` -note: required by a bound in `qux` - --> $DIR/impl-trait-with-missing-bounds.rs:50:16 - | -LL | fn qux(_: impl std::fmt::Debug) {} - | ^^^^^^^^^^^^^^^ required by this bound in `qux` -help: introduce a type parameter with a trait bound instead of using `impl Trait` - | -LL | fn foo(constraints: I) where ::Item: Debug { - | +++++++++++++ ~ ++++++++++++++++++++++++++++++++++ - error[E0277]: `::Item` doesn't implement `Debug` --> $DIR/impl-trait-with-missing-bounds.rs:14:13 | @@ -83,6 +66,23 @@ help: introduce a type parameter with a trait bound instead of using `impl Trait LL | fn bak(constraints: I) where ::Item: Debug { | +++++++++++++++++++++++++++++++ ~ ++++++++++++++++++++++++++++++++++ +error[E0277]: `::Item` doesn't implement `Debug` + --> $DIR/impl-trait-with-missing-bounds.rs:6:13 + | +LL | qux(constraint); + | ^^^^^^^^^^ `::Item` cannot be formatted using `{:?}` because it doesn't implement `Debug` + | + = help: the trait `Debug` is not implemented for `::Item` +note: required by a bound in `qux` + --> $DIR/impl-trait-with-missing-bounds.rs:50:16 + | +LL | fn qux(_: impl std::fmt::Debug) {} + | ^^^^^^^^^^^^^^^ required by this bound in `qux` +help: introduce a type parameter with a trait bound instead of using `impl Trait` + | +LL | fn foo(constraints: I) where ::Item: Debug { + | +++++++++++++ ~ ++++++++++++++++++++++++++++++++++ + error[E0277]: `::Item` doesn't implement `Debug` --> $DIR/impl-trait-with-missing-bounds.rs:45:13 | diff --git a/src/test/ui/suggestions/suggest-ref-macro.stderr b/src/test/ui/suggestions/suggest-ref-macro.stderr index 147001f0c948b..1f41d2329ee9e 100644 --- a/src/test/ui/suggestions/suggest-ref-macro.stderr +++ b/src/test/ui/suggestions/suggest-ref-macro.stderr @@ -1,11 +1,3 @@ -error[E0308]: mismatched types - --> $DIR/suggest-ref-macro.rs:8:1 - | -LL | #[hello] - | ^^^^^^^^ expected `&mut i32`, found integer - | - = note: this error originates in the attribute macro `hello` (in Nightly builds, run with -Z macro-backtrace for more info) - error[E0308]: mismatched types --> $DIR/suggest-ref-macro.rs:15:11 | @@ -29,6 +21,14 @@ LL | bla!(456); | expected `&mut i32`, found integer | help: consider mutably borrowing here: `&mut 456` +error[E0308]: mismatched types + --> $DIR/suggest-ref-macro.rs:8:1 + | +LL | #[hello] + | ^^^^^^^^ expected `&mut i32`, found integer + | + = note: this error originates in the attribute macro `hello` (in Nightly builds, run with -Z macro-backtrace for more info) + error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/union/union-derive-clone.mirunsafeck.stderr b/src/test/ui/union/union-derive-clone.mirunsafeck.stderr index 414d2759a4798..b52117cd19cca 100644 --- a/src/test/ui/union/union-derive-clone.mirunsafeck.stderr +++ b/src/test/ui/union/union-derive-clone.mirunsafeck.stderr @@ -1,16 +1,3 @@ -error[E0277]: the trait bound `U1: Copy` is not satisfied - --> $DIR/union-derive-clone.rs:6:10 - | -LL | #[derive(Clone)] - | ^^^^^ the trait `Copy` is not implemented for `U1` - | -note: required by a bound in `AssertParamIsCopy` - --> $SRC_DIR/core/src/clone.rs:LL:COL - | -LL | pub struct AssertParamIsCopy { - | ^^^^ required by this bound in `AssertParamIsCopy` - = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info) - error[E0599]: the method `clone` exists for union `U5`, but its trait bounds were not satisfied --> $DIR/union-derive-clone.rs:38:15 | @@ -30,6 +17,19 @@ LL | let w = u.clone(); `CloneNoCopy: Copy` which is required by `U5: Clone` +error[E0277]: the trait bound `U1: Copy` is not satisfied + --> $DIR/union-derive-clone.rs:6:10 + | +LL | #[derive(Clone)] + | ^^^^^ the trait `Copy` is not implemented for `U1` + | +note: required by a bound in `AssertParamIsCopy` + --> $SRC_DIR/core/src/clone.rs:LL:COL + | +LL | pub struct AssertParamIsCopy { + | ^^^^ required by this bound in `AssertParamIsCopy` + = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info) + error: aborting due to 2 previous errors Some errors have detailed explanations: E0277, E0599. diff --git a/src/test/ui/union/union-derive-clone.thirunsafeck.stderr b/src/test/ui/union/union-derive-clone.thirunsafeck.stderr index 414d2759a4798..b52117cd19cca 100644 --- a/src/test/ui/union/union-derive-clone.thirunsafeck.stderr +++ b/src/test/ui/union/union-derive-clone.thirunsafeck.stderr @@ -1,16 +1,3 @@ -error[E0277]: the trait bound `U1: Copy` is not satisfied - --> $DIR/union-derive-clone.rs:6:10 - | -LL | #[derive(Clone)] - | ^^^^^ the trait `Copy` is not implemented for `U1` - | -note: required by a bound in `AssertParamIsCopy` - --> $SRC_DIR/core/src/clone.rs:LL:COL - | -LL | pub struct AssertParamIsCopy { - | ^^^^ required by this bound in `AssertParamIsCopy` - = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info) - error[E0599]: the method `clone` exists for union `U5`, but its trait bounds were not satisfied --> $DIR/union-derive-clone.rs:38:15 | @@ -30,6 +17,19 @@ LL | let w = u.clone(); `CloneNoCopy: Copy` which is required by `U5: Clone` +error[E0277]: the trait bound `U1: Copy` is not satisfied + --> $DIR/union-derive-clone.rs:6:10 + | +LL | #[derive(Clone)] + | ^^^^^ the trait `Copy` is not implemented for `U1` + | +note: required by a bound in `AssertParamIsCopy` + --> $SRC_DIR/core/src/clone.rs:LL:COL + | +LL | pub struct AssertParamIsCopy { + | ^^^^ required by this bound in `AssertParamIsCopy` + = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info) + error: aborting due to 2 previous errors Some errors have detailed explanations: E0277, E0599. From 26eeec0bafabb08df96168448f4b64d9fb650b0b Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 14 Jul 2021 18:04:56 +0200 Subject: [PATCH 2/5] Compute item_generics_num_lifetimes during resolution. --- compiler/rustc_ast_lowering/src/lib.rs | 47 +++---------------------- compiler/rustc_ast_lowering/src/path.rs | 11 ++---- compiler/rustc_resolve/src/late.rs | 15 ++++++++ compiler/rustc_resolve/src/lib.rs | 11 ++++-- 4 files changed, 30 insertions(+), 54 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 196d48faf5173..5d3a5fc20e042 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -39,7 +39,6 @@ use rustc_ast::node_id::NodeMap; use rustc_ast::token::{self, Token}; use rustc_ast::tokenstream::{CanSynthesizeMissingTokens, TokenStream, TokenTree}; use rustc_ast::visit::{self, AssocCtxt, Visitor}; -use rustc_ast::walk_list; use rustc_ast::{self as ast, *}; use rustc_ast_pretty::pprust; use rustc_data_structures::captures::Captures; @@ -48,7 +47,7 @@ use rustc_data_structures::sync::Lrc; use rustc_errors::{struct_span_err, Applicability}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Namespace, PartialRes, PerNS, Res}; -use rustc_hir::def_id::{DefId, DefIdMap, DefPathHash, LocalDefId, CRATE_DEF_ID}; +use rustc_hir::def_id::{DefId, DefPathHash, LocalDefId, CRATE_DEF_ID}; use rustc_hir::definitions::{DefKey, DefPathData, Definitions}; use rustc_hir::intravisit; use rustc_hir::{ConstArg, GenericArg, InferKind, ParamName}; @@ -159,8 +158,6 @@ struct LoweringContext<'a, 'hir: 'a> { current_module: LocalDefId, - type_def_lifetime_params: DefIdMap, - current_hir_id_owner: (LocalDefId, u32), item_local_id_counters: NodeMap, node_id_to_hir_id: IndexVec>, @@ -172,7 +169,7 @@ struct LoweringContext<'a, 'hir: 'a> { pub trait ResolverAstLowering { fn def_key(&mut self, id: DefId) -> DefKey; - fn item_generics_num_lifetimes(&self, def: DefId, sess: &Session) -> usize; + fn item_generics_num_lifetimes(&self, def: DefId) -> usize; fn legacy_const_generic_args(&mut self, expr: &Expr) -> Option>; @@ -336,7 +333,6 @@ pub fn lower_crate<'a, 'hir>( is_in_trait_impl: false, is_in_dyn_type: false, anonymous_lifetime_mode: AnonymousLifetimeMode::PassThrough, - type_def_lifetime_params: Default::default(), current_module: CRATE_DEF_ID, current_hir_id_owner: (CRATE_DEF_ID, 0), item_local_id_counters: Default::default(), @@ -452,26 +448,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { fn visit_item(&mut self, item: &'tcx Item) { self.lctx.allocate_hir_id_counter(item.id); - match item.kind { - ItemKind::Struct(_, ref generics) - | ItemKind::Union(_, ref generics) - | ItemKind::Enum(_, ref generics) - | ItemKind::TyAlias(box TyAliasKind(_, ref generics, ..)) - | ItemKind::Trait(box TraitKind(_, _, ref generics, ..)) => { - let def_id = self.lctx.resolver.local_def_id(item.id); - let count = generics - .params - .iter() - .filter(|param| { - matches!(param.kind, ast::GenericParamKind::Lifetime { .. }) - }) - .count(); - self.lctx.type_def_lifetime_params.insert(def_id.to_def_id(), count); - } - ItemKind::Use(ref use_tree) => { - self.allocate_use_tree_hir_id_counters(use_tree); - } - _ => {} + if let ItemKind::Use(ref use_tree) = item.kind { + self.allocate_use_tree_hir_id_counters(use_tree); } visit::walk_item(self, item); @@ -486,23 +464,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.lctx.allocate_hir_id_counter(item.id); visit::walk_foreign_item(self, item); } - - fn visit_ty(&mut self, t: &'tcx Ty) { - match t.kind { - // Mirrors the case in visit::walk_ty - TyKind::BareFn(ref f) => { - walk_list!(self, visit_generic_param, &f.generic_params); - // Mirrors visit::walk_fn_decl - for parameter in &f.decl.inputs { - // We don't lower the ids of argument patterns - self.visit_pat(¶meter.pat); - self.visit_ty(¶meter.ty) - } - self.visit_fn_ret_ty(&f.decl.output) - } - _ => visit::walk_ty(self, t), - } - } } self.lower_node_id(CRATE_NODE_ID); diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs index a11d020c9315f..90a22b5c20952 100644 --- a/compiler/rustc_ast_lowering/src/path.rs +++ b/compiler/rustc_ast_lowering/src/path.rs @@ -90,15 +90,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { _ => ParenthesizedGenericArgs::Err, }; - let num_lifetimes = type_def_id.map_or(0, |def_id| { - if let Some(&n) = self.type_def_lifetime_params.get(&def_id) { - return n; - } - assert!(!def_id.is_local()); - let n = self.resolver.item_generics_num_lifetimes(def_id, self.sess); - self.type_def_lifetime_params.insert(def_id, n); - n - }); + let num_lifetimes = type_def_id + .map_or(0, |def_id| self.resolver.item_generics_num_lifetimes(def_id)); self.lower_path_segment( p.span, segment, diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 5c7b4b028227e..4a0287d83ffd9 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -952,6 +952,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { match item.kind { ItemKind::TyAlias(box TyAliasKind(_, ref generics, _, _)) | ItemKind::Fn(box FnKind(_, _, ref generics, _)) => { + self.compute_num_lifetime_params(item.id, generics); self.with_generic_param_rib(generics, ItemRibKind(HasGenericParams::Yes), |this| { visit::walk_item(this, item) }); @@ -960,6 +961,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { ItemKind::Enum(_, ref generics) | ItemKind::Struct(_, ref generics) | ItemKind::Union(_, ref generics) => { + self.compute_num_lifetime_params(item.id, generics); self.resolve_adt(item, generics); } @@ -970,10 +972,12 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { items: ref impl_items, .. }) => { + self.compute_num_lifetime_params(item.id, generics); self.resolve_implementation(generics, of_trait, &self_ty, item.id, impl_items); } ItemKind::Trait(box TraitKind(.., ref generics, ref bounds, ref trait_items)) => { + self.compute_num_lifetime_params(item.id, generics); // Create a new rib for the trait-wide type parameters. self.with_generic_param_rib(generics, ItemRibKind(HasGenericParams::Yes), |this| { let local_def_id = this.r.local_def_id(item.id).to_def_id(); @@ -1025,6 +1029,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { } ItemKind::TraitAlias(ref generics, ref bounds) => { + self.compute_num_lifetime_params(item.id, generics); // Create a new rib for the trait-wide type parameters. self.with_generic_param_rib(generics, ItemRibKind(HasGenericParams::Yes), |this| { let local_def_id = this.r.local_def_id(item.id).to_def_id(); @@ -2463,6 +2468,16 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { Some((ident.name, ns)), ) } + + fn compute_num_lifetime_params(&mut self, id: NodeId, generics: &Generics) { + let def_id = self.r.local_def_id(id); + let count = generics + .params + .iter() + .filter(|param| matches!(param.kind, ast::GenericParamKind::Lifetime { .. })) + .count(); + self.r.item_generics_num_lifetimes.insert(def_id, count); + } } impl<'a> Resolver<'a> { diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index da3beac081961..2101381553be1 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -1030,6 +1030,8 @@ pub struct Resolver<'a> { trait_impl_items: FxHashSet, legacy_const_generic_args: FxHashMap>>, + /// Amount of lifetime parameters for each item in the crate. + item_generics_num_lifetimes: FxHashMap, main_def: Option, } @@ -1109,8 +1111,12 @@ impl ResolverAstLowering for Resolver<'_> { } } - fn item_generics_num_lifetimes(&self, def_id: DefId, sess: &Session) -> usize { - self.cstore().item_generics_num_lifetimes(def_id, sess) + fn item_generics_num_lifetimes(&self, def_id: DefId) -> usize { + if let Some(def_id) = def_id.as_local() { + self.item_generics_num_lifetimes[&def_id] + } else { + self.cstore().item_generics_num_lifetimes(def_id, self.session) + } } fn legacy_const_generic_args(&mut self, expr: &Expr) -> Option> { @@ -1390,6 +1396,7 @@ impl<'a> Resolver<'a> { next_disambiguator: Default::default(), trait_impl_items: Default::default(), legacy_const_generic_args: Default::default(), + item_generics_num_lifetimes: Default::default(), main_def: Default::default(), }; From 635978041d3b65cd89cc109a83fc761221b4f1d0 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Fri, 16 Jul 2021 21:55:10 +0200 Subject: [PATCH 3/5] Compute all_traits_impls during resolution. --- compiler/rustc_ast_lowering/src/item.rs | 9 --------- compiler/rustc_ast_lowering/src/lib.rs | 4 ---- compiler/rustc_hir/src/hir.rs | 1 - compiler/rustc_middle/src/hir/mod.rs | 2 +- compiler/rustc_middle/src/ty/mod.rs | 2 ++ compiler/rustc_resolve/src/late.rs | 9 ++++++++- compiler/rustc_resolve/src/lib.rs | 6 +++++- compiler/rustc_typeck/src/coherence/mod.rs | 2 +- 8 files changed, 17 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 8daeef0cbd95f..8e74a20f60aae 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -383,15 +383,6 @@ impl<'hir> LoweringContext<'_, 'hir> { this.lower_trait_ref(trait_ref, ImplTraitContext::disallowed()) }); - if let Some(ref trait_ref) = trait_ref { - if let Res::Def(DefKind::Trait, def_id) = trait_ref.path.res { - this.trait_impls - .entry(def_id) - .or_default() - .push(lowered_trait_def_id); - } - } - let lowered_ty = this.lower_ty(ty, ImplTraitContext::disallowed()); (trait_ref, lowered_ty) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 5d3a5fc20e042..7a26aa5c3d6c8 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -104,8 +104,6 @@ struct LoweringContext<'a, 'hir: 'a> { owners: IndexVec>>, bodies: BTreeMap>, - trait_impls: BTreeMap>, - modules: BTreeMap, generator_kind: Option, @@ -324,7 +322,6 @@ pub fn lower_crate<'a, 'hir>( arena, owners: IndexVec::default(), bodies: BTreeMap::new(), - trait_impls: BTreeMap::new(), modules: BTreeMap::new(), attrs: BTreeMap::default(), catch_scopes: Vec::new(), @@ -512,7 +509,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let krate = hir::Crate { owners: self.owners, bodies: self.bodies, - trait_impls: self.trait_impls, modules: self.modules, proc_macros, trait_map, diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index d629cb6021456..489b2848b0985 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -672,7 +672,6 @@ pub struct ModuleItems { pub struct Crate<'hir> { pub owners: IndexVec>>, pub bodies: BTreeMap>, - pub trait_impls: BTreeMap>, /// A list of modules written out in the order in which they /// appear in the crate. This includes the main crate module. diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index 158499bc0aef7..34aee4f1b3b3f 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -170,7 +170,7 @@ pub fn provide(providers: &mut Providers) { } }; providers.opt_def_kind = |tcx, def_id| tcx.hir().opt_def_kind(def_id.expect_local()); - providers.all_local_trait_impls = |tcx, ()| &tcx.hir_crate(()).trait_impls; + providers.all_local_trait_impls = |tcx, ()| &tcx.resolutions(()).trait_impls; providers.expn_that_defined = |tcx, id| { let id = id.expect_local(); tcx.resolutions(()).definitions.expansion_that_defined(id) diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index cfb49b7d9b8c5..6ff1215b149bb 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -44,6 +44,7 @@ use rustc_span::Span; use rustc_target::abi::Align; use std::cmp::Ordering; +use std::collections::BTreeMap; use std::hash::{Hash, Hasher}; use std::ops::ControlFlow; use std::{fmt, ptr, str}; @@ -132,6 +133,7 @@ pub struct ResolverOutputs { /// via `extern crate` item and not `--extern` option or compiler built-in. pub extern_prelude: FxHashMap, pub main_def: Option, + pub trait_impls: BTreeMap>, } #[derive(Clone, Copy, Debug)] diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 4a0287d83ffd9..7b65ab2acf6c4 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -1281,7 +1281,14 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { this.with_self_rib(Res::SelfTy(None, None), |this| { // Resolve the trait reference, if necessary. this.with_optional_trait_ref(opt_trait_reference.as_ref(), |this, trait_id| { - let item_def_id = this.r.local_def_id(item_id).to_def_id(); + let item_def_id = this.r.local_def_id(item_id); + + // Register the trait definitions from here. + if let Some(trait_id) = trait_id { + this.r.trait_impls.entry(trait_id).or_default().push(item_def_id); + } + + let item_def_id = item_def_id.to_def_id(); this.with_self_rib(Res::SelfTy(trait_id, Some((item_def_id, false))), |this| { if let Some(trait_ref) = opt_trait_reference.as_ref() { // Resolve type arguments in the trait path. diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 2101381553be1..51e0ee0a57fe2 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -60,7 +60,7 @@ use rustc_span::{Span, DUMMY_SP}; use smallvec::{smallvec, SmallVec}; use std::cell::{Cell, RefCell}; -use std::collections::BTreeSet; +use std::collections::{BTreeMap, BTreeSet}; use std::ops::ControlFlow; use std::{cmp, fmt, iter, ptr}; use tracing::debug; @@ -1034,6 +1034,7 @@ pub struct Resolver<'a> { item_generics_num_lifetimes: FxHashMap, main_def: Option, + trait_impls: BTreeMap>, } /// Nothing really interesting here; it just provides memory for the rest of the crate. @@ -1398,6 +1399,7 @@ impl<'a> Resolver<'a> { legacy_const_generic_args: Default::default(), item_generics_num_lifetimes: Default::default(), main_def: Default::default(), + trait_impls: Default::default(), }; let root_parent_scope = ParentScope::module(graph_root, &resolver); @@ -1455,6 +1457,7 @@ impl<'a> Resolver<'a> { .map(|(ident, entry)| (ident.name, entry.introduced_by_item)) .collect(), main_def, + trait_impls: self.trait_impls, } } @@ -1474,6 +1477,7 @@ impl<'a> Resolver<'a> { .map(|(ident, entry)| (ident.name, entry.introduced_by_item)) .collect(), main_def: self.main_def.clone(), + trait_impls: self.trait_impls.clone(), } } diff --git a/compiler/rustc_typeck/src/coherence/mod.rs b/compiler/rustc_typeck/src/coherence/mod.rs index 03a9fe01795f5..7ac26a31872df 100644 --- a/compiler/rustc_typeck/src/coherence/mod.rs +++ b/compiler/rustc_typeck/src/coherence/mod.rs @@ -195,7 +195,7 @@ fn coherent_trait(tcx: TyCtxt<'_>, def_id: DefId) { } pub fn check_coherence(tcx: TyCtxt<'_>) { - for &trait_def_id in tcx.hir().krate().trait_impls.keys() { + for &trait_def_id in tcx.all_local_trait_impls(()).keys() { tcx.ensure().coherent_trait(trait_def_id); } From f8efe5d8222db70964f46b6523be81d6e7c38e65 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Fri, 16 Jul 2021 22:22:08 +0200 Subject: [PATCH 4/5] Compute proc_macros in resolutions. --- compiler/rustc_ast/src/ast.rs | 7 ---- compiler/rustc_ast/src/mut_visit.rs | 8 ++--- compiler/rustc_ast_lowering/src/lib.rs | 4 --- .../src/proc_macro_harness.rs | 36 +++++++------------ compiler/rustc_expand/src/base.rs | 8 +++++ compiler/rustc_hir/src/hir.rs | 3 -- compiler/rustc_interface/src/passes.rs | 2 +- compiler/rustc_metadata/src/rmeta/encoder.rs | 20 ++++++----- compiler/rustc_middle/src/ty/mod.rs | 3 ++ compiler/rustc_parse/src/parser/item.rs | 3 +- compiler/rustc_resolve/src/lib.rs | 8 +++++ compiler/rustc_resolve/src/macros.rs | 4 +++ 12 files changed, 52 insertions(+), 54 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 0632d937c4c17..443698a796ddc 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -502,13 +502,6 @@ pub struct Crate { pub attrs: Vec, pub items: Vec>, pub span: Span, - /// The order of items in the HIR is unrelated to the order of - /// items in the AST. However, we generate proc macro harnesses - /// based on the AST order, and later refer to these harnesses - /// from the HIR. This field keeps track of the order in which - /// we generated proc macros harnesses, so that we can map - /// HIR proc macros items back to their harness items. - pub proc_macros: Vec, } /// Possible values inside of compile-time attribute lists. diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 368a23e34290d..b7e446a8bee2b 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -1059,7 +1059,7 @@ pub fn noop_visit_fn_header(header: &mut FnHeader, vis: &mut T) { // FIXME: Avoid visiting the crate as a `Mod` item, flat map only the inner items if possible, // or make crate visiting first class if necessary. pub fn noop_visit_crate(krate: &mut Crate, vis: &mut T) { - visit_clobber(krate, |Crate { attrs, items, span, proc_macros }| { + visit_clobber(krate, |Crate { attrs, items, span }| { let item_vis = Visibility { kind: VisibilityKind::Public, span: span.shrink_to_lo(), tokens: None }; let item = P(Item { @@ -1075,13 +1075,11 @@ pub fn noop_visit_crate(krate: &mut Crate, vis: &mut T) { let len = items.len(); if len == 0 { - Crate { attrs: vec![], items: vec![], span, proc_macros } + Crate { attrs: vec![], items: vec![], span } } else if len == 1 { let Item { attrs, span, kind, .. } = items.into_iter().next().unwrap().into_inner(); match kind { - ItemKind::Mod(_, ModKind::Loaded(items, ..)) => { - Crate { attrs, items, span, proc_macros } - } + ItemKind::Mod(_, ModKind::Loaded(items, ..)) => Crate { attrs, items, span }, _ => panic!("visitor converted a module to not a module"), } } else { diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 7a26aa5c3d6c8..f8d366fdee752 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -474,9 +474,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.owners.ensure_contains_elem(CRATE_DEF_ID, || None); self.owners[CRATE_DEF_ID] = Some(hir::OwnerNode::Crate(module)); - let proc_macros = - c.proc_macros.iter().map(|id| self.node_id_to_hir_id[*id].unwrap()).collect(); - let mut trait_map: FxHashMap<_, FxHashMap<_, _>> = FxHashMap::default(); for (k, v) in self.resolver.take_trait_map().into_iter() { if let Some(Some(hir_id)) = self.node_id_to_hir_id.get(k) { @@ -510,7 +507,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { owners: self.owners, bodies: self.bodies, modules: self.modules, - proc_macros, trait_map, attrs: self.attrs, }; diff --git a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs index 7971c1fff428c..6f61e4cba0776 100644 --- a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs +++ b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs @@ -13,7 +13,6 @@ use rustc_span::source_map::SourceMap; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{Span, DUMMY_SP}; use smallvec::smallvec; -use std::cell::RefCell; struct ProcMacroDerive { id: NodeId, @@ -90,7 +89,7 @@ pub fn inject( return krate; } - let decls = mk_decls(&mut krate, &mut cx, ¯os); + let decls = mk_decls(&mut cx, ¯os); krate.items.push(decls); krate @@ -289,15 +288,7 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> { // // ... // ]; // } -fn mk_decls( - ast_krate: &mut ast::Crate, - cx: &mut ExtCtxt<'_>, - macros: &[ProcMacro], -) -> P { - // We're the ones filling in this Vec, - // so it should be empty to start with - assert!(ast_krate.proc_macros.is_empty()); - +fn mk_decls(cx: &mut ExtCtxt<'_>, macros: &[ProcMacro]) -> P { let expn_id = cx.resolver.expansion_for_ast_pass( DUMMY_SP, AstPass::ProcMacroHarness, @@ -316,26 +307,25 @@ fn mk_decls( let attr = Ident::new(sym::attr, span); let bang = Ident::new(sym::bang, span); - let krate_ref = RefCell::new(ast_krate); - - // We add NodeIds to 'krate.proc_macros' in the order + // We add NodeIds to 'resolver.proc_macros' in the order // that we generate expressions. The position of each NodeId // in the 'proc_macros' Vec corresponds to its position // in the static array that will be generated let decls = { - let local_path = - |sp: Span, name| cx.expr_path(cx.path(sp.with_ctxt(span.ctxt()), vec![name])); - let proc_macro_ty_method_path = |method| { + let local_path = |cx: &ExtCtxt<'_>, sp: Span, name| { + cx.expr_path(cx.path(sp.with_ctxt(span.ctxt()), vec![name])) + }; + let proc_macro_ty_method_path = |cx: &ExtCtxt<'_>, method| { cx.expr_path(cx.path(span, vec![proc_macro, bridge, client, proc_macro_ty, method])) }; macros .iter() .map(|m| match m { ProcMacro::Derive(cd) => { - krate_ref.borrow_mut().proc_macros.push(cd.id); + cx.resolver.declare_proc_macro(cd.id); cx.expr_call( span, - proc_macro_ty_method_path(custom_derive), + proc_macro_ty_method_path(cx, custom_derive), vec![ cx.expr_str(cd.span, cd.trait_name), cx.expr_vec_slice( @@ -345,12 +335,12 @@ fn mk_decls( .map(|&s| cx.expr_str(cd.span, s)) .collect::>(), ), - local_path(cd.span, cd.function_name), + local_path(cx, cd.span, cd.function_name), ], ) } ProcMacro::Def(ca) => { - krate_ref.borrow_mut().proc_macros.push(ca.id); + cx.resolver.declare_proc_macro(ca.id); let ident = match ca.def_type { ProcMacroDefType::Attr => attr, ProcMacroDefType::Bang => bang, @@ -358,10 +348,10 @@ fn mk_decls( cx.expr_call( span, - proc_macro_ty_method_path(ident), + proc_macro_ty_method_path(cx, ident), vec![ cx.expr_str(ca.span, ca.function_name.name), - local_path(ca.span, ca.function_name), + local_path(cx, ca.span, ca.function_name), ], ) } diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index a4b7bdd9155cc..ebf168d7de7b4 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -894,6 +894,14 @@ pub trait ResolverExpand { /// Decodes the proc-macro quoted span in the specified crate, with the specified id. /// No caching is performed. fn get_proc_macro_quoted_span(&self, krate: CrateNum, id: usize) -> Span; + + /// The order of items in the HIR is unrelated to the order of + /// items in the AST. However, we generate proc macro harnesses + /// based on the AST order, and later refer to these harnesses + /// from the HIR. This field keeps track of the order in which + /// we generated proc macros harnesses, so that we can map + /// HIR proc macros items back to their harness items. + fn declare_proc_macro(&mut self, id: NodeId); } #[derive(Clone, Default)] diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 489b2848b0985..a43ef9bb1a0b0 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -676,9 +676,6 @@ pub struct Crate<'hir> { /// A list of modules written out in the order in which they /// appear in the crate. This includes the main crate module. pub modules: BTreeMap, - /// A list of proc macro HirIds, written out in the order in which - /// they are declared in the static array generated by proc_macro_harness. - pub proc_macros: Vec, /// Map indicating what traits are in scope for places where this /// is relevant; generated by resolve. diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 5dc57f6023b76..7127ec57c08c3 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -324,7 +324,7 @@ pub fn configure_and_expand( }; let extern_mod_loaded = |ident: Ident, attrs, items, span| { - let krate = ast::Crate { attrs, items, span, proc_macros: vec![] }; + let krate = ast::Crate { attrs, items, span }; pre_expansion_lint(sess, lint_store, &krate, &ident.name.as_str()); (krate.attrs, krate.items) }; diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 2cd4fe3b70621..d8b9a4799760e 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -454,7 +454,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let table = self.tcx.resolutions(()).definitions.def_path_table(); if self.is_proc_macro { for def_index in std::iter::once(CRATE_DEF_INDEX) - .chain(self.tcx.hir().krate().proc_macros.iter().map(|p| p.owner.local_def_index)) + .chain(self.tcx.resolutions(()).proc_macros.iter().map(|p| p.local_def_index)) { let def_key = self.lazy(table.def_key(def_index)); let def_path_hash = self.lazy(table.def_path_hash(def_index)); @@ -1630,7 +1630,8 @@ impl EncodeContext<'a, 'tcx> { let proc_macro_decls_static = tcx.proc_macro_decls_static(()).unwrap().local_def_index; let stability = tcx.lookup_stability(DefId::local(CRATE_DEF_INDEX)).copied(); - let macros = self.lazy(hir.krate().proc_macros.iter().map(|p| p.owner.local_def_index)); + let macros = + self.lazy(tcx.resolutions(()).proc_macros.iter().map(|p| p.local_def_index)); let spans = self.tcx.sess.parse_sess.proc_macro_quoted_spans(); for (i, span) in spans.into_iter().enumerate() { let span = self.lazy(span); @@ -1649,13 +1650,14 @@ impl EncodeContext<'a, 'tcx> { // Normally, this information is encoded when we walk the items // defined in this crate. However, we skip doing that for proc-macro crates, // so we manually encode just the information that we need - for proc_macro in &hir.krate().proc_macros { - let id = proc_macro.owner.local_def_index; - let mut name = hir.name(*proc_macro); - let span = hir.span(*proc_macro); + for &proc_macro in &tcx.resolutions(()).proc_macros { + let id = proc_macro; + let proc_macro = hir.local_def_id_to_hir_id(proc_macro); + let mut name = hir.name(proc_macro); + let span = hir.span(proc_macro); // Proc-macros may have attributes like `#[allow_internal_unstable]`, // so downstream crates need access to them. - let attrs = hir.attrs(*proc_macro); + let attrs = hir.attrs(proc_macro); let macro_kind = if tcx.sess.contains_name(attrs, sym::proc_macro) { MacroKind::Bang } else if tcx.sess.contains_name(attrs, sym::proc_macro_attribute) { @@ -1673,10 +1675,10 @@ impl EncodeContext<'a, 'tcx> { bug!("Unknown proc-macro type for item {:?}", id); }; - let mut def_key = self.tcx.hir().def_key(proc_macro.owner); + let mut def_key = self.tcx.hir().def_key(id); def_key.disambiguated_data.data = DefPathData::MacroNs(name); - let def_id = DefId::local(id); + let def_id = id.to_def_id(); record!(self.tables.def_kind[def_id] <- DefKind::Macro(macro_kind)); record!(self.tables.kind[def_id] <- EntryKind::ProcMacro(macro_kind)); record!(self.tables.attributes[def_id] <- attrs); diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 6ff1215b149bb..d01ca27b85118 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -134,6 +134,9 @@ pub struct ResolverOutputs { pub extern_prelude: FxHashMap, pub main_def: Option, pub trait_impls: BTreeMap>, + /// A list of proc macro LocalDefIds, written out in the order in which + /// they are declared in the static array generated by proc_macro_harness. + pub proc_macros: Vec, } #[derive(Clone, Copy, Debug)] diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index e5537d43ebaa1..10c73fd64bc19 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -26,8 +26,7 @@ impl<'a> Parser<'a> { /// Parses a source module as a crate. This is the main entry point for the parser. pub fn parse_crate_mod(&mut self) -> PResult<'a, ast::Crate> { let (attrs, items, span) = self.parse_mod(&token::Eof)?; - let proc_macros = Vec::new(); // Filled in by `proc_macro_harness::inject()`. - Ok(ast::Crate { attrs, items, span, proc_macros }) + Ok(ast::Crate { attrs, items, span }) } /// Parses a `mod { ... }` or `mod ;` item. diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 51e0ee0a57fe2..152d34fd63558 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -1035,6 +1035,9 @@ pub struct Resolver<'a> { main_def: Option, trait_impls: BTreeMap>, + /// A list of proc macro LocalDefIds, written out in the order in which + /// they are declared in the static array generated by proc_macro_harness. + proc_macros: Vec, } /// Nothing really interesting here; it just provides memory for the rest of the crate. @@ -1400,6 +1403,7 @@ impl<'a> Resolver<'a> { item_generics_num_lifetimes: Default::default(), main_def: Default::default(), trait_impls: Default::default(), + proc_macros: Default::default(), }; let root_parent_scope = ParentScope::module(graph_root, &resolver); @@ -1434,6 +1438,7 @@ impl<'a> Resolver<'a> { } pub fn into_outputs(self) -> ResolverOutputs { + let proc_macros = self.proc_macros.iter().map(|id| self.local_def_id(*id)).collect(); let definitions = self.definitions; let visibilities = self.visibilities; let extern_crate_map = self.extern_crate_map; @@ -1458,10 +1463,12 @@ impl<'a> Resolver<'a> { .collect(), main_def, trait_impls: self.trait_impls, + proc_macros, } } pub fn clone_outputs(&self) -> ResolverOutputs { + let proc_macros = self.proc_macros.iter().map(|id| self.local_def_id(*id)).collect(); ResolverOutputs { definitions: self.definitions.clone(), cstore: Box::new(self.cstore().clone()), @@ -1478,6 +1485,7 @@ impl<'a> Resolver<'a> { .collect(), main_def: self.main_def.clone(), trait_impls: self.trait_impls.clone(), + proc_macros, } } diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 7f86f891c4450..6dc3aa0888a8b 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -466,6 +466,10 @@ impl<'a> ResolverExpand for Resolver<'a> { fn get_proc_macro_quoted_span(&self, krate: CrateNum, id: usize) -> Span { self.crate_loader.cstore().get_proc_macro_quoted_span_untracked(krate, id, self.session) } + + fn declare_proc_macro(&mut self, id: NodeId) { + self.proc_macros.push(id) + } } impl<'a> Resolver<'a> { From 5e3cd6a8b29b312c796c5a83afd4a5fa21513f8e Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 1 Sep 2021 20:06:08 +0200 Subject: [PATCH 5/5] Bless ast-json tests. --- src/test/ui/ast-json/ast-json-noexpand-output.stdout | 2 +- src/test/ui/ast-json/ast-json-output.stdout | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/ui/ast-json/ast-json-noexpand-output.stdout b/src/test/ui/ast-json/ast-json-noexpand-output.stdout index 0307875c154b8..8961655ede36f 100644 --- a/src/test/ui/ast-json/ast-json-noexpand-output.stdout +++ b/src/test/ui/ast-json/ast-json-noexpand-output.stdout @@ -1 +1 @@ -{"attrs":[{"kind":{"variant":"Normal","fields":[{"path":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"crate_type","span":{"lo":0,"hi":0}},"id":0,"args":null}],"tokens":null},"args":{"variant":"Eq","fields":[{"lo":0,"hi":0},{"kind":{"variant":"Interpolated","fields":[{"variant":"NtExpr","fields":[{"id":0,"kind":{"variant":"Lit","fields":[{"token":{"kind":"Str","symbol":"lib","suffix":null},"kind":{"variant":"Str","fields":["lib","Cooked"]},"span":{"lo":0,"hi":0}}]},"span":{"lo":0,"hi":0},"attrs":{"0":null},"tokens":{"0":[[{"variant":"Token","fields":[{"kind":{"variant":"Literal","fields":[{"kind":"Str","symbol":"lib","suffix":null}]},"span":{"lo":0,"hi":0}}]},"Alone"]]}}]}]},"span":{"lo":0,"hi":0}}]},"tokens":null},{"0":[[{"variant":"Token","fields":[{"kind":"Pound","span":{"lo":0,"hi":0}}]},"Joint"],[{"variant":"Token","fields":[{"kind":"Not","span":{"lo":0,"hi":0}}]},"Alone"],[{"variant":"Delimited","fields":[{"open":{"lo":0,"hi":0},"close":{"lo":0,"hi":0}},"Bracket",{"0":[[{"variant":"Token","fields":[{"kind":{"variant":"Ident","fields":["crate_type",false]},"span":{"lo":0,"hi":0}}]},"Alone"],[{"variant":"Token","fields":[{"kind":"Eq","span":{"lo":0,"hi":0}}]},"Alone"],[{"variant":"Token","fields":[{"kind":{"variant":"Literal","fields":[{"kind":"Str","symbol":"lib","suffix":null}]},"span":{"lo":0,"hi":0}}]},"Alone"]]}]},"Alone"]]}]},"id":null,"style":"Inner","span":{"lo":0,"hi":0}}],"items":[{"attrs":[],"id":0,"span":{"lo":0,"hi":0},"vis":{"kind":"Inherited","span":{"lo":0,"hi":0},"tokens":null},"ident":{"name":"core","span":{"lo":0,"hi":0}},"kind":{"variant":"ExternCrate","fields":[null]},"tokens":null}],"span":{"lo":0,"hi":0},"proc_macros":[]} +{"attrs":[{"kind":{"variant":"Normal","fields":[{"path":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"crate_type","span":{"lo":0,"hi":0}},"id":0,"args":null}],"tokens":null},"args":{"variant":"Eq","fields":[{"lo":0,"hi":0},{"kind":{"variant":"Interpolated","fields":[{"variant":"NtExpr","fields":[{"id":0,"kind":{"variant":"Lit","fields":[{"token":{"kind":"Str","symbol":"lib","suffix":null},"kind":{"variant":"Str","fields":["lib","Cooked"]},"span":{"lo":0,"hi":0}}]},"span":{"lo":0,"hi":0},"attrs":{"0":null},"tokens":{"0":[[{"variant":"Token","fields":[{"kind":{"variant":"Literal","fields":[{"kind":"Str","symbol":"lib","suffix":null}]},"span":{"lo":0,"hi":0}}]},"Alone"]]}}]}]},"span":{"lo":0,"hi":0}}]},"tokens":null},{"0":[[{"variant":"Token","fields":[{"kind":"Pound","span":{"lo":0,"hi":0}}]},"Joint"],[{"variant":"Token","fields":[{"kind":"Not","span":{"lo":0,"hi":0}}]},"Alone"],[{"variant":"Delimited","fields":[{"open":{"lo":0,"hi":0},"close":{"lo":0,"hi":0}},"Bracket",{"0":[[{"variant":"Token","fields":[{"kind":{"variant":"Ident","fields":["crate_type",false]},"span":{"lo":0,"hi":0}}]},"Alone"],[{"variant":"Token","fields":[{"kind":"Eq","span":{"lo":0,"hi":0}}]},"Alone"],[{"variant":"Token","fields":[{"kind":{"variant":"Literal","fields":[{"kind":"Str","symbol":"lib","suffix":null}]},"span":{"lo":0,"hi":0}}]},"Alone"]]}]},"Alone"]]}]},"id":null,"style":"Inner","span":{"lo":0,"hi":0}}],"items":[{"attrs":[],"id":0,"span":{"lo":0,"hi":0},"vis":{"kind":"Inherited","span":{"lo":0,"hi":0},"tokens":null},"ident":{"name":"core","span":{"lo":0,"hi":0}},"kind":{"variant":"ExternCrate","fields":[null]},"tokens":null}],"span":{"lo":0,"hi":0}} diff --git a/src/test/ui/ast-json/ast-json-output.stdout b/src/test/ui/ast-json/ast-json-output.stdout index 535f57bf6af85..082f04134ce8f 100644 --- a/src/test/ui/ast-json/ast-json-output.stdout +++ b/src/test/ui/ast-json/ast-json-output.stdout @@ -1 +1 @@ -{"attrs":[{"kind":{"variant":"Normal","fields":[{"path":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"crate_type","span":{"lo":0,"hi":0}},"id":0,"args":null}],"tokens":null},"args":{"variant":"Eq","fields":[{"lo":0,"hi":0},{"kind":{"variant":"Interpolated","fields":[{"variant":"NtExpr","fields":[{"id":0,"kind":{"variant":"Lit","fields":[{"token":{"kind":"Str","symbol":"lib","suffix":null},"kind":{"variant":"Str","fields":["lib","Cooked"]},"span":{"lo":0,"hi":0}}]},"span":{"lo":0,"hi":0},"attrs":{"0":null},"tokens":{"0":[[{"variant":"Token","fields":[{"kind":{"variant":"Literal","fields":[{"kind":"Str","symbol":"lib","suffix":null}]},"span":{"lo":0,"hi":0}}]},"Alone"]]}}]}]},"span":{"lo":0,"hi":0}}]},"tokens":null},{"0":[[{"variant":"Token","fields":[{"kind":"Pound","span":{"lo":0,"hi":0}}]},"Joint"],[{"variant":"Token","fields":[{"kind":"Not","span":{"lo":0,"hi":0}}]},"Alone"],[{"variant":"Delimited","fields":[{"open":{"lo":0,"hi":0},"close":{"lo":0,"hi":0}},"Bracket",{"0":[[{"variant":"Token","fields":[{"kind":{"variant":"Ident","fields":["crate_type",false]},"span":{"lo":0,"hi":0}}]},"Alone"],[{"variant":"Token","fields":[{"kind":"Eq","span":{"lo":0,"hi":0}}]},"Alone"],[{"variant":"Token","fields":[{"kind":{"variant":"Literal","fields":[{"kind":"Str","symbol":"lib","suffix":null}]},"span":{"lo":0,"hi":0}}]},"Alone"]]}]},"Alone"]]}]},"id":null,"style":"Inner","span":{"lo":0,"hi":0}}],"items":[{"attrs":[{"kind":{"variant":"Normal","fields":[{"path":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"prelude_import","span":{"lo":0,"hi":0}},"id":0,"args":null}],"tokens":null},"args":"Empty","tokens":null},null]},"id":null,"style":"Outer","span":{"lo":0,"hi":0}}],"id":0,"span":{"lo":0,"hi":0},"vis":{"kind":"Inherited","span":{"lo":0,"hi":0},"tokens":null},"ident":{"name":"","span":{"lo":0,"hi":0}},"kind":{"variant":"Use","fields":[{"prefix":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"{{root}}","span":{"lo":0,"hi":0}},"id":0,"args":null},{"ident":{"name":"std","span":{"lo":0,"hi":0}},"id":0,"args":null},{"ident":{"name":"prelude","span":{"lo":0,"hi":0}},"id":0,"args":null},{"ident":{"name":"rust_2015","span":{"lo":0,"hi":0}},"id":0,"args":null}],"tokens":null},"kind":"Glob","span":{"lo":0,"hi":0}}]},"tokens":null},{"attrs":[{"kind":{"variant":"Normal","fields":[{"path":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"macro_use","span":{"lo":0,"hi":0}},"id":0,"args":null}],"tokens":null},"args":"Empty","tokens":null},null]},"id":null,"style":"Outer","span":{"lo":0,"hi":0}}],"id":0,"span":{"lo":0,"hi":0},"vis":{"kind":"Inherited","span":{"lo":0,"hi":0},"tokens":null},"ident":{"name":"std","span":{"lo":0,"hi":0}},"kind":{"variant":"ExternCrate","fields":[null]},"tokens":null},{"attrs":[],"id":0,"span":{"lo":0,"hi":0},"vis":{"kind":"Inherited","span":{"lo":0,"hi":0},"tokens":null},"ident":{"name":"core","span":{"lo":0,"hi":0}},"kind":{"variant":"ExternCrate","fields":[null]},"tokens":null}],"span":{"lo":0,"hi":0},"proc_macros":[]} +{"attrs":[{"kind":{"variant":"Normal","fields":[{"path":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"crate_type","span":{"lo":0,"hi":0}},"id":0,"args":null}],"tokens":null},"args":{"variant":"Eq","fields":[{"lo":0,"hi":0},{"kind":{"variant":"Interpolated","fields":[{"variant":"NtExpr","fields":[{"id":0,"kind":{"variant":"Lit","fields":[{"token":{"kind":"Str","symbol":"lib","suffix":null},"kind":{"variant":"Str","fields":["lib","Cooked"]},"span":{"lo":0,"hi":0}}]},"span":{"lo":0,"hi":0},"attrs":{"0":null},"tokens":{"0":[[{"variant":"Token","fields":[{"kind":{"variant":"Literal","fields":[{"kind":"Str","symbol":"lib","suffix":null}]},"span":{"lo":0,"hi":0}}]},"Alone"]]}}]}]},"span":{"lo":0,"hi":0}}]},"tokens":null},{"0":[[{"variant":"Token","fields":[{"kind":"Pound","span":{"lo":0,"hi":0}}]},"Joint"],[{"variant":"Token","fields":[{"kind":"Not","span":{"lo":0,"hi":0}}]},"Alone"],[{"variant":"Delimited","fields":[{"open":{"lo":0,"hi":0},"close":{"lo":0,"hi":0}},"Bracket",{"0":[[{"variant":"Token","fields":[{"kind":{"variant":"Ident","fields":["crate_type",false]},"span":{"lo":0,"hi":0}}]},"Alone"],[{"variant":"Token","fields":[{"kind":"Eq","span":{"lo":0,"hi":0}}]},"Alone"],[{"variant":"Token","fields":[{"kind":{"variant":"Literal","fields":[{"kind":"Str","symbol":"lib","suffix":null}]},"span":{"lo":0,"hi":0}}]},"Alone"]]}]},"Alone"]]}]},"id":null,"style":"Inner","span":{"lo":0,"hi":0}}],"items":[{"attrs":[{"kind":{"variant":"Normal","fields":[{"path":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"prelude_import","span":{"lo":0,"hi":0}},"id":0,"args":null}],"tokens":null},"args":"Empty","tokens":null},null]},"id":null,"style":"Outer","span":{"lo":0,"hi":0}}],"id":0,"span":{"lo":0,"hi":0},"vis":{"kind":"Inherited","span":{"lo":0,"hi":0},"tokens":null},"ident":{"name":"","span":{"lo":0,"hi":0}},"kind":{"variant":"Use","fields":[{"prefix":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"{{root}}","span":{"lo":0,"hi":0}},"id":0,"args":null},{"ident":{"name":"std","span":{"lo":0,"hi":0}},"id":0,"args":null},{"ident":{"name":"prelude","span":{"lo":0,"hi":0}},"id":0,"args":null},{"ident":{"name":"rust_2015","span":{"lo":0,"hi":0}},"id":0,"args":null}],"tokens":null},"kind":"Glob","span":{"lo":0,"hi":0}}]},"tokens":null},{"attrs":[{"kind":{"variant":"Normal","fields":[{"path":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"macro_use","span":{"lo":0,"hi":0}},"id":0,"args":null}],"tokens":null},"args":"Empty","tokens":null},null]},"id":null,"style":"Outer","span":{"lo":0,"hi":0}}],"id":0,"span":{"lo":0,"hi":0},"vis":{"kind":"Inherited","span":{"lo":0,"hi":0},"tokens":null},"ident":{"name":"std","span":{"lo":0,"hi":0}},"kind":{"variant":"ExternCrate","fields":[null]},"tokens":null},{"attrs":[],"id":0,"span":{"lo":0,"hi":0},"vis":{"kind":"Inherited","span":{"lo":0,"hi":0},"tokens":null},"ident":{"name":"core","span":{"lo":0,"hi":0}},"kind":{"variant":"ExternCrate","fields":[null]},"tokens":null}],"span":{"lo":0,"hi":0}}