Skip to content

Commit

Permalink
Use span of the closure args in free region errors
Browse files Browse the repository at this point in the history
  • Loading branch information
matthewjasper committed Aug 5, 2018
1 parent ddcf17e commit f72b8a4
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 55 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

use borrow_check::nll::region_infer::RegionInferenceContext;
use borrow_check::nll::ToRegionVid;
use borrow_check::nll::universal_regions::DefiningTy;
use rustc::hir;
use rustc::hir::def_id::DefId;
use rustc::infer::InferCtxt;
Expand Down Expand Up @@ -72,7 +73,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
})
.or_else(|| {
self.give_name_if_anonymous_region_appears_in_output(
infcx.tcx, mir, fr, counter, diag)
infcx.tcx, mir, mir_def_id, fr, counter, diag)
})
.unwrap_or_else(|| span_bug!(mir.span, "can't make a name for free region {:?}", fr))
}
Expand Down Expand Up @@ -107,13 +108,46 @@ impl<'tcx> RegionInferenceContext<'tcx> {
},

ty::BoundRegion::BrEnv => {
let closure_span = tcx.hir.span_if_local(mir_def_id).unwrap();
let region_name = self.synthesize_region_name(counter);
diag.span_label(
closure_span,
format!("lifetime `{}` represents the closure body", region_name),
);
Some(region_name)
let mir_node_id = tcx.hir.as_local_node_id(mir_def_id).expect("non-local mir");
let def_ty = self.universal_regions.defining_ty;

if let DefiningTy::Closure(def_id, substs) = def_ty {
let args_span = if let hir::ExprKind::Closure(_, _, _, span, _)
= tcx.hir.expect_expr(mir_node_id).node
{
span
} else {
bug!("Closure is not defined by a closure expr");
};
let region_name = self.synthesize_region_name(counter);
diag.span_label(
args_span,
format!("lifetime `{}` represents this closure's body", region_name),
);

let closure_kind_ty = substs.closure_kind_ty(def_id, tcx);
let note = match closure_kind_ty.to_opt_closure_kind() {
Some(ty::ClosureKind::Fn) => {
"closure implements `Fn`, so references to captured variables \
can't escape the closure"
}
Some(ty::ClosureKind::FnMut) => {
"closure implements `FnMut`, so references to captured variables \
can't escape the closure"
}
Some(ty::ClosureKind::FnOnce) => {
bug!("BrEnv in a `FnOnce` closure");
}
None => bug!("Closure kind not inferred in borrow check"),
};

diag.note(note);

Some(region_name)
} else {
// Can't have BrEnv in functions, constants or generators.
bug!("BrEnv outside of closure.");
}
}

ty::BoundRegion::BrAnon(_) | ty::BoundRegion::BrFresh(_) => None,
Expand Down Expand Up @@ -545,6 +579,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
&self,
tcx: TyCtxt<'_, '_, 'tcx>,
mir: &Mir<'tcx>,
mir_def_id: DefId,
fr: RegionVid,
counter: &mut usize,
diag: &mut DiagnosticBuilder<'_>,
Expand All @@ -558,9 +593,18 @@ impl<'tcx> RegionInferenceContext<'tcx> {
return None;
}

let mir_node_id = tcx.hir.as_local_node_id(mir_def_id).expect("non-local mir");
let args_span = if let hir::ExprKind::Closure(_, _, _, span, _)
= tcx.hir.expect_expr(mir_node_id).node
{
span
} else {
mir.span
};

let region_name = self.synthesize_region_name(counter);
diag.span_label(
mir.span,
args_span,
format!("lifetime `{}` appears in return type", region_name),
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@ error: unsatisfied lifetime constraints
--> $DIR/E0621-does-not-trigger-for-closures.rs:25:26
|
LL | invoke(&x, |a, b| if a > b { a } else { b }); //~ ERROR E0495
| ----------^^^^^-----------------
| | | |
| | | requires that `'1` must outlive `'2`
| ------ ^^^^^ requires that `'1` must outlive `'2`
| | |
| | has type `&'1 i32`
| lifetime `'2` appears in return type

Expand Down
20 changes: 9 additions & 11 deletions src/test/ui/issue-40510-1.nll.stderr
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
error: unsatisfied lifetime constraints
--> $DIR/issue-40510-1.rs:18:9
|
LL | || {
| _____-
| |_____|
| ||
LL | || &mut x
| || ^^^^^^ return requires that `'1` must outlive `'2`
LL | || };
| || -
| ||_____|
| |______lifetime `'1` represents the closure body
| lifetime `'2` appears in return type
LL | || {
| --
| |
| lifetime `'1` represents this closure's body
| lifetime `'2` appears in return type
LL | &mut x
| ^^^^^^ return requires that `'1` must outlive `'2`
|
= note: closure implements `FnMut`, so references to captured variables can't escape the closure

error: aborting due to previous error

25 changes: 11 additions & 14 deletions src/test/ui/issue-40510-3.nll.stderr
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
error: unsatisfied lifetime constraints
--> $DIR/issue-40510-3.rs:18:9
|
LL | || {
| _____-
| |_____|
| ||
LL | || || {
| ||_________^
LL | ||| x.push(())
LL | ||| }
| |||_________^ requires that `'1` must outlive `'2`
LL | || };
| || -
| ||_____|
| |______lifetime `'1` represents the closure body
| lifetime `'2` appears in return type
LL | || {
| --
| |
| lifetime `'1` represents this closure's body
| lifetime `'2` appears in return type
LL | / || {
LL | | x.push(())
LL | | }
| |_________^ requires that `'1` must outlive `'2`
|
= note: closure implements `FnMut`, so references to captured variables can't escape the closure

error: aborting due to previous error

25 changes: 11 additions & 14 deletions src/test/ui/issue-49824.nll.stderr
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
error: unsatisfied lifetime constraints
--> $DIR/issue-49824.rs:22:9
|
LL | || {
| _____-
| |_____|
| ||
LL | || || {
| ||_________^
LL | ||| let _y = &mut x;
LL | ||| }
| |||_________^ requires that `'1` must outlive `'2`
LL | || };
| || -
| ||_____|
| |______lifetime `'1` represents the closure body
| lifetime `'2` appears in return type
LL | || {
| --
| |
| lifetime `'1` represents this closure's body
| lifetime `'2` appears in return type
LL | / || {
LL | | let _y = &mut x;
LL | | }
| |_________^ requires that `'1` must outlive `'2`
|
= note: closure implements `FnMut`, so references to captured variables can't escape the closure

error: aborting due to previous error

9 changes: 5 additions & 4 deletions src/test/ui/nll/issue-48238.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ error: unsatisfied lifetime constraints
--> $DIR/issue-48238.rs:21:13
|
LL | move || use_val(&orig); //~ ERROR
| --------^^^^^^^^^^^^^^
| | |
| | argument requires that `'1` must outlive `'2`
| lifetime `'1` represents the closure body
| ------- ^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
| |
| lifetime `'1` represents this closure's body
| lifetime `'2` appears in return type
|
= note: closure implements `Fn`, so references to captured variables can't escape the closure

error: aborting due to previous error

0 comments on commit f72b8a4

Please sign in to comment.