Michael (cc'ing rust-dev)- On 22 May 2014, at 16:32, Michael Woerister <michaelwoeris...@posteo.net> wrote:
> Lately I've been thinking that it might be nice if one could omit the > lifetimes from the list of generic parameters, as in: > > fn foo<T>(x: &'a T, y: &'b MyStruct) -> (&'b int, &'a uint) > > instead of > > fn foo<'a, 'b, T>(x: &'a T, y: &'b MyStruct) -> (&'b int, &'a uint) > > Especially for otherwise non-generic functions, having to explicitly list > lifetimes seems a bit redundant, as they are unambiguously defined in the > function signature anyway (as opposed to type parameters, which don't have > the special `'` marker). Note that this is not true in the general case. Consider e.g. methods with an type impl or a trait impl: in that scenario, one could bind lifetimes on the method itself, or in the type/trait being implemented. This distinction matters (in terms of what limits it imposes on the clients of those types/traits). (I provide a concrete example after my signature.) There are other changes one could make to still accommodate a change like you suggest in the general case, such as inferring some binding site (e.g. the nearest one) if a lifetime is otherwise found to be unbound. But I personally do not think such changes improve the character of the language (IMHO); I'd rather have a straight-forward rule that one applies in every context. Cheers, -Felix Concrete Example: The variants below are quite different. #[deriving(Show)] struct S<'a> { p: &'a int } impl<'a> S<'a> { #[cfg(variant1)] fn foo(&mut self, arg: &'a int) -> &'a int { let old = self.p; self.p = arg; old } #[cfg(variant2)] fn foo<'a>(&mut self, arg: &'a int) -> &'a int { let old = self.p; self.p = arg; old } #[cfg(variant3)] fn foo<'a>(&mut self, arg: &'a int) -> &'a int { arg } #[cfg(variant4)] fn foo<'a>(&mut self, arg: &'a int) -> &'a int { self.p } #[cfg(variant5)] fn foo<'a>(&self, arg: &'a int) -> &'a int { self.p } #[cfg(variant6)] fn foo<'a>(&'a self, arg: &'a int) -> &'a int { let _ = arg; self.p } } #[allow(unused_mut)] fn main() { let x = 3; let mut s = S{ p: &x }; let y = 4; println!("begin: {:?}", s); let z = s.foo(&y); println!("later: {:?} z: {:?}", s, z); } Half of them do not compile (for differing reasons). Variants 1, 3, and 6 do run (and each produces a different output), but the interesting points come from understanding why the other cases do not compile. (FYI: It is probably easier to talk about the example if you first alpha-rename the method-bound lifetimes to something other than `'a`.) _______________________________________________ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev