Rollup merge of #55687 - alexreg:fix-24010, r=scalexm
Take supertraits into account when calculating associated types Fixes #24010 and #23856. Applies to trait aliases too. As a by-product, this PR also makes repeated bindings of the same associated item in the same definition a hard error. This was previously a warning with a note about it becoming a hard error in the future. See #50589 for more info. I talked about this with @nikomatsakis recently, but only very superficially, so this shouldn't stop anyone from assigning it to themself to review and r+. N.B. The "WIP" commits represent imperfect attempts to solve the problem just for trait objects, but I've left them in for reference for the sake of whomever is reviewing this. CC @carllerche @theemathas @durka @mbrubeck
This commit is contained in:
commit
0e912b2c17
28 changed files with 302 additions and 199 deletions
|
|
@ -0,0 +1,17 @@
|
|||
// Copyright 2018 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.
|
||||
|
||||
#![feature(trait_alias)]
|
||||
|
||||
trait I32Iterator = Iterator<Item = i32>;
|
||||
|
||||
fn main() {
|
||||
let _: &I32Iterator<Item = u32> = &vec![42].into_iter();
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
error[E0271]: type mismatch resolving `<std::vec::IntoIter<u32> as std::iter::Iterator>::Item == i32`
|
||||
--> $DIR/associated-types-overridden-binding-2.rs:16:39
|
||||
|
|
||||
LL | let _: &I32Iterator<Item = u32> = &vec![42].into_iter();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ expected u32, found i32
|
||||
|
|
||||
= note: expected type `u32`
|
||||
found type `i32`
|
||||
= note: required for the cast to the object type `dyn I32Iterator<Item=u32, Item=i32>`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0271`.
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
// Copyright 2018 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.
|
||||
|
||||
#![feature(trait_alias)]
|
||||
|
||||
trait Foo: Iterator<Item = i32> {}
|
||||
trait Bar: Foo<Item = u32> {}
|
||||
|
||||
trait I32Iterator = Iterator<Item = i32>;
|
||||
trait U32Iterator = I32Iterator<Item = u32>;
|
||||
|
||||
fn main() {
|
||||
let _: &I32Iterator<Item = u32>;
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
error[E0284]: type annotations required: cannot resolve `<Self as std::iter::Iterator>::Item == i32`
|
||||
--> $DIR/associated-types-overridden-binding.rs:14:1
|
||||
|
|
||||
LL | trait Bar: Foo<Item = u32> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: required by `Foo`
|
||||
--> $DIR/associated-types-overridden-binding.rs:13:1
|
||||
|
|
||||
LL | trait Foo: Iterator<Item = i32> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0284`.
|
||||
|
|
@ -14,5 +14,4 @@ trait Trait {
|
|||
|
||||
type Foo = Trait; //~ ERROR E0191
|
||||
|
||||
fn main() {
|
||||
}
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -8,16 +8,15 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// compile-pass
|
||||
|
||||
use std::iter::Iterator;
|
||||
trait Foo: Iterator<Item = i32, Item = i32> {}
|
||||
|
||||
type Unit = ();
|
||||
|
||||
fn test() -> Box<Iterator<Item = (), Item = Unit>> {
|
||||
fn test() -> Box<Iterator<Item = (), Item = Unit>> {
|
||||
Box::new(None.into_iter())
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let _: &Iterator<Item = i32, Item = i32>;
|
||||
test();
|
||||
}
|
||||
19
src/test/ui/error-codes/E0719.stderr
Normal file
19
src/test/ui/error-codes/E0719.stderr
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
|
||||
--> $DIR/E0719.rs:11:33
|
||||
|
|
||||
LL | trait Foo: Iterator<Item = i32, Item = i32> {}
|
||||
| ---------- ^^^^^^^^^^ re-bound here
|
||||
| |
|
||||
| `Item` bound here first
|
||||
|
||||
error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
|
||||
--> $DIR/E0719.rs:15:38
|
||||
|
|
||||
LL | fn test() -> Box<Iterator<Item = (), Item = Unit>> {
|
||||
| --------- ^^^^^^^^^^^ re-bound here
|
||||
| |
|
||||
| `Item` bound here first
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0719`.
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
// compile-pass
|
||||
|
||||
#![crate_type = "lib"]
|
||||
#![feature(linkage)]
|
||||
|
||||
// MergeFunctions will merge these via an anonymous internal
|
||||
// backing function, which must be named if ThinLTO buffers are used
|
||||
|
||||
#[linkage = "weak"]
|
||||
pub fn fn1(a: u32, b: u32, c: u32) -> u32 {
|
||||
a + b + c
|
||||
}
|
||||
|
||||
#[linkage = "weak"]
|
||||
pub fn fn2(a: u32, b: u32, c: u32) -> u32 {
|
||||
a + b + c
|
||||
}
|
||||
27
src/test/ui/issues/issue-51947.rs
Normal file
27
src/test/ui/issues/issue-51947.rs
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
// Copyright 2018 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.
|
||||
|
||||
// compile-pass
|
||||
|
||||
#![crate_type = "lib"]
|
||||
#![feature(linkage)]
|
||||
|
||||
// MergeFunctions will merge these via an anonymous internal
|
||||
// backing function, which must be named if ThinLTO buffers are used
|
||||
|
||||
#[linkage = "weak"]
|
||||
pub fn fn1(a: u32, b: u32, c: u32) -> u32 {
|
||||
a + b + c
|
||||
}
|
||||
|
||||
#[linkage = "weak"]
|
||||
pub fn fn2(a: u32, b: u32, c: u32) -> u32 {
|
||||
a + b + c
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
warning: associated type binding `Item` specified more than once
|
||||
--> $DIR/issue-50589-multiple-associated-types.rs:17:39
|
||||
|
|
||||
LL | fn test() -> Box<Iterator<Item = (), Item = Unit>> {
|
||||
| --------- ^^^^^^^^^^^ used more than once
|
||||
| |
|
||||
| first use of `Item`
|
||||
|
|
||||
= note: #[warn(duplicate_associated_type_bindings)] on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #50589 <https://github.com/rust-lang/rust/issues/50589>
|
||||
|
||||
warning: associated type binding `Item` specified more than once
|
||||
--> $DIR/issue-50589-multiple-associated-types.rs:17:39
|
||||
|
|
||||
LL | fn test() -> Box<Iterator<Item = (), Item = Unit>> {
|
||||
| --------- ^^^^^^^^^^^ used more than once
|
||||
| |
|
||||
| first use of `Item`
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #50589 <https://github.com/rust-lang/rust/issues/50589>
|
||||
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
error[E0038]: the trait `EqAlias` cannot be made into an object
|
||||
--> $DIR/trait-alias-objects.rs:17:13
|
||||
--> $DIR/trait-alias-object.rs:17:13
|
||||
|
|
||||
LL | let _: &dyn EqAlias = &123;
|
||||
| ^^^^^^^^^^^ the trait `EqAlias` cannot be made into an object
|
||||
|
|
@ -7,7 +7,7 @@ LL | let _: &dyn EqAlias = &123;
|
|||
= note: the trait cannot use `Self` as a type parameter in the supertraits or where-clauses
|
||||
|
||||
error[E0191]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) must be specified
|
||||
--> $DIR/trait-alias-objects.rs:18:13
|
||||
--> $DIR/trait-alias-object.rs:18:13
|
||||
|
|
||||
LL | let _: &dyn IteratorAlias = &vec![123].into_iter();
|
||||
| ^^^^^^^^^^^^^^^^^ missing associated type `Item` value
|
||||
Loading…
Add table
Add a link
Reference in a new issue