mirror of https://github.com/rust-lang/rfcs.git
Merge branch 'shadowing' of https://github.com/nikomatsakis/rfcs into nikomatsakis-shadowing
This commit is contained in:
commit
0647cda999
|
@ -0,0 +1,91 @@
|
|||
- Start Date: 2014-11-29
|
||||
- RFC PR: #459
|
||||
- Rust Issue: [19390](https://github.com/rust-lang/rust/issues/19390)
|
||||
|
||||
# Summary
|
||||
|
||||
Disallow type/lifetime parameter shadowing.
|
||||
|
||||
# Motivation
|
||||
|
||||
Today we allow type and lifetime parameters to be shadowed. This is a
|
||||
common source of bugs as well as confusing errors. An example of such a confusing case is:
|
||||
|
||||
```rust
|
||||
struct Foo<'a> {
|
||||
x: &'a int
|
||||
}
|
||||
|
||||
impl<'a> Foo<'a> {
|
||||
fn set<'a>(&mut self, v: &'a int) {
|
||||
self.x = v;
|
||||
}
|
||||
}
|
||||
|
||||
fn main() { }
|
||||
```
|
||||
|
||||
In this example, the lifetime parameter `'a` is shadowed on the method, leading to two
|
||||
logically distinct lifetime parameters with the same name. This then leads to the error
|
||||
message:
|
||||
|
||||
mismatched types: expected `&'a int`, found `&'a int` (lifetime mismatch)
|
||||
|
||||
which is obviously completely unhelpful.
|
||||
|
||||
Similar errors can occur with type parameters:
|
||||
|
||||
```rust
|
||||
struct Foo<T> {
|
||||
x: T
|
||||
}
|
||||
|
||||
impl<T> Foo<T> {
|
||||
fn set<T>(&mut self, v: T) {
|
||||
self.x = v;
|
||||
}
|
||||
}
|
||||
|
||||
fn main() { }
|
||||
```
|
||||
|
||||
Compiling this program yields:
|
||||
|
||||
mismatched types: expected `T`, found `T` (expected type parameter, found a different type parameter)
|
||||
|
||||
Here the error message was improved by [a recent PR][pr], but this is
|
||||
still a somewhat confusing situation.
|
||||
|
||||
Anecdotally, this kind of accidental shadowing is fairly frequent
|
||||
occurrence. It recently arose on [this discuss thread][dt], for
|
||||
example.
|
||||
|
||||
[dt]: http://discuss.rust-lang.org/t/confused-by-lifetime-error-messages-tell-me-about-it/358/41?u=nikomatsakis
|
||||
[pr]: https://github.com/rust-lang/rust/pull/18264
|
||||
|
||||
# Detailed design
|
||||
|
||||
Disallow shadowed type/lifetime parameter declarations. An error would
|
||||
be reported by the resolve/resolve-lifetime passes in the compiler and
|
||||
hence fairly early in the pipeline.
|
||||
|
||||
# Drawbacks
|
||||
|
||||
We otherwise allow shadowing, so it is inconsistent.
|
||||
|
||||
# Alternatives
|
||||
|
||||
We could use a lint instead. However, we'd want to ensure that the
|
||||
lint error messages were printed *before* type-checking begins. We
|
||||
could do this, perhaps, by running the lint printing pass multiple
|
||||
times. This might be useful in any case as the placement of lints in
|
||||
the compiler pipeline has proven problematic before.
|
||||
|
||||
We could also attempt to improve the error messages. Doing so for
|
||||
lifetimes is definitely important in any case, but also somewhat
|
||||
tricky due to the extensive inference. It is usually easier and more
|
||||
reliable to help avoid the error in the first place.
|
||||
|
||||
# Unresolved questions
|
||||
|
||||
None.
|
Loading…
Reference in New Issue