From 6d4c2141b5042bd9469005444987f5fb3f20fa73 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Sun, 7 May 2017 19:57:51 +0300 Subject: [PATCH] rustc: use DefId instead of CodeExtent for FreeRegion's scope. --- src/librustc/ich/impls_ty.rs | 7 +-- src/librustc/infer/error_reporting/mod.rs | 2 +- src/librustc/infer/mod.rs | 2 +- src/librustc/infer/region_inference/mod.rs | 27 +++++----- src/librustc/middle/free_region.rs | 9 ++-- src/librustc/middle/liveness.rs | 4 +- src/librustc/middle/mem_categorization.rs | 2 +- src/librustc/middle/region.rs | 25 +++------- src/librustc/middle/resolve_lifetime.rs | 9 ++-- src/librustc/traits/object_safety.rs | 2 +- src/librustc/ty/context.rs | 14 ------ src/librustc/ty/fold.rs | 4 +- src/librustc/ty/mod.rs | 49 +++---------------- src/librustc/ty/sty.rs | 10 ++-- src/librustc/util/ppaux.rs | 4 +- .../borrowck/gather_loans/mod.rs | 4 +- src/librustc_driver/test.rs | 28 +++++------ src/librustc_mir/build/mod.rs | 5 +- src/librustc_mir/hair/cx/expr.rs | 20 ++------ src/librustc_typeck/astconv.rs | 2 +- src/librustc_typeck/check/closure.rs | 3 +- src/librustc_typeck/check/compare_method.rs | 6 +-- src/librustc_typeck/check/mod.rs | 34 ++++++++++--- src/librustc_typeck/check/regionck.rs | 4 +- src/librustc_typeck/check/wfcheck.rs | 19 +++---- src/test/compile-fail/issue-37884.rs | 4 +- ...x1-return-one-existing-name-if-else.stderr | 14 +++--- .../ex2a-push-one-existing-name.stderr | 14 +++--- .../ex2b-push-no-existing-names.stderr | 14 +++--- .../ex2c-push-inference-variable.stderr | 14 +++--- .../ex2d-push-inference-variable-2.stderr | 14 +++--- .../ex2e-push-inference-variable-3.stderr | 14 +++--- 32 files changed, 149 insertions(+), 234 deletions(-) diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index 52bdb5d0240..f822361198f 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -409,11 +409,6 @@ fn hash_stable(&self, Free(call_site_scope_data, decl) }); -impl_stable_hash_for!(struct ::middle::region::CallSiteScopeData { - fn_id, - body_id -}); - impl_stable_hash_for!(struct ty::DebruijnIndex { depth }); @@ -466,7 +461,7 @@ fn hash_stable(&self, custom_kind }); -impl_stable_hash_for!(struct ty::FreeRegion<'tcx> { +impl_stable_hash_for!(struct ty::FreeRegion { scope, bound_region }); diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 4c27bade0f7..389103e203e 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -184,7 +184,7 @@ fn explain_span<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, } }; - let node = fr.scope.map(|s| s.node_id()) + let node = self.hir.as_local_node_id(fr.scope) .unwrap_or(DUMMY_NODE_ID); let unknown; let tag = match self.hir.find(node) { diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index 7959a38f26e..23d720433c2 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -1009,7 +1009,7 @@ pub fn probe(&self, f: F) -> R where } pub fn add_given(&self, - sub: ty::FreeRegion<'tcx>, + sub: ty::FreeRegion, sup: ty::RegionVid) { self.region_vars.add_given(sub, sup); diff --git a/src/librustc/infer/region_inference/mod.rs b/src/librustc/infer/region_inference/mod.rs index 39554d1fa3a..4c82c3bfb85 100644 --- a/src/librustc/infer/region_inference/mod.rs +++ b/src/librustc/infer/region_inference/mod.rs @@ -127,7 +127,7 @@ pub enum UndoLogEntry<'tcx> { AddVerify(usize), /// We added the given `given` - AddGiven(ty::FreeRegion<'tcx>, ty::RegionVid), + AddGiven(ty::FreeRegion, ty::RegionVid), /// We added a GLB/LUB "combinaton variable" AddCombination(CombineMapType, TwoRegions<'tcx>), @@ -213,7 +213,7 @@ pub struct RegionVarBindings<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { // record the fact that `'a <= 'b` is implied by the fn signature, // and then ignore the constraint when solving equations. This is // a bit of a hack but seems to work. - givens: RefCell, ty::RegionVid)>>, + givens: RefCell>, lubs: RefCell>, glbs: RefCell>, @@ -661,7 +661,7 @@ fn add_verify(&self, verify: Verify<'tcx>) { } } - pub fn add_given(&self, sub: ty::FreeRegion<'tcx>, sup: ty::RegionVid) { + pub fn add_given(&self, sub: ty::FreeRegion, sup: ty::RegionVid) { // cannot add givens once regions are resolved assert!(self.values_are_none()); @@ -931,19 +931,18 @@ fn lub_concrete_regions(&self, b); } - (&ReFree(fr), &ReScope(s_id)) | - (&ReScope(s_id), &ReFree(fr)) => { + (&ReFree(ref fr), &ReScope(s_id)) | + (&ReScope(s_id), &ReFree(ref fr)) => { // A "free" region can be interpreted as "some region - // at least as big as the block fr.scope_id". So, we can + // at least as big as fr.scope". So, we can // reasonably compare free regions and scopes: - if let Some(fr_scope) = fr.scope { - let r_id = region_rels.region_maps.nearest_common_ancestor(fr_scope, s_id); - if r_id == fr_scope { - // if the free region's scope `fr.scope_id` is bigger than - // the scope region `s_id`, then the LUB is the free - // region itself: - return self.tcx.mk_region(ReFree(fr)); - } + let fr_scope = region_rels.region_maps.free_extent(self.tcx, fr); + let r_id = region_rels.region_maps.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: + return self.tcx.mk_region(ReFree(*fr)); } // otherwise, we don't know what the free region is, diff --git a/src/librustc/middle/free_region.rs b/src/librustc/middle/free_region.rs index 2dc7aac04ae..e0d13878f14 100644 --- a/src/librustc/middle/free_region.rs +++ b/src/librustc/middle/free_region.rs @@ -71,12 +71,9 @@ pub fn is_subregion_of(&self, (&ty::ReScope(sub_scope), &ty::ReScope(super_scope)) => self.region_maps.is_subscope_of(sub_scope, super_scope), - (&ty::ReScope(sub_scope), &ty::ReFree(fr)) => { - // 1. It is safe to unwrap `fr.scope` because we - // should only ever wind up comparing against - // `ReScope` in the context of a method or - // body, where `fr.scope` should be `Some`. - self.region_maps.is_subscope_of(sub_scope, fr.scope.unwrap() /*1*/) || + (&ty::ReScope(sub_scope), &ty::ReFree(ref fr)) => { + let fr_scope = self.region_maps.free_extent(self.tcx, fr); + self.region_maps.is_subscope_of(sub_scope, fr_scope) || self.is_static(super_region) } diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 3acbc15f331..732fb054bc4 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -1440,9 +1440,7 @@ fn check_ret(&self, // within the fn body, late-bound regions are liberated // and must outlive the *call-site* of the function. let fn_ret = - self.ir.tcx.liberate_late_bound_regions( - Some(self.ir.tcx.call_site_extent(id)), - &fn_ret); + self.ir.tcx.liberate_late_bound_regions(def_id, &fn_ret); if !fn_ret.is_never() && self.live_on_entry(entry_ln, self.s.no_ret_var).is_some() { let param_env = self.ir.tcx.parameter_environment(def_id); diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index c489689d588..8e25c6facf2 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -790,7 +790,7 @@ fn env_deref(&self, // The environment of a closure is guaranteed to // outlive any bindings introduced in the body of the // closure itself. - scope: Some(self.tcx().call_site_extent(upvar_id.closure_expr_id)), + scope: self.tcx().hir.local_def_id(upvar_id.closure_expr_id), bound_region: ty::BrEnv })); diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index 087ab4b94da..3f707ac95f7 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -120,23 +120,6 @@ pub enum CodeExtentData { Remainder(BlockRemainder) } -/// extent of call-site for a function/method. -#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, RustcEncodable, - RustcDecodable, Debug, Copy)] -pub struct CallSiteScopeData { - pub fn_id: ast::NodeId, pub body_id: ast::NodeId, -} - -impl CallSiteScopeData { - pub fn to_code_extent<'a, 'tcx, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> CodeExtent<'tcx> { - tcx.intern_code_extent( - match *self { - CallSiteScopeData { fn_id, body_id } => - CodeExtentData::CallSiteScope { fn_id: fn_id, body_id: body_id }, - }) - } -} - /// Represents a subscope of `block` for a binding that is introduced /// by `block.stmts[first_statement_index]`. Such subscopes represent /// a suffix of the block. Note that each subscope does not include @@ -612,6 +595,14 @@ fn ancestors_of<'a, 'tcx>(scope_map: &FxHashMap, CodeExtent<'tc } } } + + /// Assuming that the provided region was defined within this `RegionMaps`, + /// returns the outermost `CodeExtent` that the region outlives. + pub fn free_extent<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, fr: &ty::FreeRegion) + -> CodeExtent<'tcx> { + let scope_id = tcx.hir.as_local_node_id(fr.scope).unwrap(); + tcx.call_site_extent(scope_id) + } } /// Records the lifetime of a local variable as `cx.var_parent` diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index 67b8dfb2d8e..55770efa9ad 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -19,7 +19,6 @@ use session::Session; use hir::def::Def; use hir::def_id::DefId; -use middle::region; use ty; use std::cell::Cell; @@ -42,7 +41,7 @@ pub enum Region { EarlyBound(/* index */ u32, /* lifetime decl */ ast::NodeId), LateBound(ty::DebruijnIndex, /* lifetime decl */ ast::NodeId), LateBoundAnon(ty::DebruijnIndex, /* anon index */ u32), - Free(region::CallSiteScopeData, /* lifetime decl */ ast::NodeId), + Free(DefId, /* lifetime decl */ ast::NodeId), } impl Region { @@ -897,9 +896,6 @@ fn resolve_lifetime_ref(&mut self, lifetime_ref: &hir::Lifetime) { if let Some(mut def) = result { if let Some(body_id) = outermost_body { let fn_id = self.hir_map.body_owner(body_id); - let scope_data = region::CallSiteScopeData { - fn_id: fn_id, body_id: body_id.node_id - }; match self.hir_map.get(fn_id) { hir::map::NodeItem(&hir::Item { node: hir::ItemFn(..), .. @@ -910,7 +906,8 @@ fn resolve_lifetime_ref(&mut self, lifetime_ref: &hir::Lifetime) { hir::map::NodeImplItem(&hir::ImplItem { node: hir::ImplItemKind::Method(..), .. }) => { - def = Region::Free(scope_data, def.id().unwrap()); + let scope = self.hir_map.local_def_id(fn_id); + def = Region::Free(scope, def.id().unwrap()); } _ => {} } diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index ea1a2f9a982..dbc1f070af8 100644 --- a/src/librustc/traits/object_safety.rs +++ b/src/librustc/traits/object_safety.rs @@ -206,7 +206,7 @@ fn generics_require_sized_self(self, def_id: DefId) -> bool { }; // Search for a predicate like `Self : Sized` amongst the trait bounds. - let free_substs = self.construct_free_substs(def_id, None); + let free_substs = self.construct_free_substs(def_id); let predicates = self.predicates_of(def_id); let predicates = predicates.instantiate(self, free_substs).predicates; elaborate_predicates(self, predicates) diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 54081c613cb..d69a9b3a8ce 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -655,11 +655,6 @@ pub fn node_extent(self, n: ast::NodeId) -> CodeExtent<'gcx> { self.intern_code_extent(CodeExtentData::Misc(n)) } - // Returns the code extent for an item - the destruction scope. - pub fn item_extent(self, n: ast::NodeId) -> CodeExtent<'gcx> { - self.intern_code_extent(CodeExtentData::DestructionScope(n)) - } - pub fn call_site_extent(self, fn_id: ast::NodeId) -> CodeExtent<'gcx> { self.intern_code_extent(CodeExtentData::CallSiteScope { fn_id, @@ -852,15 +847,6 @@ fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<&'tcx Sub } } -impl<'a, 'tcx> Lift<'tcx> for ty::FreeRegion<'a> { - type Lifted = ty::FreeRegion<'tcx>; - fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option { - let scope = self.scope.map(|code_extent| tcx.intern_code_extent(*code_extent)); - let bound_region = self.bound_region; - Some(ty::FreeRegion { scope, bound_region }) - } -} - impl<'a, 'tcx> Lift<'tcx> for Region<'a> { type Lifted = Region<'tcx>; fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option> { diff --git a/src/librustc/ty/fold.rs b/src/librustc/ty/fold.rs index 21ccf6f987b..fc20b1bee4e 100644 --- a/src/librustc/ty/fold.rs +++ b/src/librustc/ty/fold.rs @@ -39,7 +39,7 @@ //! These methods return true to indicate that the visitor has found what it is looking for //! and does not need to visit anything else. -use middle::region; +use hir::def_id::DefId; use ty::subst::Substs; use ty::adjustment; use ty::{self, Binder, Ty, TyCtxt, TypeFlags}; @@ -330,7 +330,7 @@ pub fn replace_late_bound_regions(self, /// Replace any late-bound regions bound in `value` with free variants attached to scope-id /// `scope_id`. pub fn liberate_late_bound_regions(self, - all_outlive_scope: Option>, + all_outlive_scope: DefId, value: &Binder) -> T where T : TypeFoldable<'tcx> diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 0f20d2361c6..4b10ec67def 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -23,7 +23,6 @@ use middle::const_val::ConstVal; use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem}; use middle::privacy::AccessLevels; -use middle::region::CodeExtent; use middle::resolve_lifetime::ObjectLifetimeDefault; use mir::Mir; use traits; @@ -1244,28 +1243,11 @@ pub struct ParameterEnvironment<'tcx> { /// See `construct_free_substs` for details. pub free_substs: &'tcx Substs<'tcx>, - /// Each type parameter has an implicit region bound that - /// indicates it must outlive at least the function body (the user - /// may specify stronger requirements). This field indicates the - /// region of the callee. If it is `None`, then the parameter - /// environment is for an item or something where the "callee" is - /// not clear. - pub implicit_region_bound: Option>, - /// Obligations that the caller must satisfy. This is basically /// the set of bounds on the in-scope type parameters, translated /// into Obligations, and elaborated and normalized. pub caller_bounds: &'tcx [ty::Predicate<'tcx>], - /// Scope that is attached to free regions for this scope. This is - /// usually the id of the fn body, but for more abstract scopes - /// like structs we use None or the item extent. - /// - /// FIXME(#3696). It would be nice to refactor so that free - /// regions don't have this implicit scope and instead introduce - /// relationships in the environment. - pub free_id_outlive: Option>, - /// A cache for `moves_by_default`. pub is_copy_cache: RefCell, bool>>, @@ -1283,9 +1265,7 @@ pub fn with_caller_bounds(&self, { ParameterEnvironment { free_substs: self.free_substs, - implicit_region_bound: self.implicit_region_bound, caller_bounds: caller_bounds, - free_id_outlive: self.free_id_outlive, is_copy_cache: RefCell::new(FxHashMap()), is_sized_cache: RefCell::new(FxHashMap()), is_freeze_cache: RefCell::new(FxHashMap()), @@ -2394,8 +2374,6 @@ pub fn empty_parameter_environment(self) -> ParameterEnvironment<'tcx> { ty::ParameterEnvironment { free_substs: self.intern_substs(&[]), caller_bounds: Slice::empty(), - implicit_region_bound: None, - free_id_outlive: None, is_copy_cache: RefCell::new(FxHashMap()), is_sized_cache: RefCell::new(FxHashMap()), is_freeze_cache: RefCell::new(FxHashMap()), @@ -2407,15 +2385,12 @@ pub fn empty_parameter_environment(self) -> ParameterEnvironment<'tcx> { /// In general, this means converting from bound parameters to /// free parameters. Since we currently represent bound/free type /// parameters in the same way, this only has an effect on regions. - pub fn construct_free_substs(self, - def_id: DefId, - free_id_outlive: Option>) - -> &'gcx Substs<'gcx> { + pub fn construct_free_substs(self, def_id: DefId) -> &'gcx Substs<'gcx> { let substs = Substs::for_item(self.global_tcx(), def_id, |def, _| { // map bound 'a => free 'a self.global_tcx().mk_region(ReFree(FreeRegion { - scope: free_id_outlive, + scope: def_id, bound_region: def.to_bound_region() })) }, |def, _| { @@ -2433,14 +2408,7 @@ pub fn parameter_environment(self, def_id: DefId) -> ParameterEnvironment<'gcx> // Construct the free substs. // - let free_id_outlive = self.hir.as_local_node_id(def_id).map(|id| { - if self.hir.maybe_body_owned_by(id).is_some() { - self.call_site_extent(id) - } else { - self.item_extent(id) - } - }); - let free_substs = self.construct_free_substs(def_id, free_id_outlive); + let free_substs = self.construct_free_substs(def_id); // // Compute the bounds on Self and the type parameters. @@ -2449,7 +2417,7 @@ pub fn parameter_environment(self, def_id: DefId) -> ParameterEnvironment<'gcx> let tcx = self.global_tcx(); let generic_predicates = tcx.predicates_of(def_id); let bounds = generic_predicates.instantiate(tcx, free_substs); - let bounds = tcx.liberate_late_bound_regions(free_id_outlive, &ty::Binder(bounds)); + let bounds = tcx.liberate_late_bound_regions(def_id, &ty::Binder(bounds)); let predicates = bounds.predicates; // Finally, we have to normalize the bounds in the environment, in @@ -2466,17 +2434,16 @@ pub fn parameter_environment(self, def_id: DefId) -> ParameterEnvironment<'gcx> // let unnormalized_env = ty::ParameterEnvironment { - free_substs: free_substs, - implicit_region_bound: free_id_outlive.map(|f| tcx.mk_region(ty::ReScope(f))), + free_substs, caller_bounds: tcx.intern_predicates(&predicates), - free_id_outlive: free_id_outlive, is_copy_cache: RefCell::new(FxHashMap()), is_sized_cache: RefCell::new(FxHashMap()), is_freeze_cache: RefCell::new(FxHashMap()), }; - let body_id = free_id_outlive.map(|f| f.node_id()) - .unwrap_or(DUMMY_NODE_ID); + let body_id = self.hir.as_local_node_id(def_id).map_or(DUMMY_NODE_ID, |id| { + self.hir.maybe_body_owned_by(id).map_or(id, |body| body.node_id) + }); let cause = traits::ObligationCause::misc(tcx.def_span(def_id), body_id); traits::normalize_param_env_or_error(tcx, def_id, unnormalized_env, cause) } diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 89960b0e4f6..1b09baccadb 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -43,12 +43,8 @@ pub struct TypeAndMut<'tcx> { RustcEncodable, RustcDecodable, Copy)] /// A "free" region `fr` can be interpreted as "some region /// at least as big as the scope `fr.scope`". -/// -/// If `fr.scope` is None, then this is in some context (e.g., an -/// impl) where lifetimes are more abstract and the notion of the -/// caller/callee stack frames are not applicable. -pub struct FreeRegion<'tcx> { - pub scope: Option>, +pub struct FreeRegion { + pub scope: DefId, pub bound_region: BoundRegion, } @@ -760,7 +756,7 @@ pub enum RegionKind<'tcx> { /// When checking a function body, the types of all arguments and so forth /// that refer to bound region parameters are modified to refer to free /// region parameters. - ReFree(FreeRegion<'tcx>), + ReFree(FreeRegion), /// A concrete region naming some statically determined extent /// (e.g. an expression or sequence of statements) within the diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index d773bb2da08..307897c4eb4 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -508,10 +508,8 @@ impl<'tcx> fmt::Debug for ty::ParameterEnvironment<'tcx> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "ParameterEnvironment(\ free_substs={:?}, \ - implicit_region_bound={:?}, \ caller_bounds={:?})", self.free_substs, - self.implicit_region_bound, self.caller_bounds) } } @@ -544,7 +542,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { } } -impl<'tcx> fmt::Debug for ty::FreeRegion<'tcx> { +impl fmt::Debug for ty::FreeRegion { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "ReFree({:?}, {:?})", self.scope, self.bound_region) diff --git a/src/librustc_borrowck/borrowck/gather_loans/mod.rs b/src/librustc_borrowck/borrowck/gather_loans/mod.rs index 8c1bcdc1fe2..ca0e5dad65b 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/mod.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/mod.rs @@ -353,7 +353,9 @@ fn guarantee_valid(&mut self, let loan_scope = match *loan_region { ty::ReScope(scope) => scope, - ty::ReFree(ref fr) => fr.scope.unwrap_or(self.item_ub), + ty::ReFree(ref fr) => { + self.bccx.region_maps.free_extent(self.tcx(), fr) + } ty::ReStatic => self.item_ub, diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index 3b4f2560fc5..e8885626151 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -330,15 +330,15 @@ pub fn t_rptr_scope(&self, id: u32) -> Ty<'tcx> { self.infcx.tcx.mk_imm_ref(self.infcx.tcx.mk_region(r), self.tcx().types.isize) } - pub fn re_free(&self, nid: ast::NodeId, id: u32) -> ty::Region<'tcx> { + pub fn re_free(&self, id: u32) -> ty::Region<'tcx> { self.infcx.tcx.mk_region(ty::ReFree(ty::FreeRegion { - scope: Some(self.tcx().node_extent(nid)), + scope: self.infcx.tcx.hir.local_def_id(ast::CRATE_NODE_ID), bound_region: ty::BrAnon(id), })) } - pub fn t_rptr_free(&self, nid: u32, id: u32) -> Ty<'tcx> { - let r = self.re_free(ast::NodeId::from_u32(nid), id); + pub fn t_rptr_free(&self, id: u32) -> Ty<'tcx> { + let r = self.re_free(id); self.infcx.tcx.mk_imm_ref(r, self.tcx().types.isize) } @@ -464,7 +464,7 @@ fn sub_free_bound_false() { test_env(EMPTY_SOURCE_STR, errors(&[]), |mut env| { env.create_simple_region_hierarchy(); - let t_rptr_free1 = env.t_rptr_free(1, 1); + let t_rptr_free1 = env.t_rptr_free(1); let t_rptr_bound1 = env.t_rptr_late_bound(1); env.check_not_sub(env.t_fn(&[t_rptr_free1], env.tcx().types.isize), env.t_fn(&[t_rptr_bound1], env.tcx().types.isize)); @@ -482,7 +482,7 @@ fn sub_bound_free_true() { test_env(EMPTY_SOURCE_STR, errors(&[]), |mut env| { env.create_simple_region_hierarchy(); let t_rptr_bound1 = env.t_rptr_late_bound(1); - let t_rptr_free1 = env.t_rptr_free(1, 1); + let t_rptr_free1 = env.t_rptr_free(1); env.check_sub(env.t_fn(&[t_rptr_bound1], env.tcx().types.isize), env.t_fn(&[t_rptr_free1], env.tcx().types.isize)); }) @@ -518,7 +518,7 @@ fn lub_free_bound_infer() { env.create_simple_region_hierarchy(); let t_infer1 = env.infcx.next_ty_var(TypeVariableOrigin::MiscVariable(DUMMY_SP)); let t_rptr_bound1 = env.t_rptr_late_bound(1); - let t_rptr_free1 = env.t_rptr_free(1, 1); + let t_rptr_free1 = env.t_rptr_free(1); env.check_lub(env.t_fn(&[t_infer1], env.tcx().types.isize), env.t_fn(&[t_rptr_bound1], env.tcx().types.isize), env.t_fn(&[t_rptr_free1], env.tcx().types.isize)); @@ -541,7 +541,7 @@ fn lub_bound_free() { test_env(EMPTY_SOURCE_STR, errors(&[]), |mut env| { env.create_simple_region_hierarchy(); let t_rptr_bound1 = env.t_rptr_late_bound(1); - let t_rptr_free1 = env.t_rptr_free(1, 1); + let t_rptr_free1 = env.t_rptr_free(1); env.check_lub(env.t_fn(&[t_rptr_bound1], env.tcx().types.isize), env.t_fn(&[t_rptr_free1], env.tcx().types.isize), env.t_fn(&[t_rptr_free1], env.tcx().types.isize)); @@ -574,8 +574,8 @@ fn lub_bound_bound_inverse_order() { fn lub_free_free() { test_env(EMPTY_SOURCE_STR, errors(&[]), |mut env| { env.create_simple_region_hierarchy(); - let t_rptr_free1 = env.t_rptr_free(1, 1); - let t_rptr_free2 = env.t_rptr_free(1, 2); + let t_rptr_free1 = env.t_rptr_free(1); + let t_rptr_free2 = env.t_rptr_free(2); let t_rptr_static = env.t_rptr_static(); env.check_lub(env.t_fn(&[t_rptr_free1], env.tcx().types.isize), env.t_fn(&[t_rptr_free2], env.tcx().types.isize), @@ -600,8 +600,8 @@ fn lub_returning_scope() { fn glb_free_free_with_common_scope() { test_env(EMPTY_SOURCE_STR, errors(&[]), |mut env| { env.create_simple_region_hierarchy(); - let t_rptr_free1 = env.t_rptr_free(1, 1); - let t_rptr_free2 = env.t_rptr_free(1, 2); + let t_rptr_free1 = env.t_rptr_free(1); + let t_rptr_free2 = env.t_rptr_free(2); let t_rptr_scope = env.t_rptr_scope(1); env.check_glb(env.t_fn(&[t_rptr_free1], env.tcx().types.isize), env.t_fn(&[t_rptr_free2], env.tcx().types.isize), @@ -625,7 +625,7 @@ fn glb_bound_free() { test_env(EMPTY_SOURCE_STR, errors(&[]), |mut env| { env.create_simple_region_hierarchy(); let t_rptr_bound1 = env.t_rptr_late_bound(1); - let t_rptr_free1 = env.t_rptr_free(1, 1); + let t_rptr_free1 = env.t_rptr_free(1); env.check_glb(env.t_fn(&[t_rptr_bound1], env.tcx().types.isize), env.t_fn(&[t_rptr_free1], env.tcx().types.isize), env.t_fn(&[t_rptr_bound1], env.tcx().types.isize)); @@ -751,7 +751,7 @@ fn escaping() { assert!(!env.t_nil().has_escaping_regions()); - let t_rptr_free1 = env.t_rptr_free(1, 1); + let t_rptr_free1 = env.t_rptr_free(1); assert!(!t_rptr_free1.has_escaping_regions()); let t_rptr_bound1 = env.t_rptr_late_bound_with_debruijn(1, ty::DebruijnIndex::new(1)); diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index b441f509b53..a3b1b24f20a 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -206,13 +206,14 @@ fn closure_self_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, -> Ty<'tcx> { let closure_ty = tcx.body_tables(body_id).node_id_to_type(closure_expr_id); + let closure_def_id = tcx.hir.local_def_id(closure_expr_id); let region = ty::ReFree(ty::FreeRegion { - scope: Some(tcx.call_site_extent(closure_expr_id)), + scope: closure_def_id, bound_region: ty::BoundRegion::BrEnv, }); let region = tcx.mk_region(region); - match tcx.closure_kind(tcx.hir.local_def_id(closure_expr_id)) { + match tcx.closure_kind(closure_def_id) { ty::ClosureKind::Fn => tcx.mk_ref(region, ty::TypeAndMut { ty: closure_ty, diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index 6a1817aba09..a692e987761 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -14,7 +14,6 @@ use hair::cx::Cx; use hair::cx::block; use hair::cx::to_ref::ToRef; -use rustc::hir::map; use rustc::hir::def::{Def, CtorKind}; use rustc::middle::const_val::ConstVal; use rustc::ty::{self, AdtKind, VariantDef, Ty}; @@ -807,33 +806,20 @@ fn convert_var<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, closure_expr_id); let var_ty = cx.tables().node_id_to_type(id_var); - let body_id = match cx.tcx.hir.find(closure_expr_id) { - Some(map::NodeExpr(expr)) => { - match expr.node { - hir::ExprClosure(.., body, _) => body.node_id, - _ => { - span_bug!(expr.span, "closure expr is not a closure expr"); - } - } - } - _ => { - span_bug!(expr.span, "ast-map has garbage for closure expr"); - } - }; - // FIXME free regions in closures are not right let closure_ty = cx.tables().node_id_to_type(closure_expr_id); // FIXME we're just hard-coding the idea that the // signature will be &self or &mut self and hence will // have a bound region with number 0 + let closure_def_id = cx.tcx.hir.local_def_id(closure_expr_id); let region = ty::ReFree(ty::FreeRegion { - scope: Some(cx.tcx.node_extent(body_id)), + scope: closure_def_id, bound_region: ty::BoundRegion::BrAnon(0), }); let region = cx.tcx.mk_region(region); - let self_expr = match cx.tcx.closure_kind(cx.tcx.hir.local_def_id(closure_expr_id)) { + let self_expr = match cx.tcx.closure_kind(closure_def_id) { ty::ClosureKind::Fn => { let ref_closure_ty = cx.tcx.mk_ref(region, ty::TypeAndMut { diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index adcb3d682ca..dfcc68bf390 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -129,7 +129,7 @@ pub fn ast_region_to_region(&self, Some(&rl::Region::Free(scope, id)) => { let name = tcx.hir.name(id); tcx.mk_region(ty::ReFree(ty::FreeRegion { - scope: Some(scope.to_code_extent(tcx)), + scope, bound_region: ty::BrNamed(tcx.hir.local_def_id(id), name) })) diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index c234629e528..dc1aa9f8592 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/src/librustc_typeck/check/closure.rs @@ -73,8 +73,7 @@ fn check_closure(&self, debug!("check_closure: expr.id={:?} closure_type={:?}", expr.id, closure_type); - let extent = self.tcx.call_site_extent(expr.id); - let fn_sig = self.tcx.liberate_late_bound_regions(Some(extent), &sig); + let fn_sig = self.tcx.liberate_late_bound_regions(expr_def_id, &sig); let fn_sig = self.inh.normalize_associated_types_in(body.value.span, body.value.id, &fn_sig); diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index 034d718723d..9248415ad5b 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -226,7 +226,7 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, normalize_cause.clone()); tcx.infer_ctxt(trait_param_env, Reveal::UserFacing).enter(|infcx| { - let inh = Inherited::new(infcx); + let inh = Inherited::new(infcx, impl_m.def_id); let infcx = &inh.infcx; debug!("compare_impl_method: caller_bounds={:?}", @@ -283,7 +283,7 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, debug!("compare_impl_method: impl_fty={:?}", impl_fty); let trait_sig = tcx.liberate_late_bound_regions( - infcx.parameter_environment.free_id_outlive, + impl_m.def_id, &m_sig(trait_m)); let trait_sig = trait_sig.subst(tcx, trait_to_skol_substs); @@ -726,7 +726,7 @@ pub fn compare_const_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, debug!("compare_const_impl(impl_trait_ref={:?})", impl_trait_ref); tcx.infer_ctxt((), Reveal::UserFacing).enter(|infcx| { - let inh = Inherited::new(infcx); + let inh = Inherited::new(infcx, impl_c.def_id); let infcx = &inh.infcx; // The below is for the most part highly similar to the procedure diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index f632d090b41..7861aa09d0f 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -176,6 +176,14 @@ pub struct Inherited<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { // variables to get the concrete type, which can be used to // deanonymize TyAnon, after typeck is done with all functions. anon_types: RefCell>>, + + /// Each type parameter has an implicit region bound that + /// indicates it must outlive at least the function body (the user + /// may specify stronger requirements). This field indicates the + /// region of the callee. If it is `None`, then the parameter + /// environment is for an item or something where the "callee" is + /// not clear. + implicit_region_bound: Option>, } impl<'a, 'gcx, 'tcx> Deref for Inherited<'a, 'gcx, 'tcx> { @@ -522,7 +530,8 @@ fn deref(&self) -> &Self::Target { /// Necessary because we can't write the following bound: /// F: for<'b, 'tcx> where 'gcx: 'tcx FnOnce(Inherited<'b, 'gcx, 'tcx>). pub struct InheritedBuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { - infcx: infer::InferCtxtBuilder<'a, 'gcx, 'tcx> + infcx: infer::InferCtxtBuilder<'a, 'gcx, 'tcx>, + def_id: DefId, } impl<'a, 'gcx, 'tcx> Inherited<'a, 'gcx, 'tcx> { @@ -531,7 +540,8 @@ pub fn build(tcx: TyCtxt<'a, 'gcx, 'gcx>, def_id: DefId) let tables = ty::TypeckTables::empty(); let param_env = tcx.parameter_environment(def_id); InheritedBuilder { - infcx: tcx.infer_ctxt((tables, param_env), Reveal::UserFacing) + infcx: tcx.infer_ctxt((tables, param_env), Reveal::UserFacing), + def_id, } } } @@ -540,12 +550,24 @@ impl<'a, 'gcx, 'tcx> InheritedBuilder<'a, 'gcx, 'tcx> { fn enter(&'tcx mut self, f: F) -> R where F: for<'b> FnOnce(Inherited<'b, 'gcx, 'tcx>) -> R { - self.infcx.enter(|infcx| f(Inherited::new(infcx))) + let def_id = self.def_id; + self.infcx.enter(|infcx| f(Inherited::new(infcx, def_id))) } } impl<'a, 'gcx, 'tcx> Inherited<'a, 'gcx, 'tcx> { - fn new(infcx: InferCtxt<'a, 'gcx, 'tcx>) -> Self { + fn new(infcx: InferCtxt<'a, 'gcx, 'tcx>, def_id: DefId) -> Self { + let tcx = infcx.tcx; + let item_id = tcx.hir.as_local_node_id(def_id); + let body_id = item_id.and_then(|id| tcx.hir.maybe_body_owned_by(id)); + let implicit_region_bound = item_id.and_then(|id| { + if body_id.is_some() { + Some(tcx.mk_region(ty::ReScope(tcx.call_site_extent(id)))) + } else { + None + } + }); + Inherited { infcx: infcx, fulfillment_cx: RefCell::new(traits::FulfillmentContext::new()), @@ -553,6 +575,7 @@ fn new(infcx: InferCtxt<'a, 'gcx, 'tcx>) -> Self { deferred_call_resolutions: RefCell::new(DefIdMap()), deferred_cast_checks: RefCell::new(Vec::new()), anon_types: RefCell::new(NodeMap()), + implicit_region_bound, } } @@ -778,11 +801,10 @@ fn typeck_tables_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, check_abi(tcx, span, fn_sig.abi()); // Compute the fty from point of view of inside fn. - let fn_scope = inh.tcx.call_site_extent(id); let fn_sig = fn_sig.subst(inh.tcx, &inh.parameter_environment.free_substs); let fn_sig = - inh.tcx.liberate_late_bound_regions(Some(fn_scope), &fn_sig); + inh.tcx.liberate_late_bound_regions(def_id, &fn_sig); let fn_sig = inh.normalize_associated_types_in(body.value.span, body_id.node_id, &fn_sig); diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index 261845c793c..bdaf3db8780 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -1612,8 +1612,6 @@ fn type_bound(&self, span: Span, ty: Ty<'tcx>) -> VerifyBound<'tcx> { } fn param_bound(&self, param_ty: ty::ParamTy) -> VerifyBound<'tcx> { - let param_env = &self.parameter_environment; - debug!("param_bound(param_ty={:?})", param_ty); @@ -1621,7 +1619,7 @@ fn param_bound(&self, param_ty: ty::ParamTy) -> VerifyBound<'tcx> { // Add in the default bound of fn body that applies to all in // scope type parameters: - param_bounds.extend(param_env.implicit_region_bound); + param_bounds.extend(self.implicit_region_bound); VerifyBound::AnyRegion(param_bounds) } diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 5d8ac32e09e..225d0ce0765 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -13,7 +13,6 @@ use constrained_type_params::{identify_constrained_type_params, Parameter}; use hir::def_id::DefId; -use middle::region::{CodeExtent}; use rustc::traits::{self, ObligationCauseCode}; use rustc::ty::{self, Ty, TyCtxt}; use rustc::util::nodemap::{FxHashSet, FxHashMap}; @@ -161,7 +160,6 @@ fn check_associated_item(&mut self, let code = self.code.clone(); self.for_id(item_id, span).with_fcx(|fcx, this| { let free_substs = &fcx.parameter_environment.free_substs; - let free_id_outlive = fcx.parameter_environment.free_id_outlive; let item = fcx.tcx.associated_item(fcx.tcx.hir.local_def_id(item_id)); @@ -184,10 +182,9 @@ fn check_associated_item(&mut self, let predicates = fcx.instantiate_bounds(span, item.def_id, free_substs); let sig = method_ty.fn_sig(); this.check_fn_or_method(fcx, span, sig, &predicates, - free_id_outlive, &mut implied_bounds); + item.def_id, &mut implied_bounds); let sig_if_method = sig_if_method.expect("bad signature for method"); - this.check_method_receiver(fcx, sig_if_method, &item, - free_id_outlive, self_ty); + this.check_method_receiver(fcx, sig_if_method, &item, self_ty); } ty::AssociatedKind::Type => { if item.defaultness.has_value() { @@ -338,9 +335,8 @@ fn check_item_fn(&mut self, item: &hir::Item) { let predicates = fcx.instantiate_bounds(item.span, def_id, free_substs); let mut implied_bounds = vec![]; - let free_id_outlive = fcx.tcx.call_site_extent(item.id); this.check_fn_or_method(fcx, item.span, sig, &predicates, - Some(free_id_outlive), &mut implied_bounds); + def_id, &mut implied_bounds); implied_bounds }) } @@ -426,12 +422,12 @@ fn check_fn_or_method<'fcx, 'tcx>(&mut self, span: Span, sig: ty::PolyFnSig<'tcx>, predicates: &ty::InstantiatedPredicates<'tcx>, - free_id_outlive: Option>, + def_id: DefId, implied_bounds: &mut Vec>) { let free_substs = &fcx.parameter_environment.free_substs; let sig = fcx.instantiate_type_scheme(span, free_substs, &sig); - let sig = fcx.tcx.liberate_late_bound_regions(free_id_outlive, &sig); + let sig = fcx.tcx.liberate_late_bound_regions(def_id, &sig); for input_ty in sig.inputs() { fcx.register_wf_obligation(&input_ty, span, self.code.clone()); @@ -450,7 +446,6 @@ fn check_method_receiver<'fcx, 'tcx>(&mut self, fcx: &FnCtxt<'fcx, 'gcx, 'tcx>, method_sig: &hir::MethodSig, method: &ty::AssociatedItem, - free_id_outlive: Option>, self_ty: ty::Ty<'tcx>) { // check that the type of the method's receiver matches the @@ -467,7 +462,7 @@ fn check_method_receiver<'fcx, 'tcx>(&mut self, let free_substs = &fcx.parameter_environment.free_substs; let method_ty = fcx.tcx.type_of(method.def_id); let fty = fcx.instantiate_type_scheme(span, free_substs, &method_ty); - let sig = fcx.tcx.liberate_late_bound_regions(free_id_outlive, &fty.fn_sig()); + let sig = fcx.tcx.liberate_late_bound_regions(method.def_id, &fty.fn_sig()); debug!("check_method_receiver: sig={:?}", sig); @@ -483,7 +478,7 @@ fn check_method_receiver<'fcx, 'tcx>(&mut self, ExplicitSelf::ByBox => fcx.tcx.mk_box(self_ty) }; let rcvr_ty = fcx.instantiate_type_scheme(span, free_substs, &rcvr_ty); - let rcvr_ty = fcx.tcx.liberate_late_bound_regions(free_id_outlive, + let rcvr_ty = fcx.tcx.liberate_late_bound_regions(method.def_id, &ty::Binder(rcvr_ty)); debug!("check_method_receiver: receiver ty = {:?}", rcvr_ty); diff --git a/src/test/compile-fail/issue-37884.rs b/src/test/compile-fail/issue-37884.rs index 6e1b9b2fbed..28ce79ab5aa 100644 --- a/src/test/compile-fail/issue-37884.rs +++ b/src/test/compile-fail/issue-37884.rs @@ -16,9 +16,9 @@ fn next(&'a mut self) -> Option //~^ ERROR method not compatible with trait //~| lifetime mismatch //~| NOTE expected type `fn(&mut RepeatMut<'a, T>) -> std::option::Option<&mut T>` + //~| NOTE the anonymous lifetime #1 defined on the method body + //~| NOTE ...does not necessarily outlive the lifetime 'a as defined on the method body { - //~^ NOTE the anonymous lifetime #1 defined on the body - //~| NOTE ...does not necessarily outlive the lifetime 'a as defined on the body Some(&mut self.0) } } diff --git a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else.stderr b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else.stderr index cf272b63128..55723ee8cd9 100644 --- a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else.stderr +++ b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else.stderr @@ -4,19 +4,17 @@ error[E0312]: lifetime of reference outlives lifetime of borrowed content... 12 | if x > y { x } else { y } | ^ | -note: ...the reference is valid for the lifetime 'a as defined on the body at 11:43... - --> $DIR/ex1-return-one-existing-name-if-else.rs:11:44 +note: ...the reference is valid for the lifetime 'a as defined on the function body at 11:0... + --> $DIR/ex1-return-one-existing-name-if-else.rs:11:1 | -11 | fn foo<'a>(x: &'a i32, y: &i32) -> &'a i32 { - | ____________________________________________^ +11 | / fn foo<'a>(x: &'a i32, y: &i32) -> &'a i32 { 12 | | if x > y { x } else { y } 13 | | } | |_^ -note: ...but the borrowed content is only valid for the anonymous lifetime #1 defined on the body at 11:43 - --> $DIR/ex1-return-one-existing-name-if-else.rs:11:44 +note: ...but the borrowed content is only valid for the anonymous lifetime #1 defined on the function body at 11:0 + --> $DIR/ex1-return-one-existing-name-if-else.rs:11:1 | -11 | fn foo<'a>(x: &'a i32, y: &i32) -> &'a i32 { - | ____________________________________________^ +11 | / fn foo<'a>(x: &'a i32, y: &i32) -> &'a i32 { 12 | | if x > y { x } else { y } 13 | | } | |_^ diff --git a/src/test/ui/lifetime-errors/ex2a-push-one-existing-name.stderr b/src/test/ui/lifetime-errors/ex2a-push-one-existing-name.stderr index 6e03e66dd25..b7d985feca9 100644 --- a/src/test/ui/lifetime-errors/ex2a-push-one-existing-name.stderr +++ b/src/test/ui/lifetime-errors/ex2a-push-one-existing-name.stderr @@ -6,19 +6,17 @@ error[E0308]: mismatched types | = note: expected type `Ref<'a, _>` found type `Ref<'_, _>` -note: the anonymous lifetime #2 defined on the body at 15:51... - --> $DIR/ex2a-push-one-existing-name.rs:15:52 +note: the anonymous lifetime #2 defined on the function body at 15:0... + --> $DIR/ex2a-push-one-existing-name.rs:15:1 | -15 | fn foo<'a>(x: &mut Vec>, y: Ref) { - | ____________________________________________________^ +15 | / fn foo<'a>(x: &mut Vec>, y: Ref) { 16 | | x.push(y); 17 | | } | |_^ -note: ...does not necessarily outlive the lifetime 'a as defined on the body at 15:51 - --> $DIR/ex2a-push-one-existing-name.rs:15:52 +note: ...does not necessarily outlive the lifetime 'a as defined on the function body at 15:0 + --> $DIR/ex2a-push-one-existing-name.rs:15:1 | -15 | fn foo<'a>(x: &mut Vec>, y: Ref) { - | ____________________________________________________^ +15 | / fn foo<'a>(x: &mut Vec>, y: Ref) { 16 | | x.push(y); 17 | | } | |_^ diff --git a/src/test/ui/lifetime-errors/ex2b-push-no-existing-names.stderr b/src/test/ui/lifetime-errors/ex2b-push-no-existing-names.stderr index 028f54ce978..3a6e94f2b1c 100644 --- a/src/test/ui/lifetime-errors/ex2b-push-no-existing-names.stderr +++ b/src/test/ui/lifetime-errors/ex2b-push-no-existing-names.stderr @@ -6,19 +6,17 @@ error[E0308]: mismatched types | = note: expected type `Ref<'_, _>` found type `Ref<'_, _>` -note: the anonymous lifetime #3 defined on the body at 15:43... - --> $DIR/ex2b-push-no-existing-names.rs:15:44 +note: the anonymous lifetime #3 defined on the function body at 15:0... + --> $DIR/ex2b-push-no-existing-names.rs:15:1 | -15 | fn foo(x: &mut Vec>, y: Ref) { - | ____________________________________________^ +15 | / fn foo(x: &mut Vec>, y: Ref) { 16 | | x.push(y); 17 | | } | |_^ -note: ...does not necessarily outlive the anonymous lifetime #2 defined on the body at 15:43 - --> $DIR/ex2b-push-no-existing-names.rs:15:44 +note: ...does not necessarily outlive the anonymous lifetime #2 defined on the function body at 15:0 + --> $DIR/ex2b-push-no-existing-names.rs:15:1 | -15 | fn foo(x: &mut Vec>, y: Ref) { - | ____________________________________________^ +15 | / fn foo(x: &mut Vec>, y: Ref) { 16 | | x.push(y); 17 | | } | |_^ diff --git a/src/test/ui/lifetime-errors/ex2c-push-inference-variable.stderr b/src/test/ui/lifetime-errors/ex2c-push-inference-variable.stderr index 4621214419e..3d7064a4f71 100644 --- a/src/test/ui/lifetime-errors/ex2c-push-inference-variable.stderr +++ b/src/test/ui/lifetime-errors/ex2c-push-inference-variable.stderr @@ -4,11 +4,10 @@ error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` d 16 | let z = Ref { data: y.data }; | ^^^ | -note: first, the lifetime cannot outlive the lifetime 'c as defined on the body at 15:66... - --> $DIR/ex2c-push-inference-variable.rs:15:67 +note: first, the lifetime cannot outlive the lifetime 'c as defined on the function body at 15:0... + --> $DIR/ex2c-push-inference-variable.rs:15:1 | -15 | fn foo<'a, 'b, 'c>(x: &'a mut Vec>, y: Ref<'c, i32>) { - | ___________________________________________________________________^ +15 | / fn foo<'a, 'b, 'c>(x: &'a mut Vec>, y: Ref<'c, i32>) { 16 | | let z = Ref { data: y.data }; 17 | | x.push(z); 18 | | } @@ -18,11 +17,10 @@ note: ...so that reference does not outlive borrowed content | 16 | let z = Ref { data: y.data }; | ^^^^^^ -note: but, the lifetime must be valid for the lifetime 'b as defined on the body at 15:66... - --> $DIR/ex2c-push-inference-variable.rs:15:67 +note: but, the lifetime must be valid for the lifetime 'b as defined on the function body at 15:0... + --> $DIR/ex2c-push-inference-variable.rs:15:1 | -15 | fn foo<'a, 'b, 'c>(x: &'a mut Vec>, y: Ref<'c, i32>) { - | ___________________________________________________________________^ +15 | / fn foo<'a, 'b, 'c>(x: &'a mut Vec>, y: Ref<'c, i32>) { 16 | | let z = Ref { data: y.data }; 17 | | x.push(z); 18 | | } diff --git a/src/test/ui/lifetime-errors/ex2d-push-inference-variable-2.stderr b/src/test/ui/lifetime-errors/ex2d-push-inference-variable-2.stderr index a69694fdc2e..aced855bf66 100644 --- a/src/test/ui/lifetime-errors/ex2d-push-inference-variable-2.stderr +++ b/src/test/ui/lifetime-errors/ex2d-push-inference-variable-2.stderr @@ -4,11 +4,10 @@ error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` d 17 | let b = Ref { data: y.data }; | ^^^ | -note: first, the lifetime cannot outlive the lifetime 'c as defined on the body at 15:66... - --> $DIR/ex2d-push-inference-variable-2.rs:15:67 +note: first, the lifetime cannot outlive the lifetime 'c as defined on the function body at 15:0... + --> $DIR/ex2d-push-inference-variable-2.rs:15:1 | -15 | fn foo<'a, 'b, 'c>(x: &'a mut Vec>, y: Ref<'c, i32>) { - | ___________________________________________________________________^ +15 | / fn foo<'a, 'b, 'c>(x: &'a mut Vec>, y: Ref<'c, i32>) { 16 | | let a: &mut Vec> = x; 17 | | let b = Ref { data: y.data }; 18 | | a.push(b); @@ -19,11 +18,10 @@ note: ...so that reference does not outlive borrowed content | 17 | let b = Ref { data: y.data }; | ^^^^^^ -note: but, the lifetime must be valid for the lifetime 'b as defined on the body at 15:66... - --> $DIR/ex2d-push-inference-variable-2.rs:15:67 +note: but, the lifetime must be valid for the lifetime 'b as defined on the function body at 15:0... + --> $DIR/ex2d-push-inference-variable-2.rs:15:1 | -15 | fn foo<'a, 'b, 'c>(x: &'a mut Vec>, y: Ref<'c, i32>) { - | ___________________________________________________________________^ +15 | / fn foo<'a, 'b, 'c>(x: &'a mut Vec>, y: Ref<'c, i32>) { 16 | | let a: &mut Vec> = x; 17 | | let b = Ref { data: y.data }; 18 | | a.push(b); diff --git a/src/test/ui/lifetime-errors/ex2e-push-inference-variable-3.stderr b/src/test/ui/lifetime-errors/ex2e-push-inference-variable-3.stderr index eff15bb794b..07e2316b63d 100644 --- a/src/test/ui/lifetime-errors/ex2e-push-inference-variable-3.stderr +++ b/src/test/ui/lifetime-errors/ex2e-push-inference-variable-3.stderr @@ -4,11 +4,10 @@ error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` d 17 | let b = Ref { data: y.data }; | ^^^ | -note: first, the lifetime cannot outlive the lifetime 'c as defined on the body at 15:66... - --> $DIR/ex2e-push-inference-variable-3.rs:15:67 +note: first, the lifetime cannot outlive the lifetime 'c as defined on the function body at 15:0... + --> $DIR/ex2e-push-inference-variable-3.rs:15:1 | -15 | fn foo<'a, 'b, 'c>(x: &'a mut Vec>, y: Ref<'c, i32>) { - | ___________________________________________________________________^ +15 | / fn foo<'a, 'b, 'c>(x: &'a mut Vec>, y: Ref<'c, i32>) { 16 | | let a: &mut Vec> = x; 17 | | let b = Ref { data: y.data }; 18 | | Vec::push(a, b); @@ -19,11 +18,10 @@ note: ...so that reference does not outlive borrowed content | 17 | let b = Ref { data: y.data }; | ^^^^^^ -note: but, the lifetime must be valid for the lifetime 'b as defined on the body at 15:66... - --> $DIR/ex2e-push-inference-variable-3.rs:15:67 +note: but, the lifetime must be valid for the lifetime 'b as defined on the function body at 15:0... + --> $DIR/ex2e-push-inference-variable-3.rs:15:1 | -15 | fn foo<'a, 'b, 'c>(x: &'a mut Vec>, y: Ref<'c, i32>) { - | ___________________________________________________________________^ +15 | / fn foo<'a, 'b, 'c>(x: &'a mut Vec>, y: Ref<'c, i32>) { 16 | | let a: &mut Vec> = x; 17 | | let b = Ref { data: y.data }; 18 | | Vec::push(a, b); -- 2.44.0