+struct UsePlacementFinder {
+ target_module: NodeId,
+ span: Option<Span>,
+ found_use: bool,
+}
+
+impl<'tcx> Visitor<'tcx> for UsePlacementFinder {
+ fn visit_mod(
+ &mut self,
+ module: &'tcx ast::Mod,
+ _: Span,
+ _: &[ast::Attribute],
+ node_id: NodeId,
+ ) {
+ if self.span.is_some() {
+ return;
+ }
+ if node_id != self.target_module {
+ visit::walk_mod(self, module);
+ return;
+ }
+ // find a use statement
+ for item in &module.items {
+ match item.node {
+ ItemKind::Use(..) => {
+ // don't suggest placing a use before the prelude
+ // import or other generated ones
+ if item.span == DUMMY_SP {
+ self.span = Some(item.span.with_hi(item.span.lo()));
+ self.found_use = true;
+ return;
+ }
+ },
+ // don't place use before extern crate
+ ItemKind::ExternCrate(_) => {}
+ // but place them before the first other item
+ _ => if self.span.map_or(true, |span| item.span < span ) {
+ self.span = Some(item.span.with_hi(item.span.lo()));
+ },
+ }
+ }
+ assert!(self.span.is_some(), "a file can't have no items and emit suggestions");
+ }
+}
+