Skip to content

Commit 5f56e0b

Browse files
committed
Merge branch 'nikomatsakis-shadowing'
2 parents 63535c1 + 0647cda commit 5f56e0b

File tree

1 file changed

+91
-0
lines changed

1 file changed

+91
-0
lines changed

text/0459-disallow-shadowing.md

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
- Start Date: 2014-11-29
2+
- RFC PR: #459
3+
- Rust Issue: [19390](https://github.com/rust-lang/rust/issues/19390)
4+
5+
# Summary
6+
7+
Disallow type/lifetime parameter shadowing.
8+
9+
# Motivation
10+
11+
Today we allow type and lifetime parameters to be shadowed. This is a
12+
common source of bugs as well as confusing errors. An example of such a confusing case is:
13+
14+
```rust
15+
struct Foo<'a> {
16+
x: &'a int
17+
}
18+
19+
impl<'a> Foo<'a> {
20+
fn set<'a>(&mut self, v: &'a int) {
21+
self.x = v;
22+
}
23+
}
24+
25+
fn main() { }
26+
```
27+
28+
In this example, the lifetime parameter `'a` is shadowed on the method, leading to two
29+
logically distinct lifetime parameters with the same name. This then leads to the error
30+
message:
31+
32+
mismatched types: expected `&'a int`, found `&'a int` (lifetime mismatch)
33+
34+
which is obviously completely unhelpful.
35+
36+
Similar errors can occur with type parameters:
37+
38+
```rust
39+
struct Foo<T> {
40+
x: T
41+
}
42+
43+
impl<T> Foo<T> {
44+
fn set<T>(&mut self, v: T) {
45+
self.x = v;
46+
}
47+
}
48+
49+
fn main() { }
50+
```
51+
52+
Compiling this program yields:
53+
54+
mismatched types: expected `T`, found `T` (expected type parameter, found a different type parameter)
55+
56+
Here the error message was improved by [a recent PR][pr], but this is
57+
still a somewhat confusing situation.
58+
59+
Anecdotally, this kind of accidental shadowing is fairly frequent
60+
occurrence. It recently arose on [this discuss thread][dt], for
61+
example.
62+
63+
[dt]: http://discuss.rust-lang.org/t/confused-by-lifetime-error-messages-tell-me-about-it/358/41?u=nikomatsakis
64+
[pr]: https://github.com/rust-lang/rust/pull/18264
65+
66+
# Detailed design
67+
68+
Disallow shadowed type/lifetime parameter declarations. An error would
69+
be reported by the resolve/resolve-lifetime passes in the compiler and
70+
hence fairly early in the pipeline.
71+
72+
# Drawbacks
73+
74+
We otherwise allow shadowing, so it is inconsistent.
75+
76+
# Alternatives
77+
78+
We could use a lint instead. However, we'd want to ensure that the
79+
lint error messages were printed *before* type-checking begins. We
80+
could do this, perhaps, by running the lint printing pass multiple
81+
times. This might be useful in any case as the placement of lints in
82+
the compiler pipeline has proven problematic before.
83+
84+
We could also attempt to improve the error messages. Doing so for
85+
lifetimes is definitely important in any case, but also somewhat
86+
tricky due to the extensive inference. It is usually easier and more
87+
reliable to help avoid the error in the first place.
88+
89+
# Unresolved questions
90+
91+
None.

0 commit comments

Comments
 (0)