From b53dd71faa882b07c7250b2b57bba984746b0cc8 Mon Sep 17 00:00:00 2001 From: Miguel Guarniz Date: Wed, 15 Jun 2022 22:29:59 -0400 Subject: [PATCH 1/7] gather body owners Signed-off-by: Miguel Guarniz --- compiler/rustc_middle/src/hir/map/mod.rs | 110 +++++++++++++++++++---- compiler/rustc_middle/src/hir/mod.rs | 1 + 2 files changed, 95 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 738d47ba2968..9a6ca56bd693 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -493,18 +493,7 @@ impl<'hir> Map<'hir> { /// 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 + 'hir { - self.krate() - .owners - .iter_enumerated() - .flat_map(move |(owner, owner_info)| { - let bodies = &owner_info.as_owner()?.nodes.bodies; - Some(bodies.iter().map(move |&(local_id, _)| { - let hir_id = HirId { owner, local_id }; - let body_id = BodyId { hir_id }; - self.body_owner_def_id(body_id) - })) - }) - .flatten() + self.tcx.hir_crate_items(()).body_owners.iter().copied() } pub fn par_body_owners(self, f: F) { @@ -1239,19 +1228,28 @@ pub(super) fn hir_module_items(tcx: TyCtxt<'_>, module_id: LocalDefId) -> Module trait_items: Vec::default(), impl_items: Vec::default(), foreign_items: Vec::default(), + body_owners: Vec::default(), }; let (hir_mod, span, hir_id) = tcx.hir().get_module(module_id); collector.visit_mod(hir_mod, span, hir_id); - let ModuleCollector { submodules, items, trait_items, impl_items, foreign_items, .. } = - collector; + let ModuleCollector { + submodules, + items, + trait_items, + impl_items, + foreign_items, + body_owners, + .. + } = collector; return ModuleItems { submodules: submodules.into_boxed_slice(), items: items.into_boxed_slice(), trait_items: trait_items.into_boxed_slice(), impl_items: impl_items.into_boxed_slice(), foreign_items: foreign_items.into_boxed_slice(), + body_owners: body_owners.into_boxed_slice(), }; struct ModuleCollector<'tcx> { @@ -1261,6 +1259,7 @@ pub(super) fn hir_module_items(tcx: TyCtxt<'_>, module_id: LocalDefId) -> Module trait_items: Vec, impl_items: Vec, foreign_items: Vec, + body_owners: Vec, } impl<'hir> Visitor<'hir> for ModuleCollector<'hir> { @@ -1271,7 +1270,16 @@ pub(super) fn hir_module_items(tcx: TyCtxt<'_>, module_id: LocalDefId) -> Module } fn visit_item(&mut self, item: &'hir Item<'hir>) { + if associated_body(Node::Item(item)).is_some() { + self.body_owners.push(item.def_id); + } + self.items.push(item.item_id()); + + if self.tcx.hir().is_body_owner(item.def_id) { + self.body_owners.push(item.def_id); + } + if let ItemKind::Mod(..) = item.kind { // If this declares another module, do not recurse inside it. self.submodules.push(item.def_id); @@ -1281,19 +1289,47 @@ pub(super) fn hir_module_items(tcx: TyCtxt<'_>, module_id: LocalDefId) -> Module } fn visit_trait_item(&mut self, item: &'hir TraitItem<'hir>) { + if associated_body(Node::TraitItem(item)).is_some() { + self.body_owners.push(item.def_id); + } + self.trait_items.push(item.trait_item_id()); intravisit::walk_trait_item(self, item) } fn visit_impl_item(&mut self, item: &'hir ImplItem<'hir>) { + if associated_body(Node::ImplItem(item)).is_some() { + self.body_owners.push(item.def_id); + } + self.impl_items.push(item.impl_item_id()); intravisit::walk_impl_item(self, item) } fn visit_foreign_item(&mut self, item: &'hir ForeignItem<'hir>) { + if associated_body(Node::ForeignItem(item)).is_some() { + self.body_owners.push(item.def_id); + } + self.foreign_items.push(item.foreign_item_id()); intravisit::walk_foreign_item(self, item) } + + fn visit_expr(&mut self, ex: &'hir Expr<'hir>) { + if matches!(ex.kind, ExprKind::Closure { .. }) + && associated_body(Node::Expr(ex)).is_some() + { + self.body_owners.push(ex.hir_id.owner); + } + intravisit::walk_expr(self, ex) + } + + fn visit_anon_const(&mut self, c: &'hir AnonConst) { + if associated_body(Node::AnonConst(c)).is_some() { + self.body_owners.push(c.hir_id.owner); + } + intravisit::walk_anon_const(self, c) + } } } @@ -1305,12 +1341,20 @@ pub(crate) fn hir_crate_items(tcx: TyCtxt<'_>, _: ()) -> ModuleItems { trait_items: Vec::default(), impl_items: Vec::default(), foreign_items: Vec::default(), + body_owners: Vec::default(), }; tcx.hir().walk_toplevel_module(&mut collector); - let CrateCollector { submodules, items, trait_items, impl_items, foreign_items, .. } = - collector; + let CrateCollector { + submodules, + items, + trait_items, + impl_items, + foreign_items, + body_owners, + .. + } = collector; return ModuleItems { submodules: submodules.into_boxed_slice(), @@ -1318,6 +1362,7 @@ pub(crate) fn hir_crate_items(tcx: TyCtxt<'_>, _: ()) -> ModuleItems { trait_items: trait_items.into_boxed_slice(), impl_items: impl_items.into_boxed_slice(), foreign_items: foreign_items.into_boxed_slice(), + body_owners: body_owners.into_boxed_slice(), }; struct CrateCollector<'tcx> { @@ -1327,6 +1372,7 @@ pub(crate) fn hir_crate_items(tcx: TyCtxt<'_>, _: ()) -> ModuleItems { trait_items: Vec, impl_items: Vec, foreign_items: Vec, + body_owners: Vec, } impl<'hir> Visitor<'hir> for CrateCollector<'hir> { @@ -1337,6 +1383,10 @@ pub(crate) fn hir_crate_items(tcx: TyCtxt<'_>, _: ()) -> ModuleItems { } fn visit_item(&mut self, item: &'hir Item<'hir>) { + if associated_body(Node::Item(item)).is_some() { + self.body_owners.push(item.def_id); + } + self.items.push(item.item_id()); intravisit::walk_item(self, item) } @@ -1347,18 +1397,46 @@ pub(crate) fn hir_crate_items(tcx: TyCtxt<'_>, _: ()) -> ModuleItems { } fn visit_foreign_item(&mut self, item: &'hir ForeignItem<'hir>) { + if associated_body(Node::ForeignItem(item)).is_some() { + self.body_owners.push(item.def_id); + } + self.foreign_items.push(item.foreign_item_id()); intravisit::walk_foreign_item(self, item) } fn visit_trait_item(&mut self, item: &'hir TraitItem<'hir>) { + if associated_body(Node::TraitItem(item)).is_some() { + self.body_owners.push(item.def_id); + } + self.trait_items.push(item.trait_item_id()); intravisit::walk_trait_item(self, item) } fn visit_impl_item(&mut self, item: &'hir ImplItem<'hir>) { + if associated_body(Node::ImplItem(item)).is_some() { + self.body_owners.push(item.def_id); + } + self.impl_items.push(item.impl_item_id()); intravisit::walk_impl_item(self, item) } + + fn visit_expr(&mut self, ex: &'hir Expr<'hir>) { + if matches!(ex.kind, ExprKind::Closure { .. }) + && associated_body(Node::Expr(ex)).is_some() + { + self.body_owners.push(ex.hir_id.owner); + } + intravisit::walk_expr(self, ex) + } + + fn visit_anon_const(&mut self, c: &'hir AnonConst) { + if associated_body(Node::AnonConst(c)).is_some() { + self.body_owners.push(c.hir_id.owner); + } + intravisit::walk_anon_const(self, c) + } } } diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index 09b142e0c415..87c6f05414a7 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -43,6 +43,7 @@ pub struct ModuleItems { trait_items: Box<[TraitItemId]>, impl_items: Box<[ImplItemId]>, foreign_items: Box<[ForeignItemId]>, + body_owners: Box<[LocalDefId]>, } impl ModuleItems { From 01a957e92ac1c0ddd06a26d8af1d273f9b27d742 Mon Sep 17 00:00:00 2001 From: Miguel Guarniz Date: Wed, 22 Jun 2022 12:53:18 -0400 Subject: [PATCH 2/7] record LocalDefId of closure Signed-off-by: Miguel Guarniz --- compiler/rustc_middle/src/hir/map/mod.rs | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 9a6ca56bd693..ff71d16f83b3 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -1276,10 +1276,6 @@ pub(super) fn hir_module_items(tcx: TyCtxt<'_>, module_id: LocalDefId) -> Module self.items.push(item.item_id()); - if self.tcx.hir().is_body_owner(item.def_id) { - self.body_owners.push(item.def_id); - } - if let ItemKind::Mod(..) = item.kind { // If this declares another module, do not recurse inside it. self.submodules.push(item.def_id); @@ -1319,14 +1315,14 @@ pub(super) fn hir_module_items(tcx: TyCtxt<'_>, module_id: LocalDefId) -> Module if matches!(ex.kind, ExprKind::Closure { .. }) && associated_body(Node::Expr(ex)).is_some() { - self.body_owners.push(ex.hir_id.owner); + self.body_owners.push(self.tcx.hir().local_def_id(ex.hir_id)); } intravisit::walk_expr(self, ex) } fn visit_anon_const(&mut self, c: &'hir AnonConst) { if associated_body(Node::AnonConst(c)).is_some() { - self.body_owners.push(c.hir_id.owner); + self.body_owners.push(self.tcx.hir().local_def_id(c.hir_id)); } intravisit::walk_anon_const(self, c) } @@ -1427,14 +1423,14 @@ pub(crate) fn hir_crate_items(tcx: TyCtxt<'_>, _: ()) -> ModuleItems { if matches!(ex.kind, ExprKind::Closure { .. }) && associated_body(Node::Expr(ex)).is_some() { - self.body_owners.push(ex.hir_id.owner); + self.body_owners.push(self.tcx.hir().local_def_id(ex.hir_id)); } intravisit::walk_expr(self, ex) } fn visit_anon_const(&mut self, c: &'hir AnonConst) { if associated_body(Node::AnonConst(c)).is_some() { - self.body_owners.push(c.hir_id.owner); + self.body_owners.push(self.tcx.hir().local_def_id(c.hir_id)); } intravisit::walk_anon_const(self, c) } From e11862f811990cda65dceab96adc67c3a2096aa5 Mon Sep 17 00:00:00 2001 From: Miguel Guarniz Date: Wed, 22 Jun 2022 12:53:36 -0400 Subject: [PATCH 3/7] update test Signed-off-by: Miguel Guarniz --- .../const-extern-fn-requires-unsafe.mir.stderr | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) 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 4cd0fd2eaf76..34ec8aadbcf3 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:9:17 + --> $DIR/const-extern-fn-requires-unsafe.rs:12: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 error[E0133]: call to unsafe function is unsafe and requires unsafe function or block - --> $DIR/const-extern-fn-requires-unsafe.rs:12: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 From c6e7c0514f5b581fc5f6fcebcb803a28f7b51551 Mon Sep 17 00:00:00 2001 From: Miguel Guarniz Date: Wed, 22 Jun 2022 19:12:18 -0400 Subject: [PATCH 4/7] use gathered body_owners in par_body_owners Signed-off-by: Miguel Guarniz --- compiler/rustc_middle/src/hir/map/mod.rs | 15 +---- src/test/ui/asm/type-check-1.stderr | 54 ++++++++--------- .../const-arg-in-const-arg.full.stderr | 48 +++++++-------- .../const-arg-in-const-arg.min.stderr | 60 +++++++++---------- src/test/ui/issues/issue-47486.stderr | 12 ++-- ...use_of_moved_value_copy_suggestions.stderr | 28 ++++----- .../ui/proc-macro/attribute-with-error.stderr | 16 ++--- src/test/ui/repeat-expr/repeat_count.stderr | 12 ++-- .../impl-trait-with-missing-bounds.stderr | 38 ++++++------ .../ui/suggestions/suggest-ref-macro.stderr | 44 +++++++------- .../union-derive-clone.mirunsafeck.stderr | 34 +++++------ .../union-derive-clone.thirunsafeck.stderr | 34 +++++------ 12 files changed, 192 insertions(+), 203 deletions(-) diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index ff71d16f83b3..eef639e1589d 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -498,19 +498,8 @@ impl<'hir> Map<'hir> { pub fn par_body_owners(self, f: F) { use rustc_data_structures::sync::{par_iter, ParallelIterator}; - #[cfg(parallel_compiler)] - use rustc_rayon::iter::IndexedParallelIterator; - - par_iter(&self.krate().owners.raw).enumerate().for_each(|(owner, owner_info)| { - let owner = LocalDefId::new(owner); - if let MaybeOwner::Owner(owner_info) = owner_info { - par_iter(owner_info.nodes.bodies.range(..)).for_each(|(local_id, _)| { - let hir_id = HirId { owner, local_id: *local_id }; - let body_id = BodyId { hir_id }; - f(self.body_owner_def_id(body_id)) - }) - } - }); + + par_iter(&self.tcx.hir_crate_items(()).body_owners[..]).for_each(|&def_id| f(def_id)); } pub fn ty_param_owner(self, def_id: LocalDefId) -> LocalDefId { diff --git a/src/test/ui/asm/type-check-1.stderr b/src/test/ui/asm/type-check-1.stderr index 5a997b47d73e..162ff1d32bc4 100644 --- a/src/test/ui/asm/type-check-1.stderr +++ b/src/test/ui/asm/type-check-1.stderr @@ -33,33 +33,6 @@ LL | asm!("{}", sym x); | = help: `sym` operands must refer to either a function or a static -error[E0308]: mismatched types - --> $DIR/type-check-1.rs:58:26 - | -LL | asm!("{}", const 0f32); - | ^^^^ expected integer, found `f32` - -error[E0308]: mismatched types - --> $DIR/type-check-1.rs:60: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:62:26 - | -LL | asm!("{}", const &0); - | ^^ expected integer, found `&{integer}` - | -help: consider removing the borrow - | -LL - asm!("{}", const &0); -LL + asm!("{}", const 0); - | - error: invalid asm output --> $DIR/type-check-1.rs:15:29 | @@ -123,6 +96,33 @@ LL | asm!("{}", inout(reg) v[..]); | = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly +error[E0308]: mismatched types + --> $DIR/type-check-1.rs:58:26 + | +LL | asm!("{}", const 0f32); + | ^^^^ expected integer, found `f32` + +error[E0308]: mismatched types + --> $DIR/type-check-1.rs:60: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:62:26 + | +LL | asm!("{}", const &0); + | ^^ expected integer, found `&{integer}` + | +help: consider removing the borrow + | +LL - asm!("{}", const &0); +LL + asm!("{}", const 0); + | + error[E0308]: mismatched types --> $DIR/type-check-1.rs:76:25 | diff --git a/src/test/ui/const-generics/const-arg-in-const-arg.full.stderr b/src/test/ui/const-generics/const-arg-in-const-arg.full.stderr index dbbdb2a0ce33..8672e79b3e8c 100644 --- a/src/test/ui/const-generics/const-arg-in-const-arg.full.stderr +++ b/src/test/ui/const-generics/const-arg-in-const-arg.full.stderr @@ -22,30 +22,6 @@ note: the late bound lifetime parameter is introduced here LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } | ^^ -error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/const-arg-in-const-arg.rs:30:23 - | -LL | let _ = [0; faz::<'a>(&())]; - | ^^ - | -note: the late bound lifetime parameter is introduced here - --> $DIR/const-arg-in-const-arg.rs:8:14 - | -LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } - | ^^ - -error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/const-arg-in-const-arg.rs:33:23 - | -LL | let _ = [0; faz::<'b>(&())]; - | ^^ - | -note: the late bound lifetime parameter is introduced here - --> $DIR/const-arg-in-const-arg.rs:8:14 - | -LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } - | ^^ - error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present --> $DIR/const-arg-in-const-arg.rs:41:24 | @@ -118,6 +94,30 @@ LL | let _ = [0; bar::()]; | = help: try adding a `where` bound using this expression: `where [(); bar::()]:` +error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present + --> $DIR/const-arg-in-const-arg.rs:30:23 + | +LL | let _ = [0; faz::<'a>(&())]; + | ^^ + | +note: the late bound lifetime parameter is introduced here + --> $DIR/const-arg-in-const-arg.rs:8:14 + | +LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } + | ^^ + +error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present + --> $DIR/const-arg-in-const-arg.rs:33:23 + | +LL | let _ = [0; faz::<'b>(&())]; + | ^^ + | +note: the late bound lifetime parameter is introduced here + --> $DIR/const-arg-in-const-arg.rs:8:14 + | +LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } + | ^^ + error: unconstrained generic constant --> $DIR/const-arg-in-const-arg.rs:47:19 | diff --git a/src/test/ui/const-generics/const-arg-in-const-arg.min.stderr b/src/test/ui/const-generics/const-arg-in-const-arg.min.stderr index 6ca9a2a48592..f1353aa99437 100644 --- a/src/test/ui/const-generics/const-arg-in-const-arg.min.stderr +++ b/src/test/ui/const-generics/const-arg-in-const-arg.min.stderr @@ -241,21 +241,21 @@ LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } | ^^ error[E0747]: unresolved item provided when a constant was expected - --> $DIR/const-arg-in-const-arg.rs:27:23 + --> $DIR/const-arg-in-const-arg.rs:38:24 | -LL | let _ = [0; bar::()]; - | ^ +LL | let _: Foo<{ bar::() }>; + | ^ | help: if this generic argument was intended as a const parameter, surround it with braces | -LL | let _ = [0; bar::<{ N }>()]; - | + + +LL | let _: Foo<{ bar::<{ N }>() }>; + | + + error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/const-arg-in-const-arg.rs:30:23 + --> $DIR/const-arg-in-const-arg.rs:41:24 | -LL | let _ = [0; faz::<'a>(&())]; - | ^^ +LL | let _: Foo<{ faz::<'a>(&()) }>; + | ^^ | note: the late bound lifetime parameter is introduced here --> $DIR/const-arg-in-const-arg.rs:8:14 @@ -264,10 +264,10 @@ LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } | ^^ error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/const-arg-in-const-arg.rs:33:23 + --> $DIR/const-arg-in-const-arg.rs:44:24 | -LL | let _ = [0; faz::<'b>(&())]; - | ^^ +LL | let _: Foo<{ faz::<'b>(&()) }>; + | ^^ | note: the late bound lifetime parameter is introduced here --> $DIR/const-arg-in-const-arg.rs:8:14 @@ -275,22 +275,30 @@ note: the late bound lifetime parameter is introduced here LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } | ^^ +error: constant expression depends on a generic parameter + --> $DIR/const-arg-in-const-arg.rs:25:17 + | +LL | let _ = [0; foo::()]; + | ^^^^^^^^^^ + | + = note: this may fail depending on what value the parameter takes + error[E0747]: unresolved item provided when a constant was expected - --> $DIR/const-arg-in-const-arg.rs:38:24 + --> $DIR/const-arg-in-const-arg.rs:27:23 | -LL | let _: Foo<{ bar::() }>; - | ^ +LL | let _ = [0; bar::()]; + | ^ | help: if this generic argument was intended as a const parameter, surround it with braces | -LL | let _: Foo<{ bar::<{ N }>() }>; - | + + +LL | let _ = [0; bar::<{ N }>()]; + | + + error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/const-arg-in-const-arg.rs:41:24 + --> $DIR/const-arg-in-const-arg.rs:30:23 | -LL | let _: Foo<{ faz::<'a>(&()) }>; - | ^^ +LL | let _ = [0; faz::<'a>(&())]; + | ^^ | note: the late bound lifetime parameter is introduced here --> $DIR/const-arg-in-const-arg.rs:8:14 @@ -299,10 +307,10 @@ LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } | ^^ error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/const-arg-in-const-arg.rs:44:24 + --> $DIR/const-arg-in-const-arg.rs:33:23 | -LL | let _: Foo<{ faz::<'b>(&()) }>; - | ^^ +LL | let _ = [0; faz::<'b>(&())]; + | ^^ | note: the late bound lifetime parameter is introduced here --> $DIR/const-arg-in-const-arg.rs:8:14 @@ -310,14 +318,6 @@ note: the late bound lifetime parameter is introduced here LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } | ^^ -error: constant expression depends on a generic parameter - --> $DIR/const-arg-in-const-arg.rs:25:17 - | -LL | let _ = [0; foo::()]; - | ^^^^^^^^^^ - | - = note: this may fail depending on what value the parameter takes - error[E0747]: unresolved item provided when a constant was expected --> $DIR/const-arg-in-const-arg.rs:49:27 | diff --git a/src/test/ui/issues/issue-47486.stderr b/src/test/ui/issues/issue-47486.stderr index ca57b2d7e01d..b45f57b7b846 100644 --- a/src/test/ui/issues/issue-47486.stderr +++ b/src/test/ui/issues/issue-47486.stderr @@ -1,3 +1,9 @@ +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 | @@ -9,12 +15,6 @@ help: consider specifying the generic argument LL | [0u8; std::mem::size_of::<_>()]; | ~~~~~ -error[E0308]: mismatched types - --> $DIR/issue-47486.rs:2:10 - | -LL | () < std::mem::size_of::<_>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found `usize` - error: aborting due to 2 previous errors Some errors have detailed explanations: E0282, E0308. diff --git a/src/test/ui/moves/use_of_moved_value_copy_suggestions.stderr b/src/test/ui/moves/use_of_moved_value_copy_suggestions.stderr index 5a84e3b81a65..3e37fcb2141f 100644 --- a/src/test/ui/moves/use_of_moved_value_copy_suggestions.stderr +++ b/src/test/ui/moves/use_of_moved_value_copy_suggestions.stderr @@ -143,36 +143,36 @@ LL | fn duplicate_custom_4(t: S) -> (S, S) | ++++++++++++++ error[E0382]: use of moved value: `t` - --> $DIR/use_of_moved_value_copy_suggestions.rs:83:9 + --> $DIR/use_of_moved_value_copy_suggestions.rs:75:9 | -LL | fn existing_colon_in_where(t: T) - | - move occurs because `t` has type `T`, which does not implement the `Copy` trait -... +LL | fn existing_colon(t: T) { + | - move occurs because `t` has type `T`, which does not implement the `Copy` trait +LL | LL | [t, t]; | - ^ value used here after move | | | value moved here | -help: consider further restricting type parameter `T` +help: consider restricting type parameter `T` | -LL | T:, T: Copy - | ~~~~~~~~~ +LL | fn existing_colon(t: T) { + | ++++ error[E0382]: use of moved value: `t` - --> $DIR/use_of_moved_value_copy_suggestions.rs:75:9 + --> $DIR/use_of_moved_value_copy_suggestions.rs:83:9 | -LL | fn existing_colon(t: T) { - | - move occurs because `t` has type `T`, which does not implement the `Copy` trait -LL | +LL | fn existing_colon_in_where(t: T) + | - move occurs because `t` has type `T`, which does not implement the `Copy` trait +... LL | [t, t]; | - ^ value used here after move | | | value moved here | -help: consider restricting type parameter `T` +help: consider further restricting type parameter `T` | -LL | fn existing_colon(t: T) { - | ++++ +LL | T:, T: Copy + | ~~~~~~~~~ error: aborting due to 11 previous errors diff --git a/src/test/ui/proc-macro/attribute-with-error.stderr b/src/test/ui/proc-macro/attribute-with-error.stderr index 127c49957c1e..7f3a7e670b9b 100644 --- a/src/test/ui/proc-macro/attribute-with-error.stderr +++ b/src/test/ui/proc-macro/attribute-with-error.stderr @@ -1,11 +1,3 @@ -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 | @@ -22,6 +14,14 @@ 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-expr/repeat_count.stderr b/src/test/ui/repeat-expr/repeat_count.stderr index 59bcd954a1fd..e222c141f8b6 100644 --- a/src/test/ui/repeat-expr/repeat_count.stderr +++ b/src/test/ui/repeat-expr/repeat_count.stderr @@ -30,6 +30,12 @@ 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 | @@ -57,12 +63,6 @@ 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 229c4b824f27..a763eb6f2f85 100644 --- a/src/test/ui/suggestions/impl-trait-with-missing-bounds.stderr +++ b/src/test/ui/suggestions/impl-trait-with-missing-bounds.stderr @@ -1,3 +1,22 @@ +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` + | | + | required by a bound introduced by this call + | + = 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 | @@ -74,25 +93,6 @@ 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` - | | - | required by a bound introduced by this call - | - = 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 b0ac770c06f0..84cbc93571a7 100644 --- a/src/test/ui/suggestions/suggest-ref-macro.stderr +++ b/src/test/ui/suggestions/suggest-ref-macro.stderr @@ -1,3 +1,25 @@ +error[E0308]: mismatched types + --> $DIR/suggest-ref-macro.rs:8:1 + | +LL | #[hello] + | ^^^^^^^^ + | | + | expected `&mut i32`, found integer + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/suggest-ref-macro.rs:8:1 + | +LL | #[hello] + | _-^^^^^^^ +LL | | fn abc() {} +LL | | +LL | | fn x(_: &mut i32) {} +LL | | +LL | | macro_rules! bla { + | |_____________- + = 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 | @@ -36,28 +58,6 @@ note: function defined here LL | fn x(_: &mut i32) {} | ^ ----------- -error[E0308]: mismatched types - --> $DIR/suggest-ref-macro.rs:8:1 - | -LL | #[hello] - | ^^^^^^^^ - | | - | expected `&mut i32`, found integer - | arguments to this function are incorrect - | -note: function defined here - --> $DIR/suggest-ref-macro.rs:8:1 - | -LL | #[hello] - | _-^^^^^^^ -LL | | fn abc() {} -LL | | -LL | | fn x(_: &mut i32) {} -LL | | -LL | | macro_rules! bla { - | |_____________- - = 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 c242a7de7abf..11650a28563c 100644 --- a/src/test/ui/union/union-derive-clone.mirunsafeck.stderr +++ b/src/test/ui/union/union-derive-clone.mirunsafeck.stderr @@ -1,3 +1,20 @@ +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) +help: consider annotating `U1` with `#[derive(Copy)]` + | +LL | #[derive(Copy)] + | + error[E0599]: the method `clone` exists for union `U5`, but its trait bounds were not satisfied --> $DIR/union-derive-clone.rs:38:15 | @@ -26,23 +43,6 @@ help: consider annotating `CloneNoCopy` with `#[derive(Clone, Copy)]` LL | #[derive(Clone, Copy)] | -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) -help: consider annotating `U1` with `#[derive(Copy)]` - | -LL | #[derive(Copy)] - | - 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 c242a7de7abf..11650a28563c 100644 --- a/src/test/ui/union/union-derive-clone.thirunsafeck.stderr +++ b/src/test/ui/union/union-derive-clone.thirunsafeck.stderr @@ -1,3 +1,20 @@ +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) +help: consider annotating `U1` with `#[derive(Copy)]` + | +LL | #[derive(Copy)] + | + error[E0599]: the method `clone` exists for union `U5`, but its trait bounds were not satisfied --> $DIR/union-derive-clone.rs:38:15 | @@ -26,23 +43,6 @@ help: consider annotating `CloneNoCopy` with `#[derive(Clone, Copy)]` LL | #[derive(Clone, Copy)] | -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) -help: consider annotating `U1` with `#[derive(Copy)]` - | -LL | #[derive(Copy)] - | - error: aborting due to 2 previous errors Some errors have detailed explanations: E0277, E0599. From b599cf45d6119164bf7adc740c0c81dad2b73c1a Mon Sep 17 00:00:00 2001 From: Miguel Guarniz Date: Wed, 6 Jul 2022 18:23:38 -0400 Subject: [PATCH 5/7] inline associated_body Signed-off-by: Miguel Guarniz --- compiler/rustc_middle/src/hir/map/mod.rs | 25 +++++------------------- 1 file changed, 5 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index eef639e1589d..3240360a5398 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -39,6 +39,7 @@ pub fn fn_sig<'hir>(node: Node<'hir>) -> Option<&'hir FnSig<'hir>> { } } +#[inline] pub fn associated_body<'hir>(node: Node<'hir>) -> Option { match node { Node::Item(Item { @@ -1292,27 +1293,19 @@ pub(super) fn hir_module_items(tcx: TyCtxt<'_>, module_id: LocalDefId) -> Module } fn visit_foreign_item(&mut self, item: &'hir ForeignItem<'hir>) { - if associated_body(Node::ForeignItem(item)).is_some() { - self.body_owners.push(item.def_id); - } - self.foreign_items.push(item.foreign_item_id()); intravisit::walk_foreign_item(self, item) } fn visit_expr(&mut self, ex: &'hir Expr<'hir>) { - if matches!(ex.kind, ExprKind::Closure { .. }) - && associated_body(Node::Expr(ex)).is_some() - { + if matches!(ex.kind, ExprKind::Closure { .. }) { self.body_owners.push(self.tcx.hir().local_def_id(ex.hir_id)); } intravisit::walk_expr(self, ex) } fn visit_anon_const(&mut self, c: &'hir AnonConst) { - if associated_body(Node::AnonConst(c)).is_some() { - self.body_owners.push(self.tcx.hir().local_def_id(c.hir_id)); - } + self.body_owners.push(self.tcx.hir().local_def_id(c.hir_id)); intravisit::walk_anon_const(self, c) } } @@ -1382,10 +1375,6 @@ pub(crate) fn hir_crate_items(tcx: TyCtxt<'_>, _: ()) -> ModuleItems { } fn visit_foreign_item(&mut self, item: &'hir ForeignItem<'hir>) { - if associated_body(Node::ForeignItem(item)).is_some() { - self.body_owners.push(item.def_id); - } - self.foreign_items.push(item.foreign_item_id()); intravisit::walk_foreign_item(self, item) } @@ -1409,18 +1398,14 @@ pub(crate) fn hir_crate_items(tcx: TyCtxt<'_>, _: ()) -> ModuleItems { } fn visit_expr(&mut self, ex: &'hir Expr<'hir>) { - if matches!(ex.kind, ExprKind::Closure { .. }) - && associated_body(Node::Expr(ex)).is_some() - { + if matches!(ex.kind, ExprKind::Closure { .. }) { self.body_owners.push(self.tcx.hir().local_def_id(ex.hir_id)); } intravisit::walk_expr(self, ex) } fn visit_anon_const(&mut self, c: &'hir AnonConst) { - if associated_body(Node::AnonConst(c)).is_some() { - self.body_owners.push(self.tcx.hir().local_def_id(c.hir_id)); - } + self.body_owners.push(self.tcx.hir().local_def_id(c.hir_id)); intravisit::walk_anon_const(self, c) } } From 275497c35e00bcf6b7766c8d1cb6540caa8a4baf Mon Sep 17 00:00:00 2001 From: Miguel Guarniz Date: Wed, 6 Jul 2022 19:13:49 -0400 Subject: [PATCH 6/7] merge visitors in queries Signed-off-by: Miguel Guarniz --- compiler/rustc_middle/src/hir/map/mod.rs | 210 ++++++++--------------- 1 file changed, 75 insertions(+), 135 deletions(-) diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 3240360a5398..1ce7668e7b76 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -1211,20 +1211,12 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String { } pub(super) fn hir_module_items(tcx: TyCtxt<'_>, module_id: LocalDefId) -> ModuleItems { - let mut collector = ModuleCollector { - tcx, - submodules: Vec::default(), - items: Vec::default(), - trait_items: Vec::default(), - impl_items: Vec::default(), - foreign_items: Vec::default(), - body_owners: Vec::default(), - }; + let mut collector = ItemCollector::new(tcx, false); let (hir_mod, span, hir_id) = tcx.hir().get_module(module_id); collector.visit_mod(hir_mod, span, hir_id); - let ModuleCollector { + let ItemCollector { submodules, items, trait_items, @@ -1241,90 +1233,14 @@ pub(super) fn hir_module_items(tcx: TyCtxt<'_>, module_id: LocalDefId) -> Module foreign_items: foreign_items.into_boxed_slice(), body_owners: body_owners.into_boxed_slice(), }; - - struct ModuleCollector<'tcx> { - tcx: TyCtxt<'tcx>, - submodules: Vec, - items: Vec, - trait_items: Vec, - impl_items: Vec, - foreign_items: Vec, - body_owners: Vec, - } - - impl<'hir> Visitor<'hir> for ModuleCollector<'hir> { - type NestedFilter = nested_filter::All; - - fn nested_visit_map(&mut self) -> Self::Map { - self.tcx.hir() - } - - fn visit_item(&mut self, item: &'hir Item<'hir>) { - if associated_body(Node::Item(item)).is_some() { - self.body_owners.push(item.def_id); - } - - self.items.push(item.item_id()); - - if let ItemKind::Mod(..) = item.kind { - // If this declares another module, do not recurse inside it. - self.submodules.push(item.def_id); - } else { - intravisit::walk_item(self, item) - } - } - - fn visit_trait_item(&mut self, item: &'hir TraitItem<'hir>) { - if associated_body(Node::TraitItem(item)).is_some() { - self.body_owners.push(item.def_id); - } - - self.trait_items.push(item.trait_item_id()); - intravisit::walk_trait_item(self, item) - } - - fn visit_impl_item(&mut self, item: &'hir ImplItem<'hir>) { - if associated_body(Node::ImplItem(item)).is_some() { - self.body_owners.push(item.def_id); - } - - self.impl_items.push(item.impl_item_id()); - intravisit::walk_impl_item(self, item) - } - - fn visit_foreign_item(&mut self, item: &'hir ForeignItem<'hir>) { - self.foreign_items.push(item.foreign_item_id()); - intravisit::walk_foreign_item(self, item) - } - - fn visit_expr(&mut self, ex: &'hir Expr<'hir>) { - if matches!(ex.kind, ExprKind::Closure { .. }) { - self.body_owners.push(self.tcx.hir().local_def_id(ex.hir_id)); - } - intravisit::walk_expr(self, ex) - } - - fn visit_anon_const(&mut self, c: &'hir AnonConst) { - self.body_owners.push(self.tcx.hir().local_def_id(c.hir_id)); - intravisit::walk_anon_const(self, c) - } - } } pub(crate) fn hir_crate_items(tcx: TyCtxt<'_>, _: ()) -> ModuleItems { - let mut collector = CrateCollector { - tcx, - submodules: Vec::default(), - items: Vec::default(), - trait_items: Vec::default(), - impl_items: Vec::default(), - foreign_items: Vec::default(), - body_owners: Vec::default(), - }; + let mut collector = ItemCollector::new(tcx, true); tcx.hir().walk_toplevel_module(&mut collector); - let CrateCollector { + let ItemCollector { submodules, items, trait_items, @@ -1342,71 +1258,95 @@ pub(crate) fn hir_crate_items(tcx: TyCtxt<'_>, _: ()) -> ModuleItems { foreign_items: foreign_items.into_boxed_slice(), body_owners: body_owners.into_boxed_slice(), }; +} - struct CrateCollector<'tcx> { - tcx: TyCtxt<'tcx>, - submodules: Vec, - items: Vec, - trait_items: Vec, - impl_items: Vec, - foreign_items: Vec, - body_owners: Vec, +struct ItemCollector<'tcx> { + // When true, it collects all items in the create, + // otherwise it collects items in some module. + crate_collector: bool, + tcx: TyCtxt<'tcx>, + submodules: Vec, + items: Vec, + trait_items: Vec, + impl_items: Vec, + foreign_items: Vec, + body_owners: Vec, +} + +impl<'tcx> ItemCollector<'tcx> { + fn new(tcx: TyCtxt<'tcx>, crate_collector: bool) -> ItemCollector<'tcx> { + ItemCollector { + crate_collector, + tcx, + submodules: Vec::default(), + items: Vec::default(), + trait_items: Vec::default(), + impl_items: Vec::default(), + foreign_items: Vec::default(), + body_owners: Vec::default(), + } } +} + +impl<'hir> Visitor<'hir> for ItemCollector<'hir> { + type NestedFilter = nested_filter::All; - impl<'hir> Visitor<'hir> for CrateCollector<'hir> { - type NestedFilter = nested_filter::All; + fn nested_visit_map(&mut self) -> Self::Map { + self.tcx.hir() + } - fn nested_visit_map(&mut self) -> Self::Map { - self.tcx.hir() + fn visit_item(&mut self, item: &'hir Item<'hir>) { + if associated_body(Node::Item(item)).is_some() { + self.body_owners.push(item.def_id); } - fn visit_item(&mut self, item: &'hir Item<'hir>) { - if associated_body(Node::Item(item)).is_some() { - self.body_owners.push(item.def_id); - } + self.items.push(item.item_id()); - self.items.push(item.item_id()); + if !self.crate_collector && let ItemKind::Mod(..) = item.kind { + // If this declares another module, do not recurse inside it. + self.submodules.push(item.def_id); + } else { intravisit::walk_item(self, item) } + } - fn visit_mod(&mut self, m: &'hir Mod<'hir>, _s: Span, n: HirId) { - self.submodules.push(n.owner); - intravisit::walk_mod(self, m, n); - } + fn visit_mod(&mut self, m: &'hir Mod<'hir>, _s: Span, n: HirId) { + self.submodules.push(n.owner); + intravisit::walk_mod(self, m, n); + } - fn visit_foreign_item(&mut self, item: &'hir ForeignItem<'hir>) { - self.foreign_items.push(item.foreign_item_id()); - intravisit::walk_foreign_item(self, item) - } + fn visit_foreign_item(&mut self, item: &'hir ForeignItem<'hir>) { + self.foreign_items.push(item.foreign_item_id()); + intravisit::walk_foreign_item(self, item) + } - fn visit_trait_item(&mut self, item: &'hir TraitItem<'hir>) { - if associated_body(Node::TraitItem(item)).is_some() { - self.body_owners.push(item.def_id); - } + fn visit_anon_const(&mut self, c: &'hir AnonConst) { + self.body_owners.push(self.tcx.hir().local_def_id(c.hir_id)); + intravisit::walk_anon_const(self, c) + } - self.trait_items.push(item.trait_item_id()); - intravisit::walk_trait_item(self, item) + fn visit_expr(&mut self, ex: &'hir Expr<'hir>) { + if matches!(ex.kind, ExprKind::Closure { .. }) { + self.body_owners.push(self.tcx.hir().local_def_id(ex.hir_id)); } + intravisit::walk_expr(self, ex) + } - fn visit_impl_item(&mut self, item: &'hir ImplItem<'hir>) { - if associated_body(Node::ImplItem(item)).is_some() { - self.body_owners.push(item.def_id); - } - - self.impl_items.push(item.impl_item_id()); - intravisit::walk_impl_item(self, item) + fn visit_trait_item(&mut self, item: &'hir TraitItem<'hir>) { + if associated_body(Node::TraitItem(item)).is_some() { + self.body_owners.push(item.def_id); } - fn visit_expr(&mut self, ex: &'hir Expr<'hir>) { - if matches!(ex.kind, ExprKind::Closure { .. }) { - self.body_owners.push(self.tcx.hir().local_def_id(ex.hir_id)); - } - intravisit::walk_expr(self, ex) - } + self.trait_items.push(item.trait_item_id()); + intravisit::walk_trait_item(self, item) + } - fn visit_anon_const(&mut self, c: &'hir AnonConst) { - self.body_owners.push(self.tcx.hir().local_def_id(c.hir_id)); - intravisit::walk_anon_const(self, c) + fn visit_impl_item(&mut self, item: &'hir ImplItem<'hir>) { + if associated_body(Node::ImplItem(item)).is_some() { + self.body_owners.push(item.def_id); } + + self.impl_items.push(item.impl_item_id()); + intravisit::walk_impl_item(self, item) } } From 2d265b6f7572efc77705f139ea1fb5e2089d2a9c Mon Sep 17 00:00:00 2001 From: Miguel Guarniz Date: Wed, 13 Jul 2022 13:25:53 -0400 Subject: [PATCH 7/7] collect module item-likes in visit_items Signed-off-by: Miguel Guarniz --- compiler/rustc_middle/src/hir/map/mod.rs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 1ce7668e7b76..56cefe7e9fac 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -1238,6 +1238,10 @@ pub(super) fn hir_module_items(tcx: TyCtxt<'_>, module_id: LocalDefId) -> Module pub(crate) fn hir_crate_items(tcx: TyCtxt<'_>, _: ()) -> ModuleItems { let mut collector = ItemCollector::new(tcx, true); + // A "crate collector" and "module collector" start at a + // module item (the former starts at the crate root) but only + // the former needs to collect it. ItemCollector does not do this for us. + collector.submodules.push(CRATE_DEF_ID); tcx.hir().walk_toplevel_module(&mut collector); let ItemCollector { @@ -1302,19 +1306,18 @@ impl<'hir> Visitor<'hir> for ItemCollector<'hir> { self.items.push(item.item_id()); - if !self.crate_collector && let ItemKind::Mod(..) = item.kind { - // If this declares another module, do not recurse inside it. + // Items that are modules are handled here instead of in visit_mod. + if let ItemKind::Mod(module) = &item.kind { self.submodules.push(item.def_id); + // A module collector does not recurse inside nested modules. + if self.crate_collector { + intravisit::walk_mod(self, module, item.hir_id()); + } } else { intravisit::walk_item(self, item) } } - fn visit_mod(&mut self, m: &'hir Mod<'hir>, _s: Span, n: HirId) { - self.submodules.push(n.owner); - intravisit::walk_mod(self, m, n); - } - fn visit_foreign_item(&mut self, item: &'hir ForeignItem<'hir>) { self.foreign_items.push(item.foreign_item_id()); intravisit::walk_foreign_item(self, item)