diff --git a/src/librustc/ich/impls_mir.rs b/src/librustc/ich/impls_mir.rs index f43ac7ad0dd5a..6217f6c9fdd33 100644 --- a/src/librustc/ich/impls_mir.rs +++ b/src/librustc/ich/impls_mir.rs @@ -30,7 +30,7 @@ impl_stable_hash_for!(struct mir::LocalDecl<'tcx> { internal, is_user_variable }); -impl_stable_hash_for!(struct mir::UpvarDecl { debug_name, by_ref, mutability }); +impl_stable_hash_for!(struct mir::UpvarDecl { debug_name, var_hir_id, by_ref, mutability }); impl_stable_hash_for!(struct mir::BasicBlockData<'tcx> { statements, terminator, is_cleanup }); impl_stable_hash_for!(struct mir::UnsafetyViolation { source_info, description, kind }); impl_stable_hash_for!(struct mir::UnsafetyCheckResult { violations, unsafe_blocks }); diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index dca0d4f442a4c..cd4b32735e57a 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -15,7 +15,7 @@ use graphviz::IntoCow; use hir::def::CtorKind; use hir::def_id::DefId; -use hir::{self, InlineAsm}; +use hir::{self, HirId, InlineAsm}; use middle::region; use mir::interpret::{EvalErrorKind, Scalar, Value}; use mir::visit::MirVisitable; @@ -380,6 +380,15 @@ pub enum ClearCrossCrate { Set(T), } +impl ClearCrossCrate { + pub fn assert_crate_local(self) -> T { + match self { + ClearCrossCrate::Clear => bug!("unwrapping cross-crate data"), + ClearCrossCrate::Set(v) => v, + } + } +} + impl serialize::UseSpecializedEncodable for ClearCrossCrate {} impl serialize::UseSpecializedDecodable for ClearCrossCrate {} @@ -785,6 +794,9 @@ impl<'tcx> LocalDecl<'tcx> { pub struct UpvarDecl { pub debug_name: Name, + /// `HirId` of the captured variable + pub var_hir_id: ClearCrossCrate, + /// If true, the capture is behind a reference. pub by_ref: bool, diff --git a/src/librustc/ty/fold.rs b/src/librustc/ty/fold.rs index f55a512908499..076a19fb4ed72 100644 --- a/src/librustc/ty/fold.rs +++ b/src/librustc/ty/fold.rs @@ -253,13 +253,34 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { value.fold_with(&mut RegionFolder::new(self, skipped_regions, &mut f)) } - pub fn for_each_free_region(self, - value: &T, - callback: F) - where F: FnMut(ty::Region<'tcx>), - T: TypeFoldable<'tcx>, - { - value.visit_with(&mut RegionVisitor { + /// Invoke `callback` on every region appearing free in `value`. + pub fn for_each_free_region( + self, + value: &impl TypeFoldable<'tcx>, + mut callback: impl FnMut(ty::Region<'tcx>), + ) { + self.any_free_region_meets(value, |r| { + callback(r); + false + }); + } + + /// True if `callback` returns true for every region appearing free in `value`. + pub fn all_free_regions_meet( + self, + value: &impl TypeFoldable<'tcx>, + mut callback: impl FnMut(ty::Region<'tcx>) -> bool, + ) -> bool { + !self.any_free_region_meets(value, |r| !callback(r)) + } + + /// True if `callback` returns true for some region appearing free in `value`. + pub fn any_free_region_meets( + self, + value: &impl TypeFoldable<'tcx>, + callback: impl FnMut(ty::Region<'tcx>) -> bool, + ) -> bool { + return value.visit_with(&mut RegionVisitor { outer_index: ty::INNERMOST, callback }); @@ -287,25 +308,22 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } impl<'tcx, F> TypeVisitor<'tcx> for RegionVisitor - where F : FnMut(ty::Region<'tcx>) + where F: FnMut(ty::Region<'tcx>) -> bool { fn visit_binder>(&mut self, t: &Binder) -> bool { self.outer_index.shift_in(1); - t.skip_binder().visit_with(self); + let result = t.skip_binder().visit_with(self); self.outer_index.shift_out(1); - - false // keep visiting + result } fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool { match *r { ty::ReLateBound(debruijn, _) if debruijn < self.outer_index => { - /* ignore bound regions */ + false // ignore bound regions, keep visiting } _ => (self.callback)(r), } - - false // keep visiting } } } diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 3aaa3378bb005..3417021640f17 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -128,6 +128,8 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>( input_mir: &Mir<'gcx>, def_id: DefId, ) -> BorrowCheckResult<'gcx> { + debug!("do_mir_borrowck(def_id = {:?})", def_id); + let tcx = infcx.tcx; let attributes = tcx.get_attrs(def_id); let param_env = tcx.param_env(def_id); @@ -319,10 +321,14 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>( } } - BorrowCheckResult { + let result = BorrowCheckResult { closure_requirements: opt_closure_req, used_mut_upvars: mbcx.used_mut_upvars, - } + }; + + debug!("do_mir_borrowck: result = {:#?}", result); + + result } #[allow(dead_code)] diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs similarity index 55% rename from src/librustc_mir/borrow_check/nll/region_infer/error_reporting.rs rename to src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs index 6543516b9c2c6..786b6a77d2bdb 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs @@ -8,19 +8,21 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::fmt; -use borrow_check::nll::region_infer::{ConstraintIndex, RegionInferenceContext}; use borrow_check::nll::region_infer::values::ToElementIndex; +use borrow_check::nll::region_infer::{ConstraintIndex, RegionInferenceContext}; use borrow_check::nll::type_check::Locations; use rustc::hir::def_id::DefId; -use rustc::infer::InferCtxt; use rustc::infer::error_reporting::nice_region_error::NiceRegionError; -use rustc::mir::{self, Location, Mir, Place, StatementKind, TerminatorKind, Rvalue}; +use rustc::infer::InferCtxt; +use rustc::mir::{self, Location, Mir, Place, Rvalue, StatementKind, TerminatorKind}; use rustc::ty::RegionVid; -use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::indexed_vec::IndexVec; +use std::fmt; use syntax_pos::Span; +mod region_name; + /// Constraints that are considered interesting can be categorized to /// determine why they are interesting. Order of variants indicates /// sort order of the category, thereby influencing diagnostic output. @@ -47,115 +49,105 @@ impl fmt::Display for ConstraintCategory { } impl<'tcx> RegionInferenceContext<'tcx> { - /// When reporting an error, it is useful to be able to determine which constraints influenced - /// the region being reported as an error. This function finds all of the paths from the + /// Walks the graph of constraints (where `'a: 'b` is considered + /// an edge `'b -> 'a`) to find all paths from `from_region` to + /// `to_region`. The paths are accumulated into the vector + /// `results`. The paths are stored as a series of + /// `ConstraintIndex` values -- in other words, a list of *edges*. + /// + /// # Parameters + /// + /// - `from_region` + /// When reporting an error, it is useful to be able to determine + /// which constraints influenced the region being reported as an + /// error. This function finds all of the paths from the /// constraint. - fn find_constraint_paths_from_region( + fn find_constraint_paths_between_regions( &self, - r0: RegionVid + from_region: RegionVid, + target_test: impl Fn(RegionVid) -> bool, ) -> Vec> { - let constraints = self.constraints.clone(); - - // Mapping of regions to the previous region and constraint index that led to it. - let mut previous = FxHashMap(); - // Regions yet to be visited. - let mut next = vec! [ r0 ]; - // Regions that have been visited. - let mut visited = FxHashSet(); - // Ends of paths. - let mut end_regions = FxHashSet(); - - // When we've still got points to visit... - while let Some(current) = next.pop() { - // ...take the next point... - debug!("find_constraint_paths_from_region: current={:?} visited={:?} next={:?}", - current, visited, next); - // ...but make sure not to visit this point again... - visited.insert(current); - - // ...find the edges containing it... - let mut upcoming = Vec::new(); - for (index, constraint) in constraints.iter_enumerated() { - if constraint.sub == current { - // ...add the regions that join us with to the path we've taken... - debug!("find_constraint_paths_from_region: index={:?} constraint={:?}", - index, constraint); - let next_region = constraint.sup.clone(); - - // ...unless we've visited it since this was added... - if visited.contains(&next_region) { - debug!("find_constraint_paths_from_region: skipping as visited"); - continue; - } - - previous.insert(next_region, (index, Some(current))); - upcoming.push(next_region); - } - } + let mut results = vec![]; + self.find_constraint_paths_between_regions_helper( + from_region, + from_region, + &target_test, + &mut FxHashSet::default(), + &mut vec![], + &mut results, + ); + results + } - if upcoming.is_empty() { - // If we didn't find any edges then this is the end of a path... - debug!("find_constraint_paths_from_region: new end region current={:?}", current); - end_regions.insert(current); - } else { - // ...but, if we did find edges, then add these to the regions yet to visit. - debug!("find_constraint_paths_from_region: extend next upcoming={:?}", upcoming); - next.extend(upcoming); - } + /// Helper for `find_constraint_paths_between_regions`. + fn find_constraint_paths_between_regions_helper( + &self, + from_region: RegionVid, + current_region: RegionVid, + target_test: &impl Fn(RegionVid) -> bool, + visited: &mut FxHashSet, + stack: &mut Vec, + results: &mut Vec>, + ) { + let dependency_map = self.dependency_map.as_ref().unwrap(); + // Check if we already visited this region. + if !visited.insert(current_region) { + return; } - // Now we've visited each point, compute the final paths. - let mut paths: Vec> = Vec::new(); - debug!("find_constraint_paths_from_region: end_regions={:?}", end_regions); - for end_region in end_regions { - debug!("find_constraint_paths_from_region: end_region={:?}", end_region); - - // Get the constraint and region that led to this end point. - // We can unwrap as we know if end_point was in the vector that it - // must also be in our previous map. - let (mut index, mut region) = previous.get(&end_region).unwrap(); - debug!("find_constraint_paths_from_region: index={:?} region={:?}", index, region); - - // Keep track of the indices. - let mut path: Vec = vec![index]; - - while region.is_some() && region != Some(r0) { - let p = previous.get(®ion.unwrap()).unwrap(); - index = p.0; - region = p.1; - - debug!("find_constraint_paths_from_region: index={:?} region={:?}", index, region); - path.push(index); + // Check if we reached the region we were looking for. + if target_test(current_region) { + if !stack.is_empty() { + assert_eq!(self.constraints[stack[0]].sub, from_region); + results.push(stack.clone()); } - - // Add to our paths. - paths.push(path); + return; } - debug!("find_constraint_paths_from_region: paths={:?}", paths); - paths + self.constraints + .each_affected_by_dirty(dependency_map[current_region], |constraint| { + assert_eq!(self.constraints[constraint].sub, current_region); + stack.push(constraint); + self.find_constraint_paths_between_regions_helper( + from_region, + self.constraints[constraint].sup, + target_test, + visited, + stack, + results, + ); + stack.pop(); + }); } /// This function will return true if a constraint is interesting and false if a constraint /// is not. It is useful in filtering constraint paths to only interesting points. - fn constraint_is_interesting(&self, index: &ConstraintIndex) -> bool { - self.constraints.get(*index).filter(|constraint| { - debug!("constraint_is_interesting: locations={:?} constraint={:?}", - constraint.locations, constraint); - if let Locations::Interesting(_) = constraint.locations { true } else { false } - }).is_some() + fn constraint_is_interesting(&self, index: ConstraintIndex) -> bool { + let constraint = self.constraints[index]; + debug!( + "constraint_is_interesting: locations={:?} constraint={:?}", + constraint.locations, constraint + ); + if let Locations::Interesting(_) = constraint.locations { + true + } else { + false + } } /// This function classifies a constraint from a location. - fn classify_constraint(&self, index: &ConstraintIndex, - mir: &Mir<'tcx>) -> Option<(ConstraintCategory, Span)> { - let constraint = self.constraints.get(*index)?; + fn classify_constraint( + &self, + index: ConstraintIndex, + mir: &Mir<'tcx>, + ) -> (ConstraintCategory, Span) { + let constraint = self.constraints[index]; let span = constraint.locations.span(mir); - let location = constraint.locations.from_location()?; + let location = constraint.locations.from_location().unwrap_or(Location::START); if !self.constraint_is_interesting(index) { - return Some((ConstraintCategory::Boring, span)); + return (ConstraintCategory::Boring, span); } let data = &mir[location.block]; @@ -182,12 +174,12 @@ impl<'tcx> RegionInferenceContext<'tcx> { _ => ConstraintCategory::Other, } } - }, + } _ => ConstraintCategory::Other, } }; - Some((category, span)) + (category, span) } /// Report an error because the universal region `fr` was required to outlive @@ -207,12 +199,9 @@ impl<'tcx> RegionInferenceContext<'tcx> { outlived_fr: RegionVid, blame_span: Span, ) { - // Obviously uncool error reporting. - - let fr_name = self.to_error_region(fr); - let outlived_fr_name = self.to_error_region(outlived_fr); + debug!("report_error(fr={:?}, outlived_fr={:?})", fr, outlived_fr); - if let (Some(f), Some(o)) = (fr_name, outlived_fr_name) { + if let (Some(f), Some(o)) = (self.to_error_region(fr), self.to_error_region(outlived_fr)) { let tables = infcx.tcx.typeck_tables_of(mir_def_id); let nice = NiceRegionError::new_from_span(infcx.tcx, blame_span, o, f, Some(tables)); if let Some(_error_reported) = nice.try_report() { @@ -220,43 +209,52 @@ impl<'tcx> RegionInferenceContext<'tcx> { } } - let fr_string = match fr_name { - Some(r) => format!("free region `{}`", r), - None => format!("free region `{:?}`", fr), - }; - - let outlived_fr_string = match outlived_fr_name { - Some(r) => format!("free region `{}`", r), - None => format!("free region `{:?}`", outlived_fr), - }; + // Find all paths + let constraint_paths = self.find_constraint_paths_between_regions(outlived_fr, |r| r == fr); + debug!("report_error: constraint_paths={:#?}", constraint_paths); - let constraints = self.find_constraint_paths_from_region(fr.clone()); - let path = constraints.iter().min_by_key(|p| p.len()).unwrap(); + // Find the shortest such path. + let path = constraint_paths.iter().min_by_key(|p| p.len()).unwrap(); debug!("report_error: shortest_path={:?}", path); - let mut categorized_path = path.iter().filter_map(|index| { - self.classify_constraint(index, mir) - }).collect::>(); + // Classify each of the constraints along the path. + let mut categorized_path: Vec<(ConstraintCategory, Span)> = path.iter() + .map(|&index| self.classify_constraint(index, mir)) + .collect(); debug!("report_error: categorized_path={:?}", categorized_path); + // Find what appears to be the most interesting path to report to the user. categorized_path.sort_by(|p0, p1| p0.0.cmp(&p1.0)); debug!("report_error: sorted_path={:?}", categorized_path); - if let Some((category, span)) = &categorized_path.first() { - let mut diag = infcx.tcx.sess.struct_span_err( - *span, &format!("{} requires that data must outlive {}", - category, outlived_fr_string), - ); - - diag.emit(); - } else { - let mut diag = infcx.tcx.sess.struct_span_err( - blame_span, - &format!("{} does not outlive {}", fr_string, outlived_fr_string,), - ); - - diag.emit(); - } + // Get a span + let (category, span) = categorized_path.first().unwrap(); + let diag = &mut infcx.tcx.sess.struct_span_err( + *span, + &format!("unsatisfied lifetime constraints"), // FIXME + ); + + // Figure out how we can refer + let counter = &mut 1; + let fr_name = self.give_region_a_name(infcx.tcx, mir, mir_def_id, fr, counter, diag); + let outlived_fr_name = self.give_region_a_name( + infcx.tcx, + mir, + mir_def_id, + outlived_fr, + counter, + diag, + ); + + diag.span_label( + *span, + format!( + "{} requires that `{}` must outlive `{}`", + category, fr_name, outlived_fr_name, + ), + ); + + diag.emit(); } // Find some constraint `X: Y` where: @@ -269,8 +267,11 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// Tries to finds a good span to blame for the fact that `fr1` /// contains `fr2`. - pub(super) fn blame_constraint(&self, fr1: RegionVid, - elem: impl ToElementIndex) -> ConstraintIndex { + pub(super) fn blame_constraint( + &self, + fr1: RegionVid, + elem: impl ToElementIndex, + ) -> ConstraintIndex { // Find everything that influenced final value of `fr`. let influenced_fr1 = self.dependencies(fr1); diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs new file mode 100644 index 0000000000000..bf8c9c8c3bef4 --- /dev/null +++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs @@ -0,0 +1,256 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use borrow_check::nll::region_infer::RegionInferenceContext; +use borrow_check::nll::ToRegionVid; +use rustc::hir::def_id::DefId; +use rustc::mir::{Local, Mir}; +use rustc::ty::{self, RegionVid, TyCtxt}; +use rustc_data_structures::indexed_vec::Idx; +use rustc_errors::DiagnosticBuilder; +use syntax::ast::Name; +use syntax::symbol::keywords; +use syntax_pos::symbol::InternedString; + +impl<'tcx> RegionInferenceContext<'tcx> { + /// Maps from an internal MIR region vid to something that we can + /// report to the user. In some cases, the region vids will map + /// directly to lifetimes that the user has a name for (e.g., + /// `'static`). But frequently they will not, in which case we + /// have to find some way to identify the lifetime to the user. To + /// that end, this function takes a "diagnostic" so that it can + /// create auxiliary notes as needed. + /// + /// Example (function arguments): + /// + /// Suppose we are trying to give a name to the lifetime of the + /// reference `x`: + /// + /// ``` + /// fn foo(x: &u32) { .. } + /// ``` + /// + /// This function would create a label like this: + /// + /// ``` + /// | fn foo(x: &u32) { .. } + /// ------- fully elaborated type of `x` is `&'1 u32` + /// ``` + /// + /// and then return the name `'1` for us to use. + crate fn give_region_a_name( + &self, + tcx: TyCtxt<'_, '_, 'tcx>, + mir: &Mir<'tcx>, + mir_def_id: DefId, + fr: RegionVid, + counter: &mut usize, + diag: &mut DiagnosticBuilder, + ) -> InternedString { + debug!("give_region_a_name(fr={:?}, counter={})", fr, counter); + + assert!(self.universal_regions.is_universal_region(fr)); + + self.give_name_from_error_region(tcx, mir_def_id, fr, counter, diag) + .or_else(|| { + self.give_name_if_anonymous_region_appears_in_arguments(tcx, mir, fr, counter, diag) + }) + .or_else(|| { + self.give_name_if_anonymous_region_appears_in_upvars(tcx, mir, fr, counter, diag) + }) + .or_else(|| { + self.give_name_if_anonymous_region_appears_in_output(tcx, mir, fr, counter, diag) + }) + .unwrap_or_else(|| span_bug!(mir.span, "can't make a name for free region {:?}", fr)) + } + + /// Check for the case where `fr` maps to something that the + /// *user* has a name for. In that case, we'll be able to map + /// `fr` to a `Region<'tcx>`, and that region will be one of + /// named variants. + fn give_name_from_error_region( + &self, + tcx: TyCtxt<'_, '_, 'tcx>, + mir_def_id: DefId, + fr: RegionVid, + counter: &mut usize, + diag: &mut DiagnosticBuilder<'_>, + ) -> Option { + let error_region = self.to_error_region(fr)?; + debug!("give_region_a_name: error_region = {:?}", error_region); + match error_region { + ty::ReEarlyBound(ebr) => Some(ebr.name), + + ty::ReStatic => Some(keywords::StaticLifetime.name().as_interned_str()), + + ty::ReFree(free_region) => match free_region.bound_region { + ty::BoundRegion::BrNamed(_, name) => Some(name), + + 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) + } + + ty::BoundRegion::BrAnon(_) | ty::BoundRegion::BrFresh(_) => None, + }, + + ty::ReLateBound(..) + | ty::ReScope(..) + | ty::ReVar(..) + | ty::ReSkolemized(..) + | ty::ReEmpty + | ty::ReErased + | ty::ReClosureBound(..) + | ty::ReCanonical(..) => None, + } + } + + /// Find an argument that contains `fr` and label it with a fully + /// elaborated type, returning something like `'1`. Result looks + /// like: + /// + /// ``` + /// | fn foo(x: &u32) { .. } + /// ------- fully elaborated type of `x` is `&'1 u32` + /// ``` + fn give_name_if_anonymous_region_appears_in_arguments( + &self, + tcx: TyCtxt<'_, '_, 'tcx>, + mir: &Mir<'tcx>, + fr: RegionVid, + counter: &mut usize, + diag: &mut DiagnosticBuilder<'_>, + ) -> Option { + let implicit_inputs = self.universal_regions.defining_ty.implicit_inputs(); + let argument_index = self.universal_regions + .unnormalized_input_tys + .iter() + .skip(implicit_inputs) + .position(|arg_ty| { + debug!("give_name_if_anonymous_region_appears_in_arguments: arg_ty = {:?}", arg_ty); + tcx.any_free_region_meets(arg_ty, |r| r.to_region_vid() == fr) + })? + + implicit_inputs; + + debug!( + "give_name_if_anonymous_region_appears_in_arguments: \ + found {:?} in argument {} which has type {:?}", + fr, argument_index, self.universal_regions.unnormalized_input_tys[argument_index], + ); + + let region_name = self.synthesize_region_name(counter); + + let argument_local = Local::new(argument_index + 1); + let argument_span = mir.local_decls[argument_local].source_info.span; + diag.span_label( + argument_span, + format!("lifetime `{}` appears in this argument", region_name,), + ); + + Some(region_name) + } + + /// Find a closure upvar that contains `fr` and label it with a + /// fully elaborated type, returning something like `'1`. Result + /// looks like: + /// + /// ``` + /// | let x = Some(&22); + /// - fully elaborated type of `x` is `Option<&'1 u32>` + /// ``` + fn give_name_if_anonymous_region_appears_in_upvars( + &self, + tcx: TyCtxt<'_, '_, 'tcx>, + mir: &Mir<'tcx>, + fr: RegionVid, + counter: &mut usize, + diag: &mut DiagnosticBuilder<'_>, + ) -> Option { + let upvar_index = self.universal_regions + .defining_ty + .upvar_tys(tcx) + .position(|upvar_ty| { + debug!( + "give_name_if_anonymous_region_appears_in_upvars: upvar_ty = {:?}", + upvar_ty, + ); + tcx.any_free_region_meets(&upvar_ty, |r| r.to_region_vid() == fr) + })?; + + debug!( + "give_name_if_anonymous_region_appears_in_upvars: \ + found {:?} in upvar {} which has type {:?}", + fr, + upvar_index, + self.universal_regions + .defining_ty + .upvar_tys(tcx) + .nth(upvar_index), + ); + + let region_name = self.synthesize_region_name(counter); + + let upvar_hir_id = mir.upvar_decls[upvar_index].var_hir_id.assert_crate_local(); + let upvar_node_id = tcx.hir.hir_to_node_id(upvar_hir_id); + let upvar_span = tcx.hir.span(upvar_node_id); + let upvar_name = tcx.hir.name(upvar_node_id); + diag.span_label( + upvar_span, + format!( + "lifetime `{}` appears in the type of `{}`", + region_name, upvar_name, + ), + ); + + Some(region_name) + } + + /// Check for arguments appearing in the (closure) return type. It + /// must be a closure since, in a free fn, such an argument would + /// have to either also appear in an argument (if using elision) + /// or be early bound (named, not in argument). + fn give_name_if_anonymous_region_appears_in_output( + &self, + tcx: TyCtxt<'_, '_, 'tcx>, + mir: &Mir<'tcx>, + fr: RegionVid, + counter: &mut usize, + diag: &mut DiagnosticBuilder<'_>, + ) -> Option { + let return_ty = self.universal_regions + .unnormalized_output_ty; + debug!("give_name_if_anonymous_region_appears_in_output: return_ty = {:?}", return_ty); + if !tcx.any_free_region_meets(&return_ty, |r| r.to_region_vid() == fr) { + return None; + } + + let region_name = self.synthesize_region_name(counter); + diag.span_label( + mir.span, + format!("lifetime `{}` appears in return type", region_name), + ); + + Some(region_name) + } + + /// Create a synthetic region named `'1`, incrementing the + /// counter. + fn synthesize_region_name(&self, counter: &mut usize) -> InternedString { + let c = *counter; + *counter += 1; + + Name::intern(&format!("'{:?}", c)).as_interned_str() + } +} 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 13cc0c0419eab..164941203e054 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs @@ -256,6 +256,11 @@ impl<'tcx> RegionInferenceContext<'tcx> { fn init_universal_regions(&mut self) { // Update the names (if any) for (external_name, variable) in self.universal_regions.named_universal_regions() { + debug!( + "init_universal_regions: region {:?} has external name {:?}", + variable, + external_name + ); self.definitions[variable].external_name = Some(external_name); } diff --git a/src/librustc_mir/borrow_check/nll/universal_regions.rs b/src/librustc_mir/borrow_check/nll/universal_regions.rs index ec8cd386679c3..8590e3d0765f0 100644 --- a/src/librustc_mir/borrow_check/nll/universal_regions.rs +++ b/src/librustc_mir/borrow_check/nll/universal_regions.rs @@ -22,15 +22,16 @@ //! The code in this file doesn't *do anything* with those results; it //! just returns them for other code to use. -use rustc::hir::{self, BodyOwnerKind, HirId}; +use either::Either; use rustc::hir::def_id::DefId; -use rustc::infer::{InferCtxt, NLLRegionVariableOrigin}; -use rustc::infer::region_constraints::GenericKind; +use rustc::hir::{self, BodyOwnerKind, HirId}; use rustc::infer::outlives::bounds::{self, OutlivesBound}; use rustc::infer::outlives::free_region_map::FreeRegionRelations; -use rustc::ty::{self, RegionVid, Ty, TyCtxt, ClosureSubsts, GeneratorSubsts}; +use rustc::infer::region_constraints::GenericKind; +use rustc::infer::{InferCtxt, NLLRegionVariableOrigin}; use rustc::ty::fold::TypeFoldable; use rustc::ty::subst::Substs; +use rustc::ty::{self, ClosureSubsts, GeneratorSubsts, RegionVid, Ty, TyCtxt}; use rustc::util::nodemap::FxHashMap; use rustc_data_structures::indexed_vec::{Idx, IndexVec}; use rustc_data_structures::transitive_relation::TransitiveRelation; @@ -128,6 +129,34 @@ pub enum DefiningTy<'tcx> { Const(DefId, &'tcx Substs<'tcx>), } +impl<'tcx> DefiningTy<'tcx> { + /// Returns a list of all the upvar types for this MIR. If this is + /// not a closure or generator, there are no upvars, and hence it + /// will be an empty list. The order of types in this list will + /// match up with the `upvar_decls` field of `Mir`. + pub fn upvar_tys(self, tcx: TyCtxt<'_, '_, 'tcx>) -> impl Iterator> + 'tcx { + match self { + DefiningTy::Closure(def_id, substs) => Either::Left(substs.upvar_tys(def_id, tcx)), + DefiningTy::Generator(def_id, substs, _) => { + Either::Right(Either::Left(substs.upvar_tys(def_id, tcx))) + } + DefiningTy::FnDef(..) | DefiningTy::Const(..) => { + Either::Right(Either::Right(iter::empty())) + } + } + } + + /// Number of implicit inputs -- notably the "environment" + /// parameter for closures -- that appear in MIR but not in the + /// user's code. + pub fn implicit_inputs(self) -> usize { + match self { + DefiningTy::Closure(..) | DefiningTy::Generator(..) => 1, + DefiningTy::FnDef(..) | DefiningTy::Const(..) => 0, + } + } +} + #[derive(Debug)] struct UniversalRegionIndices<'tcx> { /// For those regions that may appear in the parameter environment @@ -493,18 +522,15 @@ impl<'cx, 'gcx, 'tcx> UniversalRegionsBuilder<'cx, 'gcx, 'tcx> { debug!( "build: global regions = {}..{}", - FIRST_GLOBAL_INDEX, - first_extern_index + FIRST_GLOBAL_INDEX, first_extern_index ); debug!( "build: extern regions = {}..{}", - first_extern_index, - first_local_index + first_extern_index, first_local_index ); debug!( "build: local regions = {}..{}", - first_local_index, - num_universals + first_local_index, num_universals ); let yield_ty = match defining_ty { @@ -545,10 +571,12 @@ impl<'cx, 'gcx, 'tcx> UniversalRegionsBuilder<'cx, 'gcx, 'tcx> { tables.node_id_to_type(self.mir_hir_id) }; + debug!("defining_ty (pre-replacement): {:?}", defining_ty); + let defining_ty = self.infcx .replace_free_regions_with_nll_infer_vars(FR, &defining_ty); - match defining_ty.sty { + match defining_ty.sty { ty::TyClosure(def_id, substs) => DefiningTy::Closure(def_id, substs), ty::TyGenerator(def_id, substs, movability) => { DefiningTy::Generator(def_id, substs, movability) @@ -587,8 +615,8 @@ impl<'cx, 'gcx, 'tcx> UniversalRegionsBuilder<'cx, 'gcx, 'tcx> { let closure_base_def_id = tcx.closure_base_def_id(self.mir_def_id); let identity_substs = Substs::identity_for_item(gcx, closure_base_def_id); let fr_substs = match defining_ty { - DefiningTy::Closure(_, ClosureSubsts { ref substs }) | - DefiningTy::Generator(_, GeneratorSubsts { ref substs }, _) => { + DefiningTy::Closure(_, ClosureSubsts { ref substs }) + | DefiningTy::Generator(_, GeneratorSubsts { ref substs }, _) => { // In the case of closures, we rely on the fact that // the first N elements in the ClosureSubsts are // inherited from the `closure_base_def_id`. @@ -726,8 +754,7 @@ impl UniversalRegionRelations { fn relate_universal_regions(&mut self, fr_a: RegionVid, fr_b: RegionVid) { debug!( "relate_universal_regions: fr_a={:?} outlives fr_b={:?}", - fr_a, - fr_b + fr_a, fr_b ); self.outlives.add(fr_a, fr_b); self.inverse_outlives.add(fr_b, fr_a); @@ -780,8 +807,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'cx, 'gcx, 'tcx> { { debug!( "replace_bound_regions_with_nll_infer_vars(value={:?}, all_outlive_scope={:?})", - value, - all_outlive_scope, + value, all_outlive_scope, ); let (value, _map) = self.tcx.replace_late_bound_regions(value, |br| { let liberated_region = self.tcx.mk_region(ty::ReFree(ty::FreeRegion { @@ -790,7 +816,10 @@ impl<'cx, 'gcx, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'cx, 'gcx, 'tcx> { })); let region_vid = self.next_nll_region_var(origin); indices.insert_late_bound_region(liberated_region, region_vid.to_region_vid()); - debug!("liberated_region={:?} => {:?}", liberated_region, region_vid); + debug!( + "liberated_region={:?} => {:?}", + liberated_region, region_vid + ); region_vid }); value @@ -803,9 +832,8 @@ impl<'tcx> UniversalRegionIndices<'tcx> { /// in later and instantiate the late-bound regions, and then we /// insert the `ReFree` version of those into the map as /// well. These are used for error reporting. - fn insert_late_bound_region(&mut self, r: ty::Region<'tcx>, - vid: ty::RegionVid) - { + fn insert_late_bound_region(&mut self, r: ty::Region<'tcx>, vid: ty::RegionVid) { + debug!("insert_late_bound_region({:?}, {:?})", r, vid); self.indices.insert(r, vid); } @@ -821,9 +849,9 @@ impl<'tcx> UniversalRegionIndices<'tcx> { if let ty::ReVar(..) = r { r.to_region_vid() } else { - *self.indices.get(&r).unwrap_or_else(|| { - bug!("cannot convert `{:?}` to a region vid", r) - }) + *self.indices + .get(&r) + .unwrap_or_else(|| bug!("cannot convert `{:?}` to a region vid", r)) } } diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index 4db5c8e9278e5..2b18771a34f02 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -534,6 +534,7 @@ fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>, }; let mut decl = UpvarDecl { debug_name: keywords::Invalid.name(), + var_hir_id: ClearCrossCrate::Set(var_hir_id), by_ref, mutability: Mutability::Not, }; diff --git a/src/test/compile-fail/borrowck/borrowck-describe-lvalue.rs b/src/test/compile-fail/borrowck/borrowck-describe-lvalue.rs index 3a7e4a13740d0..b821c7cfa34ff 100644 --- a/src/test/compile-fail/borrowck/borrowck-describe-lvalue.rs +++ b/src/test/compile-fail/borrowck/borrowck-describe-lvalue.rs @@ -302,7 +302,7 @@ fn main() { // FIXME(#49824) -- the free region error below should probably not be there let mut x = 0; || { - || { //[mir]~ ERROR free region `` does not outlive + || { //[mir]~ ERROR unsatisfied lifetime constraints let y = &mut x; &mut x; //[ast]~ ERROR cannot borrow `**x` as mutable more than once at a time //[mir]~^ ERROR cannot borrow `x` as mutable more than once at a time diff --git a/src/test/compile-fail/mir_check_cast_closure.rs b/src/test/compile-fail/mir_check_cast_closure.rs index d8f5956b58530..2200c1569e572 100644 --- a/src/test/compile-fail/mir_check_cast_closure.rs +++ b/src/test/compile-fail/mir_check_cast_closure.rs @@ -14,7 +14,7 @@ fn bar<'a, 'b>() -> fn(&'a u32, &'b u32) -> &'a u32 { let g: fn(_, _) -> _ = |_x, y| y; - //~^ ERROR free region `'b` does not outlive free region `'a` + //~^ ERROR unsatisfied lifetime constraints g //~^ WARNING not reporting region error due to nll } diff --git a/src/test/compile-fail/mir_check_cast_reify.rs b/src/test/compile-fail/mir_check_cast_reify.rs index 1f9174b3574a7..f85104dff867f 100644 --- a/src/test/compile-fail/mir_check_cast_reify.rs +++ b/src/test/compile-fail/mir_check_cast_reify.rs @@ -45,7 +45,7 @@ fn bar<'a>(x: &'a u32) -> &'static u32 { // as part of checking the `ReifyFnPointer`. let f: fn(_) -> _ = foo; //~^ WARNING not reporting region error due to nll - //~| ERROR free region `'a` does not outlive free region `'static` + //~| ERROR unsatisfied lifetime constraints f(x) } diff --git a/src/test/compile-fail/mir_check_cast_unsafe_fn.rs b/src/test/compile-fail/mir_check_cast_unsafe_fn.rs index 27ca2728ddfd6..e90242f3f87da 100644 --- a/src/test/compile-fail/mir_check_cast_unsafe_fn.rs +++ b/src/test/compile-fail/mir_check_cast_unsafe_fn.rs @@ -17,7 +17,7 @@ fn bar<'a>(input: &'a u32, f: fn(&'a u32) -> &'a u32) -> &'static u32 { // in `g`. These are related via the `UnsafeFnPointer` cast. let g: unsafe fn(_) -> _ = f; //~^ WARNING not reporting region error due to nll - //~| ERROR free region `'a` does not outlive free region `'static` + //~| ERROR unsatisfied lifetime constraints unsafe { g(input) } } diff --git a/src/test/compile-fail/mir_check_cast_unsize.rs b/src/test/compile-fail/mir_check_cast_unsize.rs index a2c840a70980b..d242186a6f7ea 100644 --- a/src/test/compile-fail/mir_check_cast_unsize.rs +++ b/src/test/compile-fail/mir_check_cast_unsize.rs @@ -15,8 +15,7 @@ use std::fmt::Debug; fn bar<'a>(x: &'a u32) -> &'static dyn Debug { - //~^ ERROR free region `'a` does not outlive free region `'static` - x + x //~ ERROR unsatisfied lifetime constraints //~^ WARNING not reporting region error due to nll } diff --git a/src/test/compile-fail/regions-static-bound.rs b/src/test/compile-fail/regions-static-bound.rs index a0097b9f6d7df..0a37df4f0c788 100644 --- a/src/test/compile-fail/regions-static-bound.rs +++ b/src/test/compile-fail/regions-static-bound.rs @@ -18,7 +18,7 @@ fn static_id_indirect<'a,'b>(t: &'a ()) -> &'static () fn static_id_wrong_way<'a>(t: &'a ()) -> &'static () where 'static: 'a { t //[ll]~ ERROR E0312 //[nll]~^ WARNING not reporting region error due to nll - //[nll]~| ERROR free region `'a` does not outlive free region `'static` + //[nll]~| ERROR unsatisfied lifetime constraints } fn error(u: &(), v: &()) { diff --git a/src/test/ui/borrowck/issue-45983.nll.stderr b/src/test/ui/borrowck/issue-45983.nll.stderr index a008a408d9711..68a039262c129 100644 --- a/src/test/ui/borrowck/issue-45983.nll.stderr +++ b/src/test/ui/borrowck/issue-45983.nll.stderr @@ -4,11 +4,15 @@ warning: not reporting region error due to nll LL | give_any(|y| x = Some(y)); | ^ -error: free region `` does not outlive free region `'_#2r` - --> $DIR/issue-45983.rs:17:27 +error: unsatisfied lifetime constraints + --> $DIR/issue-45983.rs:17:18 | +LL | let x = None; + | - lifetime `'2` appears in the type of `x` LL | give_any(|y| x = Some(y)); - | ^ + | - ^^^^^^^^^^^ free region requires that `'1` must outlive `'2` + | | + | lifetime `'1` appears in this argument error[E0594]: cannot assign to immutable item `x` --> $DIR/issue-45983.rs:17:18 diff --git a/src/test/ui/borrowck/issue-7573.nll.stderr b/src/test/ui/borrowck/issue-7573.nll.stderr index 84c6236eb0ae8..daa0a320b88d6 100644 --- a/src/test/ui/borrowck/issue-7573.nll.stderr +++ b/src/test/ui/borrowck/issue-7573.nll.stderr @@ -4,11 +4,17 @@ warning: not reporting region error due to nll LL | let mut lines_to_use: Vec<&CrateId> = Vec::new(); | ^ -error: free region `` does not outlive free region `'_#2r` +error: unsatisfied lifetime constraints --> $DIR/issue-7573.rs:32:9 | +LL | let mut lines_to_use: Vec<&CrateId> = Vec::new(); + | ---------------- lifetime `'2` appears in the type of `lines_to_use` +LL | //~^ NOTE cannot infer an appropriate lifetime +LL | let push_id = |installed_id: &CrateId| { + | ------------ lifetime `'1` appears in this argument +... LL | lines_to_use.push(installed_id); - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2` error: aborting due to previous error diff --git a/src/test/ui/borrowck/regions-escape-bound-fn-2.nll.stderr b/src/test/ui/borrowck/regions-escape-bound-fn-2.nll.stderr index ee3970aa8fd8f..4f7843b72489c 100644 --- a/src/test/ui/borrowck/regions-escape-bound-fn-2.nll.stderr +++ b/src/test/ui/borrowck/regions-escape-bound-fn-2.nll.stderr @@ -4,11 +4,15 @@ warning: not reporting region error due to nll LL | with_int(|y| x = Some(y)); | ^ -error: free region `` does not outlive free region `'_#2r` - --> $DIR/regions-escape-bound-fn-2.rs:18:27 +error: unsatisfied lifetime constraints + --> $DIR/regions-escape-bound-fn-2.rs:18:18 | +LL | let mut x = None; + | ----- lifetime `'2` appears in the type of `x` LL | with_int(|y| x = Some(y)); - | ^ + | - ^^^^^^^^^^^ free region requires that `'1` must outlive `'2` + | | + | lifetime `'1` appears in this argument error: aborting due to previous error diff --git a/src/test/ui/borrowck/regions-escape-bound-fn.nll.stderr b/src/test/ui/borrowck/regions-escape-bound-fn.nll.stderr index 07a4ab1dbb1ab..9b107ae08b477 100644 --- a/src/test/ui/borrowck/regions-escape-bound-fn.nll.stderr +++ b/src/test/ui/borrowck/regions-escape-bound-fn.nll.stderr @@ -4,11 +4,15 @@ warning: not reporting region error due to nll LL | with_int(|y| x = Some(y)); | ^^^^^^^ -error: free region `` does not outlive free region `'_#2r` - --> $DIR/regions-escape-bound-fn.rs:18:27 +error: unsatisfied lifetime constraints + --> $DIR/regions-escape-bound-fn.rs:18:18 | +LL | let mut x: Option<&isize> = None; + | ----- lifetime `'2` appears in the type of `x` LL | with_int(|y| x = Some(y)); - | ^ + | - ^^^^^^^^^^^ free region requires that `'1` must outlive `'2` + | | + | lifetime `'1` appears in this argument error: aborting due to previous error diff --git a/src/test/ui/borrowck/regions-escape-unboxed-closure.nll.stderr b/src/test/ui/borrowck/regions-escape-unboxed-closure.nll.stderr index 14c255ef52778..8095330154d4c 100644 --- a/src/test/ui/borrowck/regions-escape-unboxed-closure.nll.stderr +++ b/src/test/ui/borrowck/regions-escape-unboxed-closure.nll.stderr @@ -4,11 +4,15 @@ warning: not reporting region error due to nll LL | with_int(&mut |y| x = Some(y)); | ^^^^^^^ -error: free region `` does not outlive free region `'_#2r` - --> $DIR/regions-escape-unboxed-closure.rs:16:32 +error: unsatisfied lifetime constraints + --> $DIR/regions-escape-unboxed-closure.rs:16:23 | +LL | let mut x: Option<&isize> = None; + | ----- lifetime `'2` appears in the type of `x` LL | with_int(&mut |y| x = Some(y)); - | ^ + | - ^^^^^^^^^^^ free region requires that `'1` must outlive `'2` + | | + | lifetime `'1` appears in this argument error: aborting due to previous error diff --git a/src/test/ui/closure-expected-type/expect-region-supply-region.nll.stderr b/src/test/ui/closure-expected-type/expect-region-supply-region.nll.stderr index bbae80e16abde..5487d34813b47 100644 --- a/src/test/ui/closure-expected-type/expect-region-supply-region.nll.stderr +++ b/src/test/ui/closure-expected-type/expect-region-supply-region.nll.stderr @@ -22,23 +22,37 @@ warning: not reporting region error due to nll LL | f = Some(x); | ^^^^^^^ -error: free region `` does not outlive free region `'_#2r` - --> $DIR/expect-region-supply-region.rs:28:18 +error: unsatisfied lifetime constraints + --> $DIR/expect-region-supply-region.rs:28:9 | +LL | let mut f: Option<&u32> = None; + | ----- lifetime `'2` appears in the type of `f` +LL | closure_expecting_bound(|x| { + | - lifetime `'1` appears in this argument LL | f = Some(x); //~ ERROR borrowed data cannot be stored outside of its closure - | ^ + | ^^^^^^^^^^^ free region requires that `'1` must outlive `'2` -error: free region `` does not outlive free region `'_#2r` - --> $DIR/expect-region-supply-region.rs:38:18 +error: unsatisfied lifetime constraints + --> $DIR/expect-region-supply-region.rs:38:9 | +LL | let mut f: Option<&u32> = None; + | ----- lifetime `'2` appears in the type of `f` +LL | closure_expecting_bound(|x: &u32| { + | - lifetime `'1` appears in this argument LL | f = Some(x); //~ ERROR borrowed data cannot be stored outside of its closure - | ^ + | ^^^^^^^^^^^ free region requires that `'1` must outlive `'2` -error: free region `` does not outlive free region `'_#2r` - --> $DIR/expect-region-supply-region.rs:52:18 +error: unsatisfied lifetime constraints + --> $DIR/expect-region-supply-region.rs:52:9 | +LL | let mut f: Option<&u32> = None; + | ----- lifetime `'2` appears in the type of `f` +... +LL | closure_expecting_bound(|x: &'x u32| { + | - lifetime `'1` appears in this argument +... LL | f = Some(x); - | ^ + | ^^^^^^^^^^^ free region requires that `'1` must outlive `'2` error: aborting due to 3 previous errors diff --git a/src/test/ui/error-codes/E0621-does-not-trigger-for-closures.nll.stderr b/src/test/ui/error-codes/E0621-does-not-trigger-for-closures.nll.stderr index 5ae6afa7b17e2..9c7e3db67a611 100644 --- a/src/test/ui/error-codes/E0621-does-not-trigger-for-closures.nll.stderr +++ b/src/test/ui/error-codes/E0621-does-not-trigger-for-closures.nll.stderr @@ -4,11 +4,15 @@ warning: not reporting region error due to nll LL | invoke(&x, |a, b| if a > b { a } else { b }); //~ ERROR E0495 | ^^^^^^ -error: free region `` does not outlive free region `'_#2r` +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 - | ^^^^^ + | ----------^^^^^----------------- + | | | | + | | | free region requires that `'1` must outlive `'2` + | | lifetime `'1` appears in this argument + | lifetime `'2` appears in return type error: aborting due to previous error diff --git a/src/test/ui/impl-trait/static-return-lifetime-infered.nll.stderr b/src/test/ui/impl-trait/static-return-lifetime-infered.nll.stderr index 7099316d694a2..9aad7efdee5b2 100644 --- a/src/test/ui/impl-trait/static-return-lifetime-infered.nll.stderr +++ b/src/test/ui/impl-trait/static-return-lifetime-infered.nll.stderr @@ -10,17 +10,19 @@ warning: not reporting region error due to nll LL | self.x.iter().map(|a| a.0) | ^^^^ -error: free region `` does not outlive free region `'static` +error: unsatisfied lifetime constraints --> $DIR/static-return-lifetime-infered.rs:17:9 | +LL | fn iter_values_anon(&self) -> impl Iterator { + | ----- lifetime `'1` appears in this argument LL | self.x.iter().map(|a| a.0) - | ^^^^^^^^^^^^^ + | ^^^^^^ cast requires that `'1` must outlive `'static` -error: free region `'a` does not outlive free region `'static` +error: unsatisfied lifetime constraints --> $DIR/static-return-lifetime-infered.rs:21:9 | LL | self.x.iter().map(|a| a.0) - | ^^^^^^^^^^^^^ + | ^^^^^^ cast requires that `'a` must outlive `'static` error: aborting due to 2 previous errors diff --git a/src/test/ui/in-band-lifetimes/impl/dyn-trait.nll.stderr b/src/test/ui/in-band-lifetimes/impl/dyn-trait.nll.stderr index 4cf7feddd4654..19e10ba6da8b9 100644 --- a/src/test/ui/in-band-lifetimes/impl/dyn-trait.nll.stderr +++ b/src/test/ui/in-band-lifetimes/impl/dyn-trait.nll.stderr @@ -4,11 +4,11 @@ warning: not reporting region error due to nll LL | static_val(x); //~ ERROR cannot infer | ^ -error: free region `'a` does not outlive free region `'static` +error: unsatisfied lifetime constraints --> $DIR/dyn-trait.rs:32:5 | LL | static_val(x); //~ ERROR cannot infer - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ argument requires that `'a` must outlive `'static` error: aborting due to previous error diff --git a/src/test/ui/nll/closure-requirements/escape-argument-callee.rs b/src/test/ui/nll/closure-requirements/escape-argument-callee.rs index 1e168028c7c9a..78208d6d7db7d 100644 --- a/src/test/ui/nll/closure-requirements/escape-argument-callee.rs +++ b/src/test/ui/nll/closure-requirements/escape-argument-callee.rs @@ -34,7 +34,7 @@ fn test() { { let y = 22; let mut closure = expect_sig(|p, y| *p = y); - //~^ ERROR does not outlive free region + //~^ ERROR //~| WARNING not reporting region error due to nll closure(&mut p, &y); } diff --git a/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr b/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr index 067b5ebc6c4ad..d6f542183603e 100644 --- a/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr +++ b/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr @@ -4,11 +4,14 @@ warning: not reporting region error due to nll LL | let mut closure = expect_sig(|p, y| *p = y); | ^ -error: free region `ReFree(DefId(0/1:9 ~ escape_argument_callee[317d]::test[0]::{{closure}}[0]), BrAnon(3))` does not outlive free region `ReFree(DefId(0/1:9 ~ escape_argument_callee[317d]::test[0]::{{closure}}[0]), BrAnon(2))` +error: unsatisfied lifetime constraints --> $DIR/escape-argument-callee.rs:36:45 | LL | let mut closure = expect_sig(|p, y| *p = y); - | ^^^^^^ + | - - ^^^^^^ free region requires that `'1` must outlive `'2` + | | | + | | lifetime `'1` appears in this argument + | lifetime `'2` appears in this argument note: No external requirements --> $DIR/escape-argument-callee.rs:36:38 diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.rs b/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.rs index e7ec0b9684d2c..b879f9a33986d 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.rs +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.rs @@ -54,8 +54,7 @@ fn supply<'a, 'b, 'c>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>, cell_c: Cell // Only works if 'x: 'y: let p = x.get(); //~^ WARN not reporting region error due to nll - //~| ERROR does not outlive free region - demand_y(x, y, p) + demand_y(x, y, p) //~ ERROR }, ); } diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr index c88f0efba6f4b..a7a50a3a02981 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr @@ -4,11 +4,16 @@ warning: not reporting region error due to nll LL | let p = x.get(); | ^^^^^^^ -error: free region `ReFree(DefId(0/1:20 ~ propagate_approximated_fail_no_postdom[317d]::supply[0]::{{closure}}[0]), BrAnon(1))` does not outlive free region `ReFree(DefId(0/1:20 ~ propagate_approximated_fail_no_postdom[317d]::supply[0]::{{closure}}[0]), BrAnon(2))` - --> $DIR/propagate-approximated-fail-no-postdom.rs:55:17 +error: unsatisfied lifetime constraints + --> $DIR/propagate-approximated-fail-no-postdom.rs:57:13 | -LL | let p = x.get(); - | ^ +LL | |_outlives1, _outlives2, _outlives3, x, y| { + | ---------- ---------- lifetime `'2` appears in this argument + | | + | lifetime `'1` appears in this argument +... +LL | demand_y(x, y, p) //~ ERROR + | ^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2` note: No external requirements --> $DIR/propagate-approximated-fail-no-postdom.rs:53:9 @@ -17,8 +22,7 @@ LL | / |_outlives1, _outlives2, _outlives3, x, y| { LL | | // Only works if 'x: 'y: LL | | let p = x.get(); LL | | //~^ WARN not reporting region error due to nll -LL | | //~| ERROR does not outlive free region -LL | | demand_y(x, y, p) +LL | | demand_y(x, y, p) //~ ERROR LL | | }, | |_________^ | diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.rs b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.rs index 5a71e75d4b2cd..a8ab41cebacce 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.rs +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.rs @@ -31,7 +31,7 @@ fn case1() { foo(cell, |cell_a, cell_x| { //~^ WARNING not reporting region error due to nll cell_a.set(cell_x.get()); // forces 'x: 'a, error in closure - //~^ ERROR argument requires that data must outlive free region + //~^ ERROR }) } diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr index 656c1b46a3ce5..96f3d6a6a533a 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr @@ -4,11 +4,16 @@ warning: not reporting region error due to nll LL | foo(cell, |cell_a, cell_x| { | ^^^ -error: argument requires that data must outlive free region `'_#1r` - --> $DIR/propagate-approximated-shorter-to-static-comparing-against-free.rs:33:20 +error: unsatisfied lifetime constraints + --> $DIR/propagate-approximated-shorter-to-static-comparing-against-free.rs:33:9 | +LL | foo(cell, |cell_a, cell_x| { + | ------ ------ lifetime `'1` appears in this argument + | | + | lifetime `'2` appears in this argument +LL | //~^ WARNING not reporting region error due to nll LL | cell_a.set(cell_x.get()); // forces 'x: 'a, error in closure - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2` note: No external requirements --> $DIR/propagate-approximated-shorter-to-static-comparing-against-free.rs:31:15 @@ -17,7 +22,7 @@ LL | foo(cell, |cell_a, cell_x| { | _______________^ LL | | //~^ WARNING not reporting region error due to nll LL | | cell_a.set(cell_x.get()); // forces 'x: 'a, error in closure -LL | | //~^ ERROR argument requires that data must outlive free region +LL | | //~^ ERROR LL | | }) | |_____^ | 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 b25b0e25df211..26faccdde71ae 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 @@ -43,7 +43,7 @@ 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, |_outlives, x, y| { - //~^ ERROR argument requires that data must outlive free region + //~^ ERROR // Only works if 'x: 'y: demand_y(x, y, x.get()) //~ WARNING not reporting region error due to nll 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 40f215619c689..f65e7161ca8c5 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 @@ -9,7 +9,7 @@ note: External requirements | LL | establish_relationships(&cell_a, &cell_b, |_outlives, x, y| { | _______________________________________________^ -LL | | //~^ ERROR argument requires that data must outlive free region +LL | | //~^ ERROR LL | | LL | | // Only works if 'x: 'y: LL | | demand_y(x, y, x.get()) //~ WARNING not reporting region error due to nll @@ -23,23 +23,23 @@ LL | | }); = note: number of external vids: 2 = note: where '_#1r: '_#0r -error: argument requires that data must outlive free region `ReStatic` +error: unsatisfied lifetime constraints --> $DIR/propagate-approximated-shorter-to-static-no-bound.rs:45:5 | LL | / establish_relationships(&cell_a, &cell_b, |_outlives, x, y| { -LL | | //~^ ERROR argument requires that data must outlive free region +LL | | //~^ ERROR LL | | LL | | // Only works if 'x: 'y: LL | | demand_y(x, y, x.get()) //~ WARNING not reporting region error due to nll LL | | }); - | |______^ + | |______^ argument requires that `'a` must outlive `'static` note: No external requirements --> $DIR/propagate-approximated-shorter-to-static-no-bound.rs:44:1 | 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 argument requires that data must outlive free region +LL | | //~^ ERROR LL | | ... | LL | | }); 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 db9951bcc0f21..703d60371cdfc 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 @@ -46,7 +46,7 @@ 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 argument requires that data must outlive free region + //~^ ERROR // Only works if 'x: 'y: demand_y(x, y, x.get()) //~^ WARNING not reporting region error due to nll 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 d89ff028a5042..f1b2c9f198d69 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 @@ -9,7 +9,7 @@ note: External requirements | LL | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| { | _______________________________________________^ -LL | | //~^ ERROR argument requires that data must outlive free region +LL | | //~^ ERROR LL | | // Only works if 'x: 'y: LL | | demand_y(x, y, x.get()) LL | | //~^ WARNING not reporting region error due to nll @@ -23,23 +23,23 @@ LL | | }); = note: number of external vids: 3 = note: where '_#1r: '_#0r -error: argument requires that data must outlive free region `ReStatic` +error: unsatisfied lifetime constraints --> $DIR/propagate-approximated-shorter-to-static-wrong-bound.rs:48:5 | LL | / establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| { -LL | | //~^ ERROR argument requires that data must outlive free region +LL | | //~^ ERROR LL | | // Only works if 'x: 'y: LL | | demand_y(x, y, x.get()) LL | | //~^ WARNING not reporting region error due to nll LL | | }); - | |______^ + | |______^ argument requires that `'a` must outlive `'static` note: No external requirements --> $DIR/propagate-approximated-shorter-to-static-wrong-bound.rs:47:1 | 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 argument requires that data must outlive free region +LL | | //~^ ERROR LL | | // Only works if 'x: 'y: ... | LL | | }); diff --git a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.rs b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.rs index 316268e7e726d..4b1f5231b3e87 100644 --- a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.rs +++ b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.rs @@ -46,7 +46,7 @@ fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { // Only works if 'x: 'y: demand_y(x, y, x.get()) //~^ WARN not reporting region error due to nll - //~| ERROR argument requires that data must outlive free region + //~| ERROR }); } diff --git a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr index 74c0576e03b62..fb98c506c7d28 100644 --- a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr @@ -4,11 +4,16 @@ warning: not reporting region error due to nll LL | demand_y(x, y, x.get()) | ^^^^^^^^^^^^^^^^^^^^^^^ -error: argument requires that data must outlive free region `ReFree(DefId(0/1:18 ~ propagate_fail_to_approximate_longer_no_bounds[317d]::supply[0]::{{closure}}[0]), BrAnon(2))` +error: unsatisfied lifetime constraints --> $DIR/propagate-fail-to-approximate-longer-no-bounds.rs:47:9 | +LL | establish_relationships(&cell_a, &cell_b, |_outlives, x, y| { + | --------- - lifetime `'1` appears in this argument + | | + | lifetime `'2` appears in this argument +LL | // Only works if 'x: 'y: LL | demand_y(x, y, x.get()) - | ^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2` note: No external requirements --> $DIR/propagate-fail-to-approximate-longer-no-bounds.rs:45:47 @@ -18,7 +23,7 @@ LL | establish_relationships(&cell_a, &cell_b, |_outlives, x, y| { LL | | // Only works if 'x: 'y: LL | | demand_y(x, y, x.get()) LL | | //~^ WARN not reporting region error due to nll -LL | | //~| ERROR argument requires that data must outlive free region +LL | | //~| ERROR LL | | }); | |_____^ | diff --git a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.rs b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.rs index afb61b221be94..62a20c1bfe76e 100644 --- a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.rs +++ b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.rs @@ -50,7 +50,7 @@ fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { // Only works if 'x: 'y: demand_y(x, y, x.get()) //~^ WARN not reporting region error due to nll - //~| ERROR does not outlive free region + //~| ERROR }); } diff --git a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr index 2fd6ce50095fc..73d39a8502b64 100644 --- a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr @@ -4,11 +4,16 @@ warning: not reporting region error due to nll LL | demand_y(x, y, x.get()) | ^^^^^^^^^^^^^^^^^^^^^^^ -error: free region `ReFree(DefId(0/1:18 ~ propagate_fail_to_approximate_longer_wrong_bounds[317d]::supply[0]::{{closure}}[0]), BrAnon(2))` does not outlive free region `ReFree(DefId(0/1:18 ~ propagate_fail_to_approximate_longer_wrong_bounds[317d]::supply[0]::{{closure}}[0]), BrAnon(4))` - --> $DIR/propagate-fail-to-approximate-longer-wrong-bounds.rs:51:18 +error: unsatisfied lifetime constraints + --> $DIR/propagate-fail-to-approximate-longer-wrong-bounds.rs:51:9 | +LL | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| { + | ---------- ---------- lifetime `'2` appears in this argument + | | + | lifetime `'1` appears in this argument +LL | // Only works if 'x: 'y: LL | demand_y(x, y, x.get()) - | ^ + | ^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2` note: No external requirements --> $DIR/propagate-fail-to-approximate-longer-wrong-bounds.rs:49:47 @@ -18,7 +23,7 @@ LL | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, LL | | // Only works if 'x: 'y: LL | | demand_y(x, y, x.get()) LL | | //~^ WARN not reporting region error due to nll -LL | | //~| ERROR does not outlive free region +LL | | //~| ERROR LL | | }); | |_____^ | diff --git a/src/test/ui/nll/closure-requirements/region-lbr-named-does-not-outlive-static.rs b/src/test/ui/nll/closure-requirements/region-lbr-named-does-not-outlive-static.rs index dedbd8df41b13..b5e8c95bc13b7 100644 --- a/src/test/ui/nll/closure-requirements/region-lbr-named-does-not-outlive-static.rs +++ b/src/test/ui/nll/closure-requirements/region-lbr-named-does-not-outlive-static.rs @@ -18,7 +18,7 @@ fn foo<'a>(x: &'a u32) -> &'static u32 { &*x //~^ WARN not reporting region error due to nll - //~| ERROR does not outlive free region + //~| ERROR } fn main() { } diff --git a/src/test/ui/nll/closure-requirements/region-lbr-named-does-not-outlive-static.stderr b/src/test/ui/nll/closure-requirements/region-lbr-named-does-not-outlive-static.stderr index 9520b446303c3..d012dca25271c 100644 --- a/src/test/ui/nll/closure-requirements/region-lbr-named-does-not-outlive-static.stderr +++ b/src/test/ui/nll/closure-requirements/region-lbr-named-does-not-outlive-static.stderr @@ -4,11 +4,11 @@ warning: not reporting region error due to nll LL | &*x | ^^^ -error: free region `ReFree(DefId(0/0:3 ~ region_lbr_named_does_not_outlive_static[317d]::foo[0]), BrNamed(crate0:DefIndex(1:9), 'a))` does not outlive free region `ReStatic` +error: unsatisfied lifetime constraints --> $DIR/region-lbr-named-does-not-outlive-static.rs:19:5 | LL | &*x - | ^^^ + | ^^^ free region requires that `'a` must outlive `'static` error: aborting due to previous error diff --git a/src/test/ui/nll/closure-requirements/return-wrong-bound-region.rs b/src/test/ui/nll/closure-requirements/return-wrong-bound-region.rs index 60f82ca0eefb9..d88729d04d95b 100644 --- a/src/test/ui/nll/closure-requirements/return-wrong-bound-region.rs +++ b/src/test/ui/nll/closure-requirements/return-wrong-bound-region.rs @@ -20,7 +20,7 @@ fn test() { expect_sig(|a, b| b); // ought to return `a` //~^ WARN not reporting region error due to nll - //~| ERROR does not outlive free region + //~| ERROR } fn expect_sig(f: F) -> F diff --git a/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr b/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr index 04ff4aaadf875..5724cdbd8c95b 100644 --- a/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr +++ b/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr @@ -4,11 +4,14 @@ warning: not reporting region error due to nll LL | expect_sig(|a, b| b); // ought to return `a` | ^ -error: free region `ReFree(DefId(0/1:9 ~ return_wrong_bound_region[317d]::test[0]::{{closure}}[0]), BrAnon(2))` does not outlive free region `ReFree(DefId(0/1:9 ~ return_wrong_bound_region[317d]::test[0]::{{closure}}[0]), BrAnon(1))` +error: unsatisfied lifetime constraints --> $DIR/return-wrong-bound-region.rs:21:23 | LL | expect_sig(|a, b| b); // ought to return `a` - | ^ + | - - ^ free region requires that `'1` must outlive `'2` + | | | + | | lifetime `'1` appears in this argument + | lifetime `'2` appears in this argument note: No external requirements --> $DIR/return-wrong-bound-region.rs:21:16 @@ -27,7 +30,7 @@ note: No external requirements LL | / fn test() { LL | | expect_sig(|a, b| b); // ought to return `a` LL | | //~^ WARN not reporting region error due to nll -LL | | //~| ERROR does not outlive free region +LL | | //~| ERROR LL | | } | |_^ | diff --git a/src/test/ui/nll/issue-48238.rs b/src/test/ui/nll/issue-48238.rs index 6f7644da3d349..7c5527ae1e7b1 100644 --- a/src/test/ui/nll/issue-48238.rs +++ b/src/test/ui/nll/issue-48238.rs @@ -18,5 +18,5 @@ fn use_val<'a>(val: &'a u8) -> &'a u8 { fn main() { let orig: u8 = 5; - move || use_val(&orig); //~ ERROR free region `` does not outlive free region `'_#1r` + move || use_val(&orig); //~ ERROR } diff --git a/src/test/ui/nll/issue-48238.stderr b/src/test/ui/nll/issue-48238.stderr index 29385d9b2430f..7bdac345e9047 100644 --- a/src/test/ui/nll/issue-48238.stderr +++ b/src/test/ui/nll/issue-48238.stderr @@ -1,8 +1,12 @@ -error: free region `` does not outlive free region `'_#1r` - --> $DIR/issue-48238.rs:21:21 +error: unsatisfied lifetime constraints + --> $DIR/issue-48238.rs:21:13 | -LL | move || use_val(&orig); //~ ERROR free region `` does not outlive free region `'_#1r` - | ^^^^^ +LL | move || use_val(&orig); //~ ERROR + | --------^^^^^^^^^^^^^^ + | | | + | | argument requires that `'1` must outlive `'2` + | lifetime `'1` represents the closure body + | lifetime `'2` appears in return type error: aborting due to previous error diff --git a/src/test/ui/nll/issue-50716.rs b/src/test/ui/nll/issue-50716.rs index a41af168c3e4e..beb2ff79e902b 100644 --- a/src/test/ui/nll/issue-50716.rs +++ b/src/test/ui/nll/issue-50716.rs @@ -22,7 +22,7 @@ where for<'b> &'b T: A, <&'static T as A>::X: Sized { - let _x = *s; //~ ERROR assignment requires that data must outlive free region `'static` + let _x = *s; //~ ERROR } fn main() {} diff --git a/src/test/ui/nll/issue-50716.stderr b/src/test/ui/nll/issue-50716.stderr index de69f8cfbcb6e..48862166f897f 100644 --- a/src/test/ui/nll/issue-50716.stderr +++ b/src/test/ui/nll/issue-50716.stderr @@ -1,8 +1,8 @@ -error: assignment requires that data must outlive free region `'static` +error: unsatisfied lifetime constraints --> $DIR/issue-50716.rs:25:14 | -LL | let _x = *s; //~ ERROR assignment requires that data must outlive free region `'static` - | ^^ +LL | let _x = *s; //~ ERROR + | ^^ assignment requires that `'a` must outlive `'static` error: aborting due to previous error diff --git a/src/test/ui/nll/ty-outlives/projection-one-region-closure.rs b/src/test/ui/nll/ty-outlives/projection-one-region-closure.rs index 3832be6288aef..0a8801a3c4d6d 100644 --- a/src/test/ui/nll/ty-outlives/projection-one-region-closure.rs +++ b/src/test/ui/nll/ty-outlives/projection-one-region-closure.rs @@ -55,7 +55,7 @@ where with_signature(cell, t, |cell, t| require(cell, t)); //~^ WARNING not reporting region error due to nll //~| ERROR the parameter type `T` may not live long enough - //~| ERROR argument requires that data must outlive free region + //~| ERROR } #[rustc_regions] @@ -67,7 +67,7 @@ where with_signature(cell, t, |cell, t| require(cell, t)); //~^ WARNING not reporting region error due to nll //~| ERROR the parameter type `T` may not live long enough - //~| ERROR argument requires that data must outlive free region + //~| ERROR } #[rustc_regions] @@ -89,7 +89,7 @@ where with_signature(cell, t, |cell, t| require(cell, t)); //~^ WARNING not reporting region error due to nll //~| ERROR the parameter type `T` may not live long enough - //~| ERROR argument requires that data must outlive free region + //~| ERROR } #[rustc_regions] 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 898c995e09b9d..b84ee4de5a3cc 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 @@ -40,11 +40,11 @@ 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: argument requires that data must outlive free region `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:5 | LL | with_signature(cell, t, |cell, t| require(cell, t)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a` note: No external requirements --> $DIR/projection-one-region-closure.rs:51:1 @@ -54,7 +54,7 @@ LL | | where LL | | T: Anything<'b>, LL | | { ... | -LL | | //~| ERROR argument requires that data must outlive free region +LL | | //~| ERROR LL | | } | |_^ | @@ -88,11 +88,11 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); | = help: consider adding an explicit lifetime bound `T: ReEarlyBound(0, 'a)`... -error: argument requires that data must outlive free region `ReEarlyBound(0, 'a)` +error: unsatisfied lifetime constraints --> $DIR/projection-one-region-closure.rs:67:5 | LL | with_signature(cell, t, |cell, t| require(cell, t)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a` note: No external requirements --> $DIR/projection-one-region-closure.rs:62:1 @@ -102,7 +102,7 @@ LL | | where LL | | T: Anything<'b>, LL | | 'a: 'a, ... | -LL | | //~| ERROR argument requires that data must outlive free region +LL | | //~| ERROR LL | | } | |_^ | @@ -137,11 +137,11 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); | = help: consider adding an explicit lifetime bound `T: ReEarlyBound(0, 'a)`... -error: argument requires that data must outlive free region `ReEarlyBound(0, 'a)` +error: unsatisfied lifetime constraints --> $DIR/projection-one-region-closure.rs:89:5 | LL | with_signature(cell, t, |cell, t| require(cell, t)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a` note: No external requirements --> $DIR/projection-one-region-closure.rs:74:1 @@ -151,7 +151,7 @@ LL | | where LL | | T: Anything<'b>, LL | | T::AssocType: 'a, ... | -LL | | //~| ERROR argument requires that data must outlive free region +LL | | //~| ERROR LL | | } | |_^ | diff --git a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.rs b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.rs index da76193459b30..6317d6eca1f1d 100644 --- a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.rs +++ b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.rs @@ -46,7 +46,7 @@ where { with_signature(cell, t, |cell, t| require(cell, t)); //~^ WARNING not reporting region error due to nll - //~| ERROR argument requires that data must outlive free region + //~| ERROR } #[rustc_regions] @@ -57,7 +57,7 @@ where { with_signature(cell, t, |cell, t| require(cell, t)); //~^ WARNING not reporting region error due to nll - //~| ERROR argument requires that data must outlive free region + //~| ERROR } #[rustc_regions] @@ -78,7 +78,7 @@ where with_signature(cell, t, |cell, t| require(cell, t)); //~^ WARNING not reporting region error due to nll - //~| ERROR argument requires that data must outlive free region + //~| ERROR } #[rustc_regions] 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 be11c6249f0ba..42ecd6f986075 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 @@ -31,11 +31,11 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); = note: number of external vids: 3 = note: where '_#1r: '_#2r -error: argument requires that data must outlive free region `ReFree(DefId(0/0:8 ~ projection_one_region_trait_bound_closure[317d]::no_relationships_late[0]), BrNamed(crate0:DefIndex(1:16), 'a))` +error: unsatisfied lifetime constraints --> $DIR/projection-one-region-trait-bound-closure.rs:47:5 | LL | with_signature(cell, t, |cell, t| require(cell, t)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a` note: No external requirements --> $DIR/projection-one-region-trait-bound-closure.rs:43:1 @@ -45,7 +45,7 @@ LL | | where LL | | T: Anything<'b>, LL | | { ... | -LL | | //~| ERROR argument requires that data must outlive free region +LL | | //~| ERROR LL | | } | |_^ | @@ -70,11 +70,11 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); = note: number of external vids: 4 = note: where '_#2r: '_#3r -error: argument requires that data must outlive free region `ReEarlyBound(0, 'a)` +error: unsatisfied lifetime constraints --> $DIR/projection-one-region-trait-bound-closure.rs:58:5 | LL | with_signature(cell, t, |cell, t| require(cell, t)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a` note: No external requirements --> $DIR/projection-one-region-trait-bound-closure.rs:53:1 @@ -84,7 +84,7 @@ LL | | where LL | | T: Anything<'b>, LL | | 'a: 'a, ... | -LL | | //~| ERROR argument requires that data must outlive free region +LL | | //~| ERROR LL | | } | |_^ | @@ -110,11 +110,11 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); = note: number of external vids: 4 = note: where '_#2r: '_#3r -error: argument requires that data must outlive free region `ReEarlyBound(0, 'a)` +error: unsatisfied lifetime constraints --> $DIR/projection-one-region-trait-bound-closure.rs:79:5 | LL | with_signature(cell, t, |cell, t| require(cell, t)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a` note: No external requirements --> $DIR/projection-one-region-trait-bound-closure.rs:64:1 @@ -124,7 +124,7 @@ LL | | where LL | | T: Anything<'b>, LL | | T::AssocType: 'a, ... | -LL | | //~| ERROR argument requires that data must outlive free region +LL | | //~| ERROR LL | | } | |_^ | diff --git a/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.rs b/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.rs index 5e481a9626f08..2552054fd5f42 100644 --- a/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.rs +++ b/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.rs @@ -107,7 +107,7 @@ where { with_signature(cell, t, |cell, t| require(cell, t)); //~^ WARNING not reporting region error due to nll - //~| ERROR argument requires that data must outlive free region + //~| ERROR } #[rustc_regions] diff --git a/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr b/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr index 546384e8545e3..b0f823ad3d56b 100644 --- a/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr +++ b/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr @@ -239,11 +239,11 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); = note: number of external vids: 3 = note: where >::AssocType: '_#2r -error: argument requires that data must outlive free region `ReFree(DefId(0/0:13 ~ projection_two_region_trait_bound_closure[317d]::two_regions[0]), BrNamed(crate0:DefIndex(1:43), 'a))` +error: unsatisfied lifetime constraints --> $DIR/projection-two-region-trait-bound-closure.rs:108:5 | LL | with_signature(cell, t, |cell, t| require(cell, t)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a` note: No external requirements --> $DIR/projection-two-region-trait-bound-closure.rs:104:1 @@ -253,7 +253,7 @@ LL | | where LL | | T: Anything<'b, 'b>, LL | | { ... | -LL | | //~| ERROR argument requires that data must outlive free region +LL | | //~| ERROR LL | | } | |_^ | diff --git a/src/test/ui/underscore-lifetime/dyn-trait-underscore.nll.stderr b/src/test/ui/underscore-lifetime/dyn-trait-underscore.nll.stderr index 49f9044b19b24..04c3ed2d6ee19 100644 --- a/src/test/ui/underscore-lifetime/dyn-trait-underscore.nll.stderr +++ b/src/test/ui/underscore-lifetime/dyn-trait-underscore.nll.stderr @@ -22,11 +22,14 @@ warning: not reporting region error due to nll LL | Box::new(items.iter()) //~ ERROR cannot infer an appropriate lifetime | ^^^^^^^^^^^^^^^^^^^^^^ -error: cast requires that data must outlive free region `'static` +error: unsatisfied lifetime constraints --> $DIR/dyn-trait-underscore.rs:18:5 | +LL | fn a(items: &[T]) -> Box> { + | ----- lifetime `'1` appears in this argument +LL | // ^^^^^^^^^^^^^^^^^^^^^ bound *here* defaults to `'static` LL | Box::new(items.iter()) //~ ERROR cannot infer an appropriate lifetime - | ^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^ cast requires that `'1` must outlive `'static` error: aborting due to previous error