Skip to content

Commit a178cba

Browse files
committed
Auto merge of rust-lang#52021 - nikomatsakis:nll-region-errors, r=estebank
refactor and cleanup region errors for NLL This is a WIP commit. It simplifies some of the code from rust-lang#51536 and extends a few more steps towards the errors that @davidtwco and I were shooting for. These are intended as a replacement for the general "unable to infer lifetime" messages -- one that is actually actionable. We're certainly not there yet, but the overall shape hopefully gets a bit clearer. I'm thinking about trying to open up an internals thread to sketch out the overall plan and perhaps discuss how to get the wording right, which special cases to handle, etc. r? @estebank cc @davidtwco
2 parents e06c875 + 727f017 commit a178cba

File tree

53 files changed

+694
-295
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+694
-295
lines changed

src/librustc/ich/impls_mir.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ impl_stable_hash_for!(struct mir::LocalDecl<'tcx> {
3030
internal,
3131
is_user_variable
3232
});
33-
impl_stable_hash_for!(struct mir::UpvarDecl { debug_name, by_ref, mutability });
33+
impl_stable_hash_for!(struct mir::UpvarDecl { debug_name, var_hir_id, by_ref, mutability });
3434
impl_stable_hash_for!(struct mir::BasicBlockData<'tcx> { statements, terminator, is_cleanup });
3535
impl_stable_hash_for!(struct mir::UnsafetyViolation { source_info, description, kind });
3636
impl_stable_hash_for!(struct mir::UnsafetyCheckResult { violations, unsafe_blocks });

src/librustc/mir/mod.rs

+13-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
use graphviz::IntoCow;
1616
use hir::def::CtorKind;
1717
use hir::def_id::DefId;
18-
use hir::{self, InlineAsm};
18+
use hir::{self, HirId, InlineAsm};
1919
use middle::region;
2020
use mir::interpret::{EvalErrorKind, Scalar, Value};
2121
use mir::visit::MirVisitable;
@@ -380,6 +380,15 @@ pub enum ClearCrossCrate<T> {
380380
Set(T),
381381
}
382382

383+
impl<T> ClearCrossCrate<T> {
384+
pub fn assert_crate_local(self) -> T {
385+
match self {
386+
ClearCrossCrate::Clear => bug!("unwrapping cross-crate data"),
387+
ClearCrossCrate::Set(v) => v,
388+
}
389+
}
390+
}
391+
383392
impl<T: serialize::Encodable> serialize::UseSpecializedEncodable for ClearCrossCrate<T> {}
384393
impl<T: serialize::Decodable> serialize::UseSpecializedDecodable for ClearCrossCrate<T> {}
385394

@@ -785,6 +794,9 @@ impl<'tcx> LocalDecl<'tcx> {
785794
pub struct UpvarDecl {
786795
pub debug_name: Name,
787796

797+
/// `HirId` of the captured variable
798+
pub var_hir_id: ClearCrossCrate<HirId>,
799+
788800
/// If true, the capture is behind a reference.
789801
pub by_ref: bool,
790802

src/librustc/ty/fold.rs

+32-14
Original file line numberDiff line numberDiff line change
@@ -253,13 +253,34 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
253253
value.fold_with(&mut RegionFolder::new(self, skipped_regions, &mut f))
254254
}
255255

256-
pub fn for_each_free_region<T,F>(self,
257-
value: &T,
258-
callback: F)
259-
where F: FnMut(ty::Region<'tcx>),
260-
T: TypeFoldable<'tcx>,
261-
{
262-
value.visit_with(&mut RegionVisitor {
256+
/// Invoke `callback` on every region appearing free in `value`.
257+
pub fn for_each_free_region(
258+
self,
259+
value: &impl TypeFoldable<'tcx>,
260+
mut callback: impl FnMut(ty::Region<'tcx>),
261+
) {
262+
self.any_free_region_meets(value, |r| {
263+
callback(r);
264+
false
265+
});
266+
}
267+
268+
/// True if `callback` returns true for every region appearing free in `value`.
269+
pub fn all_free_regions_meet(
270+
self,
271+
value: &impl TypeFoldable<'tcx>,
272+
mut callback: impl FnMut(ty::Region<'tcx>) -> bool,
273+
) -> bool {
274+
!self.any_free_region_meets(value, |r| !callback(r))
275+
}
276+
277+
/// True if `callback` returns true for some region appearing free in `value`.
278+
pub fn any_free_region_meets(
279+
self,
280+
value: &impl TypeFoldable<'tcx>,
281+
callback: impl FnMut(ty::Region<'tcx>) -> bool,
282+
) -> bool {
283+
return value.visit_with(&mut RegionVisitor {
263284
outer_index: ty::INNERMOST,
264285
callback
265286
});
@@ -287,25 +308,22 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
287308
}
288309

289310
impl<'tcx, F> TypeVisitor<'tcx> for RegionVisitor<F>
290-
where F : FnMut(ty::Region<'tcx>)
311+
where F: FnMut(ty::Region<'tcx>) -> bool
291312
{
292313
fn visit_binder<T: TypeFoldable<'tcx>>(&mut self, t: &Binder<T>) -> bool {
293314
self.outer_index.shift_in(1);
294-
t.skip_binder().visit_with(self);
315+
let result = t.skip_binder().visit_with(self);
295316
self.outer_index.shift_out(1);
296-
297-
false // keep visiting
317+
result
298318
}
299319

300320
fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
301321
match *r {
302322
ty::ReLateBound(debruijn, _) if debruijn < self.outer_index => {
303-
/* ignore bound regions */
323+
false // ignore bound regions, keep visiting
304324
}
305325
_ => (self.callback)(r),
306326
}
307-
308-
false // keep visiting
309327
}
310328
}
311329
}

src/librustc_mir/borrow_check/mod.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,8 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
128128
input_mir: &Mir<'gcx>,
129129
def_id: DefId,
130130
) -> BorrowCheckResult<'gcx> {
131+
debug!("do_mir_borrowck(def_id = {:?})", def_id);
132+
131133
let tcx = infcx.tcx;
132134
let attributes = tcx.get_attrs(def_id);
133135
let param_env = tcx.param_env(def_id);
@@ -319,10 +321,14 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
319321
}
320322
}
321323

322-
BorrowCheckResult {
324+
let result = BorrowCheckResult {
323325
closure_requirements: opt_closure_req,
324326
used_mut_upvars: mbcx.used_mut_upvars,
325-
}
327+
};
328+
329+
debug!("do_mir_borrowck: result = {:#?}", result);
330+
331+
result
326332
}
327333

328334
#[allow(dead_code)]

0 commit comments

Comments
 (0)