Auto merge of #47144 - estebank:moved-closure-arg, r=nikomatsakis
Custom error when moving arg outside of its closure When given the following code: ```rust fn give_any<F: for<'r> FnOnce(&'r ())>(f: F) { f(&()); } fn main() { let mut x = None; give_any(|y| x = Some(y)); } ``` provide a custom error: ``` error: borrowed data cannot be moved outside of its closure --> file.rs:7:27 | 6 | let mut x = None; | ----- borrowed data cannot be moved into here... 7 | give_any(|y| x = Some(y)); | --- ^ cannot be moved outside of its closure | | | ...because it cannot outlive this closure ``` instead of the generic lifetime error: ``` error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements --> file.rs:7:27 | 7 | give_any(|y| x = Some(y)); | ^ | note: first, the lifetime cannot outlive the anonymous lifetime #2 defined on the body at 7:14... --> file.rs:7:14 | 7 | give_any(|y| x = Some(y)); | ^^^^^^^^^^^^^^^ note: ...so that expression is assignable (expected &(), found &()) --> file.rs:7:27 | 7 | give_any(|y| x = Some(y)); | ^ note: but, the lifetime must be valid for the block suffix following statement 0 at 6:5... --> file.rs:6:5 | 6 | / let mut x = None; 7 | | give_any(|y| x = Some(y)); 8 | | } | |_^ note: ...so that variable is valid at time of its declaration --> file.rs:6:9 | 6 | let mut x = None; | ^^^^^ ``` Fix #45983.
This commit is contained in:
commit
bc072ed0ca
18 changed files with 352 additions and 21 deletions
|
@ -1067,6 +1067,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||
sub_region: Region<'tcx>,
|
||||
sup_origin: SubregionOrigin<'tcx>,
|
||||
sup_region: Region<'tcx>) {
|
||||
|
||||
let mut err = self.report_inference_failure(var_origin);
|
||||
|
||||
self.tcx.note_and_explain_region(region_scope_tree, &mut err,
|
||||
|
|
|
@ -53,7 +53,7 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> {
|
|||
///
|
||||
/// It will later be extended to trait objects.
|
||||
pub(super) fn try_report_anon_anon_conflict(&self) -> Option<ErrorReported> {
|
||||
let NiceRegionError { span, sub, sup, .. } = *self;
|
||||
let (span, sub, sup) = self.get_regions();
|
||||
|
||||
// Determine whether the sub and sup consist of both anonymous (elided) regions.
|
||||
let anon_reg_sup = self.is_suitable_region(sup)?;
|
||||
|
|
|
@ -18,46 +18,64 @@ use util::common::ErrorReported;
|
|||
mod different_lifetimes;
|
||||
mod find_anon_type;
|
||||
mod named_anon_conflict;
|
||||
mod outlives_closure;
|
||||
mod util;
|
||||
|
||||
impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
|
||||
pub fn try_report_nice_region_error(&self, error: &RegionResolutionError<'tcx>) -> bool {
|
||||
let (span, sub, sup) = match *error {
|
||||
ConcreteFailure(ref origin, sub, sup) => (origin.span(), sub, sup),
|
||||
SubSupConflict(_, ref origin, sub, _, sup) => (origin.span(), sub, sup),
|
||||
_ => return false, // inapplicable
|
||||
};
|
||||
match *error {
|
||||
ConcreteFailure(..) | SubSupConflict(..) => {}
|
||||
_ => return false, // inapplicable
|
||||
}
|
||||
|
||||
if let Some(tables) = self.in_progress_tables {
|
||||
let tables = tables.borrow();
|
||||
NiceRegionError::new(self.tcx, span, sub, sup, Some(&tables)).try_report().is_some()
|
||||
NiceRegionError::new(self.tcx, error.clone(), Some(&tables)).try_report().is_some()
|
||||
} else {
|
||||
NiceRegionError::new(self.tcx, span, sub, sup, None).try_report().is_some()
|
||||
NiceRegionError::new(self.tcx, error.clone(), None).try_report().is_some()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct NiceRegionError<'cx, 'gcx: 'tcx, 'tcx: 'cx> {
|
||||
tcx: TyCtxt<'cx, 'gcx, 'tcx>,
|
||||
span: Span,
|
||||
sub: ty::Region<'tcx>,
|
||||
sup: ty::Region<'tcx>,
|
||||
error: Option<RegionResolutionError<'tcx>>,
|
||||
regions: Option<(Span, ty::Region<'tcx>, ty::Region<'tcx>)>,
|
||||
tables: Option<&'cx ty::TypeckTables<'tcx>>,
|
||||
}
|
||||
|
||||
impl<'cx, 'gcx, 'tcx> NiceRegionError<'cx, 'gcx, 'tcx> {
|
||||
pub fn new(
|
||||
tcx: TyCtxt<'cx, 'gcx, 'tcx>,
|
||||
error: RegionResolutionError<'tcx>,
|
||||
tables: Option<&'cx ty::TypeckTables<'tcx>>,
|
||||
) -> Self {
|
||||
Self { tcx, error: Some(error), regions: None, tables }
|
||||
}
|
||||
|
||||
pub fn new_from_span(
|
||||
tcx: TyCtxt<'cx, 'gcx, 'tcx>,
|
||||
span: Span,
|
||||
sub: ty::Region<'tcx>,
|
||||
sup: ty::Region<'tcx>,
|
||||
tables: Option<&'cx ty::TypeckTables<'tcx>>,
|
||||
) -> Self {
|
||||
Self { tcx, span, sub, sup, tables }
|
||||
Self { tcx, error: None, regions: Some((span, sub, sup)), tables }
|
||||
}
|
||||
|
||||
pub fn try_report(&self) -> Option<ErrorReported> {
|
||||
self.try_report_named_anon_conflict()
|
||||
.or_else(|| self.try_report_anon_anon_conflict())
|
||||
.or_else(|| self.try_report_outlives_closure())
|
||||
}
|
||||
|
||||
pub fn get_regions(&self) -> (Span, ty::Region<'tcx>, ty::Region<'tcx>) {
|
||||
match (&self.error, self.regions) {
|
||||
(&Some(ConcreteFailure(ref origin, sub, sup)), None) => (origin.span(), sub, sup),
|
||||
(&Some(SubSupConflict(_, ref origin, sub, _, sup)), None) => (origin.span(), sub, sup),
|
||||
(None, Some((span, sub, sup))) => (span, sub, sup),
|
||||
(Some(_), Some(_)) => panic!("incorrectly built NiceRegionError"),
|
||||
_ => panic!("trying to report on an incorrect lifetime failure"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> {
|
|||
/// When given a `ConcreteFailure` for a function with arguments containing a named region and
|
||||
/// an anonymous region, emit an descriptive diagnostic error.
|
||||
pub(super) fn try_report_named_anon_conflict(&self) -> Option<ErrorReported> {
|
||||
let NiceRegionError { span, sub, sup, .. } = *self;
|
||||
let (span, sub, sup) = self.get_regions();
|
||||
|
||||
debug!(
|
||||
"try_report_named_anon_conflict(sub={:?}, sup={:?})",
|
||||
|
|
|
@ -0,0 +1,124 @@
|
|||
// Copyright 2018 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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! Error Reporting for Anonymous Region Lifetime Errors
|
||||
//! where both the regions are anonymous.
|
||||
|
||||
use infer::error_reporting::nice_region_error::NiceRegionError;
|
||||
use infer::SubregionOrigin;
|
||||
use ty::RegionKind;
|
||||
use hir::{Expr, ExprClosure};
|
||||
use hir::map::NodeExpr;
|
||||
use util::common::ErrorReported;
|
||||
use infer::lexical_region_resolve::RegionResolutionError::SubSupConflict;
|
||||
|
||||
impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> {
|
||||
/// Print the error message for lifetime errors when binding excapes a closure.
|
||||
///
|
||||
/// Consider a case where we have
|
||||
///
|
||||
/// ```no_run
|
||||
/// fn with_int<F>(f: F) where F: FnOnce(&isize) {
|
||||
/// let x = 3;
|
||||
/// f(&x);
|
||||
/// }
|
||||
/// fn main() {
|
||||
/// let mut x = None;
|
||||
/// with_int(|y| x = Some(y));
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// the output will be
|
||||
///
|
||||
/// ```text
|
||||
/// let mut x = None;
|
||||
/// ----- borrowed data cannot be stored into here...
|
||||
/// with_int(|y| x = Some(y));
|
||||
/// --- ^ cannot be stored outside of its closure
|
||||
/// |
|
||||
/// ...because it cannot outlive this closure
|
||||
/// ```
|
||||
pub(super) fn try_report_outlives_closure(&self) -> Option<ErrorReported> {
|
||||
if let Some(SubSupConflict(origin,
|
||||
ref sub_origin,
|
||||
_,
|
||||
ref sup_origin,
|
||||
sup_region)) = self.error {
|
||||
|
||||
// #45983: when trying to assign the contents of an argument to a binding outside of a
|
||||
// closure, provide a specific message pointing this out.
|
||||
if let (&SubregionOrigin::BindingTypeIsNotValidAtDecl(ref external_span),
|
||||
&RegionKind::ReFree(ref free_region)) = (&sub_origin, sup_region) {
|
||||
let hir = &self.tcx.hir;
|
||||
if let Some(node_id) = hir.as_local_node_id(free_region.scope) {
|
||||
match hir.get(node_id) {
|
||||
NodeExpr(Expr {
|
||||
node: ExprClosure(_, _, _, closure_span, false),
|
||||
..
|
||||
}) => {
|
||||
let sup_sp = sup_origin.span();
|
||||
let origin_sp = origin.span();
|
||||
let mut err = self.tcx.sess.struct_span_err(
|
||||
sup_sp,
|
||||
"borrowed data cannot be stored outside of its closure");
|
||||
err.span_label(sup_sp, "cannot be stored outside of its closure");
|
||||
if origin_sp == sup_sp || origin_sp.contains(sup_sp) {
|
||||
// // sup_sp == origin.span():
|
||||
//
|
||||
// let mut x = None;
|
||||
// ----- borrowed data cannot be stored into here...
|
||||
// with_int(|y| x = Some(y));
|
||||
// --- ^ cannot be stored outside of its closure
|
||||
// |
|
||||
// ...because it cannot outlive this closure
|
||||
//
|
||||
// // origin.contains(&sup_sp):
|
||||
//
|
||||
// let mut f: Option<&u32> = None;
|
||||
// ----- borrowed data cannot be stored into here...
|
||||
// closure_expecting_bound(|x: &'x u32| {
|
||||
// ------------ ... because it cannot outlive this closure
|
||||
// f = Some(x);
|
||||
// ^ cannot be stored outside of its closure
|
||||
err.span_label(*external_span,
|
||||
"borrowed data cannot be stored into here...");
|
||||
err.span_label(*closure_span,
|
||||
"...because it cannot outlive this closure");
|
||||
} else {
|
||||
// FIXME: the wording for this case could be much improved
|
||||
//
|
||||
// let mut lines_to_use: Vec<&CrateId> = Vec::new();
|
||||
// - cannot infer an appropriate lifetime...
|
||||
// let push_id = |installed_id: &CrateId| {
|
||||
// ------- ------------------------ borrowed data cannot outlive this closure
|
||||
// |
|
||||
// ...so that variable is valid at time of its declaration
|
||||
// lines_to_use.push(installed_id);
|
||||
// ^^^^^^^^^^^^ cannot be stored outside of its closure
|
||||
err.span_label(origin_sp,
|
||||
"cannot infer an appropriate lifetime...");
|
||||
err.span_label(*external_span,
|
||||
"...so that variable is valid at time of its \
|
||||
declaration");
|
||||
err.span_label(*closure_span,
|
||||
"borrowed data cannot outlive this closure");
|
||||
}
|
||||
err.emit();
|
||||
return Some(ErrorReported);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
||||
|
|
@ -989,7 +989,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
|
||||
if let (Some(f), Some(o)) = (fr_name, outlived_fr_name) {
|
||||
let tables = infcx.tcx.typeck_tables_of(mir_def_id);
|
||||
let nice = NiceRegionError::new(infcx.tcx, blame_span, o, f, Some(tables));
|
||||
let nice = NiceRegionError::new_from_span(infcx.tcx, blame_span, o, f, Some(tables));
|
||||
if let Some(ErrorReported) = nice.try_report() {
|
||||
return;
|
||||
}
|
||||
|
|
19
src/test/ui/borrowck/issue-45983.rs
Normal file
19
src/test/ui/borrowck/issue-45983.rs
Normal file
|
@ -0,0 +1,19 @@
|
|||
// Copyright 2018 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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
fn give_any<F: for<'r> FnOnce(&'r ())>(f: F) {
|
||||
f(&());
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x = None;
|
||||
give_any(|y| x = Some(y));
|
||||
//~^ ERROR borrowed data cannot be stored outside of its closure
|
||||
}
|
12
src/test/ui/borrowck/issue-45983.stderr
Normal file
12
src/test/ui/borrowck/issue-45983.stderr
Normal file
|
@ -0,0 +1,12 @@
|
|||
error: borrowed data cannot be stored outside of its closure
|
||||
--> $DIR/issue-45983.rs:17:27
|
||||
|
|
||||
16 | let x = None;
|
||||
| - borrowed data cannot be stored into here...
|
||||
17 | give_any(|y| x = Some(y));
|
||||
| --- ^ cannot be stored outside of its closure
|
||||
| |
|
||||
| ...because it cannot outlive this closure
|
||||
|
||||
error: aborting due to previous error
|
||||
|
|
@ -24,9 +24,14 @@ impl CrateId {
|
|||
}
|
||||
|
||||
pub fn remove_package_from_database() {
|
||||
let mut lines_to_use: Vec<&CrateId> = Vec::new(); //~ ERROR E0495
|
||||
let mut lines_to_use: Vec<&CrateId> = Vec::new();
|
||||
//~^ NOTE cannot infer an appropriate lifetime
|
||||
let push_id = |installed_id: &CrateId| {
|
||||
//~^ NOTE borrowed data cannot outlive this closure
|
||||
//~| NOTE ...so that variable is valid at time of its declaration
|
||||
lines_to_use.push(installed_id);
|
||||
//~^ ERROR borrowed data cannot be stored outside of its closure
|
||||
//~| NOTE cannot be stored outside of its closure
|
||||
};
|
||||
list_database(push_id);
|
||||
|
16
src/test/ui/borrowck/issue-7573.stderr
Normal file
16
src/test/ui/borrowck/issue-7573.stderr
Normal file
|
@ -0,0 +1,16 @@
|
|||
error: borrowed data cannot be stored outside of its closure
|
||||
--> $DIR/issue-7573.rs:32:27
|
||||
|
|
||||
27 | let mut lines_to_use: Vec<&CrateId> = Vec::new();
|
||||
| - cannot infer an appropriate lifetime...
|
||||
28 | //~^ NOTE cannot infer an appropriate lifetime
|
||||
29 | let push_id = |installed_id: &CrateId| {
|
||||
| ------- ------------------------ borrowed data cannot outlive this closure
|
||||
| |
|
||||
| ...so that variable is valid at time of its declaration
|
||||
...
|
||||
32 | lines_to_use.push(installed_id);
|
||||
| ^^^^^^^^^^^^ cannot be stored outside of its closure
|
||||
|
||||
error: aborting due to previous error
|
||||
|
|
@ -16,5 +16,5 @@ fn with_int<F>(f: F) where F: FnOnce(&isize) {
|
|||
fn main() {
|
||||
let mut x = None;
|
||||
with_int(|y| x = Some(y));
|
||||
//~^ ERROR cannot infer
|
||||
//~^ ERROR borrowed data cannot be stored outside of its closure
|
||||
}
|
12
src/test/ui/borrowck/regions-escape-bound-fn-2.stderr
Normal file
12
src/test/ui/borrowck/regions-escape-bound-fn-2.stderr
Normal file
|
@ -0,0 +1,12 @@
|
|||
error: borrowed data cannot be stored outside of its closure
|
||||
--> $DIR/regions-escape-bound-fn-2.rs:18:27
|
||||
|
|
||||
17 | let mut x = None;
|
||||
| ----- borrowed data cannot be stored into here...
|
||||
18 | with_int(|y| x = Some(y));
|
||||
| --- ^ cannot be stored outside of its closure
|
||||
| |
|
||||
| ...because it cannot outlive this closure
|
||||
|
||||
error: aborting due to previous error
|
||||
|
|
@ -15,5 +15,6 @@ fn with_int<F>(f: F) where F: FnOnce(&isize) {
|
|||
|
||||
fn main() {
|
||||
let mut x: Option<&isize> = None;
|
||||
with_int(|y| x = Some(y)); //~ ERROR cannot infer
|
||||
with_int(|y| x = Some(y));
|
||||
//~^ ERROR borrowed data cannot be stored outside of its closure
|
||||
}
|
12
src/test/ui/borrowck/regions-escape-bound-fn.stderr
Normal file
12
src/test/ui/borrowck/regions-escape-bound-fn.stderr
Normal file
|
@ -0,0 +1,12 @@
|
|||
error: borrowed data cannot be stored outside of its closure
|
||||
--> $DIR/regions-escape-bound-fn.rs:18:27
|
||||
|
|
||||
17 | let mut x: Option<&isize> = None;
|
||||
| ----- borrowed data cannot be stored into here...
|
||||
18 | with_int(|y| x = Some(y));
|
||||
| --- ^ cannot be stored outside of its closure
|
||||
| |
|
||||
| ...because it cannot outlive this closure
|
||||
|
||||
error: aborting due to previous error
|
||||
|
|
@ -13,5 +13,6 @@ fn with_int(f: &mut FnMut(&isize)) {
|
|||
|
||||
fn main() {
|
||||
let mut x: Option<&isize> = None;
|
||||
with_int(&mut |y| x = Some(y)); //~ ERROR cannot infer
|
||||
with_int(&mut |y| x = Some(y));
|
||||
//~^ ERROR borrowed data cannot be stored outside of its closure
|
||||
}
|
12
src/test/ui/borrowck/regions-escape-unboxed-closure.stderr
Normal file
12
src/test/ui/borrowck/regions-escape-unboxed-closure.stderr
Normal file
|
@ -0,0 +1,12 @@
|
|||
error: borrowed data cannot be stored outside of its closure
|
||||
--> $DIR/regions-escape-unboxed-closure.rs:16:32
|
||||
|
|
||||
15 | let mut x: Option<&isize> = None;
|
||||
| ----- borrowed data cannot be stored into here...
|
||||
16 | with_int(&mut |y| x = Some(y));
|
||||
| --- ^ cannot be stored outside of its closure
|
||||
| |
|
||||
| ...because it cannot outlive this closure
|
||||
|
||||
error: aborting due to previous error
|
||||
|
|
@ -25,7 +25,7 @@ fn expect_bound_supply_nothing() {
|
|||
// it to escape into `f`:
|
||||
let mut f: Option<&u32> = None;
|
||||
closure_expecting_bound(|x| {
|
||||
f = Some(x); //~ ERROR E0495
|
||||
f = Some(x); //~ ERROR borrowed data cannot be stored outside of its closure
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,7 @@ fn expect_bound_supply_bound() {
|
|||
// closure:
|
||||
let mut f: Option<&u32> = None;
|
||||
closure_expecting_bound(|x: &u32| {
|
||||
f = Some(x); //~ ERROR E0495
|
||||
f = Some(x); //~ ERROR borrowed data cannot be stored outside of its closure
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -50,7 +50,7 @@ fn expect_bound_supply_named<'x>() {
|
|||
|
||||
// And we still cannot let `x` escape into `f`.
|
||||
f = Some(x);
|
||||
//~^ ERROR cannot infer
|
||||
//~^ ERROR borrowed data cannot be stored outside of its closure
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
error: borrowed data cannot be stored outside of its closure
|
||||
--> $DIR/expect-region-supply-region.rs:28:18
|
||||
|
|
||||
26 | let mut f: Option<&u32> = None;
|
||||
| ----- borrowed data cannot be stored into here...
|
||||
27 | closure_expecting_bound(|x| {
|
||||
| --- ...because it cannot outlive this closure
|
||||
28 | f = Some(x); //~ ERROR borrowed data cannot be stored outside of its closure
|
||||
| ^ cannot be stored outside of its closure
|
||||
|
||||
error: borrowed data cannot be stored outside of its closure
|
||||
--> $DIR/expect-region-supply-region.rs:38:18
|
||||
|
|
||||
36 | let mut f: Option<&u32> = None;
|
||||
| ----- borrowed data cannot be stored into here...
|
||||
37 | closure_expecting_bound(|x: &u32| {
|
||||
| --------- ...because it cannot outlive this closure
|
||||
38 | f = Some(x); //~ ERROR borrowed data cannot be stored outside of its closure
|
||||
| ^ cannot be stored outside of its closure
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/expect-region-supply-region.rs:47:33
|
||||
|
|
||||
47 | closure_expecting_bound(|x: &'x u32| {
|
||||
| ^^^^^^^ lifetime mismatch
|
||||
|
|
||||
= note: expected type `&u32`
|
||||
found type `&'x u32`
|
||||
note: the anonymous lifetime #2 defined on the body at 47:29...
|
||||
--> $DIR/expect-region-supply-region.rs:47:29
|
||||
|
|
||||
47 | closure_expecting_bound(|x: &'x u32| {
|
||||
| _____________________________^
|
||||
48 | | //~^ ERROR mismatched types
|
||||
49 | | //~| ERROR mismatched types
|
||||
50 | |
|
||||
... |
|
||||
53 | | //~^ ERROR borrowed data cannot be stored outside of its closure
|
||||
54 | | });
|
||||
| |_____^
|
||||
note: ...does not necessarily outlive the lifetime 'x as defined on the function body at 42:1
|
||||
--> $DIR/expect-region-supply-region.rs:42:1
|
||||
|
|
||||
42 | / fn expect_bound_supply_named<'x>() {
|
||||
43 | | let mut f: Option<&u32> = None;
|
||||
44 | |
|
||||
45 | | // Here we give a type annotation that `x` should be free. We get
|
||||
... |
|
||||
54 | | });
|
||||
55 | | }
|
||||
| |_^
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/expect-region-supply-region.rs:47:33
|
||||
|
|
||||
47 | closure_expecting_bound(|x: &'x u32| {
|
||||
| ^^^^^^^ lifetime mismatch
|
||||
|
|
||||
= note: expected type `&u32`
|
||||
found type `&'x u32`
|
||||
note: the lifetime 'x as defined on the function body at 42:1...
|
||||
--> $DIR/expect-region-supply-region.rs:42:1
|
||||
|
|
||||
42 | / fn expect_bound_supply_named<'x>() {
|
||||
43 | | let mut f: Option<&u32> = None;
|
||||
44 | |
|
||||
45 | | // Here we give a type annotation that `x` should be free. We get
|
||||
... |
|
||||
54 | | });
|
||||
55 | | }
|
||||
| |_^
|
||||
note: ...does not necessarily outlive the anonymous lifetime #2 defined on the body at 47:29
|
||||
--> $DIR/expect-region-supply-region.rs:47:29
|
||||
|
|
||||
47 | closure_expecting_bound(|x: &'x u32| {
|
||||
| _____________________________^
|
||||
48 | | //~^ ERROR mismatched types
|
||||
49 | | //~| ERROR mismatched types
|
||||
50 | |
|
||||
... |
|
||||
53 | | //~^ ERROR borrowed data cannot be stored outside of its closure
|
||||
54 | | });
|
||||
| |_____^
|
||||
|
||||
error: borrowed data cannot be stored outside of its closure
|
||||
--> $DIR/expect-region-supply-region.rs:52:18
|
||||
|
|
||||
43 | let mut f: Option<&u32> = None;
|
||||
| ----- borrowed data cannot be stored into here...
|
||||
...
|
||||
47 | closure_expecting_bound(|x: &'x u32| {
|
||||
| ------------ ...because it cannot outlive this closure
|
||||
...
|
||||
52 | f = Some(x);
|
||||
| ^ cannot be stored outside of its closure
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
Loading…
Add table
Reference in a new issue