From 516a177273b1f6943f63abd2a74ffa5f53542fdb Mon Sep 17 00:00:00 2001 From: Cameron Zwarich Date: Wed, 21 May 2014 21:44:49 -0700 Subject: [PATCH] Add a suggestion to use a `let` binding on some borrowck errors. --- src/librustc/middle/borrowck/mod.rs | 19 +++++++++++++++++- .../compile-fail/borrowck-let-suggestion.rs | 20 +++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 src/test/compile-fail/borrowck-let-suggestion.rs diff --git a/src/librustc/middle/borrowck/mod.rs b/src/librustc/middle/borrowck/mod.rs index 0f67520d8d3..eaa39ee231d 100644 --- a/src/librustc/middle/borrowck/mod.rs +++ b/src/librustc/middle/borrowck/mod.rs @@ -689,11 +689,16 @@ impl<'a> BorrowckCtxt<'a> { "reference must be valid for ", sub_scope, "..."); + let suggestion = if is_statement_scope(self.tcx, super_scope) { + "; consider using a `let` binding to increase its lifetime" + } else { + "" + }; note_and_explain_region( self.tcx, "...but borrowed value is only valid for ", super_scope, - ""); + suggestion); } err_borrowed_pointer_too_short(loan_scope, ptr_scope, _) => { @@ -779,6 +784,18 @@ impl<'a> BorrowckCtxt<'a> { } } +fn is_statement_scope(tcx: &ty::ctxt, region: ty::Region) -> bool { + match region { + ty::ReScope(node_id) => { + match tcx.map.find(node_id) { + Some(ast_map::NodeStmt(_)) => true, + _ => false + } + } + _ => false + } +} + impl DataFlowOperator for LoanDataFlowOperator { #[inline] fn initial_value(&self) -> bool { diff --git a/src/test/compile-fail/borrowck-let-suggestion.rs b/src/test/compile-fail/borrowck-let-suggestion.rs new file mode 100644 index 00000000000..a03087f9b2d --- /dev/null +++ b/src/test/compile-fail/borrowck-let-suggestion.rs @@ -0,0 +1,20 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn f() { + let x = [1].iter(); //~ ERROR borrowed value does not live long enough + //~^^ NOTE reference must be valid for the block + //~^^ NOTE consider using a `let` binding to increase its lifetime +} + +fn main() { + f(); +} +