From 6f99a27886023acf4d10efb4d56c89c88ffee9be Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Thu, 17 Jul 2014 21:44:59 -0700 Subject: [PATCH] librustc: Implement lifetime elision. This implements RFC 39. Omitted lifetimes in return values will now be inferred to more useful defaults, and an error is reported if a lifetime in a return type is omitted and one of the two lifetime elision rules does not specify what it should be. This primarily breaks two uncommon code patterns. The first is this: unsafe fn get_foo_out_of_thin_air() -> &Foo { ... } This should be changed to: unsafe fn get_foo_out_of_thin_air() -> &'static Foo { ... } The second pattern that needs to be changed is this: enum MaybeBorrowed<'a> { Borrowed(&'a str), Owned(String), } fn foo() -> MaybeBorrowed { Owned(format!("hello world")) } Change code like this to: enum MaybeBorrowed<'a> { Borrowed(&'a str), Owned(String), } fn foo() -> MaybeBorrowed<'static> { Owned(format!("hello world")) } Closes #15552. [breaking-change] --- src/libcollections/dlist.rs | 8 +- src/libgraphviz/lib.rs | 4 +- src/libgraphviz/maybe_owned_vec.rs | 2 +- src/libgreen/sched.rs | 4 +- src/librustc/middle/trans/basic_block.rs | 2 +- src/librustc/middle/ty.rs | 52 ++++++++++ src/librustc/middle/typeck/astconv.rs | 94 ++++++++++++++----- src/librustc/middle/typeck/rscope.rs | 16 +++- src/librustrt/local_data.rs | 2 +- src/librustrt/rtio.rs | 2 +- src/librustuv/file.rs | 2 +- src/test/auxiliary/overloaded_autoderef_xc.rs | 6 +- src/test/bench/shootout-k-nucleotide.rs | 2 +- .../borrowck-borrow-from-temporary.rs | 2 +- .../borrowck-borrow-mut-object-twice.rs | 2 +- ...rrowck-borrow-overloaded-auto-deref-mut.rs | 22 ++--- .../borrowck-borrow-overloaded-auto-deref.rs | 18 ++-- .../borrowck-managed-pointer-deref-scope.rs | 2 +- .../compile-fail/borrowck-object-lifetime.rs | 6 +- .../borrowck-overloaded-index-2.rs | 2 +- .../borrowck-vec-pattern-element-loan.rs | 6 +- .../borrowck-vec-pattern-tail-element-loan.rs | 2 +- .../compile-fail/cleanup-rvalue-scopes-cf.rs | 4 +- .../drop-with-active-borrows-2.rs | 2 +- src/test/compile-fail/infinite-autoderef.rs | 2 +- src/test/compile-fail/issue-11681.rs | 2 +- src/test/compile-fail/issue-3154.rs | 2 +- src/test/compile-fail/issue-4972.rs | 2 +- src/test/compile-fail/isuue-12470.rs | 2 +- ...-return-type-requires-explicit-lifetime.rs | 32 +++++++ ...time-inference-give-expl-lifetime-param.rs | 39 +++----- .../compile-fail/regions-creating-enums.rs | 2 +- .../compile-fail/regions-creating-enums4.rs | 2 +- .../regions-fn-subtyping-return-static.rs | 2 +- src/test/compile-fail/regions-fn-subtyping.rs | 2 +- .../regions-infer-at-fn-not-param.rs | 2 +- .../regions-infer-borrow-scope-too-big.rs | 2 +- .../regions-infer-borrow-scope-within-loop.rs | 2 +- .../compile-fail/regions-infer-not-param.rs | 4 +- ...ions-lifetime-of-struct-or-enum-variant.rs | 4 +- src/test/compile-fail/regions-ret-borrowed.rs | 2 +- src/test/compile-fail/regions-ret.rs | 2 +- .../compile-fail/regions-trait-variance.rs | 4 +- .../borrowck-scope-of-deref-issue-4666.rs | 2 +- .../class-impl-very-parameterized-trait.rs | 6 +- src/test/run-pass/cleanup-rvalue-for-scope.rs | 2 +- src/test/run-pass/issue-2502.rs | 2 +- src/test/run-pass/issue-2748-a.rs | 2 +- src/test/run-pass/issue-4464.rs | 2 +- src/test/run-pass/issue-5708.rs | 2 +- src/test/run-pass/issue-7911.rs | 8 +- .../nullable-pointer-iotareduction.rs | 2 +- src/test/run-pass/operator-overloading.rs | 2 +- .../run-pass/overloaded-autoderef-count.rs | 4 +- .../run-pass/overloaded-autoderef-order.rs | 4 +- .../run-pass/overloaded-autoderef-vtable.rs | 6 +- src/test/run-pass/overloaded-deref-count.rs | 4 +- src/test/run-pass/overloaded-index.rs | 4 +- .../regions-addr-of-interior-of-unique-box.rs | 2 +- src/test/run-pass/regions-addr-of-ret.rs | 2 +- src/test/run-pass/regions-copy-closure.rs | 2 +- .../run-pass/regions-dependent-addr-of.rs | 18 ++-- src/test/run-pass/regions-dependent-autofn.rs | 4 +- .../run-pass/regions-escape-into-other-fn.rs | 2 +- .../regions-infer-borrow-scope-view.rs | 2 +- ...gions-infer-borrow-scope-within-loop-ok.rs | 2 +- .../run-pass/regions-infer-borrow-scope.rs | 2 +- src/test/run-pass/regions-nullary-variant.rs | 2 +- src/test/run-pass/regions-params.rs | 2 +- .../regions-return-interior-of-option.rs | 2 +- src/test/run-pass/regions-static-closure.rs | 2 +- 71 files changed, 303 insertions(+), 168 deletions(-) create mode 100644 src/test/compile-fail/lifetime-elision-return-type-requires-explicit-lifetime.rs diff --git a/src/libcollections/dlist.rs b/src/libcollections/dlist.rs index 226fbbe7f941b..48ea1bd1c0150 100644 --- a/src/libcollections/dlist.rs +++ b/src/libcollections/dlist.rs @@ -87,12 +87,14 @@ impl Rawlink { } /// Convert the `Rawlink` into an Option value - fn resolve_immut(&self) -> Option<&T> { - unsafe { self.p.to_option() } + fn resolve_immut<'a>(&self) -> Option<&'a T> { + unsafe { + mem::transmute(self.p.to_option()) + } } /// Convert the `Rawlink` into an Option value - fn resolve(&mut self) -> Option<&mut T> { + fn resolve<'a>(&mut self) -> Option<&'a mut T> { if self.p.is_null() { None } else { diff --git a/src/libgraphviz/lib.rs b/src/libgraphviz/lib.rs index 24698d09f56e5..3c93a795071a6 100644 --- a/src/libgraphviz/lib.rs +++ b/src/libgraphviz/lib.rs @@ -455,12 +455,12 @@ impl<'a> LabelText<'a> { } /// Puts `prefix` on a line above this label, with a blank line separator. - pub fn prefix_line(self, prefix: LabelText) -> LabelText { + pub fn prefix_line(self, prefix: LabelText) -> LabelText<'static> { prefix.suffix_line(self) } /// Puts `suffix` on a line below this label, with a blank line separator. - pub fn suffix_line(self, suffix: LabelText) -> LabelText { + pub fn suffix_line(self, suffix: LabelText) -> LabelText<'static> { let prefix = self.pre_escaped_content().into_string(); let suffix = suffix.pre_escaped_content(); EscStr(str::Owned(prefix.append(r"\n\n").append(suffix.as_slice()))) diff --git a/src/libgraphviz/maybe_owned_vec.rs b/src/libgraphviz/maybe_owned_vec.rs index ec60be195158a..9e52af72138bb 100644 --- a/src/libgraphviz/maybe_owned_vec.rs +++ b/src/libgraphviz/maybe_owned_vec.rs @@ -109,7 +109,7 @@ impl<'b,T> slice::Vector for MaybeOwnedVector<'b,T> { } impl<'a,T> FromIterator for MaybeOwnedVector<'a,T> { - fn from_iter>(iterator: I) -> MaybeOwnedVector { + fn from_iter>(iterator: I) -> MaybeOwnedVector<'a,T> { // If we are building from scratch, might as well build the // most flexible variant. Growable(FromIterator::from_iter(iterator)) diff --git a/src/libgreen/sched.rs b/src/libgreen/sched.rs index 7603b0a8013c7..7151a78eacd43 100644 --- a/src/libgreen/sched.rs +++ b/src/libgreen/sched.rs @@ -959,13 +959,13 @@ impl CleanupJob { type UnsafeTaskReceiver = raw::Closure; trait ClosureConverter { fn from_fn(|&mut Scheduler, Box|) -> Self; - fn to_fn(self) -> |&mut Scheduler, Box|; + fn to_fn(self) -> |&mut Scheduler, Box|:'static ; } impl ClosureConverter for UnsafeTaskReceiver { fn from_fn(f: |&mut Scheduler, Box|) -> UnsafeTaskReceiver { unsafe { mem::transmute(f) } } - fn to_fn(self) -> |&mut Scheduler, Box| { + fn to_fn(self) -> |&mut Scheduler, Box|:'static { unsafe { mem::transmute(self) } } } diff --git a/src/librustc/middle/trans/basic_block.rs b/src/librustc/middle/trans/basic_block.rs index 13b8ed4df6b82..013350717171c 100644 --- a/src/librustc/middle/trans/basic_block.rs +++ b/src/librustc/middle/trans/basic_block.rs @@ -31,7 +31,7 @@ impl BasicBlock { } } - pub fn pred_iter(self) -> Preds { + pub fn pred_iter(self) -> Preds<'static> { self.as_value().user_iter() .filter(|user| user.is_a_terminator_inst()) .map(|user| user.get_parent().unwrap()) diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 50563d42e4412..9b55ee657fc00 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -4872,3 +4872,55 @@ pub enum ExplicitSelfCategory { ByBoxExplicitSelfCategory, } +/// Pushes all the lifetimes in the given type onto the given list. A +/// "lifetime in a type" is a lifetime specified by a reference or a lifetime +/// in a list of type substitutions. This does *not* traverse into nominal +/// types, nor does it resolve fictitious types. +pub fn accumulate_lifetimes_in_type(accumulator: &mut Vec, + typ: t) { + walk_ty(typ, |typ| { + match get(typ).sty { + ty_rptr(region, _) => accumulator.push(region), + ty_enum(_, ref substs) | + ty_trait(box TyTrait { + substs: ref substs, + .. + }) | + ty_struct(_, ref substs) => { + match substs.regions { + subst::ErasedRegions => {} + subst::NonerasedRegions(ref regions) => { + for region in regions.iter() { + accumulator.push(*region) + } + } + } + } + ty_closure(ref closure_ty) => { + match closure_ty.store { + RegionTraitStore(region, _) => accumulator.push(region), + UniqTraitStore => {} + } + } + ty_nil | + ty_bot | + ty_bool | + ty_char | + ty_int(_) | + ty_uint(_) | + ty_float(_) | + ty_box(_) | + ty_uniq(_) | + ty_str | + ty_vec(_, _) | + ty_ptr(_) | + ty_bare_fn(_) | + ty_tup(_) | + ty_param(_) | + ty_infer(_) | + ty_unboxed_closure(_) | + ty_err => {} + } + }) +} + diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs index de169a886cfd3..e129492dbc2f8 100644 --- a/src/librustc/middle/typeck/astconv.rs +++ b/src/librustc/middle/typeck/astconv.rs @@ -55,6 +55,7 @@ use middle::lang_items::FnMutTraitLangItem; use middle::subst::{FnSpace, TypeSpace, SelfSpace, Subst, Substs}; use middle::ty; use middle::ty_fold::TypeFolder; +use middle::typeck::rscope::{ExplicitRscope, ImpliedSingleRscope}; use middle::typeck::rscope::RegionScope; use middle::typeck::{TypeAndSubsts, infer, lookup_def_tcx, rscope}; use middle::typeck; @@ -931,31 +932,45 @@ fn ty_of_method_or_bare_fn( Option) { debug!("ty_of_method_or_bare_fn"); - // new region names that appear inside of the fn decl are bound to - // that function type + // New region names that appear inside of the arguments of the function + // declaration are bound to that function type. let rb = rscope::BindingRscope::new(id); + // `implied_output_region` is the region that will be assumed for any + // region parameters in the return type. In accordance with the rules for + // lifetime elision, we can determine it in two ways. First (determined + // here), if self is by-reference, then the implied output region is the + // region of the self parameter. let mut explicit_self_category_result = None; - let self_ty = opt_self_info.and_then(|self_info| { - // Figure out and record the explicit self category. - let explicit_self_category = - determine_explicit_self_category(this, &rb, &self_info); - explicit_self_category_result = Some(explicit_self_category); - match explicit_self_category { - ty::StaticExplicitSelfCategory => None, - ty::ByValueExplicitSelfCategory => { - Some(self_info.untransformed_self_ty) - } - ty::ByReferenceExplicitSelfCategory(region, mutability) => { - Some(ty::mk_rptr(this.tcx(), region, - ty::mt {ty: self_info.untransformed_self_ty, - mutbl: mutability})) - } - ty::ByBoxExplicitSelfCategory => { - Some(ty::mk_uniq(this.tcx(), self_info.untransformed_self_ty)) + let (self_ty, mut implied_output_region) = match opt_self_info { + None => (None, None), + Some(self_info) => { + // Figure out and record the explicit self category. + let explicit_self_category = + determine_explicit_self_category(this, &rb, &self_info); + explicit_self_category_result = Some(explicit_self_category); + match explicit_self_category { + ty::StaticExplicitSelfCategory => (None, None), + ty::ByValueExplicitSelfCategory => { + (Some(self_info.untransformed_self_ty), None) + } + ty::ByReferenceExplicitSelfCategory(region, mutability) => { + (Some(ty::mk_rptr(this.tcx(), + region, + ty::mt { + ty: self_info.untransformed_self_ty, + mutbl: mutability + })), + Some(region)) + } + ty::ByBoxExplicitSelfCategory => { + (Some(ty::mk_uniq(this.tcx(), + self_info.untransformed_self_ty)), + None) + } } } - }); + }; // HACK(eddyb) replace the fake self type in the AST with the actual type. let input_tys = if self_ty.is_some() { @@ -964,12 +979,47 @@ fn ty_of_method_or_bare_fn( decl.inputs.as_slice() }; let input_tys = input_tys.iter().map(|a| ty_of_arg(this, &rb, a, None)); + let self_and_input_tys: Vec<_> = + self_ty.move_iter().chain(input_tys).collect(); + + // Second, if there was exactly one lifetime (either a substitution or a + // reference) in the arguments, then any anonymous regions in the output + // have that lifetime. + if implied_output_region.is_none() { + let mut self_and_input_tys_iter = self_and_input_tys.iter(); + if self_ty.is_some() { + // Skip the first argument if `self` is present. + drop(self_and_input_tys_iter.next()) + } - let self_and_input_tys = self_ty.move_iter().chain(input_tys).collect(); + let mut accumulator = Vec::new(); + for input_type in self_and_input_tys_iter { + ty::accumulate_lifetimes_in_type(&mut accumulator, *input_type) + } + if accumulator.len() == 1 { + implied_output_region = Some(*accumulator.get(0)); + } + } let output_ty = match decl.output.node { ast::TyInfer => this.ty_infer(decl.output.span), - _ => ast_ty_to_ty(this, &rb, &*decl.output) + _ => { + match implied_output_region { + Some(implied_output_region) => { + let rb = ImpliedSingleRscope { + region: implied_output_region, + }; + ast_ty_to_ty(this, &rb, &*decl.output) + } + None => { + // All regions must be explicitly specified in the output + // if the lifetime elision rules do not apply. This saves + // the user from potentially-confusing errors. + let rb = ExplicitRscope; + ast_ty_to_ty(this, &rb, &*decl.output) + } + } + } }; (ty::BareFnTy { diff --git a/src/librustc/middle/typeck/rscope.rs b/src/librustc/middle/typeck/rscope.rs index 2abbd916d7627..cdb691073cd36 100644 --- a/src/librustc/middle/typeck/rscope.rs +++ b/src/librustc/middle/typeck/rscope.rs @@ -64,10 +64,24 @@ impl RegionScope for BindingRscope { fn anon_regions(&self, _: Span, count: uint) - -> Result , ()> { + -> Result, ()> { let idx = self.anon_bindings.get(); self.anon_bindings.set(idx + count); Ok(Vec::from_fn(count, |i| ty::ReLateBound(self.binder_id, ty::BrAnon(idx + i)))) } } + +/// A scope in which we generate one specific region. This occurs after the +/// `->` (i.e. in the return type) of function signatures. +pub struct ImpliedSingleRscope { + pub region: ty::Region, +} + +impl RegionScope for ImpliedSingleRscope { + fn anon_regions(&self, _: Span, count: uint) + -> Result,()> { + Ok(Vec::from_elem(count, self.region.clone())) + } +} + diff --git a/src/librustrt/local_data.rs b/src/librustrt/local_data.rs index ace53478d0a03..7434951d3ee91 100644 --- a/src/librustrt/local_data.rs +++ b/src/librustrt/local_data.rs @@ -94,7 +94,7 @@ pub type Map = Vec>; type TLSValue = Box; // Gets the map from the runtime. Lazily initialises if not done so already. -unsafe fn get_local_map() -> Option<&mut Map> { +unsafe fn get_local_map<'a>() -> Option<&'a mut Map> { if !Local::exists(None::) { return None } let task: *mut Task = Local::unsafe_borrow(); diff --git a/src/librustrt/rtio.rs b/src/librustrt/rtio.rs index 343b911fb83f3..81a033e4c987e 100644 --- a/src/librustrt/rtio.rs +++ b/src/librustrt/rtio.rs @@ -134,7 +134,7 @@ impl<'a> Drop for LocalIo<'a> { impl<'a> LocalIo<'a> { /// Returns the local I/O: either the local scheduler's I/O services or /// the native I/O services. - pub fn borrow() -> Option { + pub fn borrow() -> Option> { // FIXME(#11053): bad // // This is currently very unsafely implemented. We don't actually diff --git a/src/librustuv/file.rs b/src/librustuv/file.rs index 26ba601f73ec1..f42f42d211160 100644 --- a/src/librustuv/file.rs +++ b/src/librustuv/file.rs @@ -469,7 +469,7 @@ mod test { use super::super::Loop; use super::super::local_loop; - fn l() -> &mut Loop { &mut local_loop().loop_ } + fn l() -> &'static mut Loop { &mut local_loop().loop_ } #[test] fn file_test_full_simple_sync() { diff --git a/src/test/auxiliary/overloaded_autoderef_xc.rs b/src/test/auxiliary/overloaded_autoderef_xc.rs index dbb978a0b4ed9..26d61e166f26b 100644 --- a/src/test/auxiliary/overloaded_autoderef_xc.rs +++ b/src/test/auxiliary/overloaded_autoderef_xc.rs @@ -15,17 +15,17 @@ struct DerefWithHelper { } trait Helper { - fn helper_borrow<'a>(&'a self) -> &'a T; + fn helper_borrow(&self) -> &T; } impl Helper for Option { - fn helper_borrow<'a>(&'a self) -> &'a T { + fn helper_borrow(&self) -> &T { self.as_ref().unwrap() } } impl> Deref for DerefWithHelper { - fn deref<'a>(&'a self) -> &'a T { + fn deref(&self) -> &T { self.helper.helper_borrow() } } diff --git a/src/test/bench/shootout-k-nucleotide.rs b/src/test/bench/shootout-k-nucleotide.rs index fe0744e5e7c37..b31b524cf9b45 100644 --- a/src/test/bench/shootout-k-nucleotide.rs +++ b/src/test/bench/shootout-k-nucleotide.rs @@ -156,7 +156,7 @@ impl Table { } } - fn iter<'a>(&'a self) -> Items<'a> { + fn iter(&self) -> Items { Items { cur: None, items: self.items.iter() } } } diff --git a/src/test/compile-fail/borrowck-borrow-from-temporary.rs b/src/test/compile-fail/borrowck-borrow-from-temporary.rs index a2f5e28de3bdf..784bd1e8ae45d 100644 --- a/src/test/compile-fail/borrowck-borrow-from-temporary.rs +++ b/src/test/compile-fail/borrowck-borrow-from-temporary.rs @@ -13,7 +13,7 @@ struct Foo(int); -fn foo() -> &int { +fn foo<'a>() -> &'a int { let &Foo(ref x) = &Foo(3); //~ ERROR borrowed value does not live long enough x } diff --git a/src/test/compile-fail/borrowck-borrow-mut-object-twice.rs b/src/test/compile-fail/borrowck-borrow-mut-object-twice.rs index 34b9c31fdd82f..7175194355b0a 100644 --- a/src/test/compile-fail/borrowck-borrow-mut-object-twice.rs +++ b/src/test/compile-fail/borrowck-borrow-mut-object-twice.rs @@ -12,7 +12,7 @@ // other `&mut` pointers. trait Foo { - fn f1<'a>(&'a mut self) -> &'a (); + fn f1(&mut self) -> &(); fn f2(&mut self); } diff --git a/src/test/compile-fail/borrowck-borrow-overloaded-auto-deref-mut.rs b/src/test/compile-fail/borrowck-borrow-overloaded-auto-deref-mut.rs index 1e04a3568c350..05bc0d1e13b2d 100644 --- a/src/test/compile-fail/borrowck-borrow-overloaded-auto-deref-mut.rs +++ b/src/test/compile-fail/borrowck-borrow-overloaded-auto-deref-mut.rs @@ -18,13 +18,13 @@ struct Own { } impl Deref for Own { - fn deref<'a>(&'a self) -> &'a T { + fn deref(&self) -> &T { unsafe { &*self.value } } } impl DerefMut for Own { - fn deref_mut<'a>(&'a mut self) -> &'a mut T { + fn deref_mut(&mut self) -> &mut T { unsafe { &mut *self.value } } } @@ -44,11 +44,11 @@ impl Point { self.y = y; } - fn x_ref<'a>(&'a self) -> &'a int { + fn x_ref(&self) -> &int { &self.x } - fn y_mut<'a>(&'a mut self) -> &'a mut int { + fn y_mut(&mut self) -> &mut int { &mut self.y } } @@ -65,19 +65,19 @@ fn deref_mut_field2(mut x: Own) { let _i = &mut x.y; } -fn deref_extend_field<'a>(x: &'a Own) -> &'a int { +fn deref_extend_field(x: &Own) -> &int { &x.y } -fn deref_extend_mut_field1<'a>(x: &'a Own) -> &'a mut int { +fn deref_extend_mut_field1(x: &Own) -> &mut int { &mut x.y //~ ERROR cannot borrow } -fn deref_extend_mut_field2<'a>(x: &'a mut Own) -> &'a mut int { +fn deref_extend_mut_field2(x: &mut Own) -> &mut int { &mut x.y } -fn deref_extend_mut_field3<'a>(x: &'a mut Own) { +fn deref_extend_mut_field3(x: &mut Own) { // Hmm, this is unfortunate, because with box it would work, // but it's presently the expected outcome. See `deref_extend_mut_field4` // for the workaround. @@ -124,15 +124,15 @@ fn deref_mut_method2(mut x: Own) { x.set(0, 0); } -fn deref_extend_method<'a>(x: &'a Own) -> &'a int { +fn deref_extend_method(x: &Own) -> &int { x.x_ref() } -fn deref_extend_mut_method1<'a>(x: &'a Own) -> &'a mut int { +fn deref_extend_mut_method1(x: &Own) -> &mut int { x.y_mut() //~ ERROR cannot borrow } -fn deref_extend_mut_method2<'a>(x: &'a mut Own) -> &'a mut int { +fn deref_extend_mut_method2(x: &mut Own) -> &mut int { x.y_mut() } diff --git a/src/test/compile-fail/borrowck-borrow-overloaded-auto-deref.rs b/src/test/compile-fail/borrowck-borrow-overloaded-auto-deref.rs index 30aed76a4ebdb..5aaefd0173990 100644 --- a/src/test/compile-fail/borrowck-borrow-overloaded-auto-deref.rs +++ b/src/test/compile-fail/borrowck-borrow-overloaded-auto-deref.rs @@ -18,7 +18,7 @@ struct Rc { } impl Deref for Rc { - fn deref<'a>(&'a self) -> &'a T { + fn deref(&self) -> &T { unsafe { &*self.value } } } @@ -38,11 +38,11 @@ impl Point { self.y = y; } - fn x_ref<'a>(&'a self) -> &'a int { + fn x_ref(&self) -> &int { &self.x } - fn y_mut<'a>(&'a mut self) -> &'a mut int { + fn y_mut(&mut self) -> &mut int { &mut self.y } } @@ -59,15 +59,15 @@ fn deref_mut_field2(mut x: Rc) { let _i = &mut x.y; //~ ERROR cannot borrow } -fn deref_extend_field<'a>(x: &'a Rc) -> &'a int { +fn deref_extend_field(x: &Rc) -> &int { &x.y } -fn deref_extend_mut_field1<'a>(x: &'a Rc) -> &'a mut int { +fn deref_extend_mut_field1(x: &Rc) -> &mut int { &mut x.y //~ ERROR cannot borrow } -fn deref_extend_mut_field2<'a>(x: &'a mut Rc) -> &'a mut int { +fn deref_extend_mut_field2(x: &mut Rc) -> &mut int { &mut x.y //~ ERROR cannot borrow } @@ -95,15 +95,15 @@ fn deref_mut_method2(mut x: Rc) { x.set(0, 0); //~ ERROR cannot borrow } -fn deref_extend_method<'a>(x: &'a Rc) -> &'a int { +fn deref_extend_method(x: &Rc) -> &int { x.x_ref() } -fn deref_extend_mut_method1<'a>(x: &'a Rc) -> &'a mut int { +fn deref_extend_mut_method1(x: &Rc) -> &mut int { x.y_mut() //~ ERROR cannot borrow } -fn deref_extend_mut_method2<'a>(x: &'a mut Rc) -> &'a mut int { +fn deref_extend_mut_method2(x: &mut Rc) -> &mut int { x.y_mut() //~ ERROR cannot borrow } diff --git a/src/test/compile-fail/borrowck-managed-pointer-deref-scope.rs b/src/test/compile-fail/borrowck-managed-pointer-deref-scope.rs index 30430e00ef342..9e6bafa1eba7c 100644 --- a/src/test/compile-fail/borrowck-managed-pointer-deref-scope.rs +++ b/src/test/compile-fail/borrowck-managed-pointer-deref-scope.rs @@ -15,7 +15,7 @@ use std::gc::{GC, Gc}; -fn foo<'a>(x: &'a Gc) -> &'a int { +fn foo(x: &Gc) -> &int { match x { &ref y => { &**y // Do not expect an error here diff --git a/src/test/compile-fail/borrowck-object-lifetime.rs b/src/test/compile-fail/borrowck-object-lifetime.rs index 9466a78588c45..c55a5a30538d8 100644 --- a/src/test/compile-fail/borrowck-object-lifetime.rs +++ b/src/test/compile-fail/borrowck-object-lifetime.rs @@ -10,14 +10,14 @@ trait Foo { - fn borrowed<'a>(&'a self) -> &'a (); + fn borrowed(&self) -> &(); } -fn borrowed_receiver<'a>(x: &'a Foo) -> &'a () { +fn borrowed_receiver(x: &Foo) -> &() { x.borrowed() } -fn owned_receiver(x: Box) -> &() { +fn owned_receiver(x: Box) -> &'static () { x.borrowed() //~ ERROR `*x` does not live long enough } diff --git a/src/test/compile-fail/borrowck-overloaded-index-2.rs b/src/test/compile-fail/borrowck-overloaded-index-2.rs index 1e3144a931fbf..6d2eae8bc1e12 100644 --- a/src/test/compile-fail/borrowck-overloaded-index-2.rs +++ b/src/test/compile-fail/borrowck-overloaded-index-2.rs @@ -13,7 +13,7 @@ struct MyVec { } impl Index for MyVec { - fn index<'a>(&'a self, &i: &uint) -> &'a T { + fn index(&self, &i: &uint) -> &T { self.data.get(i) } } diff --git a/src/test/compile-fail/borrowck-vec-pattern-element-loan.rs b/src/test/compile-fail/borrowck-vec-pattern-element-loan.rs index 3da284175541d..53ebaa38fddba 100644 --- a/src/test/compile-fail/borrowck-vec-pattern-element-loan.rs +++ b/src/test/compile-fail/borrowck-vec-pattern-element-loan.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn a() -> &[int] { +fn a<'a>() -> &'a [int] { let vec = vec!(1, 2, 3, 4); let vec: &[int] = vec.as_slice(); //~ ERROR does not live long enough let tail = match vec { @@ -18,7 +18,7 @@ fn a() -> &[int] { tail } -fn b() -> &[int] { +fn b<'a>() -> &'a [int] { let vec = vec!(1, 2, 3, 4); let vec: &[int] = vec.as_slice(); //~ ERROR does not live long enough let init = match vec { @@ -28,7 +28,7 @@ fn b() -> &[int] { init } -fn c() -> &[int] { +fn c<'a>() -> &'a [int] { let vec = vec!(1, 2, 3, 4); let vec: &[int] = vec.as_slice(); //~ ERROR does not live long enough let slice = match vec { diff --git a/src/test/compile-fail/borrowck-vec-pattern-tail-element-loan.rs b/src/test/compile-fail/borrowck-vec-pattern-tail-element-loan.rs index 26dc853859c92..57a276bec81bc 100644 --- a/src/test/compile-fail/borrowck-vec-pattern-tail-element-loan.rs +++ b/src/test/compile-fail/borrowck-vec-pattern-tail-element-loan.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn a() -> &int { +fn a<'a>() -> &'a int { let vec = vec!(1, 2, 3, 4); let vec: &[int] = vec.as_slice(); //~ ERROR `vec` does not live long enough let tail = match vec { diff --git a/src/test/compile-fail/cleanup-rvalue-scopes-cf.rs b/src/test/compile-fail/cleanup-rvalue-scopes-cf.rs index 01c6256173f03..b79f4507d4673 100644 --- a/src/test/compile-fail/cleanup-rvalue-scopes-cf.rs +++ b/src/test/compile-fail/cleanup-rvalue-scopes-cf.rs @@ -24,12 +24,12 @@ fn AddFlags(bits: u64) -> AddFlags { AddFlags { bits: bits } } -fn arg<'a>(x: &'a AddFlags) -> &'a AddFlags { +fn arg(x: &AddFlags) -> &AddFlags { x } impl AddFlags { - fn get<'a>(&'a self) -> &'a AddFlags { + fn get(&self) -> &AddFlags { self } } diff --git a/src/test/compile-fail/drop-with-active-borrows-2.rs b/src/test/compile-fail/drop-with-active-borrows-2.rs index 2700ceff68a07..1cbd6292e9907 100644 --- a/src/test/compile-fail/drop-with-active-borrows-2.rs +++ b/src/test/compile-fail/drop-with-active-borrows-2.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn read_lines_borrowed() -> Vec<&str> { +fn read_lines_borrowed<'a>() -> Vec<&'a str> { let raw_lines: Vec = vec!("foo ".to_string(), " bar".to_string()); raw_lines.iter().map(|l| l.as_slice().trim()).collect() //~^ ERROR `raw_lines` does not live long enough diff --git a/src/test/compile-fail/infinite-autoderef.rs b/src/test/compile-fail/infinite-autoderef.rs index b41797d0042fa..e4c6fa7d47f4a 100644 --- a/src/test/compile-fail/infinite-autoderef.rs +++ b/src/test/compile-fail/infinite-autoderef.rs @@ -15,7 +15,7 @@ use std::ops::Deref; struct Foo; impl Deref for Foo { - fn deref<'a>(&'a self) -> &'a Foo { + fn deref(&self) -> &Foo { self } } diff --git a/src/test/compile-fail/issue-11681.rs b/src/test/compile-fail/issue-11681.rs index dad503e88e1b9..71f1d5dcc9af4 100644 --- a/src/test/compile-fail/issue-11681.rs +++ b/src/test/compile-fail/issue-11681.rs @@ -18,7 +18,7 @@ impl Drop for Test { fn drop (&mut self) {} } -fn createTest() -> &Test { +fn createTest<'a>() -> &'a Test { let testValue = &Test; //~ ERROR borrowed value does not live long enough return testValue; } diff --git a/src/test/compile-fail/issue-3154.rs b/src/test/compile-fail/issue-3154.rs index dcb705856d997..141bf2b42791b 100644 --- a/src/test/compile-fail/issue-3154.rs +++ b/src/test/compile-fail/issue-3154.rs @@ -12,7 +12,7 @@ struct thing<'a, Q> { x: &'a Q } -fn thing(x: &Q) -> thing { +fn thing<'a,Q>(x: &Q) -> thing<'a,Q> { thing{ x: x } //~ ERROR cannot infer } diff --git a/src/test/compile-fail/issue-4972.rs b/src/test/compile-fail/issue-4972.rs index edd6932aec6f0..d684d1b376b8f 100644 --- a/src/test/compile-fail/issue-4972.rs +++ b/src/test/compile-fail/issue-4972.rs @@ -15,7 +15,7 @@ pub enum TraitWrapper { A(Box), } -fn get_tw_map<'lt>(tw: &'lt TraitWrapper) -> &'lt MyTrait { +fn get_tw_map(tw: &TraitWrapper) -> &MyTrait { match *tw { A(box ref map) => map, //~ ERROR cannot be dereferenced } diff --git a/src/test/compile-fail/isuue-12470.rs b/src/test/compile-fail/isuue-12470.rs index d4073a5e98479..bf13b7ebbdbbe 100644 --- a/src/test/compile-fail/isuue-12470.rs +++ b/src/test/compile-fail/isuue-12470.rs @@ -31,7 +31,7 @@ fn make_a<'a>(p: &'a X) -> A<'a> { A { p: p } } -fn make_make_a() -> A { +fn make_make_a<'a>() -> A<'a> { let b: Box = box B {i:1}; let bb: &B = &*b; //~ ERROR does not live long enough make_a(bb) diff --git a/src/test/compile-fail/lifetime-elision-return-type-requires-explicit-lifetime.rs b/src/test/compile-fail/lifetime-elision-return-type-requires-explicit-lifetime.rs new file mode 100644 index 0000000000000..2e05dda719080 --- /dev/null +++ b/src/test/compile-fail/lifetime-elision-return-type-requires-explicit-lifetime.rs @@ -0,0 +1,32 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Lifetime annotation needed because we have no arguments. +fn f() -> &int { //~ ERROR missing lifetime specifier + fail!() +} + +// Lifetime annotation needed because we have two by-reference parameters. +fn g(_: &int, _: &int) -> &int { //~ ERROR missing lifetime specifier + fail!() +} + +struct Foo<'a> { + x: &'a int, +} + +// Lifetime annotation needed because we have two lifetime: one as a parameter +// and one on the reference. +fn h(_: &Foo) -> &int { //~ ERROR missing lifetime specifier + fail!() +} + +fn main() {} + diff --git a/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param.rs b/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param.rs index 3328a5d23e62e..ef5a45fcf70ae 100644 --- a/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param.rs +++ b/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param.rs @@ -11,7 +11,7 @@ // ignore-tidy-linelength struct Foo<'x> { bar: int } -fn foo1(x: &Foo) -> &int { +fn foo1<'a>(x: &Foo) -> &'a int { //~^ NOTE: consider using an explicit lifetime parameter as shown: fn foo1<'a>(x: &'a Foo) -> &'a int &x.bar //~ ERROR: cannot infer } @@ -21,34 +21,28 @@ fn foo2<'a, 'b>(x: &'a Foo) -> &'b int { &x.bar //~ ERROR: cannot infer } -fn foo3(x: &Foo) -> (&int, &int) { +fn foo3<'a>(x: &Foo) -> (&'a int, &'a int) { //~^ NOTE: consider using an explicit lifetime parameter as shown: fn foo3<'a>(x: &'a Foo) -> (&'a int, &'a int) (&x.bar, &x.bar) //~ ERROR: cannot infer //~^ ERROR: cannot infer } -fn foo4<'a, 'b>(x: &'a Foo) -> (&'b int, &'a int, &int) { +fn foo4<'a, 'b>(x: &'a Foo) -> (&'b int, &'a int, &'b int) { //~^ NOTE: consider using an explicit lifetime parameter as shown: fn foo4<'a>(x: &'a Foo) -> (&'a int, &'a int, &'a int) (&x.bar, &x.bar, &x.bar) //~ ERROR: cannot infer //~^ ERROR: cannot infer } -fn foo5(x: &int) -> &int { -//~^ NOTE: consider using an explicit lifetime parameter as shown: fn foo5<'a>(x: &'a int) -> &'a int - x //~ ERROR: mismatched types - //~^ ERROR: cannot infer -} - struct Bar<'x, 'y, 'z> { bar: &'y int, baz: int } -fn bar1(x: &Bar) -> (&int, &int, &int) { -//~^ NOTE: consider using an explicit lifetime parameter as shown: fn bar1<'a, 'b, 'c, 'd>(x: &'d Bar<'b, 'a, 'c>) -> (&'a int, &'d int, &'d int) +fn bar1<'a>(x: &Bar) -> (&'a int, &'a int, &'a int) { +//~^ NOTE: consider using an explicit lifetime parameter as shown: fn bar1<'b, 'c, 'a>(x: &'a Bar<'b, 'a, 'c>) -> (&'a int, &'a int, &'a int) (x.bar, &x.baz, &x.baz) //~ ERROR: mismatched types //~^ ERROR: cannot infer //~^^ ERROR: cannot infer } -fn bar2<'a, 'b, 'c>(x: &Bar<'a, 'b, 'c>) -> (&int, &int, &int) { -//~^ NOTE: consider using an explicit lifetime parameter as shown: fn bar2<'d, 'a, 'b, 'c>(x: &'d Bar<'a, 'b, 'c>) -> (&'b int, &'d int, &'d int) +fn bar2<'a, 'b, 'c>(x: &Bar<'a, 'b, 'c>) -> (&'a int, &'a int, &'a int) { +//~^ NOTE: consider using an explicit lifetime parameter as shown: fn bar2<'a, 'c>(x: &'a Bar<'a, 'a, 'c>) -> (&'a int, &'a int, &'a int) (x.bar, &x.baz, &x.baz) //~ ERROR: mismatched types //~^ ERROR: cannot infer //~^^ ERROR: cannot infer @@ -56,13 +50,9 @@ fn bar2<'a, 'b, 'c>(x: &Bar<'a, 'b, 'c>) -> (&int, &int, &int) { struct Cat<'x, T> { cat: &'x int, t: T } struct Dog<'y> { dog: &'y int } -fn cat<'x>(x: Cat<'x, Dog>) -> &int { -//~^ NOTE: consider using an explicit lifetime parameter as shown: fn cat<'a, 'x>(x: Cat<'x, Dog<'a>>) -> &'a int - x.t.dog //~ ERROR: mismatched types -} -fn cat2<'x, 'y>(x: Cat<'x, Dog<'y>>) -> &int { -//~^ NOTE: consider using an explicit lifetime parameter as shown: fn cat2<'x, 'y>(x: Cat<'x, Dog<'y>>) -> &'y int +fn cat2<'x, 'y>(x: Cat<'x, Dog<'y>>) -> &'x int { +//~^ NOTE: consider using an explicit lifetime parameter as shown: fn cat2<'x>(x: Cat<'x, Dog<'x>>) -> &'x int x.t.dog //~ ERROR: mismatched types } @@ -70,16 +60,11 @@ struct Baz<'x> { bar: &'x int } -impl<'x> Baz<'x> { - fn baz1(&self) -> &int { - //~^ NOTE: consider using an explicit lifetime parameter as shown: fn baz1(&self) -> &'x int - self.bar //~ ERROR: mismatched types - } -} impl<'a> Baz<'a> { - fn baz2(&self, x: &int) -> (&int, &int) { - //~^ NOTE: consider using an explicit lifetime parameter as shown: fn baz2<'b>(&self, x: &'b int) -> (&'a int, &'b int) + fn baz2<'b>(&self, x: &int) -> (&'b int, &'b int) { + // The lifetime that gets assigned to `x` seems somewhat random. + // I have disabled this test for the time being. --pcwalton (self.bar, x) //~ ERROR: cannot infer //~^ ERROR: mismatched types //~^^ ERROR: mismatched types diff --git a/src/test/compile-fail/regions-creating-enums.rs b/src/test/compile-fail/regions-creating-enums.rs index 4fd3cd2704437..ed3ce1fd0f077 100644 --- a/src/test/compile-fail/regions-creating-enums.rs +++ b/src/test/compile-fail/regions-creating-enums.rs @@ -27,7 +27,7 @@ fn compute(x: &ast) -> uint { } } -fn map_nums(x: &ast, f: |uint| -> uint) -> &ast { +fn map_nums<'a,'b>(x: &ast, f: |uint| -> uint) -> &'a ast<'b> { match *x { num(x) => { return &num(f(x)); //~ ERROR borrowed value does not live long enough diff --git a/src/test/compile-fail/regions-creating-enums4.rs b/src/test/compile-fail/regions-creating-enums4.rs index 0cd5a97596045..082ba0f0cf103 100644 --- a/src/test/compile-fail/regions-creating-enums4.rs +++ b/src/test/compile-fail/regions-creating-enums4.rs @@ -13,7 +13,7 @@ enum ast<'a> { add(&'a ast<'a>, &'a ast<'a>) } -fn mk_add_bad2<'a>(x: &'a ast<'a>, y: &'a ast<'a>, z: &ast) -> ast { +fn mk_add_bad2<'a,'b>(x: &'a ast<'a>, y: &'a ast<'a>, z: &ast) -> ast<'b> { add(x, y) //~ ERROR cannot infer } diff --git a/src/test/compile-fail/regions-fn-subtyping-return-static.rs b/src/test/compile-fail/regions-fn-subtyping-return-static.rs index c03040fe0f211..2d20634cdc41d 100644 --- a/src/test/compile-fail/regions-fn-subtyping-return-static.rs +++ b/src/test/compile-fail/regions-fn-subtyping-return-static.rs @@ -40,7 +40,7 @@ fn bar<'a,'b>(x: &'a S) -> &'b S { } // Meets F, but not G. -fn baz<'a>(x: &'a S) -> &'a S { +fn baz(x: &S) -> &S { fail!() } diff --git a/src/test/compile-fail/regions-fn-subtyping.rs b/src/test/compile-fail/regions-fn-subtyping.rs index 0cbd37a3b9a5e..30b33e82a4b79 100644 --- a/src/test/compile-fail/regions-fn-subtyping.rs +++ b/src/test/compile-fail/regions-fn-subtyping.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn of() -> |T| { fail!(); } +fn of<'a,T>() -> |T|:'a { fail!(); } fn subtype(x: |T|) { fail!(); } fn test_fn<'x,'y,'z,T>(_x: &'x T, _y: &'y T, _z: &'z T) { diff --git a/src/test/compile-fail/regions-infer-at-fn-not-param.rs b/src/test/compile-fail/regions-infer-at-fn-not-param.rs index 4c883656d61a5..e5444aadc1ca6 100644 --- a/src/test/compile-fail/regions-infer-at-fn-not-param.rs +++ b/src/test/compile-fail/regions-infer-at-fn-not-param.rs @@ -20,7 +20,7 @@ struct not_parameterized2 { g: ||: 'static } -fn take1(p: parameterized1) -> parameterized1 { p } +fn take1<'a>(p: parameterized1) -> parameterized1<'a> { p } //~^ ERROR mismatched types //~^^ ERROR cannot infer diff --git a/src/test/compile-fail/regions-infer-borrow-scope-too-big.rs b/src/test/compile-fail/regions-infer-borrow-scope-too-big.rs index 028988dbd4fa5..b00ceec028782 100644 --- a/src/test/compile-fail/regions-infer-borrow-scope-too-big.rs +++ b/src/test/compile-fail/regions-infer-borrow-scope-too-big.rs @@ -21,7 +21,7 @@ fn x_coord<'r>(p: &'r point) -> &'r int { return &p.x; } -fn foo(p: Gc) -> &int { +fn foo<'a>(p: Gc) -> &'a int { let xc = x_coord(&*p); //~ ERROR `*p` does not live long enough assert_eq!(*xc, 3); return xc; diff --git a/src/test/compile-fail/regions-infer-borrow-scope-within-loop.rs b/src/test/compile-fail/regions-infer-borrow-scope-within-loop.rs index bb021d4135a16..ce6a51e8fb5e7 100644 --- a/src/test/compile-fail/regions-infer-borrow-scope-within-loop.rs +++ b/src/test/compile-fail/regions-infer-borrow-scope-within-loop.rs @@ -12,7 +12,7 @@ use std::gc::Gc; -fn borrow<'r, T>(x: &'r T) -> &'r T {x} +fn borrow(x: &T) -> &T {x} fn foo(cond: || -> bool, make_box: || -> Gc) { let mut y: ∫ diff --git a/src/test/compile-fail/regions-infer-not-param.rs b/src/test/compile-fail/regions-infer-not-param.rs index 86f98d5cc3515..cadf66c328686 100644 --- a/src/test/compile-fail/regions-infer-not-param.rs +++ b/src/test/compile-fail/regions-infer-not-param.rs @@ -22,12 +22,12 @@ struct indirect2<'a> { g: |direct<'a>|: 'static } -fn take_direct(p: direct) -> direct { p } //~ ERROR mismatched types +fn take_direct<'a,'b>(p: direct<'a>) -> direct<'b> { p } //~ ERROR mismatched types //~^ ERROR cannot infer fn take_indirect1(p: indirect1) -> indirect1 { p } -fn take_indirect2(p: indirect2) -> indirect2 { p } //~ ERROR mismatched types +fn take_indirect2<'a,'b>(p: indirect2<'a>) -> indirect2<'b> { p } //~ ERROR mismatched types //~^ ERROR cannot infer fn main() {} diff --git a/src/test/compile-fail/regions-lifetime-of-struct-or-enum-variant.rs b/src/test/compile-fail/regions-lifetime-of-struct-or-enum-variant.rs index c266952f08f08..27e2f5582f5a4 100644 --- a/src/test/compile-fail/regions-lifetime-of-struct-or-enum-variant.rs +++ b/src/test/compile-fail/regions-lifetime-of-struct-or-enum-variant.rs @@ -18,12 +18,12 @@ enum MyEnum { Variant1 } -fn structLifetime() -> &Test { +fn structLifetime<'a>() -> &'a Test { let testValue = &Test; //~ ERROR borrowed value does not live long enough testValue } -fn variantLifetime() -> &MyEnum { +fn variantLifetime<'a>() -> &'a MyEnum { let testValue = &Variant1; //~ ERROR borrowed value does not live long enough testValue } diff --git a/src/test/compile-fail/regions-ret-borrowed.rs b/src/test/compile-fail/regions-ret-borrowed.rs index c20764e0728d1..f9983bcf80172 100644 --- a/src/test/compile-fail/regions-ret-borrowed.rs +++ b/src/test/compile-fail/regions-ret-borrowed.rs @@ -19,7 +19,7 @@ fn with(f: |x: &int| -> R) -> R { f(&3) } -fn return_it() -> &int { +fn return_it<'a>() -> &'a int { with(|o| o) //~ ERROR mismatched types //~^ ERROR lifetime of return value does not outlive the function call //~^^ ERROR cannot infer diff --git a/src/test/compile-fail/regions-ret.rs b/src/test/compile-fail/regions-ret.rs index eccffb4051e23..4986771c79397 100644 --- a/src/test/compile-fail/regions-ret.rs +++ b/src/test/compile-fail/regions-ret.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn f<'a>(_x : &'a int) -> &'a int { +fn f(_x: &int) -> &int { return &3; //~ ERROR borrowed value does not live long enough } diff --git a/src/test/compile-fail/regions-trait-variance.rs b/src/test/compile-fail/regions-trait-variance.rs index 24dcfb87ad884..53cfd4e032497 100644 --- a/src/test/compile-fail/regions-trait-variance.rs +++ b/src/test/compile-fail/regions-trait-variance.rs @@ -34,11 +34,11 @@ struct A<'r> { p: &'r X } -fn make_a<'r>(p:&'r X) -> A<'r> { +fn make_a(p:&X) -> A { A{p:p} } -fn make_make_a() -> A { +fn make_make_a<'a>() -> A<'a> { let b: Box = box B { i: 1, }; diff --git a/src/test/run-pass/borrowck-scope-of-deref-issue-4666.rs b/src/test/run-pass/borrowck-scope-of-deref-issue-4666.rs index 420ee843766bb..02c7dc38db00f 100644 --- a/src/test/run-pass/borrowck-scope-of-deref-issue-4666.rs +++ b/src/test/run-pass/borrowck-scope-of-deref-issue-4666.rs @@ -17,7 +17,7 @@ struct Box { } impl Box { - fn get<'a>(&'a self) -> &'a uint { + fn get(&self) -> &uint { &self.x } fn set(&mut self, x: uint) { diff --git a/src/test/run-pass/class-impl-very-parameterized-trait.rs b/src/test/run-pass/class-impl-very-parameterized-trait.rs index 924625faa1010..dd3a7b86bea83 100644 --- a/src/test/run-pass/class-impl-very-parameterized-trait.rs +++ b/src/test/run-pass/class-impl-very-parameterized-trait.rs @@ -60,7 +60,7 @@ impl Mutable for cat { impl Map for cat { fn contains_key(&self, k: &int) -> bool { *k <= self.meows } - fn find<'a>(&'a self, k: &int) -> Option<&'a T> { + fn find(&self, k: &int) -> Option<&T> { if *k <= self.meows { Some(&self.name) } else { @@ -75,7 +75,7 @@ impl MutableMap for cat { true } - fn find_mut<'a>(&'a mut self, _k: &int) -> Option<&'a mut T> { fail!() } + fn find_mut(&mut self, _k: &int) -> Option<&mut T> { fail!() } fn remove(&mut self, k: &int) -> bool { if self.find(k).is_some() { @@ -91,7 +91,7 @@ impl MutableMap for cat { } impl cat { - pub fn get<'a>(&'a self, k: &int) -> &'a T { + pub fn get(&self, k: &int) -> &T { match self.find(k) { Some(v) => { v } None => { fail!("epic fail"); } diff --git a/src/test/run-pass/cleanup-rvalue-for-scope.rs b/src/test/run-pass/cleanup-rvalue-for-scope.rs index e352fc0be981e..932a5a044ad3e 100644 --- a/src/test/run-pass/cleanup-rvalue-for-scope.rs +++ b/src/test/run-pass/cleanup-rvalue-for-scope.rs @@ -42,7 +42,7 @@ fn check_flags(exp: u64) { } impl AddFlags { - fn check_flags<'a>(&'a self, exp: u64) -> &'a AddFlags { + fn check_flags(&self, exp: u64) -> &AddFlags { check_flags(exp); self } diff --git a/src/test/run-pass/issue-2502.rs b/src/test/run-pass/issue-2502.rs index 91912e00e1809..a62e329f106f5 100644 --- a/src/test/run-pass/issue-2502.rs +++ b/src/test/run-pass/issue-2502.rs @@ -19,7 +19,7 @@ impl<'a> font<'a> { } } -fn font<'r>(fontbuf: &'r Vec ) -> font<'r> { +fn font(fontbuf: &Vec ) -> font { font { fontbuf: fontbuf } diff --git a/src/test/run-pass/issue-2748-a.rs b/src/test/run-pass/issue-2748-a.rs index 455d22fe7f0f5..23e26ca5665c5 100644 --- a/src/test/run-pass/issue-2748-a.rs +++ b/src/test/run-pass/issue-2748-a.rs @@ -12,7 +12,7 @@ struct CMap<'a> { buf: &'a [u8], } -fn CMap<'r>(buf: &'r [u8]) -> CMap<'r> { +fn CMap(buf: &[u8]) -> CMap { CMap { buf: buf } diff --git a/src/test/run-pass/issue-4464.rs b/src/test/run-pass/issue-4464.rs index 529f8ecc6ebe1..822fda8a18ec8 100644 --- a/src/test/run-pass/issue-4464.rs +++ b/src/test/run-pass/issue-4464.rs @@ -8,6 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn broken<'r>(v: &'r [u8], i: uint, j: uint) -> &'r [u8] { v.slice(i, j) } +fn broken(v: &[u8], i: uint, j: uint) -> &[u8] { v.slice(i, j) } pub fn main() {} diff --git a/src/test/run-pass/issue-5708.rs b/src/test/run-pass/issue-5708.rs index 39c8562e4589b..2bb320e556235 100644 --- a/src/test/run-pass/issue-5708.rs +++ b/src/test/run-pass/issue-5708.rs @@ -33,7 +33,7 @@ struct Outer<'a> { } impl<'a> Outer<'a> { - fn new<'r>(inner: &'r Inner) -> Outer<'r> { + fn new(inner: &Inner) -> Outer { Outer { inner: inner } diff --git a/src/test/run-pass/issue-7911.rs b/src/test/run-pass/issue-7911.rs index 75494c47dcef1..d8bb61477a0c8 100644 --- a/src/test/run-pass/issue-7911.rs +++ b/src/test/run-pass/issue-7911.rs @@ -23,17 +23,17 @@ struct Foo { bar: Bar } impl FooBar for Bar {} trait Test { - fn get_immut<'r>(&'r self) -> &'r FooBar; - fn get_mut<'r>(&'r mut self) -> &'r mut FooBar; + fn get_immut(&self) -> &FooBar; + fn get_mut(&mut self) -> &mut FooBar; } macro_rules! generate_test(($type_:path, $slf:ident, $field:expr) => ( impl Test for $type_ { - fn get_immut<'r>(&'r $slf) -> &'r FooBar { + fn get_immut(&$slf) -> &FooBar { &$field as &FooBar } - fn get_mut<'r>(&'r mut $slf) -> &'r mut FooBar { + fn get_mut(&mut $slf) -> &mut FooBar { &mut $field as &mut FooBar } } diff --git a/src/test/run-pass/nullable-pointer-iotareduction.rs b/src/test/run-pass/nullable-pointer-iotareduction.rs index 8b26ece176d4d..10c07e6435400 100644 --- a/src/test/run-pass/nullable-pointer-iotareduction.rs +++ b/src/test/run-pass/nullable-pointer-iotareduction.rs @@ -29,7 +29,7 @@ impl E { Nothing(..) => true } } - fn get_ref<'r>(&'r self) -> (int, &'r T) { + fn get_ref(&self) -> (int, &T) { match *self { Nothing(..) => fail!("E::get_ref(Nothing::<{}>)", stringify!(T)), Thing(x, ref y) => (x, y) diff --git a/src/test/run-pass/operator-overloading.rs b/src/test/run-pass/operator-overloading.rs index a36d8132b260a..a896d2b06f7bd 100644 --- a/src/test/run-pass/operator-overloading.rs +++ b/src/test/run-pass/operator-overloading.rs @@ -43,7 +43,7 @@ impl ops::Not for Point { } impl ops::Index for Point { - fn index<'a>(&'a self, x: &bool) -> &'a int { + fn index(&self, x: &bool) -> &int { if *x { &self.x } else { diff --git a/src/test/run-pass/overloaded-autoderef-count.rs b/src/test/run-pass/overloaded-autoderef-count.rs index 6fdbd17c21b38..24146c4a6ea6a 100644 --- a/src/test/run-pass/overloaded-autoderef-count.rs +++ b/src/test/run-pass/overloaded-autoderef-count.rs @@ -33,14 +33,14 @@ impl DerefCounter { } impl Deref for DerefCounter { - fn deref<'a>(&'a self) -> &'a T { + fn deref(&self) -> &T { self.count_imm.set(self.count_imm.get() + 1); &self.value } } impl DerefMut for DerefCounter { - fn deref_mut<'a>(&'a mut self) -> &'a mut T { + fn deref_mut(&mut self) -> &mut T { self.count_mut += 1; &mut self.value } diff --git a/src/test/run-pass/overloaded-autoderef-order.rs b/src/test/run-pass/overloaded-autoderef-order.rs index 188c62751bcd9..0a9ac734c26fd 100644 --- a/src/test/run-pass/overloaded-autoderef-order.rs +++ b/src/test/run-pass/overloaded-autoderef-order.rs @@ -22,7 +22,7 @@ impl DerefWrapper { } impl Deref for DerefWrapper { - fn deref<'a>(&'a self) -> &'a Y { + fn deref(&self) -> &Y { &self.y } } @@ -43,7 +43,7 @@ mod priv_test { } impl Deref for DerefWrapperHideX { - fn deref<'a>(&'a self) -> &'a Y { + fn deref(&self) -> &Y { &self.y } } diff --git a/src/test/run-pass/overloaded-autoderef-vtable.rs b/src/test/run-pass/overloaded-autoderef-vtable.rs index 15b5cca9cf83e..f71afb9650743 100644 --- a/src/test/run-pass/overloaded-autoderef-vtable.rs +++ b/src/test/run-pass/overloaded-autoderef-vtable.rs @@ -15,17 +15,17 @@ struct DerefWithHelper { } trait Helper { - fn helper_borrow<'a>(&'a self) -> &'a T; + fn helper_borrow(&self) -> &T; } impl Helper for Option { - fn helper_borrow<'a>(&'a self) -> &'a T { + fn helper_borrow(&self) -> &T { self.as_ref().unwrap() } } impl> Deref for DerefWithHelper { - fn deref<'a>(&'a self) -> &'a T { + fn deref(&self) -> &T { self.helper.helper_borrow() } } diff --git a/src/test/run-pass/overloaded-deref-count.rs b/src/test/run-pass/overloaded-deref-count.rs index 283c76adf0daf..0b5406b8f67d5 100644 --- a/src/test/run-pass/overloaded-deref-count.rs +++ b/src/test/run-pass/overloaded-deref-count.rs @@ -33,14 +33,14 @@ impl DerefCounter { } impl Deref for DerefCounter { - fn deref<'a>(&'a self) -> &'a T { + fn deref(&self) -> &T { self.count_imm.set(self.count_imm.get() + 1); &self.value } } impl DerefMut for DerefCounter { - fn deref_mut<'a>(&'a mut self) -> &'a mut T { + fn deref_mut(&mut self) -> &mut T { self.count_mut += 1; &mut self.value } diff --git a/src/test/run-pass/overloaded-index.rs b/src/test/run-pass/overloaded-index.rs index 9d7c068cccd93..1187e06695070 100644 --- a/src/test/run-pass/overloaded-index.rs +++ b/src/test/run-pass/overloaded-index.rs @@ -14,7 +14,7 @@ struct Foo { } impl Index for Foo { - fn index<'a>(&'a self, z: &int) -> &'a int { + fn index(&self, z: &int) -> &int { if *z == 0 { &self.x } else { @@ -24,7 +24,7 @@ impl Index for Foo { } impl IndexMut for Foo { - fn index_mut<'a>(&'a mut self, z: &int) -> &'a mut int { + fn index_mut(&mut self, z: &int) -> &mut int { if *z == 0 { &mut self.x } else { diff --git a/src/test/run-pass/regions-addr-of-interior-of-unique-box.rs b/src/test/run-pass/regions-addr-of-interior-of-unique-box.rs index 47ae5c13d28cb..bb2885a217785 100644 --- a/src/test/run-pass/regions-addr-of-interior-of-unique-box.rs +++ b/src/test/run-pass/regions-addr-of-interior-of-unique-box.rs @@ -18,7 +18,7 @@ struct Character { pos: Box, } -fn get_x<'r>(x: &'r Character) -> &'r int { +fn get_x(x: &Character) -> &int { // interesting case because the scope of this // borrow of the unique pointer is in fact // larger than the fn itself diff --git a/src/test/run-pass/regions-addr-of-ret.rs b/src/test/run-pass/regions-addr-of-ret.rs index 357d829627da0..a046ba456a6b0 100644 --- a/src/test/run-pass/regions-addr-of-ret.rs +++ b/src/test/run-pass/regions-addr-of-ret.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn f<'a>(x : &'a int) -> &'a int { +fn f(x: &int) -> &int { return &*x; } diff --git a/src/test/run-pass/regions-copy-closure.rs b/src/test/run-pass/regions-copy-closure.rs index 65cecb2d5008b..b4523ce41ce75 100644 --- a/src/test/run-pass/regions-copy-closure.rs +++ b/src/test/run-pass/regions-copy-closure.rs @@ -12,7 +12,7 @@ struct closure_box<'a> { cl: ||: 'a, } -fn box_it<'r>(x: ||: 'r) -> closure_box<'r> { +fn box_it(x: ||) -> closure_box { closure_box {cl: x} } diff --git a/src/test/run-pass/regions-dependent-addr-of.rs b/src/test/run-pass/regions-dependent-addr-of.rs index 400ab462f761f..252c0b5578ac6 100644 --- a/src/test/run-pass/regions-dependent-addr-of.rs +++ b/src/test/run-pass/regions-dependent-addr-of.rs @@ -29,54 +29,54 @@ struct C { f: int } -fn get_v1<'v>(a: &'v A) -> &'v int { +fn get_v1(a: &A) -> &int { // Region inferencer must deduce that &v < L2 < L1 let foo = &a.value; // L1 &foo.v1 // L2 } -fn get_v2<'v>(a: &'v A, i: uint) -> &'v int { +fn get_v2(a: &A, i: uint) -> &int { let foo = &a.value; &foo.v2[i] } -fn get_v3<'v>(a: &'v A, i: uint) -> &'v int { +fn get_v3(a: &A, i: uint) -> &int { let foo = &a.value; foo.v3.get(i) } -fn get_v4<'v>(a: &'v A, _i: uint) -> &'v int { +fn get_v4(a: &A, _i: uint) -> &int { let foo = &a.value; &foo.v4.f } -fn get_v5<'v>(a: &'v A, _i: uint) -> &'v int { +fn get_v5(a: &A, _i: uint) -> &int { let foo = &a.value; &foo.v5.f } -fn get_v6_a<'v>(a: &'v A, _i: uint) -> &'v int { +fn get_v6_a(a: &A, _i: uint) -> &int { match a.value.v6 { Some(ref v) => &v.f, None => fail!() } } -fn get_v6_b<'v>(a: &'v A, _i: uint) -> &'v int { +fn get_v6_b(a: &A, _i: uint) -> &int { match *a { A { value: B { v6: Some(ref v), .. } } => &v.f, _ => fail!() } } -fn get_v6_c<'v>(a: &'v A, _i: uint) -> &'v int { +fn get_v6_c(a: &A, _i: uint) -> &int { match a { &A { value: B { v6: Some(ref v), .. } } => &v.f, _ => fail!() } } -fn get_v5_ref<'v>(a: &'v A, _i: uint) -> &'v int { +fn get_v5_ref(a: &A, _i: uint) -> &int { match &a.value { &B {v5: box C {f: ref v}, ..} => v } diff --git a/src/test/run-pass/regions-dependent-autofn.rs b/src/test/run-pass/regions-dependent-autofn.rs index e9cd7fb49731f..311fd1bcdf2e0 100644 --- a/src/test/run-pass/regions-dependent-autofn.rs +++ b/src/test/run-pass/regions-dependent-autofn.rs @@ -11,9 +11,9 @@ // Test lifetimes are linked properly when we autoslice a vector. // Issue #3148. -fn subslice<'r>(v: ||: 'r) -> ||: 'r { v } +fn subslice(v: ||) -> || { v } -fn both<'r>(v: ||: 'r) -> ||: 'r { +fn both(v: ||) -> || { subslice(subslice(v)) } diff --git a/src/test/run-pass/regions-escape-into-other-fn.rs b/src/test/run-pass/regions-escape-into-other-fn.rs index 5e2893c49809e..46e1aaa3a241b 100644 --- a/src/test/run-pass/regions-escape-into-other-fn.rs +++ b/src/test/run-pass/regions-escape-into-other-fn.rs @@ -12,7 +12,7 @@ use std::gc::GC; -fn foo<'r>(x: &'r uint) -> &'r uint { x } +fn foo(x: &uint) -> &uint { x } fn bar(x: &uint) -> uint { *x } pub fn main() { diff --git a/src/test/run-pass/regions-infer-borrow-scope-view.rs b/src/test/run-pass/regions-infer-borrow-scope-view.rs index 13200d619d02e..c4e0e3bb4fc11 100644 --- a/src/test/run-pass/regions-infer-borrow-scope-view.rs +++ b/src/test/run-pass/regions-infer-borrow-scope-view.rs @@ -9,7 +9,7 @@ // except according to those terms. -fn view<'r, T>(x: &'r [T]) -> &'r [T] {x} +fn view(x: &[T]) -> &[T] {x} pub fn main() { let v = vec!(1i, 2, 3); diff --git a/src/test/run-pass/regions-infer-borrow-scope-within-loop-ok.rs b/src/test/run-pass/regions-infer-borrow-scope-within-loop-ok.rs index 0b42f71fccb05..4d4417189c908 100644 --- a/src/test/run-pass/regions-infer-borrow-scope-within-loop-ok.rs +++ b/src/test/run-pass/regions-infer-borrow-scope-within-loop-ok.rs @@ -10,7 +10,7 @@ use std::gc::GC; -fn borrow<'r, T>(x: &'r T) -> &'r T {x} +fn borrow(x: &T) -> &T {x} pub fn main() { let x = box(GC) 3i; diff --git a/src/test/run-pass/regions-infer-borrow-scope.rs b/src/test/run-pass/regions-infer-borrow-scope.rs index abbbb51580fb7..65e753ddee12d 100644 --- a/src/test/run-pass/regions-infer-borrow-scope.rs +++ b/src/test/run-pass/regions-infer-borrow-scope.rs @@ -14,7 +14,7 @@ use std::gc::GC; struct Point {x: int, y: int} -fn x_coord<'r>(p: &'r Point) -> &'r int { +fn x_coord(p: &Point) -> &int { return &p.x; } diff --git a/src/test/run-pass/regions-nullary-variant.rs b/src/test/run-pass/regions-nullary-variant.rs index 784424ad54c8a..845ef4017447c 100644 --- a/src/test/run-pass/regions-nullary-variant.rs +++ b/src/test/run-pass/regions-nullary-variant.rs @@ -12,7 +12,7 @@ enum roption<'a> { a, b(&'a uint) } -fn mk<'r>(cond: bool, ptr: &'r uint) -> roption<'r> { +fn mk(cond: bool, ptr: &uint) -> roption { if cond {a} else {b(ptr)} } diff --git a/src/test/run-pass/regions-params.rs b/src/test/run-pass/regions-params.rs index b83d7af9a11d3..c0e821b8d3854 100644 --- a/src/test/run-pass/regions-params.rs +++ b/src/test/run-pass/regions-params.rs @@ -9,7 +9,7 @@ // except according to those terms. -fn region_identity<'r>(x: &'r uint) -> &'r uint { x } +fn region_identity(x: &uint) -> &uint { x } fn apply(t: T, f: |T| -> T) -> T { f(t) } diff --git a/src/test/run-pass/regions-return-interior-of-option.rs b/src/test/run-pass/regions-return-interior-of-option.rs index d1530c4c7b91a..f6971a8b4ad30 100644 --- a/src/test/run-pass/regions-return-interior-of-option.rs +++ b/src/test/run-pass/regions-return-interior-of-option.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn get<'r, T>(opt: &'r Option) -> &'r T { +fn get(opt: &Option) -> &T { match *opt { Some(ref v) => v, None => fail!("none") diff --git a/src/test/run-pass/regions-static-closure.rs b/src/test/run-pass/regions-static-closure.rs index d91c11dde10e2..f1d2adcaf94d8 100644 --- a/src/test/run-pass/regions-static-closure.rs +++ b/src/test/run-pass/regions-static-closure.rs @@ -12,7 +12,7 @@ struct closure_box<'a> { cl: ||: 'a, } -fn box_it<'r>(x: ||: 'r) -> closure_box<'r> { +fn box_it(x: ||) -> closure_box { closure_box {cl: x} }