rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
98.46k stars 12.73k forks source link

where bounds not properly inherited? #88048

Open SoniEx2 opened 3 years ago

SoniEx2 commented 3 years ago

I tried this code:

pub trait Kind where for<'a> &'a Self::Values: IntoIterator<Item=&'a Self> {
    type Values;
}
pub trait DataSource<T: Kind> {
    fn get_values(&self) -> &T::Values;
}

struct Foo;

impl Kind for Foo {
    type Values = Vec<Foo>;
}

struct Bar {
    foo: Vec<Foo>
}

impl DataSource<Foo> for Bar {
    fn get_values(&self) -> &Vec<Foo> {
        &self.foo
    }
}

fn main() {

}

I expected to see this happen: We thought it would just... work.

Instead, this happened: It causes this very confusing error:

   Compiling playground v0.0.1 (/playground)
error[E0277]: `&'a <T as Kind>::Values` is not an iterator
 --> src/main.rs:4:25
  |
1 | pub trait Kind where for<'a> &'a Self::Values: IntoIterator<Item=&'a Self> {
  |                                                --------------------------- required by this bound in `Kind`
...
4 | pub trait DataSource<T: Kind> {
  |                         ^^^^ `&'a <T as Kind>::Values` is not an iterator
  |
  = help: the trait `Iterator` is not implemented for `&'a <T as Kind>::Values`
  = note: required because of the requirements on the impl of `for<'a> IntoIterator` for `&'a <T as Kind>::Values`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.
error: could not compile `playground`

To learn more, run the command again with --verbose.

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=3ec5006f8378c11861c1c24614814594

This legit feels like something that should be accepted, even if RFC 1214 says it shouldn't. It became a warning on rust 1.4.0 and a hard error on rust 1.7.0.

Meta

rustc --version --verbose:

<version>
Backtrace

``` ```

SoniEx2 commented 3 years ago

Ironically, this works today:

pub trait Kind where for<'a> &'a Self::Values: IntoIterator<Item=&'a Self> {
    type Values: IntoIterator<Item=Self>;
}
pub trait DataSource<T: Kind> where for<'a> &'a T::Values: IntoIterator<Item=&'a T> {
    fn get_values(&self) -> &T::Values;
}

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=68566a3ea4869427961275309d41af9d

In fact, it just works if you copy the where for into every single thing that references T: Kind, which... is a complete pain, honestly.

SkiFire13 commented 3 years ago

Looks like a duplicate of #20671

SoniEx2 commented 3 years ago

That seems subtly different: this used to work on Rust 1.3.0, whereas that one didn't. This is a regression from stable to stable, whereas that one isn't.

Note that even something like:

pub trait Kind where for<'a> &'a Self::Values: IntoIterator<Item=&'a Self> {
    type Values: IntoIterator<Item=Self>;
}

pub trait OverridableKind: Kind {
}

fails today: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=f168037dddb59d67bfd8bfdd37e4b870

but not in 1.3.0: https://godbolt.org/#g:!((g:!((g:!((h:codeEditor,i:(fontScale:14,fontUsePx:'0',j:1,lang:rust,selection:(endColumn:2,endLineNumber:6,positionColumn:2,positionLineNumber:6,selectionStartColumn:2,selectionStartLineNumber:6,startColumn:2,startLineNumber:6),source:'pub+trait+Kind+where+for%3C!'a%3E+%26!'a+Self::Values:+IntoIterator%3CItem%3D%26!'a+Self%3E+%7B%0A++++type+Values:+IntoIterator%3CItem%3DSelf%3E%3B%0A%7D%0A%0Apub+trait+OverridableKind:+Kind+%7B%0A%7D'),l:'5',n:'0',o:'Rust+source+%231',t:'0')),k:33.333333333333336,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((h:compiler,i:(compiler:r130,filters:(b:'0',binary:'1',commentOnly:'0',demangle:'0',directives:'0',execute:'1',intel:'0',libraryCode:'0',trim:'1'),flagsViewOpen:'1',fontScale:14,fontUsePx:'0',j:1,lang:rust,libs:!(),options:'',selection:(endColumn:1,endLineNumber:1,positionColumn:1,positionLineNumber:1,selectionStartColumn:1,selectionStartLineNumber:1,startColumn:1,startLineNumber:1),source:1),l:'5',n:'0',o:'rustc+1.3.0+(Rust,+Editor+%231,+Compiler+%231)',t:'0')),k:33.333333333333336,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((h:output,i:(compiler:1,editor:1,fontScale:14,fontUsePx:'0',wrap:'1'),l:'5',n:'0',o:'Output+of+rustc+1.3.0+(Compiler+%231)',t:'0')),k:33.33333333333333,l:'4',n:'0',o:'',s:0,t:'0')),l:'2',n:'0',o:'',t:'0')),version:4