From 825810734b55ad680403655cf814c2d1312f0155 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Wed, 3 Oct 2018 21:56:11 +0100 Subject: [PATCH] Improve closure region bound errors Now use the category and span that are associated to the most interesting bound that led to the closure bound. --- src/librustc/mir/mod.rs | 7 +- src/librustc_mir/borrow_check/nll/mod.rs | 2 + .../nll/region_infer/error_reporting/mod.rs | 32 ++++- .../borrow_check/nll/region_infer/mod.rs | 25 +++- .../borrow_check/nll/type_check/mod.rs | 123 +++++++++++++----- src/test/ui/issues/issue-10291.nll.stderr | 14 +- .../propagate-approximated-ref.rs | 2 +- .../propagate-approximated-ref.stderr | 25 ++-- ...approximated-shorter-to-static-no-bound.rs | 2 +- ...oximated-shorter-to-static-no-bound.stderr | 28 ++-- ...roximated-shorter-to-static-wrong-bound.rs | 2 +- ...mated-shorter-to-static-wrong-bound.stderr | 27 ++-- .../propagate-approximated-val.rs | 2 +- .../propagate-approximated-val.stderr | 25 ++-- .../projection-one-region-closure.stderr | 8 +- ...tion-one-region-trait-bound-closure.stderr | 8 +- .../regions-addr-of-upvar-self.nll.stderr | 15 +-- .../ui/regions/regions-nested-fns.nll.stderr | 15 +-- 18 files changed, 214 insertions(+), 148 deletions(-) diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 61e8ad4a8c4..eef9c0f1cf8 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -2639,11 +2639,14 @@ pub struct ClosureOutlivesRequirement<'tcx> { // This region or type ... pub subject: ClosureOutlivesSubject<'tcx>, - // .. must outlive this one. + // ... must outlive this one. pub outlived_free_region: ty::RegionVid, - // If not, report an error here. + // If not, report an error here ... pub blame_span: Span, + + // ... due to this reason. + pub category: ConstraintCategory, } /// Outlives constraints can be categorized to determine whether and why they diff --git a/src/librustc_mir/borrow_check/nll/mod.rs b/src/librustc_mir/borrow_check/nll/mod.rs index 723b0e6fff6..6e35f2e63f7 100644 --- a/src/librustc_mir/borrow_check/nll/mod.rs +++ b/src/librustc_mir/borrow_check/nll/mod.rs @@ -138,6 +138,7 @@ pub(in borrow_check) fn compute_regions<'cx, 'gcx, 'tcx>( let MirTypeckRegionConstraints { mut liveness_constraints, outlives_constraints, + closure_bounds_mapping, type_tests, } = constraints; @@ -157,6 +158,7 @@ pub(in borrow_check) fn compute_regions<'cx, 'gcx, 'tcx>( universal_region_relations, mir, outlives_constraints, + closure_bounds_mapping, type_tests, liveness_constraints, elements, diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs index 9acfe42e6ca..43dc68fdb3b 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs @@ -10,6 +10,7 @@ use borrow_check::nll::constraints::{OutlivesConstraint}; use borrow_check::nll::region_infer::RegionInferenceContext; +use borrow_check::nll::type_check::Locations; use rustc::hir::def_id::DefId; use rustc::infer::error_reporting::nice_region_error::NiceRegionError; use rustc::infer::InferCtxt; @@ -18,7 +19,6 @@ use rustc_data_structures::indexed_vec::IndexVec; use rustc_errors::{Diagnostic, DiagnosticBuilder}; use std::collections::VecDeque; -use std::fmt; use syntax::symbol::keywords; use syntax_pos::Span; use syntax::errors::Applicability; @@ -93,7 +93,13 @@ fn best_blame_constraint( // Classify each of the constraints along the path. let mut categorized_path: Vec<(ConstraintCategory, Span)> = path .iter() - .map(|constraint| (constraint.category, constraint.locations.span(mir))) + .map(|constraint| { + if constraint.category == ConstraintCategory::ClosureBounds { + self.retrieve_closure_constraint_info(mir, &constraint) + } else { + (constraint.category, constraint.locations.span(mir)) + } + }) .collect(); debug!( "best_blame_constraint: categorized_path={:#?}", @@ -474,8 +480,24 @@ fn add_static_impl_trait_suggestion( mir: &Mir<'tcx>, fr1: RegionVid, fr2: RegionVid, - ) -> Span { - let (_, span, _) = self.best_blame_constraint(mir, fr1, |r| r == fr2); - span + ) -> (ConstraintCategory, Span) { + let (category, span, _) = self.best_blame_constraint(mir, fr1, |r| r == fr2); + (category, span) + } + + fn retrieve_closure_constraint_info( + &self, + mir: &Mir<'tcx>, + constraint: &OutlivesConstraint + ) -> (ConstraintCategory, Span) { + let loc = match constraint.locations { + Locations::All(span) => return (constraint.category, span), + Locations::Single(loc) => loc, + }; + + let opt_span_category = self + .closure_bounds_mapping[&loc] + .get(&(constraint.sup, constraint.sub)); + *opt_span_category.unwrap_or(&(constraint.category, mir.source_info(loc).span)) } } diff --git a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs index a6730fa847f..56bb6a87d44 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs @@ -25,9 +25,11 @@ use rustc::ty::{self, RegionVid, Ty, TyCtxt, TypeFoldable}; use rustc::util::common; use rustc_data_structures::bit_set::BitSet; +use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::graph::scc::Sccs; use rustc_data_structures::indexed_vec::IndexVec; use rustc_errors::{Diagnostic, DiagnosticBuilder}; +use syntax_pos::Span; use std::rc::Rc; @@ -60,10 +62,16 @@ pub struct RegionInferenceContext<'tcx> { /// the SCC (see `constraint_sccs`) and for error reporting. constraint_graph: Rc, - /// The SCC computed from `constraints` and the constraint graph. Used to compute the values - /// of each region. + /// The SCC computed from `constraints` and the constraint graph. Used to + /// compute the values of each region. constraint_sccs: Rc>, + /// Map closure bounds to a `Span` that should be used for error reporting. + closure_bounds_mapping: FxHashMap< + Location, + FxHashMap<(RegionVid, RegionVid), (ConstraintCategory, Span)>, + >, + /// Contains the minimum universe of any variable within the same /// SCC. We will ensure that no SCC contains values that are not /// visible from this index. @@ -187,6 +195,10 @@ pub(crate) fn new( universal_region_relations: Rc>, _mir: &Mir<'tcx>, outlives_constraints: ConstraintSet, + closure_bounds_mapping: FxHashMap< + Location, + FxHashMap<(RegionVid, RegionVid), (ConstraintCategory, Span)>, + >, type_tests: Vec>, liveness_constraints: LivenessValues, elements: &Rc, @@ -220,6 +232,7 @@ pub(crate) fn new( constraints, constraint_graph, constraint_sccs, + closure_bounds_mapping, scc_universes, scc_representatives, scc_values, @@ -727,6 +740,7 @@ fn try_promote_type_test<'gcx>( subject, outlived_free_region: non_local_ub, blame_span: locations.span(mir), + category: ConstraintCategory::Boring, }; debug!("try_promote_type_test: pushing {:#?}", requirement); propagated_outlives_requirements.push(requirement); @@ -1125,7 +1139,7 @@ fn check_universal_region<'gcx>( longer_fr, shorter_fr, ); - let blame_span = self.find_outlives_blame_span(mir, longer_fr, shorter_fr); + let blame_span_category = self.find_outlives_blame_span(mir, longer_fr, shorter_fr); if let Some(propagated_outlives_requirements) = propagated_outlives_requirements { // Shrink `fr` until we find a non-local region (if we do). @@ -1150,7 +1164,8 @@ fn check_universal_region<'gcx>( propagated_outlives_requirements.push(ClosureOutlivesRequirement { subject: ClosureOutlivesSubject::Region(fr_minus), outlived_free_region: shorter_fr_plus, - blame_span: blame_span, + blame_span: blame_span_category.1, + category: blame_span_category.0, }); return; } @@ -1213,7 +1228,7 @@ fn check_bound_universal_region<'gcx>( }; // Find the code to blame for the fact that `longer_fr` outlives `error_fr`. - let span = self.find_outlives_blame_span(mir, longer_fr, error_region); + let (_, span) = self.find_outlives_blame_span(mir, longer_fr, error_region); // Obviously, this error message is far from satisfactory. // At present, though, it only appears in unit tests -- diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs index 553d4a426a7..36eb695186c 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -42,7 +42,7 @@ use rustc::traits::query::{Fallible, NoSolution}; use rustc::traits::{ObligationCause, PredicateObligations}; use rustc::ty::fold::TypeFoldable; -use rustc::ty::subst::Subst; +use rustc::ty::subst::{Subst, UnpackedKind}; use rustc::ty::{self, CanonicalTy, RegionVid, ToPolyTraitRef, Ty, TyCtxt, TyKind}; use std::rc::Rc; use std::{fmt, iter}; @@ -50,7 +50,7 @@ use transform::{MirPass, MirSource}; use either::Either; -use rustc_data_structures::fx::FxHashSet; +use rustc_data_structures::fx::{FxHashMap, FxHashSet}; macro_rules! span_mirbug { ($context:expr, $elem:expr, $($message:tt)*) => ({ @@ -128,6 +128,7 @@ pub(crate) fn type_check<'gcx, 'tcx>( let mut constraints = MirTypeckRegionConstraints { liveness_constraints: LivenessValues::new(elements), outlives_constraints: ConstraintSet::default(), + closure_bounds_mapping: FxHashMap(), type_tests: Vec::default(), }; let mut placeholder_indices = PlaceholderIndices::default(); @@ -752,6 +753,11 @@ struct BorrowCheckContext<'a, 'tcx: 'a> { crate outlives_constraints: ConstraintSet, + crate closure_bounds_mapping: FxHashMap< + Location, + FxHashMap<(RegionVid, RegionVid), (ConstraintCategory, Span)>, + >, + crate type_tests: Vec>, } @@ -860,7 +866,7 @@ fn fully_perform_op( &mut self, locations: Locations, category: ConstraintCategory, - op: impl type_op::TypeOp<'gcx, 'tcx, Output = R>, + op: impl type_op::TypeOp<'gcx, 'tcx, Output=R>, ) -> Fallible { let (r, opt_data) = op.fully_perform(self.infcx)?; @@ -1103,9 +1109,9 @@ fn check_stmt(&mut self, mir: &Mir<'tcx>, stmt: &Statement<'tcx>, location: Loca let place_ty = place.ty(mir, tcx).to_ty(tcx); let rv_ty = rv.ty(mir, tcx); if let Err(terr) = - self.sub_types_or_anon(rv_ty, place_ty, location.to_locations(), category) - { - span_mirbug!( + self.sub_types_or_anon(rv_ty, place_ty, location.to_locations(), category) + { + span_mirbug!( self, stmt, "bad assignment ({:?} = {:?}): {:?}", @@ -1113,7 +1119,7 @@ fn check_stmt(&mut self, mir: &Mir<'tcx>, stmt: &Statement<'tcx>, location: Loca rv_ty, terr ); - } + } if let Some(user_ty) = self.rvalue_user_ty(rv) { if let Err(terr) = self.relate_type_and_user_type( @@ -1233,9 +1239,9 @@ fn check_terminator( let locations = term_location.to_locations(); if let Err(terr) = - self.sub_types(rv_ty, place_ty, locations, ConstraintCategory::Assignment) - { - span_mirbug!( + self.sub_types(rv_ty, place_ty, locations, ConstraintCategory::Assignment) + { + span_mirbug!( self, term, "bad DropAndReplace ({:?} = {:?}): {:?}", @@ -1243,7 +1249,7 @@ fn check_terminator( rv_ty, terr ); - } + } } TerminatorKind::SwitchInt { ref discr, @@ -1387,9 +1393,9 @@ fn check_call_dest( let locations = term_location.to_locations(); if let Err(terr) = - self.sub_types_or_anon(sig.output(), dest_ty, locations, category) - { - span_mirbug!( + self.sub_types_or_anon(sig.output(), dest_ty, locations, category) + { + span_mirbug!( self, term, "call dest mismatch ({:?} <- {:?}): {:?}", @@ -1397,7 +1403,7 @@ fn check_call_dest( sig.output(), terr ); - } + } // When `#![feature(unsized_locals)]` is not enabled, // this check is done at `check_local`. @@ -2038,7 +2044,7 @@ fn prove_aggregate_predicates( aggregate_kind, location ); - let instantiated_predicates = match aggregate_kind { + let instantiated_predicates = match aggregate_kind { AggregateKind::Adt(def, _, substs, _, _) => { tcx.predicates_of(def.did).instantiate(tcx, substs) } @@ -2064,24 +2070,7 @@ fn prove_aggregate_predicates( // these extra requirements are basically like where // clauses on the struct. AggregateKind::Closure(def_id, substs) => { - if let Some(closure_region_requirements) = - tcx.mir_borrowck(*def_id).closure_requirements - { - let closure_constraints = closure_region_requirements.apply_requirements( - self.infcx.tcx, - location, - *def_id, - *substs, - ); - - self.push_region_constraints( - location.to_locations(), - ConstraintCategory::ClosureBounds, - &closure_constraints, - ); - } - - tcx.predicates_of(*def_id).instantiate(tcx, substs.substs) + self.prove_closure_bounds(tcx, *def_id, *substs, location) } AggregateKind::Generator(def_id, substs, _) => { @@ -2097,6 +2086,72 @@ fn prove_aggregate_predicates( ); } + fn prove_closure_bounds( + &mut self, + tcx: TyCtxt<'a, 'gcx, 'tcx>, + def_id: DefId, + substs: ty::ClosureSubsts<'tcx>, + location: Location, + ) -> ty::InstantiatedPredicates<'tcx> { + if let Some(closure_region_requirements) = + tcx.mir_borrowck(def_id).closure_requirements + { + let closure_constraints = closure_region_requirements.apply_requirements( + tcx, + location, + def_id, + substs, + ); + + if let Some(ref mut borrowck_context) = self.borrowck_context { + let bounds_mapping = closure_constraints + .iter() + .enumerate() + .filter_map(|(idx, constraint)| { + let ty::OutlivesPredicate(k1, r2) = + constraint.no_late_bound_regions().unwrap_or_else(|| { + bug!( + "query_constraint {:?} contained bound regions", + constraint, + ); + }); + + match k1.unpack() { + UnpackedKind::Lifetime(r1) => { + // constraint is r1: r2 + let r1_vid = borrowck_context.universal_regions.to_region_vid(r1); + let r2_vid = borrowck_context.universal_regions.to_region_vid(r2); + let outlives_requirements = &closure_region_requirements + .outlives_requirements[idx]; + Some(( + (r1_vid, r2_vid), + ( + outlives_requirements.category, + outlives_requirements.blame_span, + ), + )) + } + UnpackedKind::Type(_) => None, + } + }) + .collect(); + + let existing = borrowck_context.constraints + .closure_bounds_mapping + .insert(location, bounds_mapping); + assert!(existing.is_none(), "Multiple closures at the same location."); + } + + self.push_region_constraints( + location.to_locations(), + ConstraintCategory::ClosureBounds, + &closure_constraints, + ); + } + + tcx.predicates_of(def_id).instantiate(tcx, substs.substs) + } + fn prove_trait_ref( &mut self, trait_ref: ty::TraitRef<'tcx>, diff --git a/src/test/ui/issues/issue-10291.nll.stderr b/src/test/ui/issues/issue-10291.nll.stderr index 201a3b3d54a..a21336654f3 100644 --- a/src/test/ui/issues/issue-10291.nll.stderr +++ b/src/test/ui/issues/issue-10291.nll.stderr @@ -1,13 +1,11 @@ error: unsatisfied lifetime constraints - --> $DIR/issue-10291.rs:12:65 + --> $DIR/issue-10291.rs:13:9 | -LL | fn test<'x>(x: &'x isize) { - | -- lifetime `'x` defined here -LL | drop:: FnMut(&'z isize) -> &'z isize>>(Box::new(|z| { - | _________________________________________________________________^ -LL | | x //~ ERROR E0312 -LL | | })); - | |_____^ closure body requires that `'x` must outlive `'static` +LL | fn test<'x>(x: &'x isize) { + | -- lifetime `'x` defined here +LL | drop:: FnMut(&'z isize) -> &'z isize>>(Box::new(|z| { +LL | x //~ ERROR E0312 + | ^ returning this value requires that `'x` must outlive `'static` error: aborting due to previous error diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-ref.rs b/src/test/ui/nll/closure-requirements/propagate-approximated-ref.rs index 700c0dffb70..3f7e400ed43 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-ref.rs +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-ref.rs @@ -51,10 +51,10 @@ fn demand_y<'x, 'y>(_cell_x: &Cell<&'x u32>, _cell_y: &Cell<&'y u32>, _y: &'y u3 #[rustc_regions] fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| { - //~^ ERROR unsatisfied lifetime constraints // Only works if 'x: 'y: demand_y(x, y, x.get()) + //~^ ERROR unsatisfied lifetime constraints }); } diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr index 2e1249a5e81..ef84820de38 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr @@ -3,10 +3,10 @@ note: External requirements | LL | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| { | _______________________________________________^ -LL | | //~^ ERROR unsatisfied lifetime constraints LL | | LL | | // Only works if 'x: 'y: LL | | demand_y(x, y, x.get()) +LL | | //~^ ERROR unsatisfied lifetime constraints LL | | }); | |_____^ | @@ -24,8 +24,8 @@ note: No external requirements | LL | / fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { LL | | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| { -LL | | //~^ ERROR unsatisfied lifetime constraints LL | | +LL | | // Only works if 'x: 'y: ... | LL | | }); LL | | } @@ -34,20 +34,15 @@ LL | | } = note: defining type: DefId(0/0:6 ~ propagate_approximated_ref[317d]::supply[0]) with substs [] error: unsatisfied lifetime constraints - --> $DIR/propagate-approximated-ref.rs:53:47 + --> $DIR/propagate-approximated-ref.rs:56:9 | -LL | fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { - | -- -- lifetime `'b` defined here - | | - | lifetime `'a` defined here -LL | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| { - | _______________________________________________^ -LL | | //~^ ERROR unsatisfied lifetime constraints -LL | | -LL | | // Only works if 'x: 'y: -LL | | demand_y(x, y, x.get()) -LL | | }); - | |_____^ closure body requires that `'a` must outlive `'b` +LL | fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +... +LL | demand_y(x, y, x.get()) + | ^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'a` must outlive `'b` error: aborting due to previous error diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.rs b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.rs index 9963954c9c2..49b62581640 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.rs +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.rs @@ -44,10 +44,10 @@ fn demand_y<'x, 'y>(_cell_x: &Cell<&'x u32>, _cell_y: &Cell<&'y u32>, _y: &'y u3 fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { establish_relationships(&cell_a, &cell_b, |_outlives, x, y| { //~^ ERROR borrowed data escapes outside of function - //~| ERROR unsatisfied lifetime constraints // Only works if 'x: 'y: demand_y(x, y, x.get()) + //~^ ERROR unsatisfied lifetime constraints }); } diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr index 9f1d9d21d11..7ebd36e10b5 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr @@ -4,10 +4,10 @@ note: External requirements LL | establish_relationships(&cell_a, &cell_b, |_outlives, x, y| { | _______________________________________________^ LL | | //~^ ERROR borrowed data escapes outside of function -LL | | //~| ERROR unsatisfied lifetime constraints LL | | LL | | // Only works if 'x: 'y: LL | | demand_y(x, y, x.get()) +LL | | //~^ ERROR unsatisfied lifetime constraints LL | | }); | |_____^ | @@ -26,7 +26,7 @@ note: No external requirements LL | / fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { LL | | establish_relationships(&cell_a, &cell_b, |_outlives, x, y| { LL | | //~^ ERROR borrowed data escapes outside of function -LL | | //~| ERROR unsatisfied lifetime constraints +LL | | ... | LL | | }); LL | | } @@ -41,29 +41,23 @@ LL | fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { | ------ `cell_a` is a reference that is only valid in the function body LL | / establish_relationships(&cell_a, &cell_b, |_outlives, x, y| { LL | | //~^ ERROR borrowed data escapes outside of function -LL | | //~| ERROR unsatisfied lifetime constraints LL | | LL | | // Only works if 'x: 'y: LL | | demand_y(x, y, x.get()) +LL | | //~^ ERROR unsatisfied lifetime constraints LL | | }); | |______^ `cell_a` escapes the function body here error: unsatisfied lifetime constraints - --> $DIR/propagate-approximated-shorter-to-static-no-bound.rs:45:47 + --> $DIR/propagate-approximated-shorter-to-static-no-bound.rs:49:9 | -LL | fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { - | -- -- lifetime `'b` defined here - | | - | lifetime `'a` defined here -LL | establish_relationships(&cell_a, &cell_b, |_outlives, x, y| { - | _______________________________________________^ -LL | | //~^ ERROR borrowed data escapes outside of function -LL | | //~| ERROR unsatisfied lifetime constraints -LL | | -LL | | // Only works if 'x: 'y: -LL | | demand_y(x, y, x.get()) -LL | | }); - | |_____^ closure body requires that `'a` must outlive `'b` +LL | fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +... +LL | demand_y(x, y, x.get()) + | ^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'a` must outlive `'b` error: aborting due to 2 previous errors diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.rs b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.rs index d35b5c34a91..0181792cbdc 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.rs +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.rs @@ -47,9 +47,9 @@ fn demand_y<'x, 'y>(_cell_x: &Cell<&'x u32>, _cell_y: &Cell<&'y u32>, _y: &'y u3 fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| { //~^ ERROR borrowed data escapes outside of function - //~| ERROR unsatisfied lifetime constraints // Only works if 'x: 'y: demand_y(x, y, x.get()) + //~^ ERROR unsatisfied lifetime constraints }); } diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr index 4e72fe4bb28..d62910576b0 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr @@ -4,9 +4,9 @@ note: External requirements LL | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| { | _______________________________________________^ LL | | //~^ ERROR borrowed data escapes outside of function -LL | | //~| ERROR unsatisfied lifetime constraints LL | | // Only works if 'x: 'y: LL | | demand_y(x, y, x.get()) +LL | | //~^ ERROR unsatisfied lifetime constraints LL | | }); | |_____^ | @@ -25,7 +25,7 @@ note: No external requirements LL | / fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { LL | | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| { LL | | //~^ ERROR borrowed data escapes outside of function -LL | | //~| ERROR unsatisfied lifetime constraints +LL | | // Only works if 'x: 'y: ... | LL | | }); LL | | } @@ -40,27 +40,22 @@ LL | fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { | ------ `cell_a` is a reference that is only valid in the function body LL | / establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| { LL | | //~^ ERROR borrowed data escapes outside of function -LL | | //~| ERROR unsatisfied lifetime constraints LL | | // Only works if 'x: 'y: LL | | demand_y(x, y, x.get()) +LL | | //~^ ERROR unsatisfied lifetime constraints LL | | }); | |______^ `cell_a` escapes the function body here error: unsatisfied lifetime constraints - --> $DIR/propagate-approximated-shorter-to-static-wrong-bound.rs:48:47 + --> $DIR/propagate-approximated-shorter-to-static-wrong-bound.rs:51:9 | -LL | fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { - | -- -- lifetime `'b` defined here - | | - | lifetime `'a` defined here -LL | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| { - | _______________________________________________^ -LL | | //~^ ERROR borrowed data escapes outside of function -LL | | //~| ERROR unsatisfied lifetime constraints -LL | | // Only works if 'x: 'y: -LL | | demand_y(x, y, x.get()) -LL | | }); - | |_____^ closure body requires that `'a` must outlive `'b` +LL | fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +... +LL | demand_y(x, y, x.get()) + | ^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'a` must outlive `'b` error: aborting due to 2 previous errors diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-val.rs b/src/test/ui/nll/closure-requirements/propagate-approximated-val.rs index 75641943f2f..1a0531cbd42 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-val.rs +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-val.rs @@ -44,10 +44,10 @@ fn demand_y<'x, 'y>(_outlives1: Cell<&&'x u32>, _outlives2: Cell<&'y &u32>, _y: #[rustc_regions] fn test<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { establish_relationships(cell_a, cell_b, |outlives1, outlives2, x, y| { - //~^ ERROR unsatisfied lifetime constraints // Only works if 'x: 'y: demand_y(outlives1, outlives2, x.get()) + //~^ ERROR unsatisfied lifetime constraints }); } diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr index de60b23ef6b..aa193682404 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr @@ -3,10 +3,10 @@ note: External requirements | LL | establish_relationships(cell_a, cell_b, |outlives1, outlives2, x, y| { | _____________________________________________^ -LL | | //~^ ERROR unsatisfied lifetime constraints LL | | LL | | // Only works if 'x: 'y: LL | | demand_y(outlives1, outlives2, x.get()) +LL | | //~^ ERROR unsatisfied lifetime constraints LL | | }); | |_____^ | @@ -24,8 +24,8 @@ note: No external requirements | LL | / fn test<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { LL | | establish_relationships(cell_a, cell_b, |outlives1, outlives2, x, y| { -LL | | //~^ ERROR unsatisfied lifetime constraints LL | | +LL | | // Only works if 'x: 'y: ... | LL | | }); LL | | } @@ -34,20 +34,15 @@ LL | | } = note: defining type: DefId(0/0:6 ~ propagate_approximated_val[317d]::test[0]) with substs [] error: unsatisfied lifetime constraints - --> $DIR/propagate-approximated-val.rs:46:45 + --> $DIR/propagate-approximated-val.rs:49:9 | -LL | fn test<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { - | -- -- lifetime `'b` defined here - | | - | lifetime `'a` defined here -LL | establish_relationships(cell_a, cell_b, |outlives1, outlives2, x, y| { - | _____________________________________________^ -LL | | //~^ ERROR unsatisfied lifetime constraints -LL | | -LL | | // Only works if 'x: 'y: -LL | | demand_y(outlives1, outlives2, x.get()) -LL | | }); - | |_____^ closure body requires that `'a` must outlive `'b` +LL | fn test<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +... +LL | demand_y(outlives1, outlives2, x.get()) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'a` must outlive `'b` error: aborting due to previous error diff --git a/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr b/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr index 455fbba2320..dc7f58fc8f8 100644 --- a/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr +++ b/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr @@ -41,7 +41,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); = help: consider adding an explicit lifetime bound `T: ReFree(DefId(0/0:8 ~ projection_one_region_closure[317d]::no_relationships_late[0]), BrNamed(crate0:DefIndex(1:16), 'a))`... error: unsatisfied lifetime constraints - --> $DIR/projection-one-region-closure.rs:55:29 + --> $DIR/projection-one-region-closure.rs:55:39 | LL | fn no_relationships_late<'a, 'b, T>(cell: Cell<&'a ()>, t: T) | -- -- lifetime `'b` defined here @@ -49,7 +49,7 @@ LL | fn no_relationships_late<'a, 'b, T>(cell: Cell<&'a ()>, t: T) | lifetime `'a` defined here ... LL | with_signature(cell, t, |cell, t| require(cell, t)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ closure body requires that `'b` must outlive `'a` + | ^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a` note: External requirements --> $DIR/projection-one-region-closure.rs:66:29 @@ -95,7 +95,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); = help: consider adding an explicit lifetime bound `T: ReEarlyBound(0, 'a)`... error: unsatisfied lifetime constraints - --> $DIR/projection-one-region-closure.rs:66:29 + --> $DIR/projection-one-region-closure.rs:66:39 | LL | fn no_relationships_early<'a, 'b, T>(cell: Cell<&'a ()>, t: T) | -- -- lifetime `'b` defined here @@ -103,7 +103,7 @@ LL | fn no_relationships_early<'a, 'b, T>(cell: Cell<&'a ()>, t: T) | lifetime `'a` defined here ... LL | with_signature(cell, t, |cell, t| require(cell, t)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ closure body requires that `'b` must outlive `'a` + | ^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a` note: External requirements --> $DIR/projection-one-region-closure.rs:80:29 diff --git a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr index b98aca74058..18d35d8b9bf 100644 --- a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr +++ b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr @@ -32,7 +32,7 @@ LL | | } ] error: unsatisfied lifetime constraints - --> $DIR/projection-one-region-trait-bound-closure.rs:47:29 + --> $DIR/projection-one-region-trait-bound-closure.rs:47:39 | LL | fn no_relationships_late<'a, 'b, T>(cell: Cell<&'a ()>, t: T) | -- -- lifetime `'b` defined here @@ -40,7 +40,7 @@ LL | fn no_relationships_late<'a, 'b, T>(cell: Cell<&'a ()>, t: T) | lifetime `'a` defined here ... LL | with_signature(cell, t, |cell, t| require(cell, t)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ closure body requires that `'b` must outlive `'a` + | ^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a` note: External requirements --> $DIR/projection-one-region-trait-bound-closure.rs:57:29 @@ -77,7 +77,7 @@ LL | | } ] error: unsatisfied lifetime constraints - --> $DIR/projection-one-region-trait-bound-closure.rs:57:29 + --> $DIR/projection-one-region-trait-bound-closure.rs:57:39 | LL | fn no_relationships_early<'a, 'b, T>(cell: Cell<&'a ()>, t: T) | -- -- lifetime `'b` defined here @@ -85,7 +85,7 @@ LL | fn no_relationships_early<'a, 'b, T>(cell: Cell<&'a ()>, t: T) | lifetime `'a` defined here ... LL | with_signature(cell, t, |cell, t| require(cell, t)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ closure body requires that `'b` must outlive `'a` + | ^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a` note: External requirements --> $DIR/projection-one-region-trait-bound-closure.rs:70:29 diff --git a/src/test/ui/regions/regions-addr-of-upvar-self.nll.stderr b/src/test/ui/regions/regions-addr-of-upvar-self.nll.stderr index 6e4bf26047e..fd52494b499 100644 --- a/src/test/ui/regions/regions-addr-of-upvar-self.nll.stderr +++ b/src/test/ui/regions/regions-addr-of-upvar-self.nll.stderr @@ -21,16 +21,13 @@ LL | let p: &'static mut usize = &mut self.food; //~ ERROR cannot in = note: closure implements `FnMut`, so references to captured variables can't escape the closure error: unsatisfied lifetime constraints - --> $DIR/regions-addr-of-upvar-self.rs:19:18 + --> $DIR/regions-addr-of-upvar-self.rs:20:17 | -LL | pub fn chase_cat(&mut self) { - | - let's call the lifetime of this reference `'1` -LL | let _f = || { - | __________________^ -LL | | let p: &'static mut usize = &mut self.food; //~ ERROR cannot infer -LL | | *p = 3; -LL | | }; - | |_________^ closure body requires that `'1` must outlive `'static` +LL | pub fn chase_cat(&mut self) { + | - let's call the lifetime of this reference `'1` +LL | let _f = || { +LL | let p: &'static mut usize = &mut self.food; //~ ERROR cannot infer + | ^ type annotation requires that `'1` must outlive `'static` error[E0597]: `self` does not live long enough --> $DIR/regions-addr-of-upvar-self.rs:20:46 diff --git a/src/test/ui/regions/regions-nested-fns.nll.stderr b/src/test/ui/regions/regions-nested-fns.nll.stderr index 4bb602d572f..cbc1e6b787d 100644 --- a/src/test/ui/regions/regions-nested-fns.nll.stderr +++ b/src/test/ui/regions/regions-nested-fns.nll.stderr @@ -36,18 +36,13 @@ LL | } = note: borrowed value must be valid for the static lifetime... error: unsatisfied lifetime constraints - --> $DIR/regions-nested-fns.rs:23:68 + --> $DIR/regions-nested-fns.rs:24:27 | -LL | fn nested<'x>(x: &'x isize) { - | -- lifetime `'x` defined here +LL | fn nested<'x>(x: &'x isize) { + | -- lifetime `'x` defined here ... -LL | ignore::< Box FnMut(&'z isize) -> &'z isize>>(Box::new(|z| { - | ____________________________________________________________________^ -LL | | if false { return x; } //~ ERROR E0312 -LL | | if false { return ay; } -LL | | return z; -LL | | })); - | |_____^ closure body requires that `'x` must outlive `'static` +LL | if false { return x; } //~ ERROR E0312 + | ^ returning this value requires that `'x` must outlive `'static` error: aborting due to 4 previous errors -- GitLab