From 010974fafe571d2cfb8bc49d079b55bbe04c418d Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Mon, 5 Jun 2017 00:28:01 +0300 Subject: [PATCH] Finish rustup. --- clippy_lints/src/escape.rs | 97 ++++++++-------------- clippy_lints/src/functions.rs | 1 - clippy_lints/src/loops.rs | 8 +- clippy_lints/src/mut_reference.rs | 13 ++- clippy_lints/src/needless_borrow.rs | 20 +++-- clippy_lints/src/needless_pass_by_value.rs | 18 ++-- clippy_lints/src/unused_io_amount.rs | 2 +- clippy_lints/src/utils/mod.rs | 27 +++--- clippy_lints/src/utils/paths.rs | 2 +- clippy_tests/examples/for_loop.stderr | 8 ++ clippy_tests/examples/mut_reference.stderr | 6 +- clippy_tests/examples/range.stderr | 40 +++++++++ 12 files changed, 131 insertions(+), 111 deletions(-) diff --git a/clippy_lints/src/escape.rs b/clippy_lints/src/escape.rs index 6c801b26209..6f073478027 100644 --- a/clippy_lints/src/escape.rs +++ b/clippy_lints/src/escape.rs @@ -5,8 +5,6 @@ use rustc::lint::*; use rustc::middle::expr_use_visitor::*; use rustc::middle::mem_categorization::{cmt, Categorization}; use rustc::ty; -use rustc::ty::layout::TargetDataLayout; -use rustc::traits::Reveal; use rustc::util::nodemap::NodeSet; use syntax::ast::NodeId; use syntax::codemap::Span; @@ -46,8 +44,7 @@ fn is_non_trait_box(ty: ty::Ty) -> bool { struct EscapeDelegate<'a, 'tcx: 'a> { set: NodeSet, tcx: ty::TyCtxt<'a, 'tcx, 'tcx>, - tables: &'a ty::TypeckTables<'tcx>, - target: TargetDataLayout, + param_env: ty::ParamEnv<'tcx>, too_large_for_stack: u64, } @@ -67,25 +64,20 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { _: Span, node_id: NodeId ) { - // we store the infcx because it is expensive to recreate - // the context each time. + let fn_def_id = cx.tcx.hir.local_def_id(node_id); + let param_env = cx.tcx.param_env(fn_def_id).reveal_all(); let mut v = EscapeDelegate { set: NodeSet(), tcx: cx.tcx, - tables: cx.tables, - target: TargetDataLayout::parse(cx.sess()), + param_env: param_env, too_large_for_stack: self.too_large_for_stack, }; - let infcx = cx.tcx.borrowck_fake_infer_ctxt(body.id()); - let fn_def_id = cx.tcx.hir.local_def_id(node_id); - let region_maps = &cx.tcx.region_maps(fn_def_id); - { - let def_id = cx.tcx.hir.body_owner_def_id(body.id()); - let param_env = cx.tcx.param_env(def_id); + cx.tcx.infer_ctxt(body.id()).enter(|infcx| { + let region_maps = &cx.tcx.region_maps(fn_def_id); let mut vis = ExprUseVisitor::new(&mut v, region_maps, &infcx, param_env); vis.consume_body(body); - } + }); for node in v.set { span_lint(cx, @@ -96,14 +88,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { } } -impl<'a, 'tcx: 'a> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> { +impl<'a, 'gcx: 'tcx, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'gcx> { fn consume(&mut self, _: NodeId, _: Span, cmt: cmt<'tcx>, mode: ConsumeMode) { if let Categorization::Local(lid) = cmt.cat { - if self.set.contains(&lid) { - if let Move(DirectRefMove) = mode { - // moved out or in. clearly can't be localized - self.set.remove(&lid); - } + if let Move(DirectRefMove) = mode { + // moved out or in. clearly can't be localized + self.set.remove(&lid); } } } @@ -151,49 +141,30 @@ impl<'a, 'tcx: 'a> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> { } fn borrow( &mut self, - borrow_id: NodeId, + _: NodeId, _: Span, cmt: cmt<'tcx>, _: ty::Region, _: ty::BorrowKind, loan_cause: LoanCause ) { - use rustc::ty::adjustment::Adjust; - if let Categorization::Local(lid) = cmt.cat { - if self.set.contains(&lid) { - if let Some(&Adjust::Deref(ref overloaded)) = - self.tables - .adjustments - .get(&borrow_id) - .map(|a| &a.kind) { - if LoanCause::AutoRef == loan_cause { - // x.foo() - if overloaded == 0 { - self.set.remove(&lid); // Used without autodereffing (i.e. x.clone()) - } - } else { - span_bug!(cmt.span, "Unknown adjusted AutoRef"); - } - } else if LoanCause::AddrOf == loan_cause { - // &x - if let Some(&Adjust::Deref(ref overloaded)) = - self.tables - .adjustments - .get(&self.tcx - .hir - .get_parent_node(borrow_id)) - .map(|a| &a.kind) { - if overloaded <= 1 { - // foo(&x) where no extra autoreffing is happening - self.set.remove(&lid); - } - } + match loan_cause { + // x.foo() + // Used without autodereffing (i.e. x.clone()) + LoanCause::AutoRef | - } else if LoanCause::MatchDiscriminant == loan_cause { - self.set.remove(&lid); // `match x` can move + // &x + // foo(&x) where no extra autoreffing is happening + LoanCause::AddrOf | + + // `match x` can move + LoanCause::MatchDiscriminant => { + self.set.remove(&lid); } + // do nothing for matches, etc. These can't escape + _ => {} } } } @@ -202,19 +173,17 @@ impl<'a, 'tcx: 'a> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> { } impl<'a, 'tcx: 'a> EscapeDelegate<'a, 'tcx> { - fn is_large_box(&self, ty: ty::Ty<'tcx>) -> bool { + fn is_large_box(&self, ty: ty::Ty) -> bool { // Large types need to be boxed to avoid stack // overflows. if ty.is_box() { - let inner = ty.boxed_ty(); - self.tcx.infer_ctxt(()).enter(|infcx| if let Ok(layout) = inner.layout(&infcx) { - let size = layout.size(&self.target); - size.bytes() > self.too_large_for_stack - } else { - false - }) - } else { - false + if let Some(inner) = self.tcx.lift(&ty.boxed_ty()) { + if let Ok(layout) = inner.layout(self.tcx, self.param_env) { + return layout.size(self.tcx).bytes() > self.too_large_for_stack; + } + } } + + false } } diff --git a/clippy_lints/src/functions.rs b/clippy_lints/src/functions.rs index 62a843885c7..463358c99b4 100644 --- a/clippy_lints/src/functions.rs +++ b/clippy_lints/src/functions.rs @@ -1,6 +1,5 @@ use rustc::hir::intravisit; use rustc::hir; -use rustc::ty; use rustc::lint::*; use std::collections::HashSet; use syntax::ast; diff --git a/clippy_lints/src/loops.rs b/clippy_lints/src/loops.rs index 2e373988887..606399af547 100644 --- a/clippy_lints/src/loops.rs +++ b/clippy_lints/src/loops.rs @@ -8,6 +8,7 @@ use rustc::lint::*; use rustc::middle::const_val::ConstVal; use rustc::middle::region::CodeExtent; use rustc::ty; +use rustc::ty::subst::Subst; use rustc_const_eval::ConstContext; use std::collections::HashMap; use syntax::ast; @@ -676,8 +677,11 @@ fn check_for_loop_arg(cx: &LateContext, pat: &Pat, arg: &Expr, expr: &Expr) { lint_iter_method(cx, args, arg, &method_name); } } else if method_name == "into_iter" && match_trait_method(cx, arg, &paths::INTO_ITERATOR) { - let fn_ty = cx.tables.expr_ty(arg); - let fn_arg_tys = fn_ty.fn_sig().inputs(); + let def_id = cx.tables.type_dependent_defs[&arg.id].def_id(); + let substs = cx.tables.node_substs(arg.id); + let method_type = cx.tcx.type_of(def_id).subst(cx.tcx, substs); + + let fn_arg_tys = method_type.fn_sig().inputs(); assert_eq!(fn_arg_tys.skip_binder().len(), 1); if fn_arg_tys.skip_binder()[0].is_region_ptr() { lint_iter_method(cx, args, arg, &method_name); diff --git a/clippy_lints/src/mut_reference.rs b/clippy_lints/src/mut_reference.rs index aa6acd6795f..781398470b8 100644 --- a/clippy_lints/src/mut_reference.rs +++ b/clippy_lints/src/mut_reference.rs @@ -1,5 +1,6 @@ use rustc::lint::*; use rustc::ty::{TypeAndMut, TypeVariants, TyS}; +use rustc::ty::subst::Subst; use rustc::hir::*; use utils::span_lint; @@ -34,23 +35,19 @@ impl LintPass for UnnecessaryMutPassed { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnnecessaryMutPassed { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) { - let borrowed_table = cx.tables; match e.node { ExprCall(ref fn_expr, ref arguments) => { - let function_type = borrowed_table.node_types - .get(&fn_expr.id) - .expect("A function with an unknown type is called. If this happened, the compiler would have \ - aborted the compilation long ago"); if let ExprPath(ref path) = fn_expr.node { check_arguments(cx, arguments, - function_type, + cx.tables.expr_ty(fn_expr), &print::to_string(print::NO_ANN, |s| s.print_qpath(path, false))); } }, ExprMethodCall(ref name, _, ref arguments) => { - let def_id = borrowed_table.type_dependent_defs[&e.id].def_id(); - let method_type = cx.tcx.type_of(def_id); + let def_id = cx.tables.type_dependent_defs[&e.id].def_id(); + let substs = cx.tables.node_substs(e.id); + let method_type = cx.tcx.type_of(def_id).subst(cx.tcx, substs); check_arguments(cx, arguments, method_type, &name.node.as_str()) }, _ => (), diff --git a/clippy_lints/src/needless_borrow.rs b/clippy_lints/src/needless_borrow.rs index 4f5ff86c5e8..c1965be2c04 100644 --- a/clippy_lints/src/needless_borrow.rs +++ b/clippy_lints/src/needless_borrow.rs @@ -5,6 +5,7 @@ use rustc::lint::*; use rustc::hir::{ExprAddrOf, Expr, MutImmutable, Pat, PatKind, BindingMode}; use rustc::ty; +use rustc::ty::adjustment::{Adjustment, Adjust}; use utils::{span_lint, in_macro}; /// **What it does:** Checks for address of operations (`&`) that are going to @@ -41,13 +42,18 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessBorrow { } if let ExprAddrOf(MutImmutable, ref inner) = e.node { if let ty::TyRef(..) = cx.tables.expr_ty(inner).sty { - if let Some(&ty::adjustment::Adjust::Deref(Some(_))) = - cx.tables.adjustments.get(&e.id).map(|a| &a.kind) { - span_lint(cx, - NEEDLESS_BORROW, - e.span, - "this expression borrows a reference that is immediately dereferenced by the \ - compiler"); + for adj3 in cx.tables.expr_adjustments(e).windows(3) { + if let [ + Adjustment { kind: Adjust::Deref(_), .. }, + Adjustment { kind: Adjust::Deref(_), .. }, + Adjustment { kind: Adjust::Borrow(_), .. } + ] = *adj3 { + span_lint(cx, + NEEDLESS_BORROW, + e.span, + "this expression borrows a reference that is immediately dereferenced by the \ + compiler"); + } } } } diff --git a/clippy_lints/src/needless_pass_by_value.rs b/clippy_lints/src/needless_pass_by_value.rs index 33e9d4a7e57..2ce22b8c9c9 100644 --- a/clippy_lints/src/needless_pass_by_value.rs +++ b/clippy_lints/src/needless_pass_by_value.rs @@ -91,12 +91,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue { // Collect moved variables and spans which will need dereferencings from the function body. let MovedVariablesCtxt { moved_vars, spans_need_deref, .. } = { let mut ctx = MovedVariablesCtxt::new(cx); - let infcx = cx.tcx.borrowck_fake_infer_ctxt(body.id()); - let region_maps = &cx.tcx.region_maps(fn_def_id); - { - let mut v = euv::ExprUseVisitor::new(&mut ctx, region_maps, &infcx); - v.consume_body(body); - } + cx.tcx.infer_ctxt(body.id()).enter(|infcx| { + let param_env = cx.tcx.param_env(fn_def_id); + let region_maps = &cx.tcx.region_maps(fn_def_id); + euv::ExprUseVisitor::new(&mut ctx, region_maps, &infcx, param_env) + .consume_body(body); + }); ctx }; @@ -199,7 +199,7 @@ impl<'a, 'tcx: 'a> MovedVariablesCtxt<'a, 'tcx> { } } - fn move_common(&mut self, _consume_id: NodeId, _span: Span, cmt: mc::cmt<'tcx>) { + fn move_common(&mut self, _consume_id: NodeId, _span: Span, cmt: mc::cmt) { let cmt = unwrap_downcast_or_interior(cmt); if_let_chain! {[ @@ -210,7 +210,7 @@ impl<'a, 'tcx: 'a> MovedVariablesCtxt<'a, 'tcx> { }} } - fn non_moving_pat(&mut self, matched_pat: &Pat, cmt: mc::cmt<'tcx>) { + fn non_moving_pat(&mut self, matched_pat: &Pat, cmt: mc::cmt) { let cmt = unwrap_downcast_or_interior(cmt); if_let_chain! {[ @@ -262,7 +262,7 @@ impl<'a, 'tcx: 'a> MovedVariablesCtxt<'a, 'tcx> { } } -impl<'a, 'tcx: 'a> euv::Delegate<'tcx> for MovedVariablesCtxt<'a, 'tcx> { +impl<'a, 'gcx: 'tcx, 'tcx> euv::Delegate<'tcx> for MovedVariablesCtxt<'a, 'gcx> { fn consume(&mut self, consume_id: NodeId, consume_span: Span, cmt: mc::cmt<'tcx>, mode: euv::ConsumeMode) { if let euv::ConsumeMode::Move(_) = mode { self.move_common(consume_id, consume_span, cmt); diff --git a/clippy_lints/src/unused_io_amount.rs b/clippy_lints/src/unused_io_amount.rs index c8ceb6be0cc..1f19e454857 100644 --- a/clippy_lints/src/unused_io_amount.rs +++ b/clippy_lints/src/unused_io_amount.rs @@ -46,7 +46,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedIoAmount { hir::ExprMatch(ref res, _, _) if is_try(expr).is_some() => { if let hir::ExprCall(ref func, ref args) = res.node { if let hir::ExprPath(ref path) = func.node { - if match_path(path, &paths::CARRIER_TRANSLATE) && args.len() == 1 { + if match_path(path, &paths::TRY_INTO_RESULT) && args.len() == 1 { check_method_call(cx, &args[0], expr); } } diff --git a/clippy_lints/src/utils/mod.rs b/clippy_lints/src/utils/mod.rs index c75e53d6ef0..d068fa51ca4 100644 --- a/clippy_lints/src/utils/mod.rs +++ b/clippy_lints/src/utils/mod.rs @@ -9,7 +9,6 @@ use rustc::traits::Reveal; use rustc::traits; use rustc::ty::subst::{Subst, Substs}; use rustc::ty; -use rustc::ty::layout::TargetDataLayout; use rustc::mir::transform::MirSource; use rustc_errors; use std::borrow::Cow; @@ -317,13 +316,15 @@ pub fn implements_trait<'a, 'tcx>( parent_node_id: Option ) -> bool { let ty = cx.tcx.erase_regions(&ty); - let mut b = if let Some(id) = parent_node_id { - cx.tcx.infer_ctxt(BodyId { node_id: id }) + let param_env = if let Some(id) = parent_node_id { + let def_id = cx.tcx.hir.body_owner_def_id(BodyId { node_id: id }); + cx.tcx.param_env(def_id).reveal_all() } else { - cx.tcx.infer_ctxt(()) + ty::ParamEnv::empty(Reveal::All) }; - b.enter(|infcx| { - let obligation = cx.tcx.predicate_for_trait_def(traits::ObligationCause::dummy(), trait_id, 0, ty, ty_params); + cx.tcx.infer_ctxt(()).enter(|infcx| { + let obligation = cx.tcx.predicate_for_trait_def( + param_env, traits::ObligationCause::dummy(), trait_id, 0, ty, ty_params); traits::SelectionContext::new(&infcx).evaluate_obligation_conservatively(&obligation) }) @@ -778,12 +779,9 @@ pub fn same_tys<'a, 'tcx>( b: ty::Ty<'tcx>, parameter_item: DefId ) -> bool { - let parameter_env = cx.tcx.param_env(parameter_item); - cx.tcx.infer_ctxt(parameter_env).enter(|infcx| { - let substs = Substs::identity_for_item(cx.tcx, parameter_item); - let new_a = a.subst(infcx.tcx, substs); - let new_b = b.subst(infcx.tcx, substs); - infcx.can_equate(&new_a, &new_b).is_ok() + let param_env = cx.tcx.param_env(parameter_item).reveal_all(); + cx.tcx.infer_ctxt(()).enter(|infcx| { + infcx.can_eq(param_env, a, b).is_ok() }) } @@ -961,7 +959,6 @@ pub fn is_try(expr: &Expr) -> Option<&Expr> { } pub fn type_size<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: ty::Ty<'tcx>) -> Option { - cx.tcx - .infer_ctxt(()) - .enter(|infcx| ty.layout(&infcx).ok().map(|lay| lay.size(&TargetDataLayout::parse(cx.sess())).bytes())) + ty.layout(cx.tcx, ty::ParamEnv::empty(Reveal::All)) + .ok().map(|layout| layout.size(cx.tcx).bytes()) } diff --git a/clippy_lints/src/utils/paths.rs b/clippy_lints/src/utils/paths.rs index 133a2d65f0e..738a497c6ab 100644 --- a/clippy_lints/src/utils/paths.rs +++ b/clippy_lints/src/utils/paths.rs @@ -9,7 +9,6 @@ pub const BOX_NEW: [&'static str; 4] = ["std", "boxed", "Box", "new"]; pub const BTREEMAP: [&'static str; 4] = ["collections", "btree", "map", "BTreeMap"]; pub const BTREEMAP_ENTRY: [&'static str; 4] = ["collections", "btree", "map", "Entry"]; pub const BTREESET: [&'static str; 4] = ["collections", "btree", "set", "BTreeSet"]; -pub const CARRIER_TRANSLATE: [&'static str; 4] = ["std", "ops", "Carrier", "translate"]; pub const CLONE: [&'static str; 4] = ["core", "clone", "Clone", "clone"]; pub const CLONE_TRAIT: [&'static str; 3] = ["core", "clone", "Clone"]; pub const CMP_MAX: [&'static str; 3] = ["core", "cmp", "max"]; @@ -72,6 +71,7 @@ pub const STRING: [&'static str; 3] = ["collections", "string", "String"]; pub const TO_OWNED: [&'static str; 3] = ["collections", "borrow", "ToOwned"]; pub const TO_STRING: [&'static str; 3] = ["collections", "string", "ToString"]; pub const TRANSMUTE: [&'static str; 4] = ["core", "intrinsics", "", "transmute"]; +pub const TRY_INTO_RESULT: [&'static str; 4] = ["std", "ops", "Try", "into_result"]; pub const VEC: [&'static str; 3] = ["collections", "vec", "Vec"]; pub const VEC_DEQUE: [&'static str; 3] = ["collections", "vec_deque", "VecDeque"]; pub const VEC_FROM_ELEM: [&'static str; 3] = ["collections", "vec", "from_elem"]; diff --git a/clippy_tests/examples/for_loop.stderr b/clippy_tests/examples/for_loop.stderr index 8ecdc6f5a26..66c42d50e19 100644 --- a/clippy_tests/examples/for_loop.stderr +++ b/clippy_tests/examples/for_loop.stderr @@ -295,6 +295,14 @@ error: this range is empty so this for loop will never run | = note: `-D reverse-range-loop` implied by `-D warnings` +error: use of deprecated item: replaced by `Iterator::step_by` + --> for_loop.rs:192:22 + | +192 | for i in (10..8).step_by(-1) { + | ^^^^^^^ + | + = note: `-D deprecated` implied by `-D warnings` + error: it is more idiomatic to loop over references to containers instead of using explicit iteration methods --> for_loop.rs:207:15 | diff --git a/clippy_tests/examples/mut_reference.stderr b/clippy_tests/examples/mut_reference.stderr index 34d33f62219..c8f606db0e1 100644 --- a/clippy_tests/examples/mut_reference.stderr +++ b/clippy_tests/examples/mut_reference.stderr @@ -1,4 +1,4 @@ -error: The function/method "takes_an_immutable_reference" doesn't need a mutable reference +error: The function/method `takes_an_immutable_reference` doesn't need a mutable reference --> mut_reference.rs:22:34 | 22 | takes_an_immutable_reference(&mut 42); @@ -6,7 +6,7 @@ error: The function/method "takes_an_immutable_reference" doesn't need a mutable | = note: `-D unnecessary-mut-passed` implied by `-D warnings` -error: The function/method "as_ptr" doesn't need a mutable reference +error: The function/method `as_ptr` doesn't need a mutable reference --> mut_reference.rs:24:12 | 24 | as_ptr(&mut 42); @@ -14,7 +14,7 @@ error: The function/method "as_ptr" doesn't need a mutable reference | = note: `-D unnecessary-mut-passed` implied by `-D warnings` -error: The function/method "takes_an_immutable_reference" doesn't need a mutable reference +error: The function/method `takes_an_immutable_reference` doesn't need a mutable reference --> mut_reference.rs:28:44 | 28 | my_struct.takes_an_immutable_reference(&mut 42); diff --git a/clippy_tests/examples/range.stderr b/clippy_tests/examples/range.stderr index 1d23f142587..2f3aa7971d0 100644 --- a/clippy_tests/examples/range.stderr +++ b/clippy_tests/examples/range.stderr @@ -6,6 +6,22 @@ error: Range::step_by(0) produces an infinite iterator. Consider using `std::ite | = note: `-D range-step-by-zero` implied by `-D warnings` +error: use of deprecated item: replaced by `Iterator::step_by` + --> range.rs:13:12 + | +13 | (0..1).step_by(0); + | ^^^^^^^ + | + = note: `-D deprecated` implied by `-D warnings` + +error: use of deprecated item: replaced by `Iterator::step_by` + --> range.rs:15:12 + | +15 | (0..1).step_by(1); + | ^^^^^^^ + | + = note: `-D deprecated` implied by `-D warnings` + error: Range::step_by(0) produces an infinite iterator. Consider using `std::iter::repeat()` instead --> range.rs:17:5 | @@ -14,6 +30,14 @@ error: Range::step_by(0) produces an infinite iterator. Consider using `std::ite | = note: `-D range-step-by-zero` implied by `-D warnings` +error: use of deprecated item: replaced by `Iterator::step_by` + --> range.rs:17:11 + | +17 | (1..).step_by(0); + | ^^^^^^^ + | + = note: `-D deprecated` implied by `-D warnings` + error: Range::step_by(0) produces an infinite iterator. Consider using `std::iter::repeat()` instead --> range.rs:18:5 | @@ -22,6 +46,14 @@ error: Range::step_by(0) produces an infinite iterator. Consider using `std::ite | = note: `-D range-step-by-zero` implied by `-D warnings` +error: use of deprecated item: replaced by `Iterator::step_by` + --> range.rs:18:13 + | +18 | (1...2).step_by(0); + | ^^^^^^^ + | + = note: `-D deprecated` implied by `-D warnings` + error: Range::step_by(0) produces an infinite iterator. Consider using `std::iter::repeat()` instead --> range.rs:21:5 | @@ -30,6 +62,14 @@ error: Range::step_by(0) produces an infinite iterator. Consider using `std::ite | = note: `-D range-step-by-zero` implied by `-D warnings` +error: use of deprecated item: replaced by `Iterator::step_by` + --> range.rs:21:7 + | +21 | x.step_by(0); + | ^^^^^^^ + | + = note: `-D deprecated` implied by `-D warnings` + error: It is more idiomatic to use v1.iter().enumerate() --> range.rs:29:14 |