Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disallow type/lifetime parameter shadowing. #459

Merged
merged 1 commit into from
Nov 29, 2014
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 91 additions & 0 deletions text/0000-parameter-shadowing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
- Start Date: (fill me in with today's date, YYYY-MM-DD)
- RFC PR: (leave this empty)
- Rust Issue: (leave this empty)

# 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.