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]
This commit is contained in:
parent
793b1424ac
commit
6f99a27886
71 changed files with 303 additions and 168 deletions
|
@ -87,12 +87,14 @@ impl<T> Rawlink<T> {
|
|||
}
|
||||
|
||||
/// 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 {
|
||||
|
|
|
@ -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())))
|
||||
|
|
|
@ -109,7 +109,7 @@ impl<'b,T> slice::Vector<T> for MaybeOwnedVector<'b,T> {
|
|||
}
|
||||
|
||||
impl<'a,T> FromIterator<T> for MaybeOwnedVector<'a,T> {
|
||||
fn from_iter<I:Iterator<T>>(iterator: I) -> MaybeOwnedVector<T> {
|
||||
fn from_iter<I:Iterator<T>>(iterator: I) -> MaybeOwnedVector<'a,T> {
|
||||
// If we are building from scratch, might as well build the
|
||||
// most flexible variant.
|
||||
Growable(FromIterator::from_iter(iterator))
|
||||
|
|
|
@ -959,13 +959,13 @@ impl CleanupJob {
|
|||
type UnsafeTaskReceiver = raw::Closure;
|
||||
trait ClosureConverter {
|
||||
fn from_fn(|&mut Scheduler, Box<GreenTask>|) -> Self;
|
||||
fn to_fn(self) -> |&mut Scheduler, Box<GreenTask>|;
|
||||
fn to_fn(self) -> |&mut Scheduler, Box<GreenTask>|:'static ;
|
||||
}
|
||||
impl ClosureConverter for UnsafeTaskReceiver {
|
||||
fn from_fn(f: |&mut Scheduler, Box<GreenTask>|) -> UnsafeTaskReceiver {
|
||||
unsafe { mem::transmute(f) }
|
||||
}
|
||||
fn to_fn(self) -> |&mut Scheduler, Box<GreenTask>| {
|
||||
fn to_fn(self) -> |&mut Scheduler, Box<GreenTask>|:'static {
|
||||
unsafe { mem::transmute(self) }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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<ty::Region>,
|
||||
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 => {}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -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<AC:AstConv>(
|
|||
Option<ty::ExplicitSelfCategory>) {
|
||||
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<AC:AstConv>(
|
|||
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();
|
||||
|
||||
let self_and_input_tys = 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 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 {
|
||||
|
|
|
@ -64,10 +64,24 @@ impl RegionScope for BindingRscope {
|
|||
fn anon_regions(&self,
|
||||
_: Span,
|
||||
count: uint)
|
||||
-> Result<Vec<ty::Region> , ()> {
|
||||
-> Result<Vec<ty::Region>, ()> {
|
||||
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<Vec<ty::Region>,()> {
|
||||
Ok(Vec::from_elem(count, self.region.clone()))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -94,7 +94,7 @@ pub type Map = Vec<Option<(*const u8, TLSValue, uint)>>;
|
|||
type TLSValue = Box<LocalData + Send>;
|
||||
|
||||
// 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::<Task>) { return None }
|
||||
|
||||
let task: *mut Task = Local::unsafe_borrow();
|
||||
|
|
|
@ -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<LocalIo> {
|
||||
pub fn borrow() -> Option<LocalIo<'a>> {
|
||||
// FIXME(#11053): bad
|
||||
//
|
||||
// This is currently very unsafely implemented. We don't actually
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -15,17 +15,17 @@ struct DerefWithHelper<H, T> {
|
|||
}
|
||||
|
||||
trait Helper<T> {
|
||||
fn helper_borrow<'a>(&'a self) -> &'a T;
|
||||
fn helper_borrow(&self) -> &T;
|
||||
}
|
||||
|
||||
impl<T> Helper<T> for Option<T> {
|
||||
fn helper_borrow<'a>(&'a self) -> &'a T {
|
||||
fn helper_borrow(&self) -> &T {
|
||||
self.as_ref().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, H: Helper<T>> Deref<T> for DerefWithHelper<H, T> {
|
||||
fn deref<'a>(&'a self) -> &'a T {
|
||||
fn deref(&self) -> &T {
|
||||
self.helper.helper_borrow()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -156,7 +156,7 @@ impl Table {
|
|||
}
|
||||
}
|
||||
|
||||
fn iter<'a>(&'a self) -> Items<'a> {
|
||||
fn iter(&self) -> Items {
|
||||
Items { cur: None, items: self.items.iter() }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
// other `&mut` pointers.
|
||||
|
||||
trait Foo {
|
||||
fn f1<'a>(&'a mut self) -> &'a ();
|
||||
fn f1(&mut self) -> &();
|
||||
fn f2(&mut self);
|
||||
}
|
||||
|
||||
|
|
|
@ -18,13 +18,13 @@ struct Own<T> {
|
|||
}
|
||||
|
||||
impl<T> Deref<T> for Own<T> {
|
||||
fn deref<'a>(&'a self) -> &'a T {
|
||||
fn deref(&self) -> &T {
|
||||
unsafe { &*self.value }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> DerefMut<T> for Own<T> {
|
||||
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<Point>) {
|
|||
let _i = &mut x.y;
|
||||
}
|
||||
|
||||
fn deref_extend_field<'a>(x: &'a Own<Point>) -> &'a int {
|
||||
fn deref_extend_field(x: &Own<Point>) -> &int {
|
||||
&x.y
|
||||
}
|
||||
|
||||
fn deref_extend_mut_field1<'a>(x: &'a Own<Point>) -> &'a mut int {
|
||||
fn deref_extend_mut_field1(x: &Own<Point>) -> &mut int {
|
||||
&mut x.y //~ ERROR cannot borrow
|
||||
}
|
||||
|
||||
fn deref_extend_mut_field2<'a>(x: &'a mut Own<Point>) -> &'a mut int {
|
||||
fn deref_extend_mut_field2(x: &mut Own<Point>) -> &mut int {
|
||||
&mut x.y
|
||||
}
|
||||
|
||||
fn deref_extend_mut_field3<'a>(x: &'a mut Own<Point>) {
|
||||
fn deref_extend_mut_field3(x: &mut Own<Point>) {
|
||||
// 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<Point>) {
|
|||
x.set(0, 0);
|
||||
}
|
||||
|
||||
fn deref_extend_method<'a>(x: &'a Own<Point>) -> &'a int {
|
||||
fn deref_extend_method(x: &Own<Point>) -> &int {
|
||||
x.x_ref()
|
||||
}
|
||||
|
||||
fn deref_extend_mut_method1<'a>(x: &'a Own<Point>) -> &'a mut int {
|
||||
fn deref_extend_mut_method1(x: &Own<Point>) -> &mut int {
|
||||
x.y_mut() //~ ERROR cannot borrow
|
||||
}
|
||||
|
||||
fn deref_extend_mut_method2<'a>(x: &'a mut Own<Point>) -> &'a mut int {
|
||||
fn deref_extend_mut_method2(x: &mut Own<Point>) -> &mut int {
|
||||
x.y_mut()
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ struct Rc<T> {
|
|||
}
|
||||
|
||||
impl<T> Deref<T> for Rc<T> {
|
||||
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<Point>) {
|
|||
let _i = &mut x.y; //~ ERROR cannot borrow
|
||||
}
|
||||
|
||||
fn deref_extend_field<'a>(x: &'a Rc<Point>) -> &'a int {
|
||||
fn deref_extend_field(x: &Rc<Point>) -> &int {
|
||||
&x.y
|
||||
}
|
||||
|
||||
fn deref_extend_mut_field1<'a>(x: &'a Rc<Point>) -> &'a mut int {
|
||||
fn deref_extend_mut_field1(x: &Rc<Point>) -> &mut int {
|
||||
&mut x.y //~ ERROR cannot borrow
|
||||
}
|
||||
|
||||
fn deref_extend_mut_field2<'a>(x: &'a mut Rc<Point>) -> &'a mut int {
|
||||
fn deref_extend_mut_field2(x: &mut Rc<Point>) -> &mut int {
|
||||
&mut x.y //~ ERROR cannot borrow
|
||||
}
|
||||
|
||||
|
@ -95,15 +95,15 @@ fn deref_mut_method2(mut x: Rc<Point>) {
|
|||
x.set(0, 0); //~ ERROR cannot borrow
|
||||
}
|
||||
|
||||
fn deref_extend_method<'a>(x: &'a Rc<Point>) -> &'a int {
|
||||
fn deref_extend_method(x: &Rc<Point>) -> &int {
|
||||
x.x_ref()
|
||||
}
|
||||
|
||||
fn deref_extend_mut_method1<'a>(x: &'a Rc<Point>) -> &'a mut int {
|
||||
fn deref_extend_mut_method1(x: &Rc<Point>) -> &mut int {
|
||||
x.y_mut() //~ ERROR cannot borrow
|
||||
}
|
||||
|
||||
fn deref_extend_mut_method2<'a>(x: &'a mut Rc<Point>) -> &'a mut int {
|
||||
fn deref_extend_mut_method2(x: &mut Rc<Point>) -> &mut int {
|
||||
x.y_mut() //~ ERROR cannot borrow
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
use std::gc::{GC, Gc};
|
||||
|
||||
fn foo<'a>(x: &'a Gc<int>) -> &'a int {
|
||||
fn foo(x: &Gc<int>) -> &int {
|
||||
match x {
|
||||
&ref y => {
|
||||
&**y // Do not expect an error here
|
||||
|
|
|
@ -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<Foo>) -> &() {
|
||||
fn owned_receiver(x: Box<Foo>) -> &'static () {
|
||||
x.borrowed() //~ ERROR `*x` does not live long enough
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ struct MyVec<T> {
|
|||
}
|
||||
|
||||
impl<T> Index<uint, T> for MyVec<T> {
|
||||
fn index<'a>(&'a self, &i: &uint) -> &'a T {
|
||||
fn index(&self, &i: &uint) -> &T {
|
||||
self.data.get(i)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<String> = 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
|
||||
|
|
|
@ -15,7 +15,7 @@ use std::ops::Deref;
|
|||
struct Foo;
|
||||
|
||||
impl Deref<Foo> for Foo {
|
||||
fn deref<'a>(&'a self) -> &'a Foo {
|
||||
fn deref(&self) -> &Foo {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ struct thing<'a, Q> {
|
|||
x: &'a Q
|
||||
}
|
||||
|
||||
fn thing<Q>(x: &Q) -> thing<Q> {
|
||||
fn thing<'a,Q>(x: &Q) -> thing<'a,Q> {
|
||||
thing{ x: x } //~ ERROR cannot infer
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ pub enum TraitWrapper {
|
|||
A(Box<MyTrait>),
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
|
|
@ -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<B> = box B {i:1};
|
||||
let bb: &B = &*b; //~ ERROR does not live long enough
|
||||
make_a(bb)
|
||||
|
|
|
@ -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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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() {}
|
||||
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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!()
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
fn of<T>() -> |T| { fail!(); }
|
||||
fn of<'a,T>() -> |T|:'a { fail!(); }
|
||||
fn subtype<T>(x: |T|) { fail!(); }
|
||||
|
||||
fn test_fn<'x,'y,'z,T>(_x: &'x T, _y: &'y T, _z: &'z T) {
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ fn x_coord<'r>(p: &'r point) -> &'r int {
|
|||
return &p.x;
|
||||
}
|
||||
|
||||
fn foo(p: Gc<point>) -> &int {
|
||||
fn foo<'a>(p: Gc<point>) -> &'a int {
|
||||
let xc = x_coord(&*p); //~ ERROR `*p` does not live long enough
|
||||
assert_eq!(*xc, 3);
|
||||
return xc;
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
use std::gc::Gc;
|
||||
|
||||
fn borrow<'r, T>(x: &'r T) -> &'r T {x}
|
||||
fn borrow<T>(x: &T) -> &T {x}
|
||||
|
||||
fn foo(cond: || -> bool, make_box: || -> Gc<int>) {
|
||||
let mut y: ∫
|
||||
|
|
|
@ -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() {}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ fn with<R>(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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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<B> = box B {
|
||||
i: 1,
|
||||
};
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -60,7 +60,7 @@ impl<T> Mutable for cat<T> {
|
|||
impl<T> Map<int, T> for cat<T> {
|
||||
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<T> MutableMap<int, T> for cat<T> {
|
|||
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<T> MutableMap<int, T> for cat<T> {
|
|||
}
|
||||
|
||||
impl<T> cat<T> {
|
||||
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"); }
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ impl<'a> font<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn font<'r>(fontbuf: &'r Vec<u8> ) -> font<'r> {
|
||||
fn font(fontbuf: &Vec<u8> ) -> font {
|
||||
font {
|
||||
fontbuf: fontbuf
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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() {}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ impl<T> E<T> {
|
|||
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)
|
||||
|
|
|
@ -43,7 +43,7 @@ impl ops::Not<Point> for Point {
|
|||
}
|
||||
|
||||
impl ops::Index<bool,int> for Point {
|
||||
fn index<'a>(&'a self, x: &bool) -> &'a int {
|
||||
fn index(&self, x: &bool) -> &int {
|
||||
if *x {
|
||||
&self.x
|
||||
} else {
|
||||
|
|
|
@ -33,14 +33,14 @@ impl<T> DerefCounter<T> {
|
|||
}
|
||||
|
||||
impl<T> Deref<T> for DerefCounter<T> {
|
||||
fn deref<'a>(&'a self) -> &'a T {
|
||||
fn deref(&self) -> &T {
|
||||
self.count_imm.set(self.count_imm.get() + 1);
|
||||
&self.value
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> DerefMut<T> for DerefCounter<T> {
|
||||
fn deref_mut<'a>(&'a mut self) -> &'a mut T {
|
||||
fn deref_mut(&mut self) -> &mut T {
|
||||
self.count_mut += 1;
|
||||
&mut self.value
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ impl<X, Y> DerefWrapper<X, Y> {
|
|||
}
|
||||
|
||||
impl<X, Y> Deref<Y> for DerefWrapper<X, Y> {
|
||||
fn deref<'a>(&'a self) -> &'a Y {
|
||||
fn deref(&self) -> &Y {
|
||||
&self.y
|
||||
}
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ mod priv_test {
|
|||
}
|
||||
|
||||
impl<X, Y> Deref<Y> for DerefWrapperHideX<X, Y> {
|
||||
fn deref<'a>(&'a self) -> &'a Y {
|
||||
fn deref(&self) -> &Y {
|
||||
&self.y
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,17 +15,17 @@ struct DerefWithHelper<H, T> {
|
|||
}
|
||||
|
||||
trait Helper<T> {
|
||||
fn helper_borrow<'a>(&'a self) -> &'a T;
|
||||
fn helper_borrow(&self) -> &T;
|
||||
}
|
||||
|
||||
impl<T> Helper<T> for Option<T> {
|
||||
fn helper_borrow<'a>(&'a self) -> &'a T {
|
||||
fn helper_borrow(&self) -> &T {
|
||||
self.as_ref().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, H: Helper<T>> Deref<T> for DerefWithHelper<H, T> {
|
||||
fn deref<'a>(&'a self) -> &'a T {
|
||||
fn deref(&self) -> &T {
|
||||
self.helper.helper_borrow()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,14 +33,14 @@ impl<T> DerefCounter<T> {
|
|||
}
|
||||
|
||||
impl<T> Deref<T> for DerefCounter<T> {
|
||||
fn deref<'a>(&'a self) -> &'a T {
|
||||
fn deref(&self) -> &T {
|
||||
self.count_imm.set(self.count_imm.get() + 1);
|
||||
&self.value
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> DerefMut<T> for DerefCounter<T> {
|
||||
fn deref_mut<'a>(&'a mut self) -> &'a mut T {
|
||||
fn deref_mut(&mut self) -> &mut T {
|
||||
self.count_mut += 1;
|
||||
&mut self.value
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ struct Foo {
|
|||
}
|
||||
|
||||
impl Index<int,int> 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<int,int> for Foo {
|
|||
}
|
||||
|
||||
impl IndexMut<int,int> 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 {
|
||||
|
|
|
@ -18,7 +18,7 @@ struct Character {
|
|||
pos: Box<Point>,
|
||||
}
|
||||
|
||||
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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
// except according to those terms.
|
||||
|
||||
|
||||
fn view<'r, T>(x: &'r [T]) -> &'r [T] {x}
|
||||
fn view<T>(x: &[T]) -> &[T] {x}
|
||||
|
||||
pub fn main() {
|
||||
let v = vec!(1i, 2, 3);
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
use std::gc::GC;
|
||||
|
||||
fn borrow<'r, T>(x: &'r T) -> &'r T {x}
|
||||
fn borrow<T>(x: &T) -> &T {x}
|
||||
|
||||
pub fn main() {
|
||||
let x = box(GC) 3i;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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)}
|
||||
}
|
||||
|
||||
|
|
|
@ -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: T, f: |T| -> T) -> T { f(t) }
|
||||
|
||||
|
|
|
@ -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<T>) -> &'r T {
|
||||
fn get<T>(opt: &Option<T>) -> &T {
|
||||
match *opt {
|
||||
Some(ref v) => v,
|
||||
None => fail!("none")
|
||||
|
|
|
@ -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}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue