Auto merge of #31925 - aturon:inherent-overlap, r=nikomatsakis

Forbid items with the same name from appearing in overlapping inherent impl blocks

For example, the following is now correctly illegal:

```rust
struct Foo;

impl Foo {
    fn id() {}
}

impl Foo {
    fn id() {}
}
```

"Overlapping" here is determined the same way it is for traits (and in fact shares the same code path): roughly, there must be some way of substituting any generic types to unify the impls, such that none of the `where` clauses are provably unsatisfiable under such a unification.

Along the way, this PR also introduces an `ImplHeader` abstraction (the first commit) that makes it easier to work with impls abstractly (without caring whether they are trait or inherent impl blocks); see the first commit.

Closes #22889
r? @nikomatsakis
This commit is contained in:
bors 2016-03-11 20:57:39 -08:00
commit 1a019dc86d
20 changed files with 253 additions and 109 deletions

View file

@ -14,7 +14,7 @@ struct Foo;
impl Foo {
const bar: bool = true;
fn bar() {} //~ ERROR duplicate associated function
fn bar() {} //~ ERROR duplicate definitions
}
fn main() {}

View file

@ -20,7 +20,7 @@ struct Baz;
impl Foo for Baz {
type Bar = i16;
type Bar = u16; //~ ERROR duplicate associated type
type Bar = u16; //~ ERROR duplicate definitions
}
fn main() {

View file

@ -19,9 +19,9 @@ trait Foo {
impl Foo for () {
type Ty = ();
type Ty = usize; //~ ERROR duplicate associated type
type Ty = usize; //~ ERROR duplicate definitions
const BAR: u32 = 7;
const BAR: u32 = 8; //~ ERROR duplicate associated constant
const BAR: u32 = 8; //~ ERROR duplicate definitions
}
fn main() {

View file

@ -11,7 +11,7 @@
struct Foo;
impl Foo {
fn orange(&self){}
fn orange(&self){} //~ ERROR duplicate method
fn orange(&self){} //~ ERROR duplicate definitions
}
fn main() {}

View file

@ -0,0 +1,44 @@
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// Test that you cannot define items with the same name in overlapping inherent
// impl blocks.
struct Foo;
impl Foo {
fn id() {} //~ ERROR E0201
}
impl Foo {
fn id() {}
}
struct Bar<T>(T);
impl<T> Bar<T> {
fn bar(&self) {} //~ ERROR E0201
}
impl Bar<u32> {
fn bar(&self) {}
}
struct Baz<T>(T);
impl<T: Copy> Baz<T> {
fn baz(&self) {} //~ ERROR E0201
}
impl<T> Baz<Vec<T>> {
fn baz(&self) {}
}
fn main() {}

View file

@ -17,7 +17,7 @@ impl Foo {
Foo { baz: 0 }.bar();
}
fn bar() { //~ ERROR duplicate associated function
fn bar() { //~ ERROR duplicate definitions
}
}

View file

@ -18,7 +18,7 @@ trait Bar {
impl Bar for Foo {
fn bar(&self) -> isize {1}
fn bar(&self) -> isize {2} //~ ERROR duplicate method
fn bar(&self) -> isize {2} //~ ERROR duplicate definitions
}
fn main() {

View file

@ -29,7 +29,7 @@ impl S {
// Cause an error. It shouldn't have any macro backtrace frames.
fn bar(&self) { }
fn bar(&self) { } //~ ERROR duplicate method
fn bar(&self) { } //~ ERROR duplicate definitions
}
fn main() { }

View file

@ -17,15 +17,15 @@ pub trait Bar {
fn quux(self);
}
impl<T> Foo<T> {
impl Foo<u8> {
// @has - '//*[@id="method.pass"]//code' 'fn pass()'
pub fn pass() {}
}
impl<T> Foo<T> {
impl Foo<u16> {
// @has - '//*[@id="method.pass-1"]//code' 'fn pass() -> usize'
pub fn pass() -> usize { 42 }
}
impl<T> Foo<T> {
impl Foo<u32> {
// @has - '//*[@id="method.pass-2"]//code' 'fn pass() -> isize'
pub fn pass() -> isize { 42 }
}