diff --git a/src/librustc_infer/infer/canonical/canonicalizer.rs b/src/librustc_infer/infer/canonical/canonicalizer.rs index 5551b56ab797b..c2dae6ba4f83d 100644 --- a/src/librustc_infer/infer/canonical/canonicalizer.rs +++ b/src/librustc_infer/infer/canonical/canonicalizer.rs @@ -332,7 +332,6 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> { ty::ReStatic | ty::ReEarlyBound(..) | ty::ReFree(_) - | ty::ReScope(_) | ty::ReEmpty(_) | ty::RePlaceholder(..) | ty::ReErased => self.canonicalize_region_mode.canonicalize_free_region(self, r), diff --git a/src/librustc_infer/infer/combine.rs b/src/librustc_infer/infer/combine.rs index 75f288f1cdcd2..70a2122a9ea5d 100644 --- a/src/librustc_infer/infer/combine.rs +++ b/src/librustc_infer/infer/combine.rs @@ -619,7 +619,6 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> { | ty::ReVar(..) | ty::ReEmpty(_) | ty::ReStatic - | ty::ReScope(..) | ty::ReEarlyBound(..) | ty::ReFree(..) => { // see common code below diff --git a/src/librustc_infer/infer/error_reporting/mod.rs b/src/librustc_infer/infer/error_reporting/mod.rs index a8d6c01785ff9..cc479aa17ce95 100644 --- a/src/librustc_infer/infer/error_reporting/mod.rs +++ b/src/librustc_infer/infer/error_reporting/mod.rs @@ -61,7 +61,6 @@ use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString}; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_hir::Node; -use rustc_middle::middle::region; use rustc_middle::ty::error::TypeError; use rustc_middle::ty::{ self, @@ -81,58 +80,12 @@ pub mod nice_region_error; pub(super) fn note_and_explain_region( tcx: TyCtxt<'tcx>, - region_scope_tree: ®ion::ScopeTree, err: &mut DiagnosticBuilder<'_>, prefix: &str, region: ty::Region<'tcx>, suffix: &str, ) { let (description, span) = match *region { - ty::ReScope(scope) => { - let new_string; - let unknown_scope = - || format!("{}unknown scope: {:?}{}. Please report a bug.", prefix, scope, suffix); - let span = scope.span(tcx, region_scope_tree); - let hir_id = scope.hir_id(region_scope_tree); - let tag = match hir_id.and_then(|hir_id| tcx.hir().find(hir_id)) { - Some(Node::Block(_)) => "block", - Some(Node::Expr(expr)) => match expr.kind { - hir::ExprKind::Call(..) => "call", - hir::ExprKind::MethodCall(..) => "method call", - hir::ExprKind::Match(.., hir::MatchSource::IfLetDesugar { .. }) => "if let", - hir::ExprKind::Match(.., hir::MatchSource::WhileLetDesugar) => "while let", - hir::ExprKind::Match(.., hir::MatchSource::ForLoopDesugar) => "for", - hir::ExprKind::Match(..) => "match", - _ => "expression", - }, - Some(Node::Stmt(_)) => "statement", - Some(Node::Item(it)) => item_scope_tag(&it), - Some(Node::TraitItem(it)) => trait_item_scope_tag(&it), - Some(Node::ImplItem(it)) => impl_item_scope_tag(&it), - Some(_) | None => { - err.span_note(span, &unknown_scope()); - return; - } - }; - let scope_decorated_tag = match scope.data { - region::ScopeData::Node => tag, - region::ScopeData::CallSite => "scope of call-site for function", - region::ScopeData::Arguments => "scope of function body", - region::ScopeData::Destruction => { - new_string = format!("destruction scope surrounding {}", tag); - &new_string[..] - } - region::ScopeData::Remainder(first_statement_index) => { - new_string = format!( - "block suffix following statement {}", - first_statement_index.index() - ); - &new_string[..] - } - }; - explain_span(tcx, scope_decorated_tag, span) - } - ty::ReEarlyBound(_) | ty::ReFree(_) | ty::ReStatic => { msg_span_from_free_region(tcx, region) } @@ -284,7 +237,6 @@ fn explain_span(tcx: TyCtxt<'tcx>, heading: &str, span: Span) -> (String, Option pub fn unexpected_hidden_region_diagnostic( tcx: TyCtxt<'tcx>, - region_scope_tree: Option<®ion::ScopeTree>, span: Span, hidden_ty: Ty<'tcx>, hidden_region: ty::Region<'tcx>, @@ -297,64 +249,56 @@ pub fn unexpected_hidden_region_diagnostic( ); // Explain the region we are capturing. - if let ty::ReEarlyBound(_) | ty::ReFree(_) | ty::ReStatic | ty::ReEmpty(_) = hidden_region { - // Assuming regionck succeeded (*), we ought to always be - // capturing *some* region from the fn header, and hence it - // ought to be free. So under normal circumstances, we will go - // down this path which gives a decent human readable - // explanation. - // - // (*) if not, the `tainted_by_errors` field would be set to - // `Some(ErrorReported)` in any case, so we wouldn't be here at all. - note_and_explain_free_region( - tcx, - &mut err, - &format!("hidden type `{}` captures ", hidden_ty), - hidden_region, - "", - ); - } else { - // Ugh. This is a painful case: the hidden region is not one - // that we can easily summarize or explain. This can happen - // in a case like - // `src/test/ui/multiple-lifetimes/ordinary-bounds-unsuited.rs`: - // - // ``` - // fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b> { - // if condition() { a } else { b } - // } - // ``` - // - // Here the captured lifetime is the intersection of `'a` and - // `'b`, which we can't quite express. - - if let Some(region_scope_tree) = region_scope_tree { - // If the `region_scope_tree` is available, this is being - // invoked from the "region inferencer error". We can at - // least report a really cryptic error for now. - note_and_explain_region( + match hidden_region { + ty::ReEmpty(ty::UniverseIndex::ROOT) => { + // All lifetimes shorter than the function body are `empty` in + // lexical region resolution. The default explanation of "an empty + // lifetime" isn't really accurate here. + let message = format!( + "hidden type `{}` captures lifetime smaller than the function body", + hidden_ty + ); + err.span_note(span, &message); + } + ty::ReEarlyBound(_) | ty::ReFree(_) | ty::ReStatic | ty::ReEmpty(_) => { + // Assuming regionck succeeded (*), we ought to always be + // capturing *some* region from the fn header, and hence it + // ought to be free. So under normal circumstances, we will go + // down this path which gives a decent human readable + // explanation. + // + // (*) if not, the `tainted_by_errors` field would be set to + // `Some(ErrorReported)` in any case, so we wouldn't be here at all. + note_and_explain_free_region( tcx, - region_scope_tree, &mut err, &format!("hidden type `{}` captures ", hidden_ty), hidden_region, "", ); - } else { - // If the `region_scope_tree` is *unavailable*, this is - // being invoked by the code that comes *after* region - // inferencing. This is a bug, as the region inferencer - // ought to have noticed the failed constraint and invoked - // error reporting, which in turn should have prevented us - // from getting trying to infer the hidden type - // completely. - tcx.sess.delay_span_bug( - span, - &format!( - "hidden type captures unexpected lifetime `{:?}` \ - but no region inference failure", - hidden_region, - ), + } + _ => { + // Ugh. This is a painful case: the hidden region is not one + // that we can easily summarize or explain. This can happen + // in a case like + // `src/test/ui/multiple-lifetimes/ordinary-bounds-unsuited.rs`: + // + // ``` + // fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b> { + // if condition() { a } else { b } + // } + // ``` + // + // Here the captured lifetime is the intersection of `'a` and + // `'b`, which we can't quite express. + + // We can at least report a really cryptic error for now. + note_and_explain_region( + tcx, + &mut err, + &format!("hidden type `{}` captures ", hidden_ty), + hidden_region, + "", ); } } @@ -363,11 +307,7 @@ pub fn unexpected_hidden_region_diagnostic( } impl<'a, 'tcx> InferCtxt<'a, 'tcx> { - pub fn report_region_errors( - &self, - region_scope_tree: ®ion::ScopeTree, - errors: &Vec>, - ) { + pub fn report_region_errors(&self, errors: &Vec>) { debug!("report_region_errors(): {} errors to start", errors.len()); // try to pre-process the errors, which will group some of them @@ -390,17 +330,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // general bit of code that displays the error information RegionResolutionError::ConcreteFailure(origin, sub, sup) => { if sub.is_placeholder() || sup.is_placeholder() { - self.report_placeholder_failure(region_scope_tree, origin, sub, sup) - .emit(); + self.report_placeholder_failure(origin, sub, sup).emit(); } else { - self.report_concrete_failure(region_scope_tree, origin, sub, sup) - .emit(); + self.report_concrete_failure(origin, sub, sup).emit(); } } RegionResolutionError::GenericBoundFailure(origin, param_ty, sub) => { self.report_generic_bound_failure( - region_scope_tree, origin.span(), Some(origin), param_ty, @@ -417,29 +354,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { sup_r, ) => { if sub_r.is_placeholder() { - self.report_placeholder_failure( - region_scope_tree, - sub_origin, - sub_r, - sup_r, - ) - .emit(); + self.report_placeholder_failure(sub_origin, sub_r, sup_r).emit(); } else if sup_r.is_placeholder() { - self.report_placeholder_failure( - region_scope_tree, - sup_origin, - sub_r, - sup_r, - ) - .emit(); + self.report_placeholder_failure(sup_origin, sub_r, sup_r).emit(); } else { self.report_sub_sup_conflict( - region_scope_tree, - var_origin, - sub_origin, - sub_r, - sup_origin, - sup_r, + var_origin, sub_origin, sub_r, sup_origin, sup_r, ); } } @@ -460,13 +380,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // value. let sub_r = self.tcx.mk_region(ty::ReEmpty(var_universe)); - self.report_placeholder_failure( - region_scope_tree, - sup_origin, - sub_r, - sup_r, - ) - .emit(); + self.report_placeholder_failure(sup_origin, sub_r, sup_r).emit(); } RegionResolutionError::MemberConstraintFailure { @@ -477,7 +391,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let hidden_ty = self.resolve_vars_if_possible(&hidden_ty); unexpected_hidden_region_diagnostic( self.tcx, - Some(region_scope_tree), span, hidden_ty, member_region, @@ -1754,19 +1667,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { pub fn report_generic_bound_failure( &self, - region_scope_tree: ®ion::ScopeTree, span: Span, origin: Option>, bound_kind: GenericKind<'tcx>, sub: Region<'tcx>, ) { - self.construct_generic_bound_failure(region_scope_tree, span, origin, bound_kind, sub) - .emit(); + self.construct_generic_bound_failure(span, origin, bound_kind, sub).emit(); } pub fn construct_generic_bound_failure( &self, - region_scope_tree: ®ion::ScopeTree, span: Span, origin: Option>, bound_kind: GenericKind<'tcx>, @@ -1918,7 +1828,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { )); note_and_explain_region( self.tcx, - region_scope_tree, &mut err, &format!("{} must be valid for ", labeled_user_string), sub, @@ -1936,7 +1845,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { fn report_sub_sup_conflict( &self, - region_scope_tree: ®ion::ScopeTree, var_origin: RegionVariableOrigin, sub_origin: SubregionOrigin<'tcx>, sub_region: Region<'tcx>, @@ -1947,7 +1855,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { note_and_explain_region( self.tcx, - region_scope_tree, &mut err, "first, the lifetime cannot outlive ", sup_region, @@ -1973,7 +1880,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { if sub_expected == sup_expected && sub_found == sup_found { note_and_explain_region( self.tcx, - region_scope_tree, &mut err, "...but the lifetime must also be valid for ", sub_region, @@ -1995,7 +1901,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { note_and_explain_region( self.tcx, - region_scope_tree, &mut err, "but, the lifetime must be valid for ", sub_region, diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/mod.rs b/src/librustc_infer/infer/error_reporting/nice_region_error/mod.rs index 2aed3d9a469fb..efe52689550c4 100644 --- a/src/librustc_infer/infer/error_reporting/nice_region_error/mod.rs +++ b/src/librustc_infer/infer/error_reporting/nice_region_error/mod.rs @@ -8,7 +8,6 @@ use rustc_span::source_map::Span; mod different_lifetimes; mod find_anon_type; mod named_anon_conflict; -mod outlives_closure; mod placeholder_error; mod static_impl_trait; mod trait_impl_difference; @@ -57,7 +56,6 @@ impl<'cx, 'tcx> NiceRegionError<'cx, 'tcx> { ErrorReported }) .or_else(|| self.try_report_anon_anon_conflict()) - .or_else(|| self.try_report_outlives_closure()) .or_else(|| self.try_report_static_impl_trait()) .or_else(|| self.try_report_impl_not_conforming_to_trait()) } diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/outlives_closure.rs b/src/librustc_infer/infer/error_reporting/nice_region_error/outlives_closure.rs deleted file mode 100644 index fc858a497597e..0000000000000 --- a/src/librustc_infer/infer/error_reporting/nice_region_error/outlives_closure.rs +++ /dev/null @@ -1,117 +0,0 @@ -//! Error Reporting for Anonymous Region Lifetime Errors -//! where both the regions are anonymous. - -use crate::infer::error_reporting::nice_region_error::NiceRegionError; -use crate::infer::lexical_region_resolve::RegionResolutionError::SubSupConflict; -use crate::infer::SubregionOrigin; -use rustc_errors::ErrorReported; -use rustc_hir::{Expr, ExprKind::Closure, Node}; -use rustc_middle::ty::RegionKind; - -impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { - /// Print the error message for lifetime errors when binding escapes a closure. - /// - /// Consider a case where we have - /// - /// ```no_run - /// fn with_int(f: F) where F: FnOnce(&isize) { - /// let x = 3; - /// f(&x); - /// } - /// fn main() { - /// let mut x = None; - /// with_int(|y| x = Some(y)); - /// } - /// ``` - /// - /// the output will be - /// - /// ```text - /// let mut x = None; - /// ----- borrowed data cannot be stored into here... - /// with_int(|y| x = Some(y)); - /// --- ^ cannot be stored outside of its closure - /// | - /// ...because it cannot outlive this closure - /// ``` - pub(super) fn try_report_outlives_closure(&self) -> Option { - if let Some(SubSupConflict(_, origin, ref sub_origin, _, ref sup_origin, sup_region)) = - self.error - { - // #45983: when trying to assign the contents of an argument to a binding outside of a - // closure, provide a specific message pointing this out. - if let ( - &SubregionOrigin::BindingTypeIsNotValidAtDecl(ref external_span), - &RegionKind::ReFree(ref free_region), - ) = (&sub_origin, sup_region) - { - let hir = &self.tcx().hir(); - if let Some(def_id) = free_region.scope.as_local() { - let hir_id = hir.as_local_hir_id(def_id); - if let Node::Expr(Expr { kind: Closure(_, _, _, closure_span, None), .. }) = - hir.get(hir_id) - { - let sup_sp = sup_origin.span(); - let origin_sp = origin.span(); - let mut err = self.tcx().sess.struct_span_err( - sup_sp, - "borrowed data cannot be stored outside of its closure", - ); - err.span_label(sup_sp, "cannot be stored outside of its closure"); - if origin_sp == sup_sp || origin_sp.contains(sup_sp) { - // // sup_sp == origin.span(): - // - // let mut x = None; - // ----- borrowed data cannot be stored into here... - // with_int(|y| x = Some(y)); - // --- ^ cannot be stored outside of its closure - // | - // ...because it cannot outlive this closure - // - // // origin.contains(&sup_sp): - // - // let mut f: Option<&u32> = None; - // ----- borrowed data cannot be stored into here... - // closure_expecting_bound(|x: &'x u32| { - // ------------ ... because it cannot outlive this closure - // f = Some(x); - // ^ cannot be stored outside of its closure - err.span_label( - *external_span, - "borrowed data cannot be stored into here...", - ); - err.span_label( - *closure_span, - "...because it cannot outlive this closure", - ); - } else { - // FIXME: the wording for this case could be much improved - // - // let mut lines_to_use: Vec<&CrateId> = Vec::new(); - // - cannot infer an appropriate lifetime... - // let push_id = |installed_id: &CrateId| { - // ------- ------------------------ borrowed data cannot outlive this closure - // | - // ...so that variable is valid at time of its declaration - // lines_to_use.push(installed_id); - // ^^^^^^^^^^^^ cannot be stored outside of its closure - err.span_label(origin_sp, "cannot infer an appropriate lifetime..."); - err.span_label( - *external_span, - "...so that variable is valid at time of its \ - declaration", - ); - err.span_label( - *closure_span, - "borrowed data cannot outlive this closure", - ); - } - err.emit(); - return Some(ErrorReported); - } - } - } - } - None - } -} diff --git a/src/librustc_infer/infer/error_reporting/note.rs b/src/librustc_infer/infer/error_reporting/note.rs index 81f37831af208..8fbb89da5af41 100644 --- a/src/librustc_infer/infer/error_reporting/note.rs +++ b/src/librustc_infer/infer/error_reporting/note.rs @@ -1,7 +1,6 @@ use crate::infer::error_reporting::{note_and_explain_region, ObligationCauseExt}; use crate::infer::{self, InferCtxt, SubregionOrigin}; use rustc_errors::{struct_span_err, DiagnosticBuilder}; -use rustc_middle::middle::region; use rustc_middle::ty::error::TypeError; use rustc_middle::ty::{self, Region}; @@ -38,65 +37,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let var_name = self.tcx.hir().name(upvar_id.var_path.hir_id); err.span_note(span, &format!("...so that closure can access `{}`", var_name)); } - infer::InfStackClosure(span) => { - err.span_note(span, "...so that closure does not outlive its stack frame"); - } - infer::InvokeClosure(span) => { - err.span_note(span, "...so that closure is not invoked outside its lifetime"); - } - infer::DerefPointer(span) => { - err.span_note(span, "...so that pointer is not dereferenced outside its lifetime"); - } - infer::ClosureCapture(span, id) => { - err.span_note( - span, - &format!( - "...so that captured variable `{}` does not outlive the \ - enclosing closure", - self.tcx.hir().name(id) - ), - ); - } - infer::IndexSlice(span) => { - err.span_note(span, "...so that slice is not indexed outside the lifetime"); - } infer::RelateObjectBound(span) => { err.span_note(span, "...so that it can be closed over into an object"); } - infer::CallRcvr(span) => { - err.span_note(span, "...so that method receiver is valid for the method call"); - } - infer::CallArg(span) => { - err.span_note(span, "...so that argument is valid for the call"); - } infer::CallReturn(span) => { err.span_note(span, "...so that return value is valid for the call"); } - infer::Operand(span) => { - err.span_note(span, "...so that operand is valid for operation"); - } - infer::AddrOf(span) => { - err.span_note(span, "...so that reference is valid at the time of borrow"); - } - infer::AutoBorrow(span) => { - err.span_note(span, "...so that auto-reference is valid at the time of borrow"); - } - infer::ExprTypeIsNotInScope(t, span) => { - err.span_note( - span, - &format!( - "...so type `{}` of expression is valid during the \ - expression", - self.ty_to_string(t) - ), - ); - } - infer::BindingTypeIsNotValidAtDecl(span) => { - err.span_note(span, "...so that variable is valid at time of its declaration"); - } - infer::ParameterInScope(_, span) => { - err.span_note(span, "...so that a type/lifetime parameter is in scope here"); - } infer::DataBorrowed(ty, span) => { err.span_note( span, @@ -126,25 +72,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ), ); } - infer::RelateDefaultParamBound(span, t) => { - err.span_note( - span, - &format!( - "...so that type parameter instantiated with `{}`, will \ - meet its declared lifetime bounds", - self.ty_to_string(t) - ), - ); - } infer::RelateRegionParamBound(span) => { err.span_note( span, "...so that the declared lifetime parameter bounds are satisfied", ); } - infer::SafeDestructor(span) => { - err.span_note(span, "...so that references are valid when the destructor runs"); - } infer::CompareImplMethodObligation { span, .. } => { err.span_note( span, @@ -157,7 +90,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { pub(super) fn report_concrete_failure( &self, - region_scope_tree: ®ion::ScopeTree, origin: SubregionOrigin<'tcx>, sub: Region<'tcx>, sup: Region<'tcx>, @@ -166,10 +98,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { infer::Subtype(box trace) => { let terr = TypeError::RegionsDoesNotOutlive(sup, sub); let mut err = self.report_and_explain_type_error(trace, &terr); - note_and_explain_region(self.tcx, region_scope_tree, &mut err, "", sup, "..."); + note_and_explain_region(self.tcx, &mut err, "", sup, "..."); note_and_explain_region( self.tcx, - region_scope_tree, &mut err, "...does not necessarily outlive ", sub, @@ -187,7 +118,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ); note_and_explain_region( self.tcx, - region_scope_tree, &mut err, "...the reference is valid for ", sub, @@ -195,7 +125,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ); note_and_explain_region( self.tcx, - region_scope_tree, &mut err, "...but the borrowed content is only valid for ", sup, @@ -215,7 +144,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ); note_and_explain_region( self.tcx, - region_scope_tree, &mut err, "...the borrowed pointer is valid for ", sub, @@ -223,7 +151,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ); note_and_explain_region( self.tcx, - region_scope_tree, &mut err, &format!("...but `{}` is only valid for ", var_name), sup, @@ -231,106 +158,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ); err } - infer::InfStackClosure(span) => { - let mut err = - struct_span_err!(self.tcx.sess, span, E0314, "closure outlives stack frame"); - note_and_explain_region( - self.tcx, - region_scope_tree, - &mut err, - "...the closure must be valid for ", - sub, - "...", - ); - note_and_explain_region( - self.tcx, - region_scope_tree, - &mut err, - "...but the closure's stack frame is only valid \ - for ", - sup, - "", - ); - err - } - infer::InvokeClosure(span) => { - let mut err = struct_span_err!( - self.tcx.sess, - span, - E0315, - "cannot invoke closure outside of its lifetime" - ); - note_and_explain_region( - self.tcx, - region_scope_tree, - &mut err, - "the closure is only valid for ", - sup, - "", - ); - err - } - infer::DerefPointer(span) => { - let mut err = struct_span_err!( - self.tcx.sess, - span, - E0473, - "dereference of reference outside its lifetime" - ); - note_and_explain_region( - self.tcx, - region_scope_tree, - &mut err, - "the reference is only valid for ", - sup, - "", - ); - err - } - infer::ClosureCapture(span, id) => { - let mut err = struct_span_err!( - self.tcx.sess, - span, - E0474, - "captured variable `{}` does not outlive the \ - enclosing closure", - self.tcx.hir().name(id) - ); - note_and_explain_region( - self.tcx, - region_scope_tree, - &mut err, - "captured variable is valid for ", - sup, - "", - ); - note_and_explain_region( - self.tcx, - region_scope_tree, - &mut err, - "closure is valid for ", - sub, - "", - ); - err - } - infer::IndexSlice(span) => { - let mut err = struct_span_err!( - self.tcx.sess, - span, - E0475, - "index of slice outside its lifetime" - ); - note_and_explain_region( - self.tcx, - region_scope_tree, - &mut err, - "the slice is only valid for ", - sup, - "", - ); - err - } infer::RelateObjectBound(span) => { let mut err = struct_span_err!( self.tcx.sess, @@ -339,17 +166,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { "lifetime of the source pointer does not outlive \ lifetime bound of the object type" ); + note_and_explain_region(self.tcx, &mut err, "object type is valid for ", sub, ""); note_and_explain_region( self.tcx, - region_scope_tree, - &mut err, - "object type is valid for ", - sub, - "", - ); - note_and_explain_region( - self.tcx, - region_scope_tree, &mut err, "source pointer is only valid for ", sup, @@ -367,22 +186,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { self.ty_to_string(ty) ); match *sub { - ty::ReStatic => note_and_explain_region( - self.tcx, - region_scope_tree, - &mut err, - "type must satisfy ", - sub, - "", - ), - _ => note_and_explain_region( - self.tcx, - region_scope_tree, - &mut err, - "type must outlive ", - sub, - "", - ), + ty::ReStatic => { + note_and_explain_region(self.tcx, &mut err, "type must satisfy ", sub, "") + } + _ => note_and_explain_region(self.tcx, &mut err, "type must outlive ", sub, ""), } err } @@ -391,7 +198,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { struct_span_err!(self.tcx.sess, span, E0478, "lifetime bound not satisfied"); note_and_explain_region( self.tcx, - region_scope_tree, &mut err, "lifetime parameter instantiated with ", sup, @@ -399,7 +205,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ); note_and_explain_region( self.tcx, - region_scope_tree, &mut err, "but lifetime parameter must outlive ", sub, @@ -407,61 +212,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ); err } - infer::RelateDefaultParamBound(span, ty) => { - let mut err = struct_span_err!( - self.tcx.sess, - span, - E0479, - "the type `{}` (provided as the value of a type \ - parameter) is not valid at this point", - self.ty_to_string(ty) - ); - note_and_explain_region( - self.tcx, - region_scope_tree, - &mut err, - "type must outlive ", - sub, - "", - ); - err - } - infer::CallRcvr(span) => { - let mut err = struct_span_err!( - self.tcx.sess, - span, - E0480, - "lifetime of method receiver does not outlive the \ - method call" - ); - note_and_explain_region( - self.tcx, - region_scope_tree, - &mut err, - "the receiver is only valid for ", - sup, - "", - ); - err - } - infer::CallArg(span) => { - let mut err = struct_span_err!( - self.tcx.sess, - span, - E0481, - "lifetime of function argument does not outlive \ - the function call" - ); - note_and_explain_region( - self.tcx, - region_scope_tree, - &mut err, - "the function argument is only valid for ", - sup, - "", - ); - err - } infer::CallReturn(span) => { let mut err = struct_span_err!( self.tcx.sess, @@ -472,7 +222,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ); note_and_explain_region( self.tcx, - region_scope_tree, &mut err, "the return value is only valid for ", sup, @@ -480,140 +229,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ); err } - infer::Operand(span) => { - let mut err = struct_span_err!( - self.tcx.sess, - span, - E0483, - "lifetime of operand does not outlive the \ - operation" - ); - note_and_explain_region( - self.tcx, - region_scope_tree, - &mut err, - "the operand is only valid for ", - sup, - "", - ); - err - } - infer::AddrOf(span) => { - let mut err = struct_span_err!( - self.tcx.sess, - span, - E0484, - "reference is not valid at the time of borrow" - ); - note_and_explain_region( - self.tcx, - region_scope_tree, - &mut err, - "the borrow is only valid for ", - sup, - "", - ); - err - } - infer::AutoBorrow(span) => { - let mut err = struct_span_err!( - self.tcx.sess, - span, - E0485, - "automatically reference is not valid at the time \ - of borrow" - ); - note_and_explain_region( - self.tcx, - region_scope_tree, - &mut err, - "the automatic borrow is only valid for ", - sup, - "", - ); - err - } - infer::ExprTypeIsNotInScope(t, span) => { - let mut err = struct_span_err!( - self.tcx.sess, - span, - E0486, - "type of expression contains references that are \ - not valid during the expression: `{}`", - self.ty_to_string(t) - ); - note_and_explain_region( - self.tcx, - region_scope_tree, - &mut err, - "type is only valid for ", - sup, - "", - ); - err - } - infer::SafeDestructor(span) => { - let mut err = struct_span_err!( - self.tcx.sess, - span, - E0487, - "unsafe use of destructor: destructor might be \ - called while references are dead" - ); - // FIXME (22171): terms "super/subregion" are suboptimal - note_and_explain_region( - self.tcx, - region_scope_tree, - &mut err, - "superregion: ", - sup, - "", - ); - note_and_explain_region( - self.tcx, - region_scope_tree, - &mut err, - "subregion: ", - sub, - "", - ); - err - } - infer::BindingTypeIsNotValidAtDecl(span) => { - let mut err = struct_span_err!( - self.tcx.sess, - span, - E0488, - "lifetime of variable does not enclose its \ - declaration" - ); - note_and_explain_region( - self.tcx, - region_scope_tree, - &mut err, - "the variable is only valid for ", - sup, - "", - ); - err - } - infer::ParameterInScope(_, span) => { - let mut err = struct_span_err!( - self.tcx.sess, - span, - E0489, - "type/lifetime parameter not in scope here" - ); - note_and_explain_region( - self.tcx, - region_scope_tree, - &mut err, - "the parameter is only valid for ", - sub, - "", - ); - err - } infer::DataBorrowed(ty, span) => { let mut err = struct_span_err!( self.tcx.sess, @@ -622,22 +237,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { "a value of type `{}` is borrowed for too long", self.ty_to_string(ty) ); - note_and_explain_region( - self.tcx, - region_scope_tree, - &mut err, - "the type is valid for ", - sub, - "", - ); - note_and_explain_region( - self.tcx, - region_scope_tree, - &mut err, - "but the borrow lasts for ", - sup, - "", - ); + note_and_explain_region(self.tcx, &mut err, "the type is valid for ", sub, ""); + note_and_explain_region(self.tcx, &mut err, "but the borrow lasts for ", sup, ""); err } infer::ReferenceOutlivesReferent(ty, span) => { @@ -648,17 +249,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { "in type `{}`, reference has a longer lifetime than the data it references", self.ty_to_string(ty) ); + note_and_explain_region(self.tcx, &mut err, "the pointer is valid for ", sub, ""); note_and_explain_region( self.tcx, - region_scope_tree, - &mut err, - "the pointer is valid for ", - sub, - "", - ); - note_and_explain_region( - self.tcx, - region_scope_tree, &mut err, "but the referenced data is only valid for ", sup, @@ -683,7 +276,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { pub(super) fn report_placeholder_failure( &self, - region_scope_tree: ®ion::ScopeTree, placeholder_origin: SubregionOrigin<'tcx>, sub: Region<'tcx>, sup: Region<'tcx>, @@ -695,7 +287,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { self.report_and_explain_type_error(trace, &terr) } - _ => self.report_concrete_failure(region_scope_tree, placeholder_origin, sub, sup), + _ => self.report_concrete_failure(placeholder_origin, sub, sup), } } } diff --git a/src/librustc_infer/infer/free_regions.rs b/src/librustc_infer/infer/free_regions.rs index e31c524c19710..d975038b010b9 100644 --- a/src/librustc_infer/infer/free_regions.rs +++ b/src/librustc_infer/infer/free_regions.rs @@ -5,7 +5,6 @@ use rustc_data_structures::transitive_relation::TransitiveRelation; use rustc_hir::def_id::DefId; -use rustc_middle::middle::region; use rustc_middle::ty::{self, Lift, Region, TyCtxt}; /// Combines a `region::ScopeTree` (which governs relationships between @@ -21,21 +20,13 @@ pub struct RegionRelations<'a, 'tcx> { /// The context used to fetch the region maps. pub context: DefId, - /// The region maps for the given context. - pub region_scope_tree: &'a region::ScopeTree, - /// Free-region relationships. pub free_regions: &'a FreeRegionMap<'tcx>, } impl<'a, 'tcx> RegionRelations<'a, 'tcx> { - pub fn new( - tcx: TyCtxt<'tcx>, - context: DefId, - region_scope_tree: &'a region::ScopeTree, - free_regions: &'a FreeRegionMap<'tcx>, - ) -> Self { - Self { tcx, context, region_scope_tree, free_regions } + pub fn new(tcx: TyCtxt<'tcx>, context: DefId, free_regions: &'a FreeRegionMap<'tcx>) -> Self { + Self { tcx, context, free_regions } } pub fn lub_free_regions(&self, r_a: Region<'tcx>, r_b: Region<'tcx>) -> Region<'tcx> { diff --git a/src/librustc_infer/infer/freshen.rs b/src/librustc_infer/infer/freshen.rs index c9ed687eaf256..b4cfcb3a1c325 100644 --- a/src/librustc_infer/infer/freshen.rs +++ b/src/librustc_infer/infer/freshen.rs @@ -127,7 +127,6 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> { ty::ReStatic | ty::ReEarlyBound(..) | ty::ReFree(_) - | ty::ReScope(_) | ty::ReVar(_) | ty::RePlaceholder(..) | ty::ReEmpty(_) diff --git a/src/librustc_infer/infer/lexical_region_resolve/graphviz.rs b/src/librustc_infer/infer/lexical_region_resolve/graphviz.rs deleted file mode 100644 index 5d3e8f440d6fd..0000000000000 --- a/src/librustc_infer/infer/lexical_region_resolve/graphviz.rs +++ /dev/null @@ -1,253 +0,0 @@ -//! This module provides linkage between libgraphviz traits and -//! `rustc_trait_selection::infer::region_constraints`, generating a -//! rendering of the graph represented by the list of `Constraint` -//! instances (which make up the edges of the graph), as well as the -//! origin for each constraint (which are attached to the labels on -//! each edge). - -/// For clarity, rename the graphviz crate locally to dot. -use graphviz as dot; - -use super::Constraint; -use crate::infer::region_constraints::RegionConstraintData; -use crate::infer::RegionRelations; -use crate::infer::SubregionOrigin; -use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_hir::def_id::DefIndex; -use rustc_middle::middle::region; -use rustc_middle::ty; - -use std::borrow::Cow; -use std::collections::btree_map::BTreeMap; -use std::collections::hash_map::Entry::Vacant; -use std::env; -use std::fs; -use std::io; -use std::sync::atomic::{AtomicBool, Ordering}; - -fn print_help_message() { - println!( - "\ --Z print-region-graph by default prints a region constraint graph for every \n\ -function body, to the path `constraints.nodeXXX.dot`, where the XXX is \n\ -replaced with the node id of the function under analysis. \n\ - \n\ -To select one particular function body, set `RUST_REGION_GRAPH_NODE=XXX`, \n\ -where XXX is the node id desired. \n\ - \n\ -To generate output to some path other than the default \n\ -`constraints.nodeXXX.dot`, set `RUST_REGION_GRAPH=/path/desired.dot`; \n\ -occurrences of the character `%` in the requested path will be replaced with\n\ -the node id of the function under analysis. \n\ - \n\ -(Since you requested help via RUST_REGION_GRAPH=help, no region constraint \n\ -graphs will be printed. \n\ -" - ); -} - -pub fn maybe_print_constraints_for<'a, 'tcx>( - region_data: &RegionConstraintData<'tcx>, - region_rels: &RegionRelations<'a, 'tcx>, -) { - let tcx = region_rels.tcx; - let context = region_rels.context; - - if !tcx.sess.opts.debugging_opts.print_region_graph { - return; - } - - let requested_node = env::var("RUST_REGION_GRAPH_NODE") - .ok() - .and_then(|s| s.parse().map(DefIndex::from_u32).ok()); - - if requested_node.is_some() && requested_node != Some(context.index) { - return; - } - - let requested_output = env::var("RUST_REGION_GRAPH"); - debug!("requested_output: {:?} requested_node: {:?}", requested_output, requested_node); - - let output_path = { - let output_template = match requested_output { - Ok(ref s) if s == "help" => { - static PRINTED_YET: AtomicBool = AtomicBool::new(false); - if !PRINTED_YET.load(Ordering::SeqCst) { - print_help_message(); - PRINTED_YET.store(true, Ordering::SeqCst); - } - return; - } - - Ok(other_path) => other_path, - Err(_) => "constraints.node%.dot".to_string(), - }; - - if output_template.is_empty() { - panic!("empty string provided as RUST_REGION_GRAPH"); - } - - if output_template.contains('%') { - let mut new_str = String::new(); - for c in output_template.chars() { - if c == '%' { - new_str.push_str(&context.index.as_u32().to_string()); - } else { - new_str.push(c); - } - } - new_str - } else { - output_template - } - }; - - if let Err(e) = dump_region_data_to(region_rels, ®ion_data.constraints, &output_path) { - let msg = format!("io error dumping region constraints: {}", e); - tcx.sess.err(&msg) - } -} - -struct ConstraintGraph<'a, 'tcx> { - graph_name: String, - region_rels: &'a RegionRelations<'a, 'tcx>, - map: &'a BTreeMap, SubregionOrigin<'tcx>>, - node_ids: FxHashMap, -} - -#[derive(Clone, Hash, PartialEq, Eq, Debug, Copy)] -enum Node { - RegionVid(ty::RegionVid), - Region(ty::RegionKind), -} - -#[derive(Clone, PartialEq, Eq, Debug, Copy)] -enum Edge<'tcx> { - Constraint(Constraint<'tcx>), - EnclScope(region::Scope, region::Scope), -} - -impl<'a, 'tcx> ConstraintGraph<'a, 'tcx> { - fn new( - name: String, - region_rels: &'a RegionRelations<'a, 'tcx>, - map: &'a ConstraintMap<'tcx>, - ) -> ConstraintGraph<'a, 'tcx> { - let mut i = 0; - let mut node_ids = FxHashMap::default(); - { - let mut add_node = |node| { - if let Vacant(e) = node_ids.entry(node) { - e.insert(i); - i += 1; - } - }; - - for (n1, n2) in map.keys().map(|c| constraint_to_nodes(c)) { - add_node(n1); - add_node(n2); - } - - region_rels.region_scope_tree.each_encl_scope(|sub, sup| { - add_node(Node::Region(ty::ReScope(sub))); - add_node(Node::Region(ty::ReScope(sup))); - }); - } - - ConstraintGraph { map, node_ids, region_rels, graph_name: name } - } -} - -impl<'a, 'tcx> dot::Labeller<'a> for ConstraintGraph<'a, 'tcx> { - type Node = Node; - type Edge = Edge<'tcx>; - fn graph_id(&self) -> dot::Id<'_> { - dot::Id::new(&*self.graph_name).unwrap() - } - fn node_id(&self, n: &Node) -> dot::Id<'_> { - let node_id = match self.node_ids.get(n) { - Some(node_id) => node_id, - None => bug!("no node_id found for node: {:?}", n), - }; - let name = || format!("node_{}", node_id); - - dot::Id::new(name()) - .unwrap_or_else(|_| bug!("failed to create graphviz node identified by {}", name())) - } - fn node_label(&self, n: &Node) -> dot::LabelText<'_> { - match *n { - Node::RegionVid(n_vid) => dot::LabelText::label(format!("{:?}", n_vid)), - Node::Region(n_rgn) => dot::LabelText::label(format!("{:?}", n_rgn)), - } - } - fn edge_label(&self, e: &Edge<'_>) -> dot::LabelText<'_> { - match *e { - Edge::Constraint(ref c) => { - dot::LabelText::label(format!("{:?}", self.map.get(c).unwrap())) - } - Edge::EnclScope(..) => dot::LabelText::label("(enclosed)".to_owned()), - } - } -} - -fn constraint_to_nodes(c: &Constraint<'_>) -> (Node, Node) { - match *c { - Constraint::VarSubVar(rv_1, rv_2) => (Node::RegionVid(rv_1), Node::RegionVid(rv_2)), - Constraint::RegSubVar(r_1, rv_2) => (Node::Region(*r_1), Node::RegionVid(rv_2)), - Constraint::VarSubReg(rv_1, r_2) => (Node::RegionVid(rv_1), Node::Region(*r_2)), - Constraint::RegSubReg(r_1, r_2) => (Node::Region(*r_1), Node::Region(*r_2)), - } -} - -fn edge_to_nodes(e: &Edge<'_>) -> (Node, Node) { - match *e { - Edge::Constraint(ref c) => constraint_to_nodes(c), - Edge::EnclScope(sub, sup) => { - (Node::Region(ty::ReScope(sub)), Node::Region(ty::ReScope(sup))) - } - } -} - -impl<'a, 'tcx> dot::GraphWalk<'a> for ConstraintGraph<'a, 'tcx> { - type Node = Node; - type Edge = Edge<'tcx>; - fn nodes(&self) -> dot::Nodes<'_, Node> { - let set = self.node_ids.keys().cloned().collect::>(); - debug!("constraint graph has {} nodes", set.len()); - set.into_iter().collect() - } - fn edges(&self) -> dot::Edges<'_, Edge<'tcx>> { - debug!("constraint graph has {} edges", self.map.len()); - let mut v: Vec<_> = self.map.keys().map(|e| Edge::Constraint(*e)).collect(); - self.region_rels - .region_scope_tree - .each_encl_scope(|sub, sup| v.push(Edge::EnclScope(sub, sup))); - debug!("region graph has {} edges", v.len()); - Cow::Owned(v) - } - fn source(&self, edge: &Edge<'tcx>) -> Node { - let (n1, _) = edge_to_nodes(edge); - debug!("edge {:?} has source {:?}", edge, n1); - n1 - } - fn target(&self, edge: &Edge<'tcx>) -> Node { - let (_, n2) = edge_to_nodes(edge); - debug!("edge {:?} has target {:?}", edge, n2); - n2 - } -} - -pub type ConstraintMap<'tcx> = BTreeMap, SubregionOrigin<'tcx>>; - -fn dump_region_data_to<'a, 'tcx>( - region_rels: &RegionRelations<'a, 'tcx>, - map: &ConstraintMap<'tcx>, - path: &str, -) -> io::Result<()> { - debug!("dump_region_data map (len: {}) path: {}", map.len(), path); - let g = ConstraintGraph::new("region_data".to_string(), region_rels, map); - debug!("dump_region_data calling render"); - let mut v = Vec::new(); - dot::render(&g, &mut v).unwrap(); - fs::write(path, &v) -} diff --git a/src/librustc_infer/infer/lexical_region_resolve/mod.rs b/src/librustc_infer/infer/lexical_region_resolve/mod.rs index 33a80fb747101..fcf1949933b11 100644 --- a/src/librustc_infer/infer/lexical_region_resolve/mod.rs +++ b/src/librustc_infer/infer/lexical_region_resolve/mod.rs @@ -18,13 +18,11 @@ use rustc_index::vec::{Idx, IndexVec}; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::ty::{ReEarlyBound, ReEmpty, ReErased, ReFree, ReStatic}; -use rustc_middle::ty::{ReLateBound, RePlaceholder, ReScope, ReVar}; +use rustc_middle::ty::{ReLateBound, RePlaceholder, ReVar}; use rustc_middle::ty::{Region, RegionVid}; use rustc_span::Span; use std::fmt; -mod graphviz; - /// This function performs lexical region resolution given a complete /// set of constraints and variable origins. It performs a fixed-point /// iteration to find region values which satisfy all constraints, @@ -49,7 +47,10 @@ pub fn resolve<'tcx>( let mut values = resolver.infer_variable_values(&mut errors); let re_erased = region_rels.tcx.lifetimes.re_erased; - values.values.iter_mut().for_each(|v| *v = VarValue::Value(re_erased)); + values.values.iter_mut().for_each(|v| match *v { + VarValue::Value(ref mut r) => *r = re_erased, + VarValue::ErrorValue => {} + }); (values, errors) } RegionckMode::Erase { suppress_errors: true } => { @@ -146,7 +147,6 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { self.region_rels.context, self.dump_constraints(self.region_rels) ); - graphviz::maybe_print_constraints_for(&self.data, self.region_rels); let graph = self.construct_graph(); self.expand_givens(&graph); @@ -290,8 +290,8 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { // Find all the "upper bounds" -- that is, each region `b` such that // `r0 <= b` must hold. - let (member_upper_bounds, _) = - self.collect_concrete_regions(graph, member_vid, OUTGOING, None); + let (member_upper_bounds, ..) = + self.collect_bounding_regions(graph, member_vid, OUTGOING, None); // Get an iterator over the *available choice* -- that is, // each choice region `c` where `lb <= c` and `c <= ub` for all the @@ -423,15 +423,6 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { match *b_data { VarValue::Value(cur_region) => { - // Identical scopes can show up quite often, if the fixed point - // iteration converges slowly. Skip them. This is purely an - // optimization. - if let (ReScope(a_scope), ReScope(cur_scope)) = (a_region, cur_region) { - if a_scope == cur_scope { - return false; - } - } - // This is a specialized version of the `lub_concrete_regions` // check below for a common case, here purely as an // optimization. @@ -525,8 +516,8 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { self.tcx().lifetimes.re_static } - (&ReEmpty(_), r @ (ReEarlyBound(_) | ReFree(_) | ReScope(_))) - | (r @ (ReEarlyBound(_) | ReFree(_) | ReScope(_)), &ReEmpty(_)) => { + (&ReEmpty(_), r @ (ReEarlyBound(_) | ReFree(_))) + | (r @ (ReEarlyBound(_) | ReFree(_)), &ReEmpty(_)) => { // All empty regions are less than early-bound, free, // and scope regions. r @@ -551,46 +542,6 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { } } - (&ReEarlyBound(_) | &ReFree(_), &ReScope(s_id)) - | (&ReScope(s_id), &ReEarlyBound(_) | &ReFree(_)) => { - // A "free" region can be interpreted as "some region - // at least as big as fr.scope". So, we can - // reasonably compare free regions and scopes: - let fr_scope = match (a, b) { - (&ReEarlyBound(ref br), _) | (_, &ReEarlyBound(ref br)) => { - self.region_rels.region_scope_tree.early_free_scope(self.tcx(), br) - } - (&ReFree(ref fr), _) | (_, &ReFree(ref fr)) => { - self.region_rels.region_scope_tree.free_scope(self.tcx(), fr) - } - _ => bug!(), - }; - let r_id = - self.region_rels.region_scope_tree.nearest_common_ancestor(fr_scope, s_id); - if r_id == fr_scope { - // if the free region's scope `fr.scope` is bigger than - // the scope region `s_id`, then the LUB is the free - // region itself: - match (a, b) { - (_, &ReScope(_)) => return a, - (&ReScope(_), _) => return b, - _ => bug!(), - } - } - - // otherwise, we don't know what the free region is, - // so we must conservatively say the LUB is static: - self.tcx().lifetimes.re_static - } - - (&ReScope(a_id), &ReScope(b_id)) => { - // The region corresponding to an outer block is a - // subtype of the region corresponding to an inner - // block. - let lub = self.region_rels.region_scope_tree.nearest_common_ancestor(a_id, b_id); - self.tcx().mk_region(ReScope(lub)) - } - (&ReEarlyBound(_) | &ReFree(_), &ReEarlyBound(_) | &ReFree(_)) => { self.region_rels.lub_free_regions(a, b) } @@ -659,7 +610,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { if !self.sub_concrete_regions(a_region, b_region) { debug!( "collect_errors: region error at {:?}: \ - cannot verify that {:?}={:?} <= {:?}", + cannot verify that {:?}={:?} <= {:?}", origin, a_vid, a_region, b_region ); *a_data = VarValue::ErrorValue; @@ -716,7 +667,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { graph: &RegionGraph<'tcx>, errors: &mut Vec>, ) { - debug!("collect_var_errors"); + debug!("collect_var_errors, var_data = {:#?}", var_data.values); // This is the best way that I have found to suppress // duplicate and related errors. Basically we keep a set of @@ -815,10 +766,10 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { ) { // Errors in expanding nodes result from a lower-bound that is // not contained by an upper-bound. - let (mut lower_bounds, lower_dup) = - self.collect_concrete_regions(graph, node_idx, INCOMING, Some(dup_vec)); - let (mut upper_bounds, upper_dup) = - self.collect_concrete_regions(graph, node_idx, OUTGOING, Some(dup_vec)); + let (mut lower_bounds, lower_vid_bounds, lower_dup) = + self.collect_bounding_regions(graph, node_idx, INCOMING, Some(dup_vec)); + let (mut upper_bounds, _, upper_dup) = + self.collect_bounding_regions(graph, node_idx, OUTGOING, Some(dup_vec)); if lower_dup || upper_dup { return; @@ -874,15 +825,22 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { // If we have a scenario like `exists<'a> { forall<'b> { 'b: // 'a } }`, we wind up without any lower-bound -- all we have // are placeholders as upper bounds, but the universe of the - // variable `'a` doesn't permit those placeholders. + // variable `'a`, or some variable that `'a` has to outlive, doesn't + // permit those placeholders. + let min_universe = lower_vid_bounds + .into_iter() + .map(|vid| self.var_infos[vid].universe) + .min() + .expect("lower_vid_bounds should at least include `node_idx`"); + for upper_bound in &upper_bounds { if let ty::RePlaceholder(p) = upper_bound.region { - if node_universe.cannot_name(p.universe) { + if min_universe.cannot_name(p.universe) { let origin = self.var_infos[node_idx].origin; errors.push(RegionResolutionError::UpperBoundUniverseConflict( node_idx, origin, - node_universe, + min_universe, upper_bound.origin.clone(), upper_bound.region, )); @@ -904,13 +862,24 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { ); } - fn collect_concrete_regions( + /// Collects all regions that "bound" the variable `orig_node_idx` in the + /// given direction. + /// + /// If `dup_vec` is `Some` it's used to track duplicates between successive + /// calls of this function. + /// + /// The return tuple fields are: + /// - a list of all concrete regions bounding the given region. + /// - the set of all region variables bounding the given region. + /// - a `bool` that's true if the returned region variables overlap with + /// those returned by a previous call for another region. + fn collect_bounding_regions( &self, graph: &RegionGraph<'tcx>, orig_node_idx: RegionVid, dir: Direction, mut dup_vec: Option<&mut IndexVec>>, - ) -> (Vec>, bool) { + ) -> (Vec>, FxHashSet, bool) { struct WalkState<'tcx> { set: FxHashSet, stack: Vec, @@ -929,9 +898,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { // direction specified process_edges(&self.data, &mut state, graph, orig_node_idx, dir); - while !state.stack.is_empty() { - let node_idx = state.stack.pop().unwrap(); - + while let Some(node_idx) = state.stack.pop() { // check whether we've visited this node on some previous walk if let Some(dup_vec) = &mut dup_vec { if dup_vec[node_idx].is_none() { @@ -949,8 +916,8 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { process_edges(&self.data, &mut state, graph, node_idx, dir); } - let WalkState { result, dup_found, .. } = state; - return (result, dup_found); + let WalkState { result, dup_found, set, .. } = state; + return (result, set, dup_found); fn process_edges<'tcx>( this: &RegionConstraintData<'tcx>, diff --git a/src/librustc_infer/infer/mod.rs b/src/librustc_infer/infer/mod.rs index 9c81a1153958b..30af7d06744d7 100644 --- a/src/librustc_infer/infer/mod.rs +++ b/src/librustc_infer/infer/mod.rs @@ -20,7 +20,6 @@ use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::infer::canonical::{Canonical, CanonicalVarValues}; use rustc_middle::infer::unify_key::{ConstVarValue, ConstVariableValue}; use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind, ToType}; -use rustc_middle::middle::region; use rustc_middle::mir; use rustc_middle::mir::interpret::ConstEvalResult; use rustc_middle::traits::select; @@ -378,22 +377,6 @@ pub enum SubregionOrigin<'tcx> { /// Arose from a subtyping relation Subtype(Box>), - /// Stack-allocated closures cannot outlive innermost loop - /// or function so as to ensure we only require finite stack - InfStackClosure(Span), - - /// Invocation of closure must be within its lifetime - InvokeClosure(Span), - - /// Dereference of reference must be within its lifetime - DerefPointer(Span), - - /// Closure bound must not outlive captured variables - ClosureCapture(Span, hir::HirId), - - /// Index into slice must be within its lifetime - IndexSlice(Span), - /// When casting `&'a T` to an `&'b Trait` object, /// relating `'a` to `'b` RelateObjectBound(Span), @@ -406,10 +389,6 @@ pub enum SubregionOrigin<'tcx> { /// that must outlive some other region. RelateRegionParamBound(Span), - /// A bound placed on type parameters that states that must outlive - /// the moment of their instantiation. - RelateDefaultParamBound(Span, Ty<'tcx>), - /// Creating a pointer `b` to contents of another reference Reborrow(Span), @@ -422,36 +401,9 @@ pub enum SubregionOrigin<'tcx> { /// (&'a &'b T) where a >= b ReferenceOutlivesReferent(Ty<'tcx>, Span), - /// Type or region parameters must be in scope. - ParameterInScope(ParameterOrigin, Span), - - /// The type T of an expression E must outlive the lifetime for E. - ExprTypeIsNotInScope(Ty<'tcx>, Span), - - /// A `ref b` whose region does not enclose the decl site - BindingTypeIsNotValidAtDecl(Span), - - /// Regions appearing in a method receiver must outlive method call - CallRcvr(Span), - - /// Regions appearing in a function argument must outlive func call - CallArg(Span), - /// Region in return type of invoked fn must enclose call CallReturn(Span), - /// Operands must be in scope - Operand(Span), - - /// Region resulting from a `&` expr must enclose the `&` expr - AddrOf(Span), - - /// An auto-borrow that does not enclose the expr where it occurs - AutoBorrow(Span), - - /// Region constraint arriving from destructor safety - SafeDestructor(Span), - /// Comparing the signature and requirements of an impl method against /// the containing trait. CompareImplMethodObligation { @@ -1260,7 +1212,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { pub fn resolve_regions_and_report_errors( &self, region_context: DefId, - region_map: ®ion::ScopeTree, outlives_env: &OutlivesEnvironment<'tcx>, mode: RegionckMode, ) { @@ -1280,12 +1231,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { .into_infos_and_data() }; - let region_rels = &RegionRelations::new( - self.tcx, - region_context, - region_map, - outlives_env.free_region_map(), - ); + let region_rels = + &RegionRelations::new(self.tcx, region_context, outlives_env.free_region_map()); let (lexical_region_resolutions, errors) = lexical_region_resolve::resolve(region_rels, var_infos, data, mode); @@ -1299,7 +1246,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // this infcx was in use. This is totally hokey but // otherwise we have a hard time separating legit region // errors from silly ones. - self.report_region_errors(region_map, &errors); + self.report_region_errors(&errors); } } @@ -1809,29 +1756,14 @@ impl<'tcx> SubregionOrigin<'tcx> { pub fn span(&self) -> Span { match *self { Subtype(ref a) => a.span(), - InfStackClosure(a) => a, - InvokeClosure(a) => a, - DerefPointer(a) => a, - ClosureCapture(a, _) => a, - IndexSlice(a) => a, RelateObjectBound(a) => a, RelateParamBound(a, _) => a, RelateRegionParamBound(a) => a, - RelateDefaultParamBound(a, _) => a, Reborrow(a) => a, ReborrowUpvar(a, _) => a, DataBorrowed(_, a) => a, ReferenceOutlivesReferent(_, a) => a, - ParameterInScope(_, a) => a, - ExprTypeIsNotInScope(_, a) => a, - BindingTypeIsNotValidAtDecl(a) => a, - CallRcvr(a) => a, - CallArg(a) => a, CallReturn(a) => a, - Operand(a) => a, - AddrOf(a) => a, - AutoBorrow(a) => a, - SafeDestructor(a) => a, CompareImplMethodObligation { span, .. } => span, } } diff --git a/src/librustc_infer/infer/region_constraints/mod.rs b/src/librustc_infer/infer/region_constraints/mod.rs index 3983e55717947..f45b224275574 100644 --- a/src/librustc_infer/infer/region_constraints/mod.rs +++ b/src/librustc_infer/infer/region_constraints/mod.rs @@ -758,11 +758,9 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> { pub fn universe(&self, region: Region<'tcx>) -> ty::UniverseIndex { match *region { - ty::ReScope(..) - | ty::ReStatic - | ty::ReErased - | ty::ReFree(..) - | ty::ReEarlyBound(..) => ty::UniverseIndex::ROOT, + ty::ReStatic | ty::ReErased | ty::ReFree(..) | ty::ReEarlyBound(..) => { + ty::UniverseIndex::ROOT + } ty::ReEmpty(ui) => ui, ty::RePlaceholder(placeholder) => placeholder.universe, ty::ReVar(vid) => self.var_universe(vid), diff --git a/src/librustc_middle/ich/impls_ty.rs b/src/librustc_middle/ich/impls_ty.rs index 377c8661cbd41..ef6247881c0be 100644 --- a/src/librustc_middle/ich/impls_ty.rs +++ b/src/librustc_middle/ich/impls_ty.rs @@ -87,9 +87,6 @@ impl<'a> HashStable> for ty::RegionKind { index.hash_stable(hcx, hasher); name.hash_stable(hcx, hasher); } - ty::ReScope(scope) => { - scope.hash_stable(hcx, hasher); - } ty::ReFree(ref free_region) => { free_region.hash_stable(hcx, hasher); } diff --git a/src/librustc_middle/middle/region.rs b/src/librustc_middle/middle/region.rs index f02d8fe8ad601..943a065a8b5e8 100644 --- a/src/librustc_middle/middle/region.rs +++ b/src/librustc_middle/middle/region.rs @@ -7,7 +7,7 @@ //! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/borrow_check.html use crate::ich::{NodeIdHashingMode, StableHashingContext}; -use crate::ty::{self, DefIdTree, TyCtxt}; +use crate::ty::TyCtxt; use rustc_hir as hir; use rustc_hir::Node; @@ -333,7 +333,7 @@ pub struct YieldData { pub source: hir::YieldSource, } -impl<'tcx> ScopeTree { +impl ScopeTree { pub fn record_scope_parent(&mut self, child: Scope, parent: Option<(Scope, ScopeDepth)>) { debug!("{:?}.parent = {:?}", child, parent); @@ -348,24 +348,6 @@ impl<'tcx> ScopeTree { } } - pub fn each_encl_scope(&self, mut e: E) - where - E: FnMut(Scope, Scope), - { - for (&child, &parent) in &self.parent_map { - e(child, parent.0) - } - } - - pub fn each_var_scope(&self, mut e: E) - where - E: FnMut(&hir::ItemLocalId, Scope), - { - for (child, &parent) in self.var_map.iter() { - e(child, parent) - } - } - pub fn opt_destruction_scope(&self, n: hir::ItemLocalId) -> Option { self.destruction_scopes.get(&n).cloned() } @@ -406,12 +388,6 @@ impl<'tcx> ScopeTree { self.parent_map.get(&id).cloned().map(|(p, _)| p) } - /// Returns the narrowest scope that encloses `id`, if any. - #[allow(dead_code)] // used in cfg - pub fn encl_scope(&self, id: Scope) -> Scope { - self.opt_encl_scope(id).unwrap() - } - /// Returns the lifetime of the local variable `var_id` pub fn var_scope(&self, var_id: hir::ItemLocalId) -> Scope { self.var_map @@ -448,17 +424,6 @@ impl<'tcx> ScopeTree { None } - /// Returns the lifetime of the variable `id`. - pub fn var_region(&self, id: hir::ItemLocalId) -> ty::RegionKind { - let scope = ty::ReScope(self.var_scope(id)); - debug!("var_region({:?}) = {:?}", id, scope); - scope - } - - pub fn scopes_intersect(&self, scope1: Scope, scope2: Scope) -> bool { - self.is_subscope_of(scope1, scope2) || self.is_subscope_of(scope2, scope1) - } - /// Returns `true` if `subscope` is equal to or is lexically nested inside `superscope`, and /// `false` otherwise. pub fn is_subscope_of(&self, subscope: Scope, superscope: Scope) -> bool { @@ -479,127 +444,6 @@ impl<'tcx> ScopeTree { true } - /// Returns the ID of the innermost containing body. - pub fn containing_body(&self, mut scope: Scope) -> Option { - loop { - if let ScopeData::CallSite = scope.data { - return Some(scope.item_local_id()); - } - - scope = self.opt_encl_scope(scope)?; - } - } - - /// Finds the nearest common ancestor of two scopes. That is, finds the - /// smallest scope which is greater than or equal to both `scope_a` and - /// `scope_b`. - pub fn nearest_common_ancestor(&self, scope_a: Scope, scope_b: Scope) -> Scope { - if scope_a == scope_b { - return scope_a; - } - - let mut a = scope_a; - let mut b = scope_b; - - // Get the depth of each scope's parent. If either scope has no parent, - // it must be the root, which means we can stop immediately because the - // root must be the nearest common ancestor. (In practice, this is - // moderately common.) - let (parent_a, parent_a_depth) = match self.parent_map.get(&a) { - Some(pd) => *pd, - None => return a, - }; - let (parent_b, parent_b_depth) = match self.parent_map.get(&b) { - Some(pd) => *pd, - None => return b, - }; - - if parent_a_depth > parent_b_depth { - // `a` is lower than `b`. Move `a` up until it's at the same depth - // as `b`. The first move up is trivial because we already found - // `parent_a` above; the loop does the remaining N-1 moves. - a = parent_a; - for _ in 0..(parent_a_depth - parent_b_depth - 1) { - a = self.parent_map.get(&a).unwrap().0; - } - } else if parent_b_depth > parent_a_depth { - // `b` is lower than `a`. - b = parent_b; - for _ in 0..(parent_b_depth - parent_a_depth - 1) { - b = self.parent_map.get(&b).unwrap().0; - } - } else { - // Both scopes are at the same depth, and we know they're not equal - // because that case was tested for at the top of this function. So - // we can trivially move them both up one level now. - assert!(parent_a_depth != 0); - a = parent_a; - b = parent_b; - } - - // Now both scopes are at the same level. We move upwards in lockstep - // until they match. In practice, this loop is almost always executed - // zero times because `a` is almost always a direct ancestor of `b` or - // vice versa. - while a != b { - a = self.parent_map.get(&a).unwrap().0; - b = self.parent_map.get(&b).unwrap().0; - } - - a - } - - /// Assuming that the provided region was defined within this `ScopeTree`, - /// returns the outermost `Scope` that the region outlives. - pub fn early_free_scope(&self, tcx: TyCtxt<'tcx>, br: &ty::EarlyBoundRegion) -> Scope { - let param_owner = tcx.parent(br.def_id).unwrap(); - - let param_owner_id = tcx.hir().as_local_hir_id(param_owner.expect_local()); - let scope = tcx - .hir() - .maybe_body_owned_by(param_owner_id) - .map(|body_id| tcx.hir().body(body_id).value.hir_id.local_id) - .unwrap_or_else(|| { - // The lifetime was defined on node that doesn't own a body, - // which in practice can only mean a trait or an impl, that - // is the parent of a method, and that is enforced below. - if Some(param_owner_id) != self.root_parent { - tcx.sess.delay_span_bug( - DUMMY_SP, - &format!( - "free_scope: {:?} not recognized by the \ - region scope tree for {:?} / {:?}", - param_owner, - self.root_parent.map(|id| tcx.hir().local_def_id(id)), - self.root_body.map(|hir_id| hir_id.owner) - ), - ); - } - - // The trait/impl lifetime is in scope for the method's body. - self.root_body.unwrap().local_id - }); - - Scope { id: scope, data: ScopeData::CallSite } - } - - /// Assuming that the provided region was defined within this `ScopeTree`, - /// returns the outermost `Scope` that the region outlives. - pub fn free_scope(&self, tcx: TyCtxt<'tcx>, fr: &ty::FreeRegion) -> Scope { - let param_owner = match fr.bound_region { - ty::BoundRegion::BrNamed(def_id, _) => tcx.parent(def_id).unwrap(), - _ => fr.scope, - }; - - // Ensure that the named late-bound lifetimes were defined - // on the same function that they ended up being freed in. - assert_eq!(param_owner, fr.scope); - - let param_owner_id = tcx.hir().as_local_hir_id(param_owner.expect_local()); - let body_id = tcx.hir().body_owned_by(param_owner_id); - Scope { id: tcx.hir().body(body_id).value.hir_id.local_id, data: ScopeData::CallSite } - } - /// Checks whether the given scope contains a `yield`. If so, /// returns `Some((span, expr_count))` with the span of a yield we found and /// the number of expressions and patterns appearing before the `yield` in the body + 1. diff --git a/src/librustc_middle/ty/print/pretty.rs b/src/librustc_middle/ty/print/pretty.rs index f4b795e548867..f03d91aa64b78 100644 --- a/src/librustc_middle/ty/print/pretty.rs +++ b/src/librustc_middle/ty/print/pretty.rs @@ -1,5 +1,4 @@ use crate::middle::cstore::{ExternCrate, ExternCrateSource}; -use crate::middle::region; use crate::mir::interpret::{sign_extend, truncate, AllocId, ConstValue, Pointer, Scalar}; use crate::ty::layout::IntegerExt; use crate::ty::subst::{GenericArg, GenericArgKind, Subst}; @@ -1588,9 +1587,9 @@ impl PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx, F> { false } - ty::ReScope(_) | ty::ReVar(_) if identify_regions => true, + ty::ReVar(_) if identify_regions => true, - ty::ReVar(_) | ty::ReScope(_) | ty::ReErased => false, + ty::ReVar(_) | ty::ReErased => false, ty::ReStatic | ty::ReEmpty(_) => true, } @@ -1666,32 +1665,12 @@ impl FmtPrinter<'_, '_, F> { } } } - ty::ReScope(scope) if identify_regions => { - match scope.data { - region::ScopeData::Node => p!(write("'{}s", scope.item_local_id().as_usize())), - region::ScopeData::CallSite => { - p!(write("'{}cs", scope.item_local_id().as_usize())) - } - region::ScopeData::Arguments => { - p!(write("'{}as", scope.item_local_id().as_usize())) - } - region::ScopeData::Destruction => { - p!(write("'{}ds", scope.item_local_id().as_usize())) - } - region::ScopeData::Remainder(first_statement_index) => p!(write( - "'{}_{}rs", - scope.item_local_id().as_usize(), - first_statement_index.index() - )), - } - return Ok(self); - } ty::ReVar(region_vid) if identify_regions => { p!(write("{:?}", region_vid)); return Ok(self); } ty::ReVar(_) => {} - ty::ReScope(_) | ty::ReErased => {} + ty::ReErased => {} ty::ReStatic => { p!(write("'static")); return Ok(self); diff --git a/src/librustc_middle/ty/structural_impls.rs b/src/librustc_middle/ty/structural_impls.rs index babe0c54801e8..569a8d90bfcc3 100644 --- a/src/librustc_middle/ty/structural_impls.rs +++ b/src/librustc_middle/ty/structural_impls.rs @@ -87,8 +87,6 @@ impl fmt::Debug for ty::RegionKind { ty::ReFree(ref fr) => fr.fmt(f), - ty::ReScope(id) => write!(f, "ReScope({:?})", id), - ty::ReStatic => write!(f, "ReStatic"), ty::ReVar(ref vid) => vid.fmt(f), diff --git a/src/librustc_middle/ty/sty.rs b/src/librustc_middle/ty/sty.rs index 0c9eef8093f33..370702f7f221d 100644 --- a/src/librustc_middle/ty/sty.rs +++ b/src/librustc_middle/ty/sty.rs @@ -6,7 +6,6 @@ use self::InferTy::*; use self::TyKind::*; use crate::infer::canonical::Canonical; -use crate::middle::region; use crate::mir::interpret::ConstValue; use crate::mir::interpret::{LitToConstInput, Scalar}; use crate::mir::Promoted; @@ -1179,17 +1178,15 @@ rustc_index::newtype_index! { pub type Region<'tcx> = &'tcx RegionKind; -/// Representation of (lexical) regions. Note that the NLL checker -/// uses a distinct representation of regions. For this reason, it -/// internally replaces all the regions with inference variables -- -/// the index of the variable is then used to index into internal NLL -/// data structures. See `rustc_mir::borrow_check` module for more -/// information. +/// Representation of regions. Note that the NLL checker uses a distinct +/// representation of regions. For this reason, it internally replaces all the +/// regions with inference variables -- the index of the variable is then used +/// to index into internal NLL data structures. See `rustc_mir::borrow_check` +/// module for more information. /// /// ## The Region lattice within a given function /// -/// In general, the (lexical, and hence deprecated) region lattice -/// looks like +/// In general, the region lattice looks like /// /// ``` /// static ----------+-----...------+ (greatest) @@ -1197,7 +1194,6 @@ pub type Region<'tcx> = &'tcx RegionKind; /// early-bound and | | /// free regions | | /// | | | -/// scope regions | | /// | | | /// empty(root) placeholder(U1) | /// | / | @@ -1212,13 +1208,7 @@ pub type Region<'tcx> = &'tcx RegionKind; /// Early-bound/free regions are the named lifetimes in scope from the /// function declaration. They have relationships to one another /// determined based on the declared relationships from the -/// function. They all collectively outlive the scope regions. (See -/// `RegionRelations` type, and particularly -/// `crate::infer::outlives::free_region_map::FreeRegionMap`.) -/// -/// The scope regions are related to one another based on the AST -/// structure. (See `RegionRelations` type, and particularly the -/// `rustc_middle::middle::region::ScopeTree`.) +/// function. /// /// Note that inference variables and bound regions are not included /// in this diagram. In the case of inference variables, they should @@ -1307,11 +1297,6 @@ pub enum RegionKind { /// region parameters. ReFree(FreeRegion), - /// A concrete region naming some statically determined scope - /// (e.g., an expression or sequence of statements) within the - /// current function. - ReScope(region::Scope), - /// Static data that has an "infinite" lifetime. Top in the region lattice. ReStatic, @@ -1535,7 +1520,6 @@ impl RegionKind { RegionKind::ReEarlyBound(ebr) => ebr.has_name(), RegionKind::ReLateBound(_, br) => br.is_named(), RegionKind::ReFree(fr) => fr.bound_region.is_named(), - RegionKind::ReScope(..) => false, RegionKind::ReStatic => true, RegionKind::ReVar(..) => false, RegionKind::RePlaceholder(placeholder) => placeholder.name.is_named(), @@ -1616,7 +1600,7 @@ impl RegionKind { flags = flags | TypeFlags::HAS_RE_PARAM; flags = flags | TypeFlags::STILL_FURTHER_SPECIALIZABLE; } - ty::ReFree { .. } | ty::ReScope { .. } => { + ty::ReFree { .. } => { flags = flags | TypeFlags::HAS_FREE_REGIONS; flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS; } diff --git a/src/librustc_mir/borrow_check/diagnostics/region_errors.rs b/src/librustc_mir/borrow_check/diagnostics/region_errors.rs index ebc8021a3c577..e19fab89eabfe 100644 --- a/src/librustc_mir/borrow_check/diagnostics/region_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/region_errors.rs @@ -162,10 +162,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { let type_test_span = type_test.locations.span(&self.body); if let Some(lower_bound_region) = lower_bound_region { - let region_scope_tree = &self.infcx.tcx.region_scope_tree(self.mir_def_id); self.infcx .construct_generic_bound_failure( - region_scope_tree, type_test_span, None, type_test.generic_kind, @@ -194,12 +192,10 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { } RegionErrorKind::UnexpectedHiddenRegion { span, hidden_ty, member_region } => { - let region_scope_tree = &self.infcx.tcx.region_scope_tree(self.mir_def_id); let named_ty = self.regioncx.name_regions(self.infcx.tcx, hidden_ty); let named_region = self.regioncx.name_regions(self.infcx.tcx, member_region); unexpected_hidden_region_diagnostic( self.infcx.tcx, - Some(region_scope_tree), span, named_ty, named_region, diff --git a/src/librustc_mir/borrow_check/diagnostics/region_name.rs b/src/librustc_mir/borrow_check/diagnostics/region_name.rs index 37e2e0475048d..e912ef7b20202 100644 --- a/src/librustc_mir/borrow_check/diagnostics/region_name.rs +++ b/src/librustc_mir/borrow_check/diagnostics/region_name.rs @@ -284,7 +284,6 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { }, ty::ReLateBound(..) - | ty::ReScope(..) | ty::ReVar(..) | ty::RePlaceholder(..) | ty::ReEmpty(_) diff --git a/src/librustc_trait_selection/opaque_types.rs b/src/librustc_trait_selection/opaque_types.rs index 2544e4ddea2ec..484677ded249f 100644 --- a/src/librustc_trait_selection/opaque_types.rs +++ b/src/librustc_trait_selection/opaque_types.rs @@ -670,7 +670,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { // `least_region`. We cannot use `push_outlives_components` because regions in // closure signatures are not included in their outlives components. We need to // ensure all regions outlive the given bound so that we don't end up with, -// say, `ReScope` appearing in a return type and causing ICEs when other +// say, `ReVar` appearing in a return type and causing ICEs when other // functions end up with region constraints involving regions from other // functions. // @@ -816,7 +816,7 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> { // The regions that we expect from borrow checking. ty::ReEarlyBound(_) | ty::ReFree(_) | ty::ReEmpty(ty::UniverseIndex::ROOT) => {} - ty::ReEmpty(_) | ty::RePlaceholder(_) | ty::ReVar(_) | ty::ReScope(_) => { + ty::ReEmpty(_) | ty::RePlaceholder(_) | ty::ReVar(_) => { // All of the regions in the type should either have been // erased by writeback, or mapped back to named regions by // borrow checking. @@ -835,7 +835,6 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> { if let Some(hidden_ty) = self.hidden_ty.take() { unexpected_hidden_region_diagnostic( self.tcx, - None, self.tcx.def_span(self.opaque_type_def_id), hidden_ty, r, diff --git a/src/librustc_trait_selection/traits/mod.rs b/src/librustc_trait_selection/traits/mod.rs index 3daa9109aafe8..d8e99dc10af2a 100644 --- a/src/librustc_trait_selection/traits/mod.rs +++ b/src/librustc_trait_selection/traits/mod.rs @@ -28,7 +28,6 @@ use crate::traits::query::evaluate_obligation::InferCtxtExt as _; use rustc_errors::ErrorReported; use rustc_hir as hir; use rustc_hir::def_id::DefId; -use rustc_middle::middle::region; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::subst::{InternalSubsts, SubstsRef}; use rustc_middle::ty::{ @@ -237,15 +236,12 @@ fn do_normalize_predicates<'tcx>( debug!("do_normalize_predictes: normalized predicates = {:?}", predicates); - let region_scope_tree = region::ScopeTree::default(); - // We can use the `elaborated_env` here; the region code only // cares about declarations like `'a: 'b`. let outlives_env = OutlivesEnvironment::new(elaborated_env); infcx.resolve_regions_and_report_errors( region_context, - ®ion_scope_tree, &outlives_env, RegionckMode::default(), ); diff --git a/src/librustc_traits/chalk/lowering.rs b/src/librustc_traits/chalk/lowering.rs index 7d48b45753810..a33ada2fb6ef1 100644 --- a/src/librustc_traits/chalk/lowering.rs +++ b/src/librustc_traits/chalk/lowering.rs @@ -394,7 +394,6 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Lifetime>> for Region<'t ty::BrEnv => unimplemented!(), }, ReFree(_) => unimplemented!(), - ReScope(_) => unimplemented!(), ReStatic => unimplemented!(), ReVar(_) => unimplemented!(), RePlaceholder(placeholder_region) => { diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index f393121a0adb8..8fa901d8a984a 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/src/librustc_typeck/check/closure.rs @@ -3,7 +3,6 @@ use super::{check_fn, Expectation, FnCtxt, GeneratorTypes}; use crate::astconv::AstConv; -use crate::middle::region; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_hir::lang_items::{FutureTraitLangItem, GeneratorTraitLangItem}; @@ -12,12 +11,11 @@ use rustc_infer::infer::LateBoundRegionConversionTime; use rustc_infer::infer::{InferOk, InferResult}; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::subst::InternalSubsts; -use rustc_middle::ty::{self, GenericParamDefKind, ToPredicate, Ty}; +use rustc_middle::ty::{self, GenericParamDefKind, Ty}; use rustc_span::source_map::Span; use rustc_target::spec::abi::Abi; use rustc_trait_selection::traits::error_reporting::ArgKind; use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _; -use rustc_trait_selection::traits::Obligation; use std::cmp; use std::iter; @@ -518,22 +516,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let InferOk { value: (), obligations } = self.at(&cause, self.param_env).eq(*expected_ty, supplied_ty)?; all_obligations.extend(obligations); - - // Also, require that the supplied type must outlive - // the closure body. - let closure_body_region = self.tcx.mk_region(ty::ReScope(region::Scope { - id: body.value.hir_id.local_id, - data: region::ScopeData::Node, - })); - all_obligations.push(Obligation::new( - cause, - self.param_env, - ty::PredicateKind::TypeOutlives(ty::Binder::dummy(ty::OutlivesPredicate( - supplied_ty, - closure_body_region, - ))) - .to_predicate(self.tcx), - )); } let (supplied_output_ty, _) = self.infcx.replace_bound_vars_with_fresh_vars( diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs index 594cdab852fda..24c319f26e71f 100644 --- a/src/librustc_typeck/check/dropck.rs +++ b/src/librustc_typeck/check/dropck.rs @@ -5,7 +5,6 @@ use rustc_errors::{struct_span_err, ErrorReported}; use rustc_infer::infer::outlives::env::OutlivesEnvironment; use rustc_infer::infer::{InferOk, RegionckMode, TyCtxtInferExt}; use rustc_infer::traits::TraitEngineExt as _; -use rustc_middle::middle::region; use rustc_middle::ty::error::TypeError; use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation}; use rustc_middle::ty::subst::{Subst, SubstsRef}; @@ -120,8 +119,6 @@ fn ensure_drop_params_and_item_params_correspond<'tcx>( return Err(ErrorReported); } - let region_scope_tree = region::ScopeTree::default(); - // NB. It seems a bit... suspicious to use an empty param-env // here. The correct thing, I imagine, would be // `OutlivesEnvironment::new(impl_param_env)`, which would @@ -134,7 +131,6 @@ fn ensure_drop_params_and_item_params_correspond<'tcx>( infcx.resolve_regions_and_report_errors( drop_impl_did.to_def_id(), - ®ion_scope_tree, &outlives_env, RegionckMode::default(), ); diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index c452859414cfb..6b7adb728e7e6 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -106,13 +106,13 @@ use rustc_hir::lang_items::{ use rustc_hir::{ExprKind, GenericArg, HirIdMap, Item, ItemKind, Node, PatKind, QPath}; use rustc_index::bit_set::BitSet; use rustc_index::vec::Idx; +use rustc_infer::infer; use rustc_infer::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse}; use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_infer::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind}; -use rustc_infer::infer::{self, InferCtxt, InferOk, InferResult, TyCtxtInferExt}; +use rustc_infer::infer::{InferCtxt, InferOk, InferResult, RegionVariableOrigin, TyCtxtInferExt}; use rustc_middle::hir::map::blocks::FnLikeNode; -use rustc_middle::middle::region; use rustc_middle::mir::interpret::ConstValue; use rustc_middle::ty::adjustment::{ Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, PointerCast, @@ -667,13 +667,6 @@ impl Inherited<'a, 'tcx> { let tcx = infcx.tcx; let item_id = tcx.hir().local_def_id_to_hir_id(def_id); let body_id = tcx.hir().maybe_body_owned_by(item_id); - let implicit_region_bound = body_id.map(|body_id| { - let body = tcx.hir().body(body_id); - tcx.mk_region(ty::ReScope(region::Scope { - id: body.value.hir_id.local_id, - data: region::ScopeData::CallSite, - })) - }); Inherited { tables: MaybeInProgressTables { maybe_tables: infcx.in_progress_tables }, @@ -686,7 +679,7 @@ impl Inherited<'a, 'tcx> { deferred_generator_interiors: RefCell::new(Vec::new()), opaque_types: RefCell::new(Default::default()), opaque_types_vars: RefCell::new(Default::default()), - implicit_region_bound, + implicit_region_bound: None, body_id, } } @@ -1337,12 +1330,9 @@ fn check_fn<'a, 'tcx>( // C-variadic fns also have a `VaList` input that's not listed in `fn_sig` // (as it's created inside the body itself, not passed in from outside). let maybe_va_list = if fn_sig.c_variadic { - let va_list_did = - tcx.require_lang_item(VaListTypeLangItem, Some(body.params.last().unwrap().span)); - let region = tcx.mk_region(ty::ReScope(region::Scope { - id: body.value.hir_id.local_id, - data: region::ScopeData::CallSite, - })); + let span = body.params.last().unwrap().span; + let va_list_did = tcx.require_lang_item(VaListTypeLangItem, Some(span)); + let region = fcx.next_region_var(RegionVariableOrigin::MiscVariable(span)); Some(tcx.type_of(va_list_did).subst(tcx, &[region.into()])) } else { diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index 049f4767247c5..90ba15aa08988 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -83,12 +83,10 @@ use rustc_hir::PatKind; use rustc_infer::infer::outlives::env::OutlivesEnvironment; use rustc_infer::infer::{self, RegionObligation, RegionckMode}; use rustc_middle::ty::adjustment; -use rustc_middle::ty::subst::{GenericArgKind, SubstsRef}; use rustc_middle::ty::{self, Ty}; use rustc_span::Span; use rustc_trait_selection::infer::OutlivesEnvironmentExt; use rustc_trait_selection::opaque_types::InferCtxtExt; -use std::mem; use std::ops::Deref; // a variation on try that just returns unit @@ -111,8 +109,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub fn regionck_expr(&self, body: &'tcx hir::Body<'tcx>) { let subject = self.tcx.hir().body_owner_def_id(body.id()); let id = body.value.hir_id; - let mut rcx = - RegionCtxt::new(self, RepeatingScope(id), id, Subject(subject), self.param_env); + let mut rcx = RegionCtxt::new(self, id, Subject(subject), self.param_env); // There are no add'l implied bounds when checking a // standalone expr (e.g., the `E` in a type like `[u32; E]`). @@ -131,13 +128,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub fn regionck_item(&self, item_id: hir::HirId, span: Span, wf_tys: &[Ty<'tcx>]) { debug!("regionck_item(item.id={:?}, wf_tys={:?})", item_id, wf_tys); let subject = self.tcx.hir().local_def_id(item_id); - let mut rcx = RegionCtxt::new( - self, - RepeatingScope(item_id), - item_id, - Subject(subject), - self.param_env, - ); + let mut rcx = RegionCtxt::new(self, item_id, Subject(subject), self.param_env); rcx.outlives_environment.add_implied_bounds(self, wf_tys, item_id, span); rcx.outlives_environment.save_implied_bounds(item_id); rcx.visit_region_obligations(item_id); @@ -156,8 +147,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { debug!("regionck_fn(id={})", fn_id); let subject = self.tcx.hir().body_owner_def_id(body.id()); let hir_id = body.value.hir_id; - let mut rcx = - RegionCtxt::new(self, RepeatingScope(hir_id), hir_id, Subject(subject), self.param_env); + let mut rcx = RegionCtxt::new(self, hir_id, Subject(subject), self.param_env); if !self.errors_reported_since_creation() { // regionck assumes typeck succeeded @@ -182,12 +172,6 @@ pub struct RegionCtxt<'a, 'tcx> { body_id: hir::HirId, body_owner: LocalDefId, - // call_site scope of innermost fn - call_site_scope: Option, - - // id of innermost fn or loop - repeating_scope: hir::HirId, - // id of AST node being analyzed (the subject of the analysis). subject_def_id: LocalDefId, } @@ -199,13 +183,11 @@ impl<'a, 'tcx> Deref for RegionCtxt<'a, 'tcx> { } } -pub struct RepeatingScope(hir::HirId); pub struct Subject(LocalDefId); impl<'a, 'tcx> RegionCtxt<'a, 'tcx> { pub fn new( fcx: &'a FnCtxt<'a, 'tcx>, - RepeatingScope(initial_repeating_scope): RepeatingScope, initial_body_id: hir::HirId, Subject(subject): Subject, param_env: ty::ParamEnv<'tcx>, @@ -215,19 +197,13 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> { RegionCtxt { fcx, region_scope_tree, - repeating_scope: initial_repeating_scope, body_id: initial_body_id, body_owner: subject, - call_site_scope: None, subject_def_id: subject, outlives_environment, } } - fn set_repeating_scope(&mut self, scope: hir::HirId) -> hir::HirId { - mem::replace(&mut self.repeating_scope, scope) - } - /// Try to resolve the type for the given node, returning `t_err` if an error results. Note that /// we never care about the details of the error, the same error will be detected and reported /// in the writeback phase. @@ -261,16 +237,10 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> { self.resolve_type(t) } - /// Try to resolve the type for the given node. - pub fn resolve_expr_type_adjusted(&mut self, expr: &hir::Expr<'_>) -> Ty<'tcx> { - let ty = self.tables.borrow().expr_ty_adjusted(expr); - self.resolve_type(ty) - } - - /// This is the "main" function when region-checking a function item or a closure - /// within a function item. It begins by updating various fields (e.g., `call_site_scope` - /// and `outlives_environment`) to be appropriate to the function and then adds constraints - /// derived from the function body. + /// This is the "main" function when region-checking a function item or a + /// closure within a function item. It begins by updating various fields + /// (e.g., `outlives_environment`) to be appropriate to the function and + /// then adds constraints derived from the function body. /// /// Note that it does **not** restore the state of the fields that /// it updates! This is intentional, since -- for the main @@ -292,10 +262,6 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> { self.body_id = body_id.hir_id; self.body_owner = self.tcx.hir().body_owner_def_id(body_id); - let call_site = - region::Scope { id: body.value.hir_id.local_id, data: region::ScopeData::CallSite }; - self.call_site_scope = Some(call_site); - let fn_sig = { match self.tables.borrow().liberated_fn_sigs().get(id) { Some(f) => *f, @@ -324,12 +290,6 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> { self.visit_body(body); self.visit_region_obligations(body_id.hir_id); - let call_site_scope = self.call_site_scope.unwrap(); - debug!("visit_fn_body body.id {:?} call_site_scope: {:?}", body.id(), call_site_scope); - let call_site_region = self.tcx.mk_region(ty::ReScope(call_site_scope)); - - self.type_of_node_must_outlive(infer::CallReturn(span), body_id.hir_id, call_site_region); - self.constrain_opaque_types( &self.fcx.opaque_types.borrow(), self.outlives_environment.free_region_map(), @@ -354,7 +314,6 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> { self.fcx.resolve_regions_and_report_errors( self.subject_def_id.to_def_id(), - &self.region_scope_tree, &self.outlives_environment, mode, ); @@ -363,34 +322,6 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> { fn constrain_bindings_in_pat(&mut self, pat: &hir::Pat<'_>) { debug!("regionck::visit_pat(pat={:?})", pat); pat.each_binding(|_, hir_id, span, _| { - // If we have a variable that contains region'd data, that - // data will be accessible from anywhere that the variable is - // accessed. We must be wary of loops like this: - // - // // from src/test/compile-fail/borrowck-lend-flow.rs - // let mut v = box 3, w = box 4; - // let mut x = &mut w; - // loop { - // **x += 1; // (2) - // borrow(v); //~ ERROR cannot borrow - // x = &mut v; // (1) - // } - // - // Typically, we try to determine the region of a borrow from - // those points where it is dereferenced. In this case, one - // might imagine that the lifetime of `x` need only be the - // body of the loop. But of course this is incorrect because - // the pointer that is created at point (1) is consumed at - // point (2), meaning that it must be live across the loop - // iteration. The easiest way to guarantee this is to require - // that the lifetime of any regions that appear in a - // variable's type enclose at least the variable's scope. - let var_scope = self.region_scope_tree.var_scope(hir_id.local_id); - let var_region = self.tcx.mk_region(ty::ReScope(var_scope)); - - let origin = infer::BindingTypeIsNotValidAtDecl(span); - self.type_of_node_must_outlive(origin, hir_id, var_region); - let typ = self.resolve_node_type(hir_id); let body_id = self.body_id; let _ = dropck::check_drop_obligations(self, typ, span, body_id); @@ -433,7 +364,6 @@ impl<'a, 'tcx> Visitor<'tcx> for RegionCtxt<'a, 'tcx> { // `visit_fn_body`. We will restore afterwards. let old_body_id = self.body_id; let old_body_owner = self.body_owner; - let old_call_site_scope = self.call_site_scope; let env_snapshot = self.outlives_environment.push_snapshot_pre_closure(); let body = self.tcx.hir().body(body_id); @@ -441,7 +371,6 @@ impl<'a, 'tcx> Visitor<'tcx> for RegionCtxt<'a, 'tcx> { // Restore state from previous function. self.outlives_environment.pop_snapshot_post_closure(env_snapshot); - self.call_site_scope = old_call_site_scope; self.body_id = old_body_id; self.body_owner = old_body_owner; } @@ -462,42 +391,6 @@ impl<'a, 'tcx> Visitor<'tcx> for RegionCtxt<'a, 'tcx> { } fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) { - debug!("regionck::visit_expr(e={:?}, repeating_scope={:?})", expr, self.repeating_scope); - - // No matter what, the type of each expression must outlive the - // scope of that expression. This also guarantees basic WF. - let expr_ty = self.resolve_node_type(expr.hir_id); - // the region corresponding to this expression - let expr_region = self.tcx.mk_region(ty::ReScope(region::Scope { - id: expr.hir_id.local_id, - data: region::ScopeData::Node, - })); - self.type_must_outlive( - infer::ExprTypeIsNotInScope(expr_ty, expr.span), - expr_ty, - expr_region, - ); - - let is_method_call = self.tables.borrow().is_method_call(expr); - - // If we are calling a method (either explicitly or via an - // overloaded operator), check that all of the types provided as - // arguments for its type parameters are well-formed, and all the regions - // provided as arguments outlive the call. - if is_method_call { - let origin = match expr.kind { - hir::ExprKind::MethodCall(..) => infer::ParameterOrigin::MethodCall, - hir::ExprKind::Unary(op, _) if op == hir::UnOp::UnDeref => { - infer::ParameterOrigin::OverloadedDeref - } - _ => infer::ParameterOrigin::OverloadedOperator, - }; - - let substs = self.tables.borrow().node_substs(expr.hir_id); - self.substs_wf_in_scope(origin, substs, expr.span, expr_region); - // Arguments (sub-expressions) are checked via `constrain_call`, below. - } - // Check any autoderefs or autorefs that appear. let cmt_result = self.constrain_adjustments(expr); @@ -512,117 +405,10 @@ impl<'a, 'tcx> Visitor<'tcx> for RegionCtxt<'a, 'tcx> { } } - debug!( - "regionck::visit_expr(e={:?}, repeating_scope={:?}) - visiting subexprs", - expr, self.repeating_scope - ); match expr.kind { - hir::ExprKind::Path(_) => { - let substs = self.tables.borrow().node_substs(expr.hir_id); - let origin = infer::ParameterOrigin::Path; - self.substs_wf_in_scope(origin, substs, expr.span, expr_region); - } - - hir::ExprKind::Call(ref callee, ref args) => { - if is_method_call { - self.constrain_call(expr, Some(&callee), args.iter().map(|e| &*e)); - } else { - self.constrain_callee(&callee); - self.constrain_call(expr, None, args.iter().map(|e| &*e)); - } - - intravisit::walk_expr(self, expr); - } - - hir::ExprKind::MethodCall(.., ref args) => { - self.constrain_call(expr, Some(&args[0]), args[1..].iter().map(|e| &*e)); - - intravisit::walk_expr(self, expr); - } - - hir::ExprKind::AssignOp(_, ref lhs, ref rhs) => { - if is_method_call { - self.constrain_call(expr, Some(&lhs), Some(&**rhs).into_iter()); - } - - intravisit::walk_expr(self, expr); - } - - hir::ExprKind::Index(ref lhs, ref rhs) if is_method_call => { - self.constrain_call(expr, Some(&lhs), Some(&**rhs).into_iter()); - - intravisit::walk_expr(self, expr); - } - - hir::ExprKind::Binary(_, ref lhs, ref rhs) if is_method_call => { - // As `ExprKind::MethodCall`, but the call is via an overloaded op. - self.constrain_call(expr, Some(&lhs), Some(&**rhs).into_iter()); - - intravisit::walk_expr(self, expr); - } - - hir::ExprKind::Binary(_, ref lhs, ref rhs) => { - // If you do `x OP y`, then the types of `x` and `y` must - // outlive the operation you are performing. - let lhs_ty = self.resolve_expr_type_adjusted(&lhs); - let rhs_ty = self.resolve_expr_type_adjusted(&rhs); - for &ty in &[lhs_ty, rhs_ty] { - self.type_must_outlive(infer::Operand(expr.span), ty, expr_region); - } - intravisit::walk_expr(self, expr); - } - - hir::ExprKind::Unary(hir::UnOp::UnDeref, ref base) => { - // For *a, the lifetime of a must enclose the deref - if is_method_call { - self.constrain_call(expr, Some(base), None::>.iter()); - } - // For overloaded derefs, base_ty is the input to `Deref::deref`, - // but it's a reference type uing the same region as the output. - let base_ty = self.resolve_expr_type_adjusted(base); - if let ty::Ref(r_ptr, _, _) = base_ty.kind { - self.mk_subregion_due_to_dereference(expr.span, expr_region, r_ptr); - } - - intravisit::walk_expr(self, expr); - } - - hir::ExprKind::Unary(_, ref lhs) if is_method_call => { - // As above. - self.constrain_call(expr, Some(&lhs), None::>.iter()); - - intravisit::walk_expr(self, expr); - } - - hir::ExprKind::Index(ref vec_expr, _) => { - // For a[b], the lifetime of a must enclose the deref - let vec_type = self.resolve_expr_type_adjusted(&vec_expr); - self.constrain_index(expr, vec_type); - - intravisit::walk_expr(self, expr); - } - - hir::ExprKind::Cast(ref source, _) => { - // Determine if we are casting `source` to a trait - // instance. If so, we have to be sure that the type of - // the source obeys the trait's region bound. - self.constrain_cast(expr, &source); - intravisit::walk_expr(self, expr); - } - hir::ExprKind::AddrOf(hir::BorrowKind::Ref, m, ref base) => { self.link_addr_of(expr, m, &base); - // Require that when you write a `&expr` expression, the - // resulting pointer has a lifetime that encompasses the - // `&expr` expression itself. Note that we constraining - // the type of the node expr.id here *before applying - // adjustments*. - // - // FIXME(https://github.com/rust-lang/rfcs/issues/811) - // nested method calls requires that this rule change - let ty0 = self.resolve_node_type(expr.hir_id); - self.type_must_outlive(infer::AddrOf(expr.span), ty0, expr_region); intravisit::walk_expr(self, expr); } @@ -632,140 +418,12 @@ impl<'a, 'tcx> Visitor<'tcx> for RegionCtxt<'a, 'tcx> { intravisit::walk_expr(self, expr); } - hir::ExprKind::Closure(.., body_id, _, _) => { - self.check_expr_fn_block(expr, body_id); - } - - hir::ExprKind::Loop(ref body, _, _) => { - let repeating_scope = self.set_repeating_scope(body.hir_id); - intravisit::walk_expr(self, expr); - self.set_repeating_scope(repeating_scope); - } - - hir::ExprKind::Ret(Some(ref ret_expr)) => { - let call_site_scope = self.call_site_scope; - debug!( - "visit_expr ExprKind::Ret ret_expr.hir_id {} call_site_scope: {:?}", - ret_expr.hir_id, call_site_scope - ); - let call_site_region = self.tcx.mk_region(ty::ReScope(call_site_scope.unwrap())); - self.type_of_node_must_outlive( - infer::CallReturn(ret_expr.span), - ret_expr.hir_id, - call_site_region, - ); - intravisit::walk_expr(self, expr); - } - - _ => { - intravisit::walk_expr(self, expr); - } + _ => intravisit::walk_expr(self, expr), } } } impl<'a, 'tcx> RegionCtxt<'a, 'tcx> { - fn constrain_cast(&mut self, cast_expr: &hir::Expr<'_>, source_expr: &hir::Expr<'_>) { - debug!("constrain_cast(cast_expr={:?}, source_expr={:?})", cast_expr, source_expr); - - let source_ty = self.resolve_node_type(source_expr.hir_id); - let target_ty = self.resolve_node_type(cast_expr.hir_id); - - self.walk_cast(cast_expr, source_ty, target_ty); - } - - fn walk_cast(&mut self, cast_expr: &hir::Expr<'_>, from_ty: Ty<'tcx>, to_ty: Ty<'tcx>) { - debug!("walk_cast(from_ty={:?}, to_ty={:?})", from_ty, to_ty); - match (&from_ty.kind, &to_ty.kind) { - /*From:*/ - (&ty::Ref(from_r, from_ty, _), /*To: */ &ty::Ref(to_r, to_ty, _)) => { - // Target cannot outlive source, naturally. - self.sub_regions(infer::Reborrow(cast_expr.span), to_r, from_r); - self.walk_cast(cast_expr, from_ty, to_ty); - } - - /*From:*/ - (_, /*To: */ &ty::Dynamic(.., r)) => { - // When T is existentially quantified as a trait - // `Foo+'to`, it must outlive the region bound `'to`. - self.type_must_outlive(infer::RelateObjectBound(cast_expr.span), from_ty, r); - } - - /*From:*/ - (&ty::Adt(from_def, _), /*To: */ &ty::Adt(to_def, _)) - if from_def.is_box() && to_def.is_box() => - { - self.walk_cast(cast_expr, from_ty.boxed_ty(), to_ty.boxed_ty()); - } - - _ => {} - } - } - - fn check_expr_fn_block(&mut self, expr: &'tcx hir::Expr<'tcx>, body_id: hir::BodyId) { - let repeating_scope = self.set_repeating_scope(body_id.hir_id); - intravisit::walk_expr(self, expr); - self.set_repeating_scope(repeating_scope); - } - - fn constrain_callee(&mut self, callee_expr: &hir::Expr<'_>) { - let callee_ty = self.resolve_node_type(callee_expr.hir_id); - match callee_ty.kind { - ty::FnDef(..) | ty::FnPtr(_) => {} - _ => { - // this should not happen, but it does if the program is - // erroneous - // - // bug!( - // callee_expr.span, - // "Calling non-function: {}", - // callee_ty); - } - } - } - - fn constrain_call<'b, I: Iterator>>( - &mut self, - call_expr: &hir::Expr<'_>, - receiver: Option<&hir::Expr<'_>>, - arg_exprs: I, - ) { - //! Invoked on every call site (i.e., normal calls, method calls, - //! and overloaded operators). Constrains the regions which appear - //! in the type of the function. Also constrains the regions that - //! appear in the arguments appropriately. - - debug!("constrain_call(call_expr={:?}, receiver={:?})", call_expr, receiver); - - // `callee_region` is the scope representing the time in which the - // call occurs. - // - // FIXME(#6268) to support nested method calls, should be callee_id - let callee_scope = - region::Scope { id: call_expr.hir_id.local_id, data: region::ScopeData::Node }; - let callee_region = self.tcx.mk_region(ty::ReScope(callee_scope)); - - debug!("callee_region={:?}", callee_region); - - for arg_expr in arg_exprs { - debug!("argument: {:?}", arg_expr); - - // ensure that any regions appearing in the argument type are - // valid for at least the lifetime of the function: - self.type_of_node_must_outlive( - infer::CallArg(arg_expr.span), - arg_expr.hir_id, - callee_region, - ); - } - - // as loop above, but for receiver - if let Some(r) = receiver { - debug!("receiver: {:?}", r); - self.type_of_node_must_outlive(infer::CallRcvr(r.span), r.hir_id, callee_region); - } - } - /// Creates a temporary `MemCategorizationContext` and pass it to the closure. fn with_mc(&self, f: F) -> R where @@ -784,79 +442,40 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> { fn constrain_adjustments(&mut self, expr: &hir::Expr<'_>) -> mc::McResult> { debug!("constrain_adjustments(expr={:?})", expr); - let mut cmt = self.with_mc(|mc| mc.cat_expr_unadjusted(expr))?; + let mut place = self.with_mc(|mc| mc.cat_expr_unadjusted(expr))?; let tables = self.tables.borrow(); let adjustments = tables.expr_adjustments(&expr); if adjustments.is_empty() { - return Ok(cmt); + return Ok(place); } debug!("constrain_adjustments: adjustments={:?}", adjustments); // If necessary, constrain destructors in the unadjusted form of this // expression. - self.check_safety_of_rvalue_destructor_if_necessary(&cmt, expr.span); + self.check_safety_of_rvalue_destructor_if_necessary(&place, expr.span); - let expr_region = self.tcx.mk_region(ty::ReScope(region::Scope { - id: expr.hir_id.local_id, - data: region::ScopeData::Node, - })); for adjustment in adjustments { - debug!("constrain_adjustments: adjustment={:?}, cmt={:?}", adjustment, cmt); + debug!("constrain_adjustments: adjustment={:?}, place={:?}", adjustment, place); if let adjustment::Adjust::Deref(Some(deref)) = adjustment.kind { - debug!("constrain_adjustments: overloaded deref: {:?}", deref); - - // Treat overloaded autoderefs as if an AutoBorrow adjustment - // was applied on the base type, as that is always the case. - let input = self - .tcx - .mk_ref(deref.region, ty::TypeAndMut { ty: cmt.ty, mutbl: deref.mutbl }); - let output = self.tcx.mk_ref( - deref.region, - ty::TypeAndMut { ty: adjustment.target, mutbl: deref.mutbl }, - ); - self.link_region( expr.span, deref.region, ty::BorrowKind::from_mutbl(deref.mutbl), - &cmt, + &place, ); - - // Specialized version of constrain_call. - self.type_must_outlive(infer::CallRcvr(expr.span), input, expr_region); - self.type_must_outlive(infer::CallReturn(expr.span), output, expr_region); } if let adjustment::Adjust::Borrow(ref autoref) = adjustment.kind { - self.link_autoref(expr, &cmt, autoref); - - // Require that the resulting region encompasses - // the current node. - // - // FIXME(#6268) remove to support nested method calls - self.type_of_node_must_outlive( - infer::AutoBorrow(expr.span), - expr.hir_id, - expr_region, - ); + self.link_autoref(expr, &place, autoref); } - cmt = self.with_mc(|mc| mc.cat_expr_adjusted(expr, cmt, &adjustment))?; + place = self.with_mc(|mc| mc.cat_expr_adjusted(expr, place, &adjustment))?; } - Ok(cmt) - } - - pub fn mk_subregion_due_to_dereference( - &mut self, - deref_span: Span, - minimum_lifetime: ty::Region<'tcx>, - maximum_lifetime: ty::Region<'tcx>, - ) { - self.sub_regions(infer::DerefPointer(deref_span), minimum_lifetime, maximum_lifetime) + Ok(place) } fn check_safety_of_rvalue_destructor_if_necessary( @@ -872,59 +491,6 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> { } } } - - /// Invoked on any index expression that occurs. Checks that if this is a slice - /// being indexed, the lifetime of the pointer includes the deref expr. - fn constrain_index(&mut self, index_expr: &hir::Expr<'_>, indexed_ty: Ty<'tcx>) { - debug!("constrain_index(index_expr=?, indexed_ty={}", self.ty_to_string(indexed_ty)); - - let r_index_expr = ty::ReScope(region::Scope { - id: index_expr.hir_id.local_id, - data: region::ScopeData::Node, - }); - if let ty::Ref(r_ptr, r_ty, _) = indexed_ty.kind { - match r_ty.kind { - ty::Slice(_) | ty::Str => { - self.sub_regions( - infer::IndexSlice(index_expr.span), - self.tcx.mk_region(r_index_expr), - r_ptr, - ); - } - _ => {} - } - } - } - - /// Guarantees that any lifetimes that appear in the type of the node `id` (after applying - /// adjustments) are valid for at least `minimum_lifetime`. - fn type_of_node_must_outlive( - &mut self, - origin: infer::SubregionOrigin<'tcx>, - hir_id: hir::HirId, - minimum_lifetime: ty::Region<'tcx>, - ) { - // Try to resolve the type. If we encounter an error, then typeck - // is going to fail anyway, so just stop here and let typeck - // report errors later on in the writeback phase. - let ty0 = self.resolve_node_type(hir_id); - - let ty = self - .tables - .borrow() - .adjustments() - .get(hir_id) - .and_then(|adj| adj.last()) - .map_or(ty0, |adj| adj.target); - let ty = self.resolve_type(ty); - debug!( - "constrain_regions_in_type_of_node(\ - ty={}, ty0={}, id={:?}, minimum_lifetime={:?})", - ty, ty0, hir_id, minimum_lifetime - ); - self.type_must_outlive(origin, ty, minimum_lifetime); - } - /// Adds constraints to inference such that `T: 'a` holds (or /// reports an error if it cannot). /// @@ -1035,13 +601,7 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> { self.link_region(expr.span, r, ty::BorrowKind::from_mutbl(m.into()), expr_cmt); } - adjustment::AutoBorrow::RawPtr(m) => { - let r = self.tcx.mk_region(ty::ReScope(region::Scope { - id: expr.hir_id.local_id, - data: region::ScopeData::Node, - })); - self.link_region(expr.span, r, ty::BorrowKind::from_mutbl(m), expr_cmt); - } + adjustment::AutoBorrow::RawPtr(_) => {} } } @@ -1251,39 +811,4 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> { } } } - - /// Checks that the values provided for type/region arguments in a given - /// expression are well-formed and in-scope. - fn substs_wf_in_scope( - &mut self, - origin: infer::ParameterOrigin, - substs: SubstsRef<'tcx>, - expr_span: Span, - expr_region: ty::Region<'tcx>, - ) { - debug!( - "substs_wf_in_scope(substs={:?}, \ - expr_region={:?}, \ - origin={:?}, \ - expr_span={:?})", - substs, expr_region, origin, expr_span - ); - - let origin = infer::ParameterInScope(origin, expr_span); - - for kind in substs { - match kind.unpack() { - GenericArgKind::Lifetime(lt) => { - self.sub_regions(origin.clone(), expr_region, lt); - } - GenericArgKind::Type(ty) => { - let ty = self.resolve_type(ty); - self.type_must_outlive(origin.clone(), ty, expr_region); - } - GenericArgKind::Const(_) => { - // Const parameters don't impose constraints. - } - } - } - } } diff --git a/src/librustc_typeck/coherence/builtin.rs b/src/librustc_typeck/coherence/builtin.rs index efa3cd9955b49..c5dd314dc6558 100644 --- a/src/librustc_typeck/coherence/builtin.rs +++ b/src/librustc_typeck/coherence/builtin.rs @@ -11,7 +11,6 @@ use rustc_hir::ItemKind; use rustc_infer::infer; use rustc_infer::infer::outlives::env::OutlivesEnvironment; use rustc_infer::infer::{RegionckMode, TyCtxtInferExt}; -use rustc_middle::middle::region; use rustc_middle::ty::adjustment::CoerceUnsizedInfo; use rustc_middle::ty::TypeFoldable; use rustc_middle::ty::{self, Ty, TyCtxt}; @@ -293,11 +292,9 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef } // Finally, resolve all regions. - let region_scope_tree = region::ScopeTree::default(); let outlives_env = OutlivesEnvironment::new(param_env); infcx.resolve_regions_and_report_errors( impl_did.to_def_id(), - ®ion_scope_tree, &outlives_env, RegionckMode::default(), ); @@ -552,14 +549,8 @@ pub fn coerce_unsized_info(tcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUnsizedI } // Finally, resolve all regions. - let region_scope_tree = region::ScopeTree::default(); let outlives_env = OutlivesEnvironment::new(param_env); - infcx.resolve_regions_and_report_errors( - impl_did, - ®ion_scope_tree, - &outlives_env, - RegionckMode::default(), - ); + infcx.resolve_regions_and_report_errors(impl_did, &outlives_env, RegionckMode::default()); CoerceUnsizedInfo { custom_kind: kind } }) diff --git a/src/librustc_typeck/impl_wf_check/min_specialization.rs b/src/librustc_typeck/impl_wf_check/min_specialization.rs index d30dc1b7a475e..08404bea56138 100644 --- a/src/librustc_typeck/impl_wf_check/min_specialization.rs +++ b/src/librustc_typeck/impl_wf_check/min_specialization.rs @@ -73,7 +73,6 @@ use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_infer::infer::outlives::env::OutlivesEnvironment; use rustc_infer::infer::{InferCtxt, RegionckMode, TyCtxtInferExt}; use rustc_infer::traits::specialization_graph::Node; -use rustc_middle::middle::region::ScopeTree; use rustc_middle::ty::subst::{GenericArg, InternalSubsts, SubstsRef}; use rustc_middle::ty::trait_def::TraitSpecializationKind; use rustc_middle::ty::{self, InstantiatedPredicates, TyCtxt, TypeFoldable}; @@ -165,12 +164,7 @@ fn get_impl_substs<'tcx>( // Conservatively use an empty `ParamEnv`. let outlives_env = OutlivesEnvironment::new(ty::ParamEnv::empty()); - infcx.resolve_regions_and_report_errors( - impl1_def_id, - &ScopeTree::default(), - &outlives_env, - RegionckMode::default(), - ); + infcx.resolve_regions_and_report_errors(impl1_def_id, &outlives_env, RegionckMode::default()); let impl2_substs = match infcx.fully_resolve(&impl2_substs) { Ok(s) => s, Err(_) => { diff --git a/src/librustc_typeck/outlives/utils.rs b/src/librustc_typeck/outlives/utils.rs index 3bbe3e34a6a45..8b06967879638 100644 --- a/src/librustc_typeck/outlives/utils.rs +++ b/src/librustc_typeck/outlives/utils.rs @@ -170,7 +170,6 @@ fn is_free_region(tcx: TyCtxt<'_>, region: Region<'_>) -> bool { // These regions don't appear in types from type declarations: RegionKind::ReErased - | RegionKind::ReScope(..) | RegionKind::ReVar(..) | RegionKind::RePlaceholder(..) | RegionKind::ReFree(..) => { diff --git a/src/librustc_typeck/variance/constraints.rs b/src/librustc_typeck/variance/constraints.rs index 3a680f55c8c30..e04af6850dea1 100644 --- a/src/librustc_typeck/variance/constraints.rs +++ b/src/librustc_typeck/variance/constraints.rs @@ -444,7 +444,6 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { } ty::ReFree(..) - | ty::ReScope(..) | ty::ReVar(..) | ty::RePlaceholder(..) | ty::ReEmpty(_) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index cf1a39232bc78..702c7d1e0f120 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -447,7 +447,6 @@ impl Clean> for ty::RegionKind { ty::ReLateBound(..) | ty::ReFree(..) - | ty::ReScope(..) | ty::ReVar(..) | ty::RePlaceholder(..) | ty::ReEmpty(_) diff --git a/src/test/ui/borrowck/issue-45983.migrate.stderr b/src/test/ui/borrowck/issue-45983.migrate.stderr deleted file mode 100644 index c1564cf07e68a..0000000000000 --- a/src/test/ui/borrowck/issue-45983.migrate.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error: borrowed data cannot be stored outside of its closure - --> $DIR/issue-45983.rs:20:27 - | -LL | let x = None; - | - borrowed data cannot be stored into here... -LL | give_any(|y| x = Some(y)); - | --- ^ cannot be stored outside of its closure - | | - | ...because it cannot outlive this closure - -error: aborting due to previous error - diff --git a/src/test/ui/borrowck/issue-45983.nll.stderr b/src/test/ui/borrowck/issue-45983.nll.stderr deleted file mode 100644 index 51bb4dee6762a..0000000000000 --- a/src/test/ui/borrowck/issue-45983.nll.stderr +++ /dev/null @@ -1,21 +0,0 @@ -error[E0521]: borrowed data escapes outside of closure - --> $DIR/issue-45983.rs:20:18 - | -LL | let x = None; - | - `x` declared here, outside of the closure body -LL | give_any(|y| x = Some(y)); - | - ^^^^^^^^^^^ `y` escapes the closure body here - | | - | `y` is a reference that is only valid in the closure body - -error[E0594]: cannot assign to `x`, as it is not declared as mutable - --> $DIR/issue-45983.rs:20:18 - | -LL | let x = None; - | - help: consider changing this to be mutable: `mut x` -LL | give_any(|y| x = Some(y)); - | ^^^^^^^^^^^ cannot assign - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0594`. diff --git a/src/test/ui/borrowck/issue-45983.rs b/src/test/ui/borrowck/issue-45983.rs index 3cd282077424b..6784f6f86a010 100644 --- a/src/test/ui/borrowck/issue-45983.rs +++ b/src/test/ui/borrowck/issue-45983.rs @@ -1,24 +1,12 @@ // As documented in Issue #45983, this test is evaluating the quality // of our diagnostics on erroneous code using higher-ranked closures. -// revisions: migrate nll - -// Since we are testing nll (and migration) explicitly as a separate -// revisions, don't worry about the --compare-mode=nll on this test. - -// ignore-compare-mode-nll -// ignore-compare-mode-polonius - -//[nll]compile-flags: -Z borrowck=mir - fn give_any FnOnce(&'r ())>(f: F) { f(&()); } fn main() { - let x = None; + let mut x = None; give_any(|y| x = Some(y)); - //[migrate]~^ ERROR borrowed data cannot be stored outside of its closure - //[nll]~^^ ERROR borrowed data escapes outside of closure - //[nll]~| ERROR cannot assign to `x`, as it is not declared as mutable + //~^ ERROR borrowed data escapes outside of closure } diff --git a/src/test/ui/borrowck/regions-escape-bound-fn-2.nll.stderr b/src/test/ui/borrowck/issue-45983.stderr similarity index 81% rename from src/test/ui/borrowck/regions-escape-bound-fn-2.nll.stderr rename to src/test/ui/borrowck/issue-45983.stderr index 68a0fe0b4f07b..efd414a2d44ff 100644 --- a/src/test/ui/borrowck/regions-escape-bound-fn-2.nll.stderr +++ b/src/test/ui/borrowck/issue-45983.stderr @@ -1,9 +1,9 @@ error[E0521]: borrowed data escapes outside of closure - --> $DIR/regions-escape-bound-fn-2.rs:8:18 + --> $DIR/issue-45983.rs:10:18 | LL | let mut x = None; | ----- `x` declared here, outside of the closure body -LL | with_int(|y| x = Some(y)); +LL | give_any(|y| x = Some(y)); | - ^^^^^^^^^^^ `y` escapes the closure body here | | | `y` is a reference that is only valid in the closure body diff --git a/src/test/ui/borrowck/issue-7573.nll.stderr b/src/test/ui/borrowck/issue-7573.nll.stderr deleted file mode 100644 index 20afecfe5de79..0000000000000 --- a/src/test/ui/borrowck/issue-7573.nll.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error[E0521]: borrowed data escapes outside of closure - --> $DIR/issue-7573.rs:21:9 - | -LL | let mut lines_to_use: Vec<&CrateId> = Vec::new(); - | ---------------- `lines_to_use` declared here, outside of the closure body -LL | -LL | let push_id = |installed_id: &CrateId| { - | ------------ `installed_id` is a reference that is only valid in the closure body -... -LL | lines_to_use.push(installed_id); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `installed_id` escapes the closure body here - -error: aborting due to previous error - diff --git a/src/test/ui/borrowck/issue-7573.rs b/src/test/ui/borrowck/issue-7573.rs index 20a6a5c92f149..7c07411533ff0 100644 --- a/src/test/ui/borrowck/issue-7573.rs +++ b/src/test/ui/borrowck/issue-7573.rs @@ -1,36 +1,34 @@ pub struct CrateId { local_path: String, - junk: String + junk: String, } impl CrateId { fn new(s: &str) -> CrateId { - CrateId { - local_path: s.to_string(), - junk: "wutevs".to_string() - } + CrateId { local_path: s.to_string(), junk: "wutevs".to_string() } } } pub fn remove_package_from_database() { let mut lines_to_use: Vec<&CrateId> = Vec::new(); - //~^ NOTE cannot infer an appropriate lifetime + //~^ NOTE `lines_to_use` declared here, outside of the closure body let push_id = |installed_id: &CrateId| { - //~^ NOTE borrowed data cannot outlive this closure - //~| NOTE ...so that variable is valid at time of its declaration + //~^ NOTE `installed_id` is a reference that is only valid in the closure body lines_to_use.push(installed_id); - //~^ ERROR borrowed data cannot be stored outside of its closure - //~| NOTE cannot be stored outside of its closure + //~^ ERROR borrowed data escapes outside of closure + //~| NOTE `installed_id` escapes the closure body here }; list_database(push_id); for l in &lines_to_use { println!("{}", l.local_path); } - } -pub fn list_database(mut f: F) where F: FnMut(&CrateId) { +pub fn list_database(mut f: F) +where + F: FnMut(&CrateId), +{ let stuff = ["foo", "bar"]; for l in &stuff { diff --git a/src/test/ui/borrowck/issue-7573.stderr b/src/test/ui/borrowck/issue-7573.stderr index 32b3ef72d8bda..815419db833e5 100644 --- a/src/test/ui/borrowck/issue-7573.stderr +++ b/src/test/ui/borrowck/issue-7573.stderr @@ -1,16 +1,14 @@ -error: borrowed data cannot be stored outside of its closure - --> $DIR/issue-7573.rs:21:27 +error[E0521]: borrowed data escapes outside of closure + --> $DIR/issue-7573.rs:17:9 | LL | let mut lines_to_use: Vec<&CrateId> = Vec::new(); - | - cannot infer an appropriate lifetime... + | ---------------- `lines_to_use` declared here, outside of the closure body LL | LL | let push_id = |installed_id: &CrateId| { - | ------- ------------------------ borrowed data cannot outlive this closure - | | - | ...so that variable is valid at time of its declaration -... + | ------------ `installed_id` is a reference that is only valid in the closure body +LL | LL | lines_to_use.push(installed_id); - | ^^^^^^^^^^^^ cannot be stored outside of its closure + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `installed_id` escapes the closure body here error: aborting due to previous error diff --git a/src/test/ui/borrowck/regions-escape-bound-fn-2.rs b/src/test/ui/borrowck/regions-escape-bound-fn-2.rs index cb423032b4610..0e98d98cf87b3 100644 --- a/src/test/ui/borrowck/regions-escape-bound-fn-2.rs +++ b/src/test/ui/borrowck/regions-escape-bound-fn-2.rs @@ -1,4 +1,7 @@ -fn with_int(f: F) where F: FnOnce(&isize) { +fn with_int(f: F) +where + F: FnOnce(&isize), +{ let x = 3; f(&x); } @@ -6,5 +9,5 @@ fn with_int(f: F) where F: FnOnce(&isize) { fn main() { let mut x = None; with_int(|y| x = Some(y)); - //~^ ERROR borrowed data cannot be stored outside of its closure + //~^ ERROR borrowed data escapes outside of closure } diff --git a/src/test/ui/borrowck/regions-escape-bound-fn-2.stderr b/src/test/ui/borrowck/regions-escape-bound-fn-2.stderr index 4b37edafa1273..1dc60bb155452 100644 --- a/src/test/ui/borrowck/regions-escape-bound-fn-2.stderr +++ b/src/test/ui/borrowck/regions-escape-bound-fn-2.stderr @@ -1,12 +1,12 @@ -error: borrowed data cannot be stored outside of its closure - --> $DIR/regions-escape-bound-fn-2.rs:8:27 +error[E0521]: borrowed data escapes outside of closure + --> $DIR/regions-escape-bound-fn-2.rs:11:18 | LL | let mut x = None; - | ----- borrowed data cannot be stored into here... + | ----- `x` declared here, outside of the closure body LL | with_int(|y| x = Some(y)); - | --- ^ cannot be stored outside of its closure - | | - | ...because it cannot outlive this closure + | - ^^^^^^^^^^^ `y` escapes the closure body here + | | + | `y` is a reference that is only valid in the closure body 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 deleted file mode 100644 index d304de92c7e18..0000000000000 --- a/src/test/ui/borrowck/regions-escape-bound-fn.nll.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0521]: borrowed data escapes outside of closure - --> $DIR/regions-escape-bound-fn.rs:8:18 - | -LL | let mut x: Option<&isize> = None; - | ----- `x` declared here, outside of the closure body -LL | with_int(|y| x = Some(y)); - | - ^^^^^^^^^^^ `y` escapes the closure body here - | | - | `y` is a reference that is only valid in the closure body - -error: aborting due to previous error - diff --git a/src/test/ui/borrowck/regions-escape-bound-fn.rs b/src/test/ui/borrowck/regions-escape-bound-fn.rs index 772df3e6c5822..f896ae7bdada2 100644 --- a/src/test/ui/borrowck/regions-escape-bound-fn.rs +++ b/src/test/ui/borrowck/regions-escape-bound-fn.rs @@ -1,4 +1,7 @@ -fn with_int(f: F) where F: FnOnce(&isize) { +fn with_int(f: F) +where + F: FnOnce(&isize), +{ let x = 3; f(&x); } @@ -6,5 +9,5 @@ fn with_int(f: F) where F: FnOnce(&isize) { fn main() { let mut x: Option<&isize> = None; with_int(|y| x = Some(y)); - //~^ ERROR borrowed data cannot be stored outside of its closure + //~^ ERROR borrowed data escapes outside of closure } diff --git a/src/test/ui/borrowck/regions-escape-bound-fn.stderr b/src/test/ui/borrowck/regions-escape-bound-fn.stderr index 4973d5306f959..5c548ec2876a3 100644 --- a/src/test/ui/borrowck/regions-escape-bound-fn.stderr +++ b/src/test/ui/borrowck/regions-escape-bound-fn.stderr @@ -1,12 +1,12 @@ -error: borrowed data cannot be stored outside of its closure - --> $DIR/regions-escape-bound-fn.rs:8:27 +error[E0521]: borrowed data escapes outside of closure + --> $DIR/regions-escape-bound-fn.rs:11:18 | LL | let mut x: Option<&isize> = None; - | ----- borrowed data cannot be stored into here... + | ----- `x` declared here, outside of the closure body LL | with_int(|y| x = Some(y)); - | --- ^ cannot be stored outside of its closure - | | - | ...because it cannot outlive this closure + | - ^^^^^^^^^^^ `y` escapes the closure body here + | | + | `y` is a reference that is only valid in the closure body 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 deleted file mode 100644 index d9931302f75fc..0000000000000 --- a/src/test/ui/borrowck/regions-escape-unboxed-closure.nll.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0521]: borrowed data escapes outside of closure - --> $DIR/regions-escape-unboxed-closure.rs:6:23 - | -LL | let mut x: Option<&isize> = None; - | ----- `x` declared here, outside of the closure body -LL | with_int(&mut |y| x = Some(y)); - | - ^^^^^^^^^^^ `y` escapes the closure body here - | | - | `y` is a reference that is only valid in the closure body - -error: aborting due to previous error - diff --git a/src/test/ui/borrowck/regions-escape-unboxed-closure.rs b/src/test/ui/borrowck/regions-escape-unboxed-closure.rs index d8bef927fd722..f01e47122d1e1 100644 --- a/src/test/ui/borrowck/regions-escape-unboxed-closure.rs +++ b/src/test/ui/borrowck/regions-escape-unboxed-closure.rs @@ -1,8 +1,7 @@ -fn with_int(f: &mut dyn FnMut(&isize)) { -} +fn with_int(f: &mut dyn FnMut(&isize)) {} fn main() { let mut x: Option<&isize> = None; with_int(&mut |y| x = Some(y)); - //~^ ERROR borrowed data cannot be stored outside of its closure + //~^ ERROR borrowed data escapes outside of closure } diff --git a/src/test/ui/borrowck/regions-escape-unboxed-closure.stderr b/src/test/ui/borrowck/regions-escape-unboxed-closure.stderr index 047e290acae14..f2a49e70d2716 100644 --- a/src/test/ui/borrowck/regions-escape-unboxed-closure.stderr +++ b/src/test/ui/borrowck/regions-escape-unboxed-closure.stderr @@ -1,12 +1,12 @@ -error: borrowed data cannot be stored outside of its closure - --> $DIR/regions-escape-unboxed-closure.rs:6:32 +error[E0521]: borrowed data escapes outside of closure + --> $DIR/regions-escape-unboxed-closure.rs:5:23 | LL | let mut x: Option<&isize> = None; - | ----- borrowed data cannot be stored into here... + | ----- `x` declared here, outside of the closure body LL | with_int(&mut |y| x = Some(y)); - | --- ^ cannot be stored outside of its closure - | | - | ...because it cannot outlive this closure + | - ^^^^^^^^^^^ `y` escapes the closure body here + | | + | `y` is a reference that is only valid in the closure body error: aborting due to previous error diff --git a/src/test/ui/c-variadic/variadic-ffi-4.nll.stderr b/src/test/ui/c-variadic/variadic-ffi-4.nll.stderr deleted file mode 100644 index 89107e799bd22..0000000000000 --- a/src/test/ui/c-variadic/variadic-ffi-4.nll.stderr +++ /dev/null @@ -1,123 +0,0 @@ -error: lifetime may not live long enough - --> $DIR/variadic-ffi-4.rs:8:5 - | -LL | pub unsafe extern "C" fn no_escape0<'f>(_: usize, ap: ...) -> VaListImpl<'f> { - | -- -- has type `core::ffi::VaListImpl<'1>` - | | - | lifetime `'f` defined here -LL | ap - | ^^ function was supposed to return data with lifetime `'1` but it is returning data with lifetime `'f` - -error: lifetime may not live long enough - --> $DIR/variadic-ffi-4.rs:8:5 - | -LL | pub unsafe extern "C" fn no_escape0<'f>(_: usize, ap: ...) -> VaListImpl<'f> { - | -- -- has type `core::ffi::VaListImpl<'1>` - | | - | lifetime `'f` defined here -LL | ap - | ^^ returning this value requires that `'1` must outlive `'f` - -error: lifetime may not live long enough - --> $DIR/variadic-ffi-4.rs:12:5 - | -LL | pub unsafe extern "C" fn no_escape1(_: usize, ap: ...) -> VaListImpl<'static> { - | -- has type `core::ffi::VaListImpl<'1>` -LL | ap - | ^^ returning this value requires that `'1` must outlive `'static` - -error: lifetime may not live long enough - --> $DIR/variadic-ffi-4.rs:16:33 - | -LL | let _ = ap.with_copy(|ap| { ap }); - | --- ^^ returning this value requires that `'1` must outlive `'2` - | | | - | | return type of closure is core::ffi::VaList<'2, '_> - | has type `core::ffi::VaList<'1, '_>` - -error: lifetime may not live long enough - --> $DIR/variadic-ffi-4.rs:20:5 - | -LL | pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { - | ------- ------- has type `core::ffi::VaListImpl<'2>` - | | - | has type `&mut core::ffi::VaListImpl<'1>` -LL | *ap0 = ap1; - | ^^^^ assignment requires that `'1` must outlive `'2` - -error: lifetime may not live long enough - --> $DIR/variadic-ffi-4.rs:20:5 - | -LL | pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { - | ------- ------- has type `core::ffi::VaListImpl<'2>` - | | - | has type `&mut core::ffi::VaListImpl<'1>` -LL | *ap0 = ap1; - | ^^^^ assignment requires that `'2` must outlive `'1` - -error: lifetime may not live long enough - --> $DIR/variadic-ffi-4.rs:24:5 - | -LL | pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { - | --- ------- has type `core::ffi::VaListImpl<'2>` - | | - | has type `&mut core::ffi::VaListImpl<'1>` -LL | ap0 = &mut ap1; - | ^^^^^^^^^^^^^^ assignment requires that `'1` must outlive `'2` - -error: lifetime may not live long enough - --> $DIR/variadic-ffi-4.rs:24:5 - | -LL | pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { - | --- ------- has type `core::ffi::VaListImpl<'2>` - | | - | has type `&mut core::ffi::VaListImpl<'1>` -LL | ap0 = &mut ap1; - | ^^^^^^^^^^^^^^ assignment requires that `'2` must outlive `'1` - -error[E0384]: cannot assign to immutable argument `ap0` - --> $DIR/variadic-ffi-4.rs:24:5 - | -LL | pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { - | --- help: make this binding mutable: `mut ap0` -LL | ap0 = &mut ap1; - | ^^^^^^^^^^^^^^ cannot assign to immutable argument - -error[E0597]: `ap1` does not live long enough - --> $DIR/variadic-ffi-4.rs:24:11 - | -LL | pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { - | - let's call the lifetime of this reference `'3` -LL | ap0 = &mut ap1; - | ------^^^^^^^^ - | | | - | | borrowed value does not live long enough - | assignment requires that `ap1` is borrowed for `'3` -... -LL | } - | - `ap1` dropped here while still borrowed - -error: lifetime may not live long enough - --> $DIR/variadic-ffi-4.rs:31:12 - | -LL | pub unsafe extern "C" fn no_escape5(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { - | ------- ------- has type `core::ffi::VaListImpl<'2>` - | | - | has type `&mut core::ffi::VaListImpl<'1>` -LL | *ap0 = ap1.clone(); - | ^^^^^^^^^^^ argument requires that `'1` must outlive `'2` - -error: lifetime may not live long enough - --> $DIR/variadic-ffi-4.rs:31:12 - | -LL | pub unsafe extern "C" fn no_escape5(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { - | ------- ------- has type `core::ffi::VaListImpl<'2>` - | | - | has type `&mut core::ffi::VaListImpl<'1>` -LL | *ap0 = ap1.clone(); - | ^^^^^^^^^^^ argument requires that `'2` must outlive `'1` - -error: aborting due to 12 previous errors - -Some errors have detailed explanations: E0384, E0597. -For more information about an error, try `rustc --explain E0384`. diff --git a/src/test/ui/c-variadic/variadic-ffi-4.rs b/src/test/ui/c-variadic/variadic-ffi-4.rs index a4d658cef1630..8064037942259 100644 --- a/src/test/ui/c-variadic/variadic-ffi-4.rs +++ b/src/test/ui/c-variadic/variadic-ffi-4.rs @@ -1,32 +1,38 @@ -#![crate_type="lib"] +#![crate_type = "lib"] #![no_std] #![feature(c_variadic)] use core::ffi::{VaList, VaListImpl}; pub unsafe extern "C" fn no_escape0<'f>(_: usize, ap: ...) -> VaListImpl<'f> { - ap //~ ERROR: mismatched types + ap + //~^ ERROR: lifetime may not live long enough + //~| ERROR: lifetime may not live long enough } pub unsafe extern "C" fn no_escape1(_: usize, ap: ...) -> VaListImpl<'static> { - ap //~ ERROR: mismatched types + ap //~ ERROR: lifetime may not live long enough } pub unsafe extern "C" fn no_escape2(_: usize, ap: ...) { - let _ = ap.with_copy(|ap| { ap }); //~ ERROR: cannot infer an appropriate lifetime + let _ = ap.with_copy(|ap| ap); //~ ERROR: lifetime may not live long enough } pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { - *ap0 = ap1; //~ ERROR: mismatched types + *ap0 = ap1; + //~^ ERROR: lifetime may not live long enough + //~| ERROR: lifetime may not live long enough } -pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { +pub unsafe extern "C" fn no_escape4(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { ap0 = &mut ap1; - //~^ ERROR: a value of type `core::ffi::VaListImpl<'_>` is borrowed for too long - //~| ERROR: mismatched types - //~| ERROR: cannot infer an appropriate lifetime + //~^ ERROR: `ap1` does not live long enough + //~| ERROR: lifetime may not live long enough + //~| ERROR: lifetime may not live long enough } pub unsafe extern "C" fn no_escape5(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { - *ap0 = ap1.clone(); //~ ERROR: mismatched types + *ap0 = ap1.clone(); + //~^ ERROR: lifetime may not live long enough + //~| ERROR: lifetime may not live long enough } diff --git a/src/test/ui/c-variadic/variadic-ffi-4.stderr b/src/test/ui/c-variadic/variadic-ffi-4.stderr index cd4cd8b198de8..65623501569e1 100644 --- a/src/test/ui/c-variadic/variadic-ffi-4.stderr +++ b/src/test/ui/c-variadic/variadic-ffi-4.stderr @@ -1,217 +1,114 @@ -error[E0308]: mismatched types +error: lifetime may not live long enough --> $DIR/variadic-ffi-4.rs:8:5 | +LL | pub unsafe extern "C" fn no_escape0<'f>(_: usize, ap: ...) -> VaListImpl<'f> { + | -- -- has type `core::ffi::VaListImpl<'1>` + | | + | lifetime `'f` defined here LL | ap - | ^^ lifetime mismatch - | - = note: expected struct `core::ffi::VaListImpl<'f>` - found struct `core::ffi::VaListImpl<'_>` -note: the scope of call-site for function at 7:78... - --> $DIR/variadic-ffi-4.rs:7:78 - | -LL | pub unsafe extern "C" fn no_escape0<'f>(_: usize, ap: ...) -> VaListImpl<'f> { - | ______________________________________________________________________________^ -LL | | ap -LL | | } - | |_^ -note: ...does not necessarily outlive the lifetime `'f` as defined on the function body at 7:37 - --> $DIR/variadic-ffi-4.rs:7:37 + | ^^ function was supposed to return data with lifetime `'1` but it is returning data with lifetime `'f` + +error: lifetime may not live long enough + --> $DIR/variadic-ffi-4.rs:8:5 | LL | pub unsafe extern "C" fn no_escape0<'f>(_: usize, ap: ...) -> VaListImpl<'f> { - | ^^ + | -- -- has type `core::ffi::VaListImpl<'1>` + | | + | lifetime `'f` defined here +LL | ap + | ^^ returning this value requires that `'1` must outlive `'f` -error[E0308]: mismatched types - --> $DIR/variadic-ffi-4.rs:12:5 +error: lifetime may not live long enough + --> $DIR/variadic-ffi-4.rs:14:5 | +LL | pub unsafe extern "C" fn no_escape1(_: usize, ap: ...) -> VaListImpl<'static> { + | -- has type `core::ffi::VaListImpl<'1>` LL | ap - | ^^ lifetime mismatch - | - = note: expected struct `core::ffi::VaListImpl<'static>` - found struct `core::ffi::VaListImpl<'_>` -note: the scope of call-site for function at 11:79... - --> $DIR/variadic-ffi-4.rs:11:79 - | -LL | pub unsafe extern "C" fn no_escape1(_: usize, ap: ...) -> VaListImpl<'static> { - | _______________________________________________________________________________^ -LL | | ap -LL | | } - | |_^ - = note: ...does not necessarily outlive the static lifetime + | ^^ returning this value requires that `'1` must outlive `'static` -error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements - --> $DIR/variadic-ffi-4.rs:16:33 - | -LL | let _ = ap.with_copy(|ap| { ap }); - | ^^ - | -note: first, the lifetime cannot outlive the anonymous lifetime #2 defined on the body at 16:26... - --> $DIR/variadic-ffi-4.rs:16:26 - | -LL | let _ = ap.with_copy(|ap| { ap }); - | ^^^^^^^^^^^ -note: ...so that the expression is assignable - --> $DIR/variadic-ffi-4.rs:16:33 - | -LL | let _ = ap.with_copy(|ap| { ap }); - | ^^ - = note: expected `core::ffi::VaList<'_, '_>` - found `core::ffi::VaList<'_, '_>` -note: but, the lifetime must be valid for the method call at 16:13... - --> $DIR/variadic-ffi-4.rs:16:13 - | -LL | let _ = ap.with_copy(|ap| { ap }); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...so type `core::ffi::VaList<'_, '_>` of expression is valid during the expression - --> $DIR/variadic-ffi-4.rs:16:13 - | -LL | let _ = ap.with_copy(|ap| { ap }); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +error: lifetime may not live long enough + --> $DIR/variadic-ffi-4.rs:18:31 + | +LL | let _ = ap.with_copy(|ap| ap); + | --- ^^ returning this value requires that `'1` must outlive `'2` + | | | + | | return type of closure is core::ffi::VaList<'2, '_> + | has type `core::ffi::VaList<'1, '_>` -error[E0308]: mismatched types - --> $DIR/variadic-ffi-4.rs:20:12 +error: lifetime may not live long enough + --> $DIR/variadic-ffi-4.rs:22:5 | +LL | pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { + | ------- ------- has type `core::ffi::VaListImpl<'2>` + | | + | has type `&mut core::ffi::VaListImpl<'1>` LL | *ap0 = ap1; - | ^^^ lifetime mismatch - | - = note: expected struct `core::ffi::VaListImpl<'_>` - found struct `core::ffi::VaListImpl<'_>` -note: the scope of call-site for function at 19:87... - --> $DIR/variadic-ffi-4.rs:19:87 - | -LL | pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { - | _______________________________________________________________________________________^ -LL | | *ap0 = ap1; -LL | | } - | |_^ -note: ...does not necessarily outlive the anonymous lifetime #2 defined on the function body at 19:1 - --> $DIR/variadic-ffi-4.rs:19:1 - | -LL | / pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { -LL | | *ap0 = ap1; -LL | | } - | |_^ + | ^^^^ assignment requires that `'1` must outlive `'2` -error[E0490]: a value of type `core::ffi::VaListImpl<'_>` is borrowed for too long - --> $DIR/variadic-ffi-4.rs:24:11 +error: lifetime may not live long enough + --> $DIR/variadic-ffi-4.rs:22:5 | -LL | ap0 = &mut ap1; - | ^^^^^^^^ - | -note: the type is valid for the anonymous lifetime #1 defined on the function body at 23:1 - --> $DIR/variadic-ffi-4.rs:23:1 - | -LL | / pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { -LL | | ap0 = &mut ap1; -LL | | -LL | | -LL | | -LL | | } - | |_^ -note: but the borrow lasts for the scope of call-site for function at 23:83 - --> $DIR/variadic-ffi-4.rs:23:83 - | -LL | pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { - | ___________________________________________________________________________________^ -LL | | ap0 = &mut ap1; -LL | | -LL | | -LL | | -LL | | } - | |_^ +LL | pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { + | ------- ------- has type `core::ffi::VaListImpl<'2>` + | | + | has type `&mut core::ffi::VaListImpl<'1>` +LL | *ap0 = ap1; + | ^^^^ assignment requires that `'2` must outlive `'1` -error[E0308]: mismatched types - --> $DIR/variadic-ffi-4.rs:24:11 +error: lifetime may not live long enough + --> $DIR/variadic-ffi-4.rs:28:5 | +LL | pub unsafe extern "C" fn no_escape4(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { + | ------- ------- has type `core::ffi::VaListImpl<'2>` + | | + | has type `&mut core::ffi::VaListImpl<'1>` LL | ap0 = &mut ap1; - | ^^^^^^^^ lifetime mismatch - | - = note: expected mutable reference `&mut core::ffi::VaListImpl<'_>` - found mutable reference `&mut core::ffi::VaListImpl<'_>` -note: the scope of call-site for function at 23:83... - --> $DIR/variadic-ffi-4.rs:23:83 - | -LL | pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { - | ___________________________________________________________________________________^ -LL | | ap0 = &mut ap1; -LL | | -LL | | -LL | | -LL | | } - | |_^ -note: ...does not necessarily outlive the anonymous lifetime #2 defined on the function body at 23:1 - --> $DIR/variadic-ffi-4.rs:23:1 - | -LL | / pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { -LL | | ap0 = &mut ap1; -LL | | -LL | | -LL | | -LL | | } - | |_^ + | ^^^^^^^^^^^^^^ assignment requires that `'1` must outlive `'2` -error[E0495]: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements - --> $DIR/variadic-ffi-4.rs:24:11 +error: lifetime may not live long enough + --> $DIR/variadic-ffi-4.rs:28:5 | +LL | pub unsafe extern "C" fn no_escape4(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { + | ------- ------- has type `core::ffi::VaListImpl<'2>` + | | + | has type `&mut core::ffi::VaListImpl<'1>` LL | ap0 = &mut ap1; - | ^^^^^^^^ - | -note: first, the lifetime cannot outlive the scope of call-site for function at 23:83... - --> $DIR/variadic-ffi-4.rs:23:83 - | -LL | pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { - | ___________________________________________________________________________________^ -LL | | ap0 = &mut ap1; -LL | | -LL | | -LL | | -LL | | } - | |_^ -note: ...so that the type `core::ffi::VaListImpl<'_>` is not borrowed for too long - --> $DIR/variadic-ffi-4.rs:24:11 - | -LL | ap0 = &mut ap1; - | ^^^^^^^^ -note: but, the lifetime must be valid for the anonymous lifetime #1 defined on the function body at 23:1... - --> $DIR/variadic-ffi-4.rs:23:1 - | -LL | / pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { -LL | | ap0 = &mut ap1; -LL | | -LL | | -LL | | -LL | | } - | |_^ -note: ...so that reference does not outlive borrowed content - --> $DIR/variadic-ffi-4.rs:24:11 + | ^^^^^^^^^^^^^^ assignment requires that `'2` must outlive `'1` + +error[E0597]: `ap1` does not live long enough + --> $DIR/variadic-ffi-4.rs:28:11 | +LL | pub unsafe extern "C" fn no_escape4(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { + | - let's call the lifetime of this reference `'3` LL | ap0 = &mut ap1; - | ^^^^^^^^ + | ------^^^^^^^^ + | | | + | | borrowed value does not live long enough + | assignment requires that `ap1` is borrowed for `'3` +... +LL | } + | - `ap1` dropped here while still borrowed -error[E0308]: mismatched types - --> $DIR/variadic-ffi-4.rs:31:12 +error: lifetime may not live long enough + --> $DIR/variadic-ffi-4.rs:35:12 | +LL | pub unsafe extern "C" fn no_escape5(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { + | ------- ------- has type `core::ffi::VaListImpl<'2>` + | | + | has type `&mut core::ffi::VaListImpl<'1>` LL | *ap0 = ap1.clone(); - | ^^^^^^^^^^^ lifetime mismatch - | - = note: expected struct `core::ffi::VaListImpl<'_>` - found struct `core::ffi::VaListImpl<'_>` -note: the scope of call-site for function at 30:87... - --> $DIR/variadic-ffi-4.rs:30:87 - | -LL | pub unsafe extern "C" fn no_escape5(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { - | _______________________________________________________________________________________^ -LL | | *ap0 = ap1.clone(); -LL | | } - | |_^ -note: ...does not necessarily outlive the anonymous lifetime #2 defined on the function body at 30:1 - --> $DIR/variadic-ffi-4.rs:30:1 + | ^^^^^^^^^^^ argument requires that `'1` must outlive `'2` + +error: lifetime may not live long enough + --> $DIR/variadic-ffi-4.rs:35:12 | -LL | / pub unsafe extern "C" fn no_escape5(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { -LL | | *ap0 = ap1.clone(); -LL | | } - | |_^ +LL | pub unsafe extern "C" fn no_escape5(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { + | ------- ------- has type `core::ffi::VaListImpl<'2>` + | | + | has type `&mut core::ffi::VaListImpl<'1>` +LL | *ap0 = ap1.clone(); + | ^^^^^^^^^^^ argument requires that `'2` must outlive `'1` -error: aborting due to 8 previous errors +error: aborting due to 11 previous errors -Some errors have detailed explanations: E0308, E0495. -For more information about an error, try `rustc --explain E0308`. +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/closures/closure-expected-type/expect-region-supply-region-2.nll.stderr b/src/test/ui/closures/closure-expected-type/expect-region-supply-region-2.nll.stderr new file mode 100644 index 0000000000000..52bca8dd63e1f --- /dev/null +++ b/src/test/ui/closures/closure-expected-type/expect-region-supply-region-2.nll.stderr @@ -0,0 +1,24 @@ +error: lifetime may not live long enough + --> $DIR/expect-region-supply-region-2.rs:14:30 + | +LL | fn expect_bound_supply_named<'x>() { + | -- lifetime `'x` defined here +... +LL | closure_expecting_bound(|x: &'x u32| { + | ^ - let's call the lifetime of this reference `'1` + | | + | requires that `'1` must outlive `'x` + +error: lifetime may not live long enough + --> $DIR/expect-region-supply-region-2.rs:14:30 + | +LL | fn expect_bound_supply_named<'x>() { + | -- lifetime `'x` defined here +... +LL | closure_expecting_bound(|x: &'x u32| { + | ^ requires that `'x` must outlive `'static` + | + = help: consider replacing `'x` with `'static` + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/closures/closure-expected-type/expect-region-supply-region-2.rs b/src/test/ui/closures/closure-expected-type/expect-region-supply-region-2.rs new file mode 100644 index 0000000000000..7405b1a1e3a28 --- /dev/null +++ b/src/test/ui/closures/closure-expected-type/expect-region-supply-region-2.rs @@ -0,0 +1,24 @@ +#![allow(warnings)] + +fn closure_expecting_bound(_: F) +where + F: FnOnce(&u32), +{ +} + +fn expect_bound_supply_named<'x>() { + let mut f: Option<&u32> = None; + + // Here we give a type annotation that `x` should be free. We get + // an error because of that. + closure_expecting_bound(|x: &'x u32| { + //~^ ERROR mismatched types + //~| ERROR mismatched types + + // Borrowck doesn't get a chance to run, but if it did it should error + // here. + f = Some(x); + }); +} + +fn main() {} diff --git a/src/test/ui/closures/closure-expected-type/expect-region-supply-region-2.stderr b/src/test/ui/closures/closure-expected-type/expect-region-supply-region-2.stderr new file mode 100644 index 0000000000000..7f527904a69e5 --- /dev/null +++ b/src/test/ui/closures/closure-expected-type/expect-region-supply-region-2.stderr @@ -0,0 +1,55 @@ +error[E0308]: mismatched types + --> $DIR/expect-region-supply-region-2.rs:14:33 + | +LL | closure_expecting_bound(|x: &'x u32| { + | ^^^^^^^ lifetime mismatch + | + = note: expected reference `&u32` + found reference `&'x u32` +note: the anonymous lifetime #2 defined on the body at 14:29... + --> $DIR/expect-region-supply-region-2.rs:14:29 + | +LL | closure_expecting_bound(|x: &'x u32| { + | _____________________________^ +LL | | +LL | | +LL | | +... | +LL | | f = Some(x); +LL | | }); + | |_____^ +note: ...does not necessarily outlive the lifetime `'x` as defined on the function body at 9:30 + --> $DIR/expect-region-supply-region-2.rs:9:30 + | +LL | fn expect_bound_supply_named<'x>() { + | ^^ + +error[E0308]: mismatched types + --> $DIR/expect-region-supply-region-2.rs:14:33 + | +LL | closure_expecting_bound(|x: &'x u32| { + | ^^^^^^^ lifetime mismatch + | + = note: expected reference `&u32` + found reference `&'x u32` +note: the lifetime `'x` as defined on the function body at 9:30... + --> $DIR/expect-region-supply-region-2.rs:9:30 + | +LL | fn expect_bound_supply_named<'x>() { + | ^^ +note: ...does not necessarily outlive the anonymous lifetime #2 defined on the body at 14:29 + --> $DIR/expect-region-supply-region-2.rs:14:29 + | +LL | closure_expecting_bound(|x: &'x u32| { + | _____________________________^ +LL | | +LL | | +LL | | +... | +LL | | f = Some(x); +LL | | }); + | |_____^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/closures/closure-expected-type/expect-region-supply-region.nll.stderr b/src/test/ui/closures/closure-expected-type/expect-region-supply-region.nll.stderr deleted file mode 100644 index d7d716ed4cb0a..0000000000000 --- a/src/test/ui/closures/closure-expected-type/expect-region-supply-region.nll.stderr +++ /dev/null @@ -1,44 +0,0 @@ -error[E0521]: borrowed data escapes outside of closure - --> $DIR/expect-region-supply-region.rs:18:9 - | -LL | let mut f: Option<&u32> = None; - | ----- `f` declared here, outside of the closure body -LL | closure_expecting_bound(|x| { - | - `x` is a reference that is only valid in the closure body -LL | f = Some(x); - | ^^^^^^^^^^^ `x` escapes the closure body here - -error[E0521]: borrowed data escapes outside of closure - --> $DIR/expect-region-supply-region.rs:28:9 - | -LL | let mut f: Option<&u32> = None; - | ----- `f` declared here, outside of the closure body -LL | closure_expecting_bound(|x: &u32| { - | - `x` is a reference that is only valid in the closure body -LL | f = Some(x); - | ^^^^^^^^^^^ `x` escapes the closure body here - -error: lifetime may not live long enough - --> $DIR/expect-region-supply-region.rs:37:30 - | -LL | fn expect_bound_supply_named<'x>() { - | -- lifetime `'x` defined here -... -LL | closure_expecting_bound(|x: &'x u32| { - | ^ - let's call the lifetime of this reference `'1` - | | - | requires that `'1` must outlive `'x` - -error: lifetime may not live long enough - --> $DIR/expect-region-supply-region.rs:37:30 - | -LL | fn expect_bound_supply_named<'x>() { - | -- lifetime `'x` defined here -... -LL | closure_expecting_bound(|x: &'x u32| { - | ^ requires that `'x` must outlive `'static` - | - = help: consider replacing `'x` with `'static` - -error: aborting due to 4 previous errors - diff --git a/src/test/ui/closures/closure-expected-type/expect-region-supply-region.rs b/src/test/ui/closures/closure-expected-type/expect-region-supply-region.rs index 28a6ab77a915e..55c6aa795c26a 100644 --- a/src/test/ui/closures/closure-expected-type/expect-region-supply-region.rs +++ b/src/test/ui/closures/closure-expected-type/expect-region-supply-region.rs @@ -1,12 +1,14 @@ #![allow(warnings)] fn closure_expecting_bound(_: F) - where F: FnOnce(&u32) +where + F: FnOnce(&u32), { } fn closure_expecting_free<'a, F>(_: F) - where F: FnOnce(&'a u32) +where + F: FnOnce(&'a u32), { } @@ -15,7 +17,7 @@ fn expect_bound_supply_nothing() { // it to escape into `f`: let mut f: Option<&u32> = None; closure_expecting_bound(|x| { - f = Some(x); //~ ERROR borrowed data cannot be stored outside of its closure + f = Some(x); //~ ERROR borrowed data escapes outside of closure }); } @@ -25,22 +27,7 @@ fn expect_bound_supply_bound() { // closure: let mut f: Option<&u32> = None; closure_expecting_bound(|x: &u32| { - f = Some(x); //~ ERROR borrowed data cannot be stored outside of its closure - }); -} - -fn expect_bound_supply_named<'x>() { - let mut f: Option<&u32> = None; - - // Here we give a type annotation that `x` should be free. We get - // an error because of that. - closure_expecting_bound(|x: &'x u32| { - //~^ ERROR mismatched types - //~| ERROR mismatched types - - // And we still cannot let `x` escape into `f`. - f = Some(x); - //~^ ERROR borrowed data cannot be stored outside of its closure + f = Some(x); //~ ERROR borrowed data escapes outside of closure }); } @@ -67,4 +54,4 @@ fn expect_free_supply_named<'x>() { closure_expecting_free(|x: &'x u32| f = Some(x)); // OK } -fn main() { } +fn main() {} diff --git a/src/test/ui/closures/closure-expected-type/expect-region-supply-region.stderr b/src/test/ui/closures/closure-expected-type/expect-region-supply-region.stderr index eb860f9aef243..213071abfffc3 100644 --- a/src/test/ui/closures/closure-expected-type/expect-region-supply-region.stderr +++ b/src/test/ui/closures/closure-expected-type/expect-region-supply-region.stderr @@ -1,87 +1,22 @@ -error: borrowed data cannot be stored outside of its closure - --> $DIR/expect-region-supply-region.rs:18:18 +error[E0521]: borrowed data escapes outside of closure + --> $DIR/expect-region-supply-region.rs:20:9 | LL | let mut f: Option<&u32> = None; - | ----- borrowed data cannot be stored into here... + | ----- `f` declared here, outside of the closure body LL | closure_expecting_bound(|x| { - | --- ...because it cannot outlive this closure + | - `x` is a reference that is only valid in the closure body LL | f = Some(x); - | ^ cannot be stored outside of its closure + | ^^^^^^^^^^^ `x` escapes the closure body here -error: borrowed data cannot be stored outside of its closure - --> $DIR/expect-region-supply-region.rs:28:18 +error[E0521]: borrowed data escapes outside of closure + --> $DIR/expect-region-supply-region.rs:30:9 | LL | let mut f: Option<&u32> = None; - | ----- borrowed data cannot be stored into here... + | ----- `f` declared here, outside of the closure body LL | closure_expecting_bound(|x: &u32| { - | --------- ...because it cannot outlive this closure + | - `x` is a reference that is only valid in the closure body LL | f = Some(x); - | ^ cannot be stored outside of its closure + | ^^^^^^^^^^^ `x` escapes the closure body here -error[E0308]: mismatched types - --> $DIR/expect-region-supply-region.rs:37:33 - | -LL | closure_expecting_bound(|x: &'x u32| { - | ^^^^^^^ lifetime mismatch - | - = note: expected reference `&u32` - found reference `&'x u32` -note: the anonymous lifetime #2 defined on the body at 37:29... - --> $DIR/expect-region-supply-region.rs:37:29 - | -LL | closure_expecting_bound(|x: &'x u32| { - | _____________________________^ -LL | | -LL | | -LL | | -... | -LL | | -LL | | }); - | |_____^ -note: ...does not necessarily outlive the lifetime `'x` as defined on the function body at 32:30 - --> $DIR/expect-region-supply-region.rs:32:30 - | -LL | fn expect_bound_supply_named<'x>() { - | ^^ - -error[E0308]: mismatched types - --> $DIR/expect-region-supply-region.rs:37:33 - | -LL | closure_expecting_bound(|x: &'x u32| { - | ^^^^^^^ lifetime mismatch - | - = note: expected reference `&u32` - found reference `&'x u32` -note: the lifetime `'x` as defined on the function body at 32:30... - --> $DIR/expect-region-supply-region.rs:32:30 - | -LL | fn expect_bound_supply_named<'x>() { - | ^^ -note: ...does not necessarily outlive the anonymous lifetime #2 defined on the body at 37:29 - --> $DIR/expect-region-supply-region.rs:37:29 - | -LL | closure_expecting_bound(|x: &'x u32| { - | _____________________________^ -LL | | -LL | | -LL | | -... | -LL | | -LL | | }); - | |_____^ - -error: borrowed data cannot be stored outside of its closure - --> $DIR/expect-region-supply-region.rs:42:18 - | -LL | let mut f: Option<&u32> = None; - | ----- borrowed data cannot be stored into here... -... -LL | closure_expecting_bound(|x: &'x u32| { - | ------------ ...because it cannot outlive this closure -... -LL | f = Some(x); - | ^ cannot be stored outside of its closure - -error: aborting due to 5 previous errors +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/error-codes/E0490.nll.stderr b/src/test/ui/error-codes/E0490.nll.stderr new file mode 100644 index 0000000000000..a1c33bbcd5f75 --- /dev/null +++ b/src/test/ui/error-codes/E0490.nll.stderr @@ -0,0 +1,28 @@ +error: lifetime may not live long enough + --> $DIR/E0490.rs:2:12 + | +LL | fn f<'a, 'b>(y: &'b ()) { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | let x: &'a _ = &y; + | ^^^^^ type annotation requires that `'b` must outlive `'a` + | + = help: consider adding the following bound: `'b: 'a` + +error[E0597]: `y` does not live long enough + --> $DIR/E0490.rs:2:20 + | +LL | fn f<'a, 'b>(y: &'b ()) { + | -- lifetime `'a` defined here +LL | let x: &'a _ = &y; + | ----- ^^ borrowed value does not live long enough + | | + | type annotation requires that `y` is borrowed for `'a` +... +LL | } + | - `y` dropped here while still borrowed + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/error-codes/E0490.rs b/src/test/ui/error-codes/E0490.rs new file mode 100644 index 0000000000000..36bafa2bd868c --- /dev/null +++ b/src/test/ui/error-codes/E0490.rs @@ -0,0 +1,8 @@ +fn f<'a, 'b>(y: &'b ()) { + let x: &'a _ = &y; + //~^ E0490 + //~| E0495 + //~| E0495 +} + +fn main() {} diff --git a/src/test/ui/error-codes/E0490.stderr b/src/test/ui/error-codes/E0490.stderr new file mode 100644 index 0000000000000..03fce213605e3 --- /dev/null +++ b/src/test/ui/error-codes/E0490.stderr @@ -0,0 +1,76 @@ +error[E0490]: a value of type `&'b ()` is borrowed for too long + --> $DIR/E0490.rs:2:20 + | +LL | let x: &'a _ = &y; + | ^^ + | +note: the type is valid for the lifetime `'a` as defined on the function body at 1:6 + --> $DIR/E0490.rs:1:6 + | +LL | fn f<'a, 'b>(y: &'b ()) { + | ^^ +note: but the borrow lasts for the lifetime `'b` as defined on the function body at 1:10 + --> $DIR/E0490.rs:1:10 + | +LL | fn f<'a, 'b>(y: &'b ()) { + | ^^ + +error[E0495]: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements + --> $DIR/E0490.rs:2:20 + | +LL | let x: &'a _ = &y; + | ^^ + | +note: first, the lifetime cannot outlive the lifetime `'b` as defined on the function body at 1:10... + --> $DIR/E0490.rs:1:10 + | +LL | fn f<'a, 'b>(y: &'b ()) { + | ^^ +note: ...so that the type `&'b ()` is not borrowed for too long + --> $DIR/E0490.rs:2:20 + | +LL | let x: &'a _ = &y; + | ^^ +note: but, the lifetime must be valid for the lifetime `'a` as defined on the function body at 1:6... + --> $DIR/E0490.rs:1:6 + | +LL | fn f<'a, 'b>(y: &'b ()) { + | ^^ +note: ...so that reference does not outlive borrowed content + --> $DIR/E0490.rs:2:20 + | +LL | let x: &'a _ = &y; + | ^^ + +error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements + --> $DIR/E0490.rs:2:20 + | +LL | let x: &'a _ = &y; + | ^^ + | +note: first, the lifetime cannot outlive the lifetime `'b` as defined on the function body at 1:10... + --> $DIR/E0490.rs:1:10 + | +LL | fn f<'a, 'b>(y: &'b ()) { + | ^^ +note: ...so that the expression is assignable + --> $DIR/E0490.rs:2:20 + | +LL | let x: &'a _ = &y; + | ^^ + = note: expected `&'a &()` + found `&'a &'b ()` +note: but, the lifetime must be valid for the lifetime `'a` as defined on the function body at 1:6... + --> $DIR/E0490.rs:1:6 + | +LL | fn f<'a, 'b>(y: &'b ()) { + | ^^ +note: ...so that the reference type `&'a &()` does not outlive the data it points at + --> $DIR/E0490.rs:2:12 + | +LL | let x: &'a _ = &y; + | ^^^^^ + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0495`. 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 deleted file mode 100644 index 5140d1a9a7add..0000000000000 --- a/src/test/ui/error-codes/E0621-does-not-trigger-for-closures.nll.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error: lifetime may not live long enough - --> $DIR/E0621-does-not-trigger-for-closures.rs:15:45 - | -LL | invoke(&x, |a, b| if a > b { a } else { b }); - | -- ^ returning this value requires that `'1` must outlive `'2` - | || - | |return type of closure is &'2 i32 - | has type `&'1 i32` - -error: aborting due to previous error - diff --git a/src/test/ui/error-codes/E0621-does-not-trigger-for-closures.rs b/src/test/ui/error-codes/E0621-does-not-trigger-for-closures.rs index c58744d386ca5..44f174c0fb76f 100644 --- a/src/test/ui/error-codes/E0621-does-not-trigger-for-closures.rs +++ b/src/test/ui/error-codes/E0621-does-not-trigger-for-closures.rs @@ -1,9 +1,7 @@ -// Test that we give the generic E0495 when one of the free regions is +// Test that we give the generic error when one of the free regions is // bound in a closure (rather than suggesting a change to the signature // of the closure, which is not specified in `foo` but rather in `invoke`). -// FIXME - This might be better as a UI test, but the finer details -// of the error seem to vary on different machines. fn invoke<'a, F>(x: &'a i32, f: F) -> &'a i32 where F: FnOnce(&'a i32, &i32) -> &'a i32 { @@ -12,7 +10,7 @@ where F: FnOnce(&'a i32, &i32) -> &'a i32 } fn foo<'a>(x: &'a i32) { - invoke(&x, |a, b| if a > b { a } else { b }); //~ ERROR E0495 + invoke(&x, |a, b| if a > b { a } else { b }); //~ ERROR lifetime may not live long enough } fn main() {} diff --git a/src/test/ui/error-codes/E0621-does-not-trigger-for-closures.stderr b/src/test/ui/error-codes/E0621-does-not-trigger-for-closures.stderr index feca7f10b706b..b9edeb8346bdc 100644 --- a/src/test/ui/error-codes/E0621-does-not-trigger-for-closures.stderr +++ b/src/test/ui/error-codes/E0621-does-not-trigger-for-closures.stderr @@ -1,30 +1,11 @@ -error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements - --> $DIR/E0621-does-not-trigger-for-closures.rs:15:5 +error: lifetime may not live long enough + --> $DIR/E0621-does-not-trigger-for-closures.rs:13:45 | LL | invoke(&x, |a, b| if a > b { a } else { b }); - | ^^^^^^ - | -note: first, the lifetime cannot outlive the anonymous lifetime #2 defined on the body at 15:16... - --> $DIR/E0621-does-not-trigger-for-closures.rs:15:16 - | -LL | invoke(&x, |a, b| if a > b { a } else { b }); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...so that reference does not outlive borrowed content - --> $DIR/E0621-does-not-trigger-for-closures.rs:15:45 - | -LL | invoke(&x, |a, b| if a > b { a } else { b }); - | ^ -note: but, the lifetime must be valid for the call at 15:5... - --> $DIR/E0621-does-not-trigger-for-closures.rs:15:5 - | -LL | invoke(&x, |a, b| if a > b { a } else { b }); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...so type `&i32` of expression is valid during the expression - --> $DIR/E0621-does-not-trigger-for-closures.rs:15:5 - | -LL | invoke(&x, |a, b| if a > b { a } else { b }); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | -- ^ returning this value requires that `'1` must outlive `'2` + | || + | |return type of closure is &'2 i32 + | has type `&'1 i32` error: aborting due to previous error -For more information about this error, try `rustc --explain E0495`. diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.stderr b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.stderr index cd2d46ac18218..b42ff1486f0a8 100644 --- a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.stderr +++ b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.stderr @@ -4,17 +4,11 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appea LL | fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'d, 'e> | ^^^^^^^^^^^^^^^^^^ | -note: hidden type `Ordinary<'_>` captures the scope of call-site for function at 23:1 - --> $DIR/ordinary-bounds-unrelated.rs:23:1 +note: hidden type `Ordinary<'_>` captures lifetime smaller than the function body + --> $DIR/ordinary-bounds-unrelated.rs:18:74 | -LL | / { -LL | | // Hidden type `Ordinary<'0>` with constraints: -LL | | // -LL | | // ``` -... | -LL | | if condition() { a } else { b } -LL | | } - | |_^ +LL | fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'d, 'e> + | ^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.stderr b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.stderr index 59ce93fa78b6b..254643c406cae 100644 --- a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.stderr +++ b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.stderr @@ -4,17 +4,11 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appea LL | fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b> | ^^^^^^^^^^^^^^^^^^ | -note: hidden type `Ordinary<'_>` captures the scope of call-site for function at 22:1 - --> $DIR/ordinary-bounds-unsuited.rs:22:1 +note: hidden type `Ordinary<'_>` captures lifetime smaller than the function body + --> $DIR/ordinary-bounds-unsuited.rs:20:62 | -LL | / { -LL | | // We return a value: -LL | | // -LL | | // ``` -... | -LL | | if condition() { a } else { b } -LL | | } - | |_^ +LL | fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b> + | ^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/regions/regions-close-object-into-object-5.rs b/src/test/ui/regions/regions-close-object-into-object-5.rs index 2921a2bb398c3..ff35b9ada45cd 100644 --- a/src/test/ui/regions/regions-close-object-into-object-5.rs +++ b/src/test/ui/regions/regions-close-object-into-object-5.rs @@ -6,22 +6,21 @@ trait A fn get(&self) -> T { panic!() } } -struct B<'a, T:'a>(&'a (A+'a)); +struct B<'a, T: 'a>(&'a (A + 'a)); trait X { fn foo(&self) {} } impl<'a, T> X for B<'a, T> {} -fn f<'a, T, U>(v: Box+'static>) -> Box { +fn f<'a, T, U>(v: Box + 'static>) -> Box { // oh dear! box B(&*v) as Box - //~^ ERROR the parameter type `T` may not live long enough - //~| ERROR the parameter type `T` may not live long enough - //~| ERROR the parameter type `T` may not live long enough - //~| ERROR the parameter type `T` may not live long enough - //~| ERROR the parameter type `T` may not live long enough - //~| ERROR the parameter type `T` may not live long enough - //~| ERROR the parameter type `T` may not live long enough + //~^ ERROR the parameter type `T` may not live long enough + //~| ERROR the parameter type `T` may not live long enough + //~| ERROR the parameter type `T` may not live long enough + //~| ERROR the parameter type `T` may not live long enough + //~| ERROR the parameter type `T` may not live long enough + //~| ERROR the parameter type `T` may not live long enough } fn main() {} diff --git a/src/test/ui/regions/regions-close-object-into-object-5.stderr b/src/test/ui/regions/regions-close-object-into-object-5.stderr index 14727000b2c24..2bcdcd1864e2f 100644 --- a/src/test/ui/regions/regions-close-object-into-object-5.stderr +++ b/src/test/ui/regions/regions-close-object-into-object-5.stderr @@ -1,7 +1,7 @@ error[E0310]: the parameter type `T` may not live long enough --> $DIR/regions-close-object-into-object-5.rs:17:5 | -LL | fn f<'a, T, U>(v: Box+'static>) -> Box { +LL | fn f<'a, T, U>(v: Box + 'static>) -> Box { | - help: consider adding an explicit lifetime bound...: `T: 'static` LL | // oh dear! LL | box B(&*v) as Box @@ -13,25 +13,10 @@ note: ...so that the type `B<'_, T>` will meet its required lifetime bounds LL | box B(&*v) as Box | ^^^^^^^^^^ -error[E0310]: the parameter type `T` may not live long enough - --> $DIR/regions-close-object-into-object-5.rs:17:5 - | -LL | fn f<'a, T, U>(v: Box+'static>) -> Box { - | - help: consider adding an explicit lifetime bound...: `T: 'static` -LL | // oh dear! -LL | box B(&*v) as Box - | ^^^^^^^^^^^^^^^^^^^^ - | -note: ...so that it can be closed over into an object - --> $DIR/regions-close-object-into-object-5.rs:17:5 - | -LL | box B(&*v) as Box - | ^^^^^^^^^^^^^^^^^^^^ - error[E0310]: the parameter type `T` may not live long enough --> $DIR/regions-close-object-into-object-5.rs:17:9 | -LL | fn f<'a, T, U>(v: Box+'static>) -> Box { +LL | fn f<'a, T, U>(v: Box + 'static>) -> Box { | - help: consider adding an explicit lifetime bound...: `T: 'static` LL | // oh dear! LL | box B(&*v) as Box @@ -46,7 +31,7 @@ LL | box B(&*v) as Box error[E0310]: the parameter type `T` may not live long enough --> $DIR/regions-close-object-into-object-5.rs:17:9 | -LL | fn f<'a, T, U>(v: Box+'static>) -> Box { +LL | fn f<'a, T, U>(v: Box + 'static>) -> Box { | - help: consider adding an explicit lifetime bound...: `T: 'static` LL | // oh dear! LL | box B(&*v) as Box @@ -61,7 +46,7 @@ LL | box B(&*v) as Box error[E0310]: the parameter type `T` may not live long enough --> $DIR/regions-close-object-into-object-5.rs:17:11 | -LL | fn f<'a, T, U>(v: Box+'static>) -> Box { +LL | fn f<'a, T, U>(v: Box + 'static>) -> Box { | - help: consider adding an explicit lifetime bound...: `T: 'static` LL | // oh dear! LL | box B(&*v) as Box @@ -76,7 +61,7 @@ LL | box B(&*v) as Box error[E0310]: the parameter type `T` may not live long enough --> $DIR/regions-close-object-into-object-5.rs:17:11 | -LL | fn f<'a, T, U>(v: Box+'static>) -> Box { +LL | fn f<'a, T, U>(v: Box + 'static>) -> Box { | - help: consider adding an explicit lifetime bound...: `T: 'static` LL | // oh dear! LL | box B(&*v) as Box @@ -91,7 +76,7 @@ LL | box B(&*v) as Box error[E0310]: the parameter type `T` may not live long enough --> $DIR/regions-close-object-into-object-5.rs:17:11 | -LL | fn f<'a, T, U>(v: Box+'static>) -> Box { +LL | fn f<'a, T, U>(v: Box + 'static>) -> Box { | - help: consider adding an explicit lifetime bound...: `T: 'static` LL | // oh dear! LL | box B(&*v) as Box @@ -103,6 +88,6 @@ note: ...so that the type `(dyn A + 'static)` is not borrowed for too long LL | box B(&*v) as Box | ^^^ -error: aborting due to 7 previous errors +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0310`. diff --git a/src/test/ui/regions/regions-close-over-type-parameter-1.nll.stderr b/src/test/ui/regions/regions-close-over-type-parameter-1.nll.stderr index 7d3d51bdb437e..3101d815881b1 100644 --- a/src/test/ui/regions/regions-close-over-type-parameter-1.nll.stderr +++ b/src/test/ui/regions/regions-close-over-type-parameter-1.nll.stderr @@ -1,5 +1,5 @@ error[E0310]: the parameter type `A` may not live long enough - --> $DIR/regions-close-over-type-parameter-1.rs:10:5 + --> $DIR/regions-close-over-type-parameter-1.rs:12:5 | LL | box v as Box | ^^^^^ @@ -7,7 +7,7 @@ LL | box v as Box = help: consider adding an explicit lifetime bound `A: 'static`... error[E0309]: the parameter type `A` may not live long enough - --> $DIR/regions-close-over-type-parameter-1.rs:20:5 + --> $DIR/regions-close-over-type-parameter-1.rs:21:5 | LL | box v as Box | ^^^^^ diff --git a/src/test/ui/regions/regions-close-over-type-parameter-1.rs b/src/test/ui/regions/regions-close-over-type-parameter-1.rs index 6a9aa66a446c3..6e708a5f70fbd 100644 --- a/src/test/ui/regions/regions-close-over-type-parameter-1.rs +++ b/src/test/ui/regions/regions-close-over-type-parameter-1.rs @@ -4,22 +4,22 @@ // an object. This should yield errors unless `A` (and the object) // both have suitable bounds. -trait SomeTrait { fn get(&self) -> isize; } +trait SomeTrait { + fn get(&self) -> isize; +} -fn make_object1(v: A) -> Box { +fn make_object1(v: A) -> Box { box v as Box - //~^ ERROR the parameter type `A` may not live long enough - //~| ERROR the parameter type `A` may not live long enough + //~^ ERROR the parameter type `A` may not live long enough } -fn make_object2<'a,A:SomeTrait+'a>(v: A) -> Box { +fn make_object2<'a, A: SomeTrait + 'a>(v: A) -> Box { box v as Box } -fn make_object3<'a,'b,A:SomeTrait+'a>(v: A) -> Box { +fn make_object3<'a, 'b, A: SomeTrait + 'a>(v: A) -> Box { box v as Box - //~^ ERROR the parameter type `A` may not live long enough - //~| ERROR the parameter type `A` may not live long enough + //~^ ERROR the parameter type `A` may not live long enough } -fn main() { } +fn main() {} diff --git a/src/test/ui/regions/regions-close-over-type-parameter-1.stderr b/src/test/ui/regions/regions-close-over-type-parameter-1.stderr index ed9a604e717dd..a7509cb608c6b 100644 --- a/src/test/ui/regions/regions-close-over-type-parameter-1.stderr +++ b/src/test/ui/regions/regions-close-over-type-parameter-1.stderr @@ -1,60 +1,32 @@ error[E0310]: the parameter type `A` may not live long enough - --> $DIR/regions-close-over-type-parameter-1.rs:10:5 + --> $DIR/regions-close-over-type-parameter-1.rs:12:5 | -LL | fn make_object1(v: A) -> Box { +LL | fn make_object1(v: A) -> Box { | -- help: consider adding an explicit lifetime bound...: `A: 'static +` LL | box v as Box | ^^^^^ | note: ...so that the type `A` will meet its required lifetime bounds - --> $DIR/regions-close-over-type-parameter-1.rs:10:5 + --> $DIR/regions-close-over-type-parameter-1.rs:12:5 | LL | box v as Box | ^^^^^ -error[E0310]: the parameter type `A` may not live long enough - --> $DIR/regions-close-over-type-parameter-1.rs:10:5 - | -LL | fn make_object1(v: A) -> Box { - | -- help: consider adding an explicit lifetime bound...: `A: 'static +` -LL | box v as Box - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: ...so that it can be closed over into an object - --> $DIR/regions-close-over-type-parameter-1.rs:10:5 - | -LL | box v as Box - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - error[E0309]: the parameter type `A` may not live long enough - --> $DIR/regions-close-over-type-parameter-1.rs:20:5 + --> $DIR/regions-close-over-type-parameter-1.rs:21:5 | -LL | fn make_object3<'a,'b,A:SomeTrait+'a>(v: A) -> Box { - | -- help: consider adding an explicit lifetime bound...: `A: 'b +` +LL | fn make_object3<'a, 'b, A: SomeTrait + 'a>(v: A) -> Box { + | -- help: consider adding an explicit lifetime bound...: `A: 'b +` LL | box v as Box | ^^^^^ | note: ...so that the type `A` will meet its required lifetime bounds - --> $DIR/regions-close-over-type-parameter-1.rs:20:5 + --> $DIR/regions-close-over-type-parameter-1.rs:21:5 | LL | box v as Box | ^^^^^ -error[E0309]: the parameter type `A` may not live long enough - --> $DIR/regions-close-over-type-parameter-1.rs:20:5 - | -LL | fn make_object3<'a,'b,A:SomeTrait+'a>(v: A) -> Box { - | -- help: consider adding an explicit lifetime bound...: `A: 'b +` -LL | box v as Box - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: ...so that it can be closed over into an object - --> $DIR/regions-close-over-type-parameter-1.rs:20:5 - | -LL | box v as Box - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors Some errors have detailed explanations: E0309, E0310. For more information about an error, try `rustc --explain E0309`. diff --git a/src/test/ui/regions/regions-escape-method.nll.stderr b/src/test/ui/regions/regions-escape-method.nll.stderr deleted file mode 100644 index 9f425125b9896..0000000000000 --- a/src/test/ui/regions/regions-escape-method.nll.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error: lifetime may not live long enough - --> $DIR/regions-escape-method.rs:15:13 - | -LL | s.f(|p| p) - | -- ^ returning this value requires that `'1` must outlive `'2` - | || - | |return type of closure is &'2 i32 - | has type `&'1 i32` - -error: aborting due to previous error - diff --git a/src/test/ui/regions/regions-escape-method.rs b/src/test/ui/regions/regions-escape-method.rs index 5127d4d1ceb0f..69c01ae6906cb 100644 --- a/src/test/ui/regions/regions-escape-method.rs +++ b/src/test/ui/regions/regions-escape-method.rs @@ -12,5 +12,5 @@ impl S { fn main() { let s = S; - s.f(|p| p) //~ ERROR cannot infer + s.f(|p| p) //~ ERROR lifetime may not live long enough } diff --git a/src/test/ui/regions/regions-escape-method.stderr b/src/test/ui/regions/regions-escape-method.stderr index ffc2a259485aa..9f425125b9896 100644 --- a/src/test/ui/regions/regions-escape-method.stderr +++ b/src/test/ui/regions/regions-escape-method.stderr @@ -1,32 +1,11 @@ -error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements +error: lifetime may not live long enough --> $DIR/regions-escape-method.rs:15:13 | LL | s.f(|p| p) - | ^ - | -note: first, the lifetime cannot outlive the anonymous lifetime #2 defined on the body at 15:9... - --> $DIR/regions-escape-method.rs:15:9 - | -LL | s.f(|p| p) - | ^^^^^ -note: ...so that the expression is assignable - --> $DIR/regions-escape-method.rs:15:13 - | -LL | s.f(|p| p) - | ^ - = note: expected `&i32` - found `&i32` -note: but, the lifetime must be valid for the method call at 15:5... - --> $DIR/regions-escape-method.rs:15:5 - | -LL | s.f(|p| p) - | ^^^^^^^^^^ -note: ...so that a type/lifetime parameter is in scope here - --> $DIR/regions-escape-method.rs:15:5 - | -LL | s.f(|p| p) - | ^^^^^^^^^^ + | -- ^ returning this value requires that `'1` must outlive `'2` + | || + | |return type of closure is &'2 i32 + | has type `&'1 i32` error: aborting due to previous error -For more information about this error, try `rustc --explain E0495`. diff --git a/src/test/ui/regions/regions-escape-via-trait-or-not.nll.stderr b/src/test/ui/regions/regions-escape-via-trait-or-not.nll.stderr deleted file mode 100644 index cae6c33ac6e17..0000000000000 --- a/src/test/ui/regions/regions-escape-via-trait-or-not.nll.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error: lifetime may not live long enough - --> $DIR/regions-escape-via-trait-or-not.rs:18:14 - | -LL | with(|o| o) - | -- ^ returning this value requires that `'1` must outlive `'2` - | || - | |return type of closure is &'2 isize - | has type `&'1 isize` - -error: aborting due to previous error - diff --git a/src/test/ui/regions/regions-escape-via-trait-or-not.rs b/src/test/ui/regions/regions-escape-via-trait-or-not.rs index 1e089616f5997..ac0e56de4a030 100644 --- a/src/test/ui/regions/regions-escape-via-trait-or-not.rs +++ b/src/test/ui/regions/regions-escape-via-trait-or-not.rs @@ -15,7 +15,7 @@ fn with(f: F) -> isize where F: FnOnce(&isize) -> R { } fn return_it() -> isize { - with(|o| o) //~ ERROR cannot infer + with(|o| o) //~ ERROR lifetime may not live long enough } fn main() { diff --git a/src/test/ui/regions/regions-escape-via-trait-or-not.stderr b/src/test/ui/regions/regions-escape-via-trait-or-not.stderr index 90823464c56d2..cae6c33ac6e17 100644 --- a/src/test/ui/regions/regions-escape-via-trait-or-not.stderr +++ b/src/test/ui/regions/regions-escape-via-trait-or-not.stderr @@ -1,32 +1,11 @@ -error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements +error: lifetime may not live long enough --> $DIR/regions-escape-via-trait-or-not.rs:18:14 | LL | with(|o| o) - | ^ - | -note: first, the lifetime cannot outlive the anonymous lifetime #2 defined on the body at 18:10... - --> $DIR/regions-escape-via-trait-or-not.rs:18:10 - | -LL | with(|o| o) - | ^^^^^ -note: ...so that the expression is assignable - --> $DIR/regions-escape-via-trait-or-not.rs:18:14 - | -LL | with(|o| o) - | ^ - = note: expected `&isize` - found `&isize` -note: but, the lifetime must be valid for the expression at 18:5... - --> $DIR/regions-escape-via-trait-or-not.rs:18:5 - | -LL | with(|o| o) - | ^^^^ -note: ...so type `fn([closure@$DIR/regions-escape-via-trait-or-not.rs:18:10: 18:15]) -> isize {with::<&isize, [closure@$DIR/regions-escape-via-trait-or-not.rs:18:10: 18:15]>}` of expression is valid during the expression - --> $DIR/regions-escape-via-trait-or-not.rs:18:5 - | -LL | with(|o| o) - | ^^^^ + | -- ^ returning this value requires that `'1` must outlive `'2` + | || + | |return type of closure is &'2 isize + | has type `&'1 isize` error: aborting due to previous error -For more information about this error, try `rustc --explain E0495`. diff --git a/src/test/ui/regions/regions-infer-call-3.nll.stderr b/src/test/ui/regions/regions-infer-call-3.nll.stderr deleted file mode 100644 index ca51555a07749..0000000000000 --- a/src/test/ui/regions/regions-infer-call-3.nll.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error: lifetime may not live long enough - --> $DIR/regions-infer-call-3.rs:8:24 - | -LL | let z = with(|y| { select(x, y) }); - | -- ^^^^^^^^^^^^ returning this value requires that `'1` must outlive `'2` - | || - | |return type of closure is &'2 isize - | has type `&'1 isize` - -error: aborting due to previous error - diff --git a/src/test/ui/regions/regions-infer-call-3.rs b/src/test/ui/regions/regions-infer-call-3.rs index a76fccbdc5218..063ec84288d1f 100644 --- a/src/test/ui/regions/regions-infer-call-3.rs +++ b/src/test/ui/regions/regions-infer-call-3.rs @@ -6,7 +6,7 @@ fn with(f: F) -> T where F: FnOnce(&isize) -> T { fn manip<'a>(x: &'a isize) -> isize { let z = with(|y| { select(x, y) }); - //~^ ERROR cannot infer + //~^ ERROR lifetime may not live long enough *z } diff --git a/src/test/ui/regions/regions-infer-call-3.stderr b/src/test/ui/regions/regions-infer-call-3.stderr index 1d6dbdb2c7b57..ca51555a07749 100644 --- a/src/test/ui/regions/regions-infer-call-3.stderr +++ b/src/test/ui/regions/regions-infer-call-3.stderr @@ -1,30 +1,11 @@ -error[E0495]: cannot infer an appropriate lifetime for lifetime parameter 'r in function call due to conflicting requirements +error: lifetime may not live long enough --> $DIR/regions-infer-call-3.rs:8:24 | LL | let z = with(|y| { select(x, y) }); - | ^^^^^^^^^^^^ - | -note: first, the lifetime cannot outlive the anonymous lifetime #2 defined on the body at 8:18... - --> $DIR/regions-infer-call-3.rs:8:18 - | -LL | let z = with(|y| { select(x, y) }); - | ^^^^^^^^^^^^^^^^^^^^ -note: ...so that reference does not outlive borrowed content - --> $DIR/regions-infer-call-3.rs:8:34 - | -LL | let z = with(|y| { select(x, y) }); - | ^ -note: but, the lifetime must be valid for the call at 8:13... - --> $DIR/regions-infer-call-3.rs:8:13 - | -LL | let z = with(|y| { select(x, y) }); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...so type `&isize` of expression is valid during the expression - --> $DIR/regions-infer-call-3.rs:8:13 - | -LL | let z = with(|y| { select(x, y) }); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | -- ^^^^^^^^^^^^ returning this value requires that `'1` must outlive `'2` + | || + | |return type of closure is &'2 isize + | has type `&'1 isize` error: aborting due to previous error -For more information about this error, try `rustc --explain E0495`. diff --git a/src/test/ui/regions/regions-return-ref-to-upvar-issue-17403.nll.stderr b/src/test/ui/regions/regions-return-ref-to-upvar-issue-17403.nll.stderr deleted file mode 100644 index 4c275b19492c6..0000000000000 --- a/src/test/ui/regions/regions-return-ref-to-upvar-issue-17403.nll.stderr +++ /dev/null @@ -1,13 +0,0 @@ -error: captured variable cannot escape `FnMut` closure body - --> $DIR/regions-return-ref-to-upvar-issue-17403.rs:7:24 - | -LL | let mut f = || &mut x; - | - ^^^^^^ returns a reference to a captured variable which escapes the closure body - | | - | inferred to be a `FnMut` closure - | - = note: `FnMut` closures only have access to their captured variables while they are executing... - = note: ...therefore, they cannot allow references to captured variables to escape - -error: aborting due to previous error - diff --git a/src/test/ui/regions/regions-return-ref-to-upvar-issue-17403.rs b/src/test/ui/regions/regions-return-ref-to-upvar-issue-17403.rs index afe87f47eadbe..86e759f088a54 100644 --- a/src/test/ui/regions/regions-return-ref-to-upvar-issue-17403.rs +++ b/src/test/ui/regions/regions-return-ref-to-upvar-issue-17403.rs @@ -4,7 +4,7 @@ fn main() { // Unboxed closure case { let mut x = 0; - let mut f = || &mut x; //~ ERROR cannot infer + let mut f = || &mut x; //~ ERROR captured variable cannot escape `FnMut` closure body let x = f(); let y = f(); } diff --git a/src/test/ui/regions/regions-return-ref-to-upvar-issue-17403.stderr b/src/test/ui/regions/regions-return-ref-to-upvar-issue-17403.stderr index 946465bcb5f26..4c275b19492c6 100644 --- a/src/test/ui/regions/regions-return-ref-to-upvar-issue-17403.stderr +++ b/src/test/ui/regions/regions-return-ref-to-upvar-issue-17403.stderr @@ -1,30 +1,13 @@ -error[E0495]: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements +error: captured variable cannot escape `FnMut` closure body --> $DIR/regions-return-ref-to-upvar-issue-17403.rs:7:24 | LL | let mut f = || &mut x; - | ^^^^^^ + | - ^^^^^^ returns a reference to a captured variable which escapes the closure body + | | + | inferred to be a `FnMut` closure | -note: first, the lifetime cannot outlive the lifetime `'_` as defined on the body at 7:21... - --> $DIR/regions-return-ref-to-upvar-issue-17403.rs:7:21 - | -LL | let mut f = || &mut x; - | ^^^^^^^^^ -note: ...so that closure can access `x` - --> $DIR/regions-return-ref-to-upvar-issue-17403.rs:7:24 - | -LL | let mut f = || &mut x; - | ^^^^^^ -note: but, the lifetime must be valid for the call at 9:17... - --> $DIR/regions-return-ref-to-upvar-issue-17403.rs:9:17 - | -LL | let y = f(); - | ^^^ -note: ...so type `&mut i32` of expression is valid during the expression - --> $DIR/regions-return-ref-to-upvar-issue-17403.rs:9:17 - | -LL | let y = f(); - | ^^^ + = note: `FnMut` closures only have access to their captured variables while they are executing... + = note: ...therefore, they cannot allow references to captured variables to escape error: aborting due to previous error -For more information about this error, try `rustc --explain E0495`. diff --git a/src/test/ui/symbol-names/impl1.rs b/src/test/ui/symbol-names/impl1.rs index 1f689a5bd2541..cdcf89e4e614e 100644 --- a/src/test/ui/symbol-names/impl1.rs +++ b/src/test/ui/symbol-names/impl1.rs @@ -3,8 +3,8 @@ // revisions: legacy v0 //[legacy]compile-flags: -Z symbol-mangling-version=legacy //[v0]compile-flags: -Z symbol-mangling-version=v0 -//[legacy]normalize-stderr-32bit: "hdb62078998ce7ea8" -> "SYMBOL_HASH" -//[legacy]normalize-stderr-64bit: "h62e540f14f879d56" -> "SYMBOL_HASH" +//[legacy]normalize-stderr-32bit: "h5ef5dfc14aeecbfc" -> "SYMBOL_HASH" +//[legacy]normalize-stderr-64bit: "h9e54d216f70fcbc5" -> "SYMBOL_HASH" #![feature(optin_builtin_traits, rustc_attrs)] #![allow(dead_code)]