diff --git a/src/librustc/ich/impls_mir.rs b/src/librustc/ich/impls_mir.rs index 656f5795e18bd..f69d1d1590059 100644 --- a/src/librustc/ich/impls_mir.rs +++ b/src/librustc/ich/impls_mir.rs @@ -550,7 +550,23 @@ impl_stable_hash_for!(struct mir::ClosureRegionRequirements<'tcx> { impl_stable_hash_for!(struct mir::ClosureOutlivesRequirement<'tcx> { subject, outlived_free_region, - blame_span + blame_span, + category +}); + +impl_stable_hash_for!(enum mir::ConstraintCategory { + Return, + TypeAnnotation, + Cast, + ClosureBounds, + CallArgument, + CopyBound, + SizedBound, + Assignment, + OpaqueType, + Boring, + BoringNoLocation, + Internal, }); impl<'a, 'gcx> HashStable> for mir::ClosureOutlivesSubject<'gcx> { diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index aec6bb7c3c1ff..eef9c0f1cf88f 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -2639,11 +2639,51 @@ 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 +/// are interesting (for error reporting). Order of variants indicates sort +/// order of the category, thereby influencing diagnostic output. +/// +/// See also [rustc_mir::borrow_check::nll::constraints] +#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)] +pub enum ConstraintCategory { + Return, + TypeAnnotation, + Cast, + + /// A constraint that came from checking the body of a closure. + /// + /// We try to get the category that the closure used when reporting this. + ClosureBounds, + CallArgument, + CopyBound, + SizedBound, + Assignment, + OpaqueType, + + /// A "boring" constraint (caused by the given location) is one that + /// the user probably doesn't want to see described in diagnostics, + /// because it is kind of an artifact of the type system setup. + /// Example: `x = Foo { field: y }` technically creates + /// intermediate regions representing the "type of `Foo { field: y + /// }`", and data flows from `y` into those variables, but they + /// are not very interesting. The assignment into `x` on the other + /// hand might be. + Boring, + // Boring and applicable everywhere. + BoringNoLocation, + + /// A constraint that doesn't correspond to anything the user sees. + Internal, } /// The subject of a ClosureOutlivesRequirement -- that is, the thing diff --git a/src/librustc_mir/borrow_check/nll/constraints/graph.rs b/src/librustc_mir/borrow_check/nll/constraints/graph.rs index 2e018f746f389..3d4b2456f9657 100644 --- a/src/librustc_mir/borrow_check/nll/constraints/graph.rs +++ b/src/librustc_mir/borrow_check/nll/constraints/graph.rs @@ -9,8 +9,9 @@ // except according to those terms. use borrow_check::nll::type_check::Locations; -use borrow_check::nll::constraints::{ConstraintCategory, ConstraintIndex}; +use borrow_check::nll::constraints::ConstraintIndex; use borrow_check::nll::constraints::{ConstraintSet, OutlivesConstraint}; +use rustc::mir::ConstraintCategory; use rustc::ty::RegionVid; use rustc_data_structures::graph; use rustc_data_structures::indexed_vec::IndexVec; diff --git a/src/librustc_mir/borrow_check/nll/constraints/mod.rs b/src/librustc_mir/borrow_check/nll/constraints/mod.rs index 76ebc06bfd2f6..a873af8333a7f 100644 --- a/src/librustc_mir/borrow_check/nll/constraints/mod.rs +++ b/src/librustc_mir/borrow_check/nll/constraints/mod.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use rustc::mir::ConstraintCategory; use rustc::ty::RegionVid; use rustc_data_structures::graph::scc::Sccs; use rustc_data_structures::indexed_vec::{Idx, IndexVec}; @@ -23,42 +24,6 @@ crate struct ConstraintSet { constraints: IndexVec, } -/// Constraints can be categorized to determine whether and why they are -/// interesting. Order of variants indicates sort order of the category, -/// thereby influencing diagnostic output. -#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash)] -pub enum ConstraintCategory { - Return, - TypeAnnotation, - Cast, - CallArgument, - - /// A constraint that came from checking the body of a closure. - /// - /// Ideally we would give an explanation that points to the relevant part - /// of the closure's body. - ClosureBounds, - CopyBound, - SizedBound, - Assignment, - OpaqueType, - - /// A "boring" constraint (caused by the given location) is one that - /// the user probably doesn't want to see described in diagnostics, - /// because it is kind of an artifact of the type system setup. - /// Example: `x = Foo { field: y }` technically creates - /// intermediate regions representing the "type of `Foo { field: y - /// }`", and data flows from `y` into those variables, but they - /// are not very interesting. The assignment into `x` on the other - /// hand might be. - Boring, - // Boring and applicable everywhere. - BoringNoLocation, - - /// A constraint that doesn't correspond to anything the user sees. - Internal, -} - impl ConstraintSet { crate fn push(&mut self, constraint: OutlivesConstraint) { debug!( diff --git a/src/librustc_mir/borrow_check/nll/mod.rs b/src/librustc_mir/borrow_check/nll/mod.rs index 723b0e6fff6f8..6e35f2e63f74c 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 31d7c7c631e17..43dc68fdb3b05 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 @@ -8,17 +8,17 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use borrow_check::nll::constraints::{OutlivesConstraint, ConstraintCategory}; +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; -use rustc::mir::{Location, Mir}; +use rustc::mir::{ConstraintCategory, Location, Mir}; use rustc::ty::{self, RegionVid}; 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; @@ -28,22 +28,26 @@ mod var_name; use self::region_name::RegionName; -impl fmt::Display for ConstraintCategory { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { +trait ConstraintDescription { + fn description(&self) -> &'static str; +} + +impl ConstraintDescription for ConstraintCategory { + fn description(&self) -> &'static str { // Must end with a space. Allows for empty names to be provided. match self { - ConstraintCategory::Assignment => write!(f, "assignment "), - ConstraintCategory::Return => write!(f, "returning this value "), - ConstraintCategory::Cast => write!(f, "cast "), - ConstraintCategory::CallArgument => write!(f, "argument "), - ConstraintCategory::TypeAnnotation => write!(f, "type annotation "), - ConstraintCategory::ClosureBounds => write!(f, "closure body "), - ConstraintCategory::SizedBound => write!(f, "proving this value is `Sized` "), - ConstraintCategory::CopyBound => write!(f, "copying this value "), - ConstraintCategory::OpaqueType => write!(f, "opaque type "), + ConstraintCategory::Assignment => "assignment ", + ConstraintCategory::Return => "returning this value ", + ConstraintCategory::Cast => "cast ", + ConstraintCategory::CallArgument => "argument ", + ConstraintCategory::TypeAnnotation => "type annotation ", + ConstraintCategory::ClosureBounds => "closure body ", + ConstraintCategory::SizedBound => "proving this value is `Sized` ", + ConstraintCategory::CopyBound => "copying this value ", + ConstraintCategory::OpaqueType => "opaque type ", ConstraintCategory::Boring | ConstraintCategory::BoringNoLocation - | ConstraintCategory::Internal => write!(f, ""), + | ConstraintCategory::Internal => "", } } } @@ -89,7 +93,13 @@ impl<'tcx> RegionInferenceContext<'tcx> { // 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={:#?}", @@ -358,7 +368,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { _ => { diag.span_label(span, format!( "{}requires that `{}` must outlive `{}`", - category, fr_name, outlived_fr_name, + category.description(), fr_name, outlived_fr_name, )); }, } @@ -470,8 +480,24 @@ impl<'tcx> RegionInferenceContext<'tcx> { 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 4a8f011b606b7..56bb6a87d44fa 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs @@ -19,15 +19,17 @@ use rustc::infer::canonical::QueryRegionConstraint; use rustc::infer::region_constraints::{GenericKind, VarInfos, VerifyBound}; use rustc::infer::{InferCtxt, NLLRegionVariableOrigin, RegionVariableOrigin}; use rustc::mir::{ - ClosureOutlivesRequirement, ClosureOutlivesSubject, ClosureRegionRequirements, Local, Location, - Mir, + ClosureOutlivesRequirement, ClosureOutlivesSubject, ClosureRegionRequirements, + ConstraintCategory, Local, Location, Mir, }; 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 @@ impl<'tcx> RegionInferenceContext<'tcx> { 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 @@ impl<'tcx> RegionInferenceContext<'tcx> { constraints, constraint_graph, constraint_sccs, + closure_bounds_mapping, scc_universes, scc_representatives, scc_values, @@ -727,6 +740,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { 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 @@ impl<'tcx> RegionInferenceContext<'tcx> { 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 @@ impl<'tcx> RegionInferenceContext<'tcx> { 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 @@ impl<'tcx> RegionInferenceContext<'tcx> { }; // 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/constraint_conversion.rs b/src/librustc_mir/borrow_check/nll/type_check/constraint_conversion.rs index dabf669eca65f..4ab0f952bdee9 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/constraint_conversion.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/constraint_conversion.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use borrow_check::nll::constraints::{ConstraintCategory, ConstraintSet, OutlivesConstraint}; +use borrow_check::nll::constraints::{ConstraintSet, OutlivesConstraint}; use borrow_check::nll::region_infer::TypeTest; use borrow_check::nll::type_check::Locations; use borrow_check::nll::universal_regions::UniversalRegions; @@ -17,6 +17,7 @@ use rustc::infer::outlives::env::RegionBoundPairs; use rustc::infer::outlives::obligations::{TypeOutlives, TypeOutlivesDelegate}; use rustc::infer::region_constraints::{GenericKind, VerifyBound}; use rustc::infer::{self, SubregionOrigin}; +use rustc::mir::ConstraintCategory; use rustc::ty::subst::UnpackedKind; use rustc::ty::{self, TyCtxt}; use syntax_pos::DUMMY_SP; diff --git a/src/librustc_mir/borrow_check/nll/type_check/free_region_relations.rs b/src/librustc_mir/borrow_check/nll/type_check/free_region_relations.rs index f33909db78f9f..35342b2129e6e 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/free_region_relations.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/free_region_relations.rs @@ -12,11 +12,11 @@ use borrow_check::nll::type_check::constraint_conversion; use borrow_check::nll::type_check::{Locations, MirTypeckRegionConstraints}; use borrow_check::nll::universal_regions::UniversalRegions; use borrow_check::nll::ToRegionVid; -use borrow_check::nll::constraints::ConstraintCategory; use rustc::infer::canonical::QueryRegionConstraint; use rustc::infer::outlives::free_region_map::FreeRegionRelations; use rustc::infer::region_constraints::GenericKind; use rustc::infer::InferCtxt; +use rustc::mir::ConstraintCategory; use rustc::traits::query::outlives_bounds::{self, OutlivesBound}; use rustc::traits::query::type_op::{self, TypeOp}; use rustc::ty::{self, RegionVid, Ty}; diff --git a/src/librustc_mir/borrow_check/nll/type_check/input_output.rs b/src/librustc_mir/borrow_check/nll/type_check/input_output.rs index 942f19965bf37..a4665984d3e0b 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/input_output.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/input_output.rs @@ -24,7 +24,7 @@ use rustc::ty::Ty; use rustc_data_structures::indexed_vec::Idx; use syntax_pos::Span; -use super::{ConstraintCategory, Locations, TypeChecker}; +use super::{Locations, TypeChecker}; impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { pub(super) fn equate_inputs_and_outputs( diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs index 6c1252fc73d8b..bc4e0ca235139 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs @@ -9,7 +9,6 @@ // except according to those terms. use borrow_check::location::LocationTable; -use borrow_check::nll::constraints::ConstraintCategory; use borrow_check::nll::region_infer::values::{self, PointIndex, RegionValueElements}; use borrow_check::nll::type_check::liveness::liveness_map::{LiveVar, NllLivenessMap}; use borrow_check::nll::type_check::liveness::local_use_map::LocalUseMap; @@ -19,7 +18,7 @@ use dataflow::move_paths::indexes::MovePathIndex; use dataflow::move_paths::MoveData; use dataflow::{FlowAtLocation, FlowsAtLocation, MaybeInitializedPlaces}; use rustc::infer::canonical::QueryRegionConstraint; -use rustc::mir::{BasicBlock, Local, Location, Mir}; +use rustc::mir::{BasicBlock, ConstraintCategory, Local, Location, Mir}; use rustc::traits::query::dropck_outlives::DropckOutlivesResult; use rustc::traits::query::type_op::outlives::DropckOutlives; use rustc::traits::query::type_op::TypeOp; 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 99ac80862b13e..36eb695186c67 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -13,7 +13,7 @@ use borrow_check::borrow_set::BorrowSet; use borrow_check::location::LocationTable; -use borrow_check::nll::constraints::{ConstraintCategory, ConstraintSet, OutlivesConstraint}; +use borrow_check::nll::constraints::{ConstraintSet, OutlivesConstraint}; use borrow_check::nll::facts::AllFacts; use borrow_check::nll::region_infer::values::LivenessValues; use borrow_check::nll::region_infer::values::PlaceholderIndices; @@ -42,7 +42,7 @@ use rustc::traits::query::type_op::custom::CustomTypeOp; 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 syntax_pos::{Span, DUMMY_SP}; 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 @@ crate struct MirTypeckRegionConstraints<'tcx> { crate outlives_constraints: ConstraintSet, + crate closure_bounds_mapping: FxHashMap< + Location, + FxHashMap<(RegionVid, RegionVid), (ConstraintCategory, Span)>, + >, + crate type_tests: Vec>, } @@ -860,7 +866,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { &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 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { 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 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { 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 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { 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 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { rv_ty, terr ); - } + } } TerminatorKind::SwitchInt { ref discr, @@ -1387,9 +1393,9 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { 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 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { sig.output(), terr ); - } + } // When `#![feature(unsized_locals)]` is not enabled, // this check is done at `check_local`. @@ -2038,7 +2044,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { 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 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { // 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 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { ); } + 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/librustc_mir/borrow_check/nll/type_check/relate_tys.rs b/src/librustc_mir/borrow_check/nll/type_check/relate_tys.rs index 4e8dbf8498e2a..41aab02d1e826 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/relate_tys.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/relate_tys.rs @@ -8,10 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use borrow_check::nll::constraints::{ConstraintCategory, OutlivesConstraint}; +use borrow_check::nll::constraints::OutlivesConstraint; use borrow_check::nll::type_check::{BorrowCheckContext, Locations}; use rustc::infer::canonical::{Canonical, CanonicalVarInfos}; use rustc::infer::{InferCtxt, NLLRegionVariableOrigin}; +use rustc::mir::ConstraintCategory; use rustc::traits::query::Fallible; use rustc::ty::fold::{TypeFoldable, TypeVisitor}; use rustc::ty::relate::{self, Relate, RelateResult, TypeRelation}; diff --git a/src/test/ui/issues/issue-10291.nll.stderr b/src/test/ui/issues/issue-10291.nll.stderr index 201a3b3d54a3f..a21336654f379 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 700c0dffb7011..3f7e400ed4360 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 2e1249a5e8126..ef84820de38eb 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 9963954c9c2d4..49b6258164013 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 9f1d9d21d11c0..7ebd36e10b564 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 d35b5c34a9181..0181792cbdcff 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 4e72fe4bb28aa..d62910576b0c3 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 75641943f2fac..1a0531cbd42f6 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 de60b23ef6b97..aa19368240418 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 455fbba232007..dc7f58fc8f843 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 b98aca74058b9..18d35d8b9bf68 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 6e4bf26047e46..fd52494b49947 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 4bb602d572fa3..cbc1e6b787db5 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