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:
commit
1a019dc86d
20 changed files with 253 additions and 109 deletions
|
|
@ -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() {}
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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() {}
|
||||
|
|
|
|||
44
src/test/compile-fail/inherent-overlap.rs
Normal file
44
src/test/compile-fail/inherent-overlap.rs
Normal 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() {}
|
||||
|
|
@ -17,7 +17,7 @@ impl Foo {
|
|||
Foo { baz: 0 }.bar();
|
||||
}
|
||||
|
||||
fn bar() { //~ ERROR duplicate associated function
|
||||
fn bar() { //~ ERROR duplicate definitions
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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() { }
|
||||
|
|
|
|||
|
|
@ -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 }
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue