Skip to content

Commit 5185160

Browse files
committed
Merge pull request rust-lang#166 from pnkfelix/fsk-fix-typo-in-39
Clarify definition of "input positions" in lifetime elision RFC.
2 parents dd6f306 + b02141b commit 5185160

File tree

1 file changed

+40
-3
lines changed

1 file changed

+40
-3
lines changed

active/0039-lifetime-elision.md

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,14 +94,20 @@ elided a single lifetime.
9494

9595
Lifetime positions can appear as either "input" or "output":
9696

97-
* For `fn` definitions, input refers to argument types while output refers to
97+
* For `fn` definitions, input refers to the types of the formal arguments
98+
in the `fn` definition, while output refers to
9899
result types. So `fn foo(s: &str) -> (&str, &str)` has elided one lifetime in
99100
input position and two lifetimes in output position.
101+
Note that the input positions of a `fn` method definition do not
102+
include the lifetimes that occur in the method's `impl` header
103+
(nor lifetimes that occur in the trait header, for a default method).
104+
100105

101106
* For `impl` headers, input refers to the lifetimes appears in the type
102107
receiving the `impl`, while output refers to the trait, if any. So `impl<'a>
103-
Foo<'a>` has `'a` in input position, while `impl<'a> SomeTrait<'a> Foo<'a>`
104-
has `'a` in both input and output positions.
108+
Foo<'a>` has `'a` in input position, while `impl<'a, 'b, 'c>
109+
SomeTrait<'b, 'c> for Foo<'a, 'c>` has `'a` in input position, `'b`
110+
in output position, and `'c` in both input and output positions.
105111

106112
### The rules
107113

@@ -152,6 +158,37 @@ impl<'a, 'b> Reader for (&'a str, &'b str) { ... } // expanded
152158

153159
impl StrSlice for &str { ... } // elided
154160
impl<'a> StrSlice<'a> for &'a str { ... } // expanded
161+
162+
trait Bar<'a> { fn bound(&'a self) -> &int { ... } fn fresh(&self) -> &int { ... } } // elided
163+
trait Bar<'a> { fn bound(&'a self) -> &'a int { ... } fn fresh<'b>(&'b self) -> &'b int { ... } } // expanded
164+
165+
impl<'a> Bar<'a> for &'a str {
166+
fn bound(&'a self) -> &'a int { ... } fn fresh(&self) -> &int { ... } // elided
167+
}
168+
impl<'a> Bar<'a> for &'a str {
169+
fn bound(&'a self) -> &'a int { ... } fn fresh<'b>(&'b self) -> &'b int { ... } // expanded
170+
}
171+
172+
// Note that when the impl reuses the same signature (with the same elisions)
173+
// from the trait definition, the expanded forms will also match, and thus
174+
// the `impl` will be compatible with the `trait`.
175+
176+
impl Bar for &str { fn bound(&self) -> &int { ... } } // elided
177+
impl<'a> Bar<'a> for &'a str { fn bound<'b>(&'b self) -> &'b int { ... } } // expanded
178+
179+
// Note that the preceding example's expanded methods do not match the
180+
// signatures from the above trait definition for `Bar`; in the general
181+
// case, if the elided signatures between the `impl` and the `trait` do
182+
// not match, an expanded `impl` may not be compatible with the given
183+
// `trait` (and thus would not compile).
184+
185+
impl Bar for &str { fn fresh(&self) -> &int { ... } } // elided
186+
impl<'a> Bar<'a> for &'a str { fn fresh<'b>(&'b self) -> &'b int { ... } } // expanded
187+
188+
impl Bar for &str {
189+
fn bound(&'a self) -> &'a int { ... } fn fresh(&self) -> &int { ... } // ILLEGAL: unbound 'a
190+
}
191+
155192
```
156193

157194
## Error messages

0 commit comments

Comments
 (0)