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

Bounds on associated types are not taken into account during typeck #26026

Closed
Gankra opened this issue Jun 5, 2015 · 3 comments
Closed

Bounds on associated types are not taken into account during typeck #26026

Gankra opened this issue Jun 5, 2015 · 3 comments
Labels
A-associated-items Area: Associated items (types, constants & functions) A-typesystem Area: The type system C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-lang Relevant to the language team, which will review and decide on the PR/issue.

Comments

@Gankra
Copy link
Contributor

Gankra commented Jun 5, 2015

Note that this is the current definition of IntoIterator:

pub trait IntoIterator {
    type Item;
    type IntoIter: Iterator<Item=Self::Item>;

    fn into_iter(self) -> Self::IntoIter;
}

So we try to make a type that can be instantiated with any IntoIter, storing its Iterator:

pub struct Internal<I> {
    iter: I
}

impl<I> Internal<I> {
    fn new<It: IntoIterator<IntoIter=I>>(iterable: It) -> Self {
        let iter = iterable.into_iter();
        Internal { iter: iter }
    }
}
<anon>:7:29: 7:40 error: the trait `core::iter::Iterator` is not implemented for the type `I` [E0277]
<anon>:7         let iter = iterable.into_iter();
                                     ^~~~~~~~~~~
<anon>:7:29: 7:40 note: `I` is not an iterator; maybe try calling `.iter()` or a similar method
<anon>:7         let iter = iterable.into_iter();
                                     ^~~~~~~~~~~

Completely nonsensical. Nothing is asking I to be an Iterator, except for IntoIterator's own definiton, which proves that it is in fact an Iterator. But ok, let's try to assert that it is:

pub struct Internal<I> {
    iter: I
}

impl<I: Iterator> Internal<I> {
    fn new<It: IntoIterator<IntoIter=I>>(iterable: It) -> Self {
        let iter = iterable.into_iter();
        Internal { iter: iter }
    }
}
<anon>:7:29: 7:40 error: type mismatch resolving `<I as core::iter::Iterator>::Item == <It as core::iter::IntoIterator>::Item`:
 expected trait `core::iter::Iterator`,
    found trait `core::iter::IntoIterator` [E0271]
<anon>:7         let iter = iterable.into_iter();
                                     ^~~~~~~~~~~

Again nothing is demanding this by IntoIterator, which is already proving it. This works, though:

pub struct Internal<I> {
    iter: I
}

impl<I: Iterator> Internal<I> {
    fn new<It: IntoIterator<IntoIter=I, Item=I::Item>>(iterable: It) -> Self {
        let iter = iterable.into_iter();
        Internal { iter: iter }
    }
}

Which shouldn't be necessary.

@Gankra Gankra added A-typesystem Area: The type system A-associated-items Area: Associated items (types, constants & functions) I-papercut labels Jun 5, 2015
@bluss
Copy link
Member

bluss commented Jun 8, 2015

Rust knows it's right the other way around. It has trouble with carrying over the information for the type equality with I.

This compiles:

pub struct Internal<I> {
    iter: I
}

impl Internal<()> {
    fn new<It: IntoIterator>(iterable: It) -> Internal<It::IntoIter> {
        let iter = iterable.into_iter();
        Internal { iter: iter }
    }
}

@steveklabnik
Copy link
Member

Triage: same issue, slightly different error message today:

error[E0277]: the trait bound `I: std::iter::Iterator` is not satisfied
 --> <anon>:6:5
  |
6 |     fn new<It: IntoIterator<IntoIter=I>>(iterable: It) -> Self {
  |     ^ trait `I: std::iter::Iterator` not satisfied
  |
  = help: consider adding a `where I: std::iter::Iterator` bound
  = note: required by `std::iter::IntoIterator`

@Mark-Simulacrum Mark-Simulacrum changed the title Type checker drops the ball with IntoIterator Bounds on associated types are not taken into account during typeck May 16, 2017
@Mark-Simulacrum Mark-Simulacrum added C-bug Category: This is a bug. and removed I-papercut labels Jul 22, 2017
@jonas-schievink jonas-schievink added T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-lang Relevant to the language team, which will review and decide on the PR/issue. labels Jun 13, 2019
Centril added a commit to Centril/rust that referenced this issue Oct 19, 2019
…asper

Use structured suggestion for restricting bounds

When a trait bound is not met and restricting a type parameter would
make the restriction hold, use a structured suggestion pointing at an
appropriate place (type param in param list or `where` clause).

Account for opaque parameters where instead of suggesting extending
the `where` clause, we suggest appending the new restriction:
`fn foo(impl Trait + UnmetTrait)`. Fix rust-lang#64565, fix rust-lang#41817, fix rust-lang#24354,
cc rust-lang#26026, cc rust-lang#37808, cc rust-lang#24159, fix rust-lang#37138, fix rust-lang#24354, cc rust-lang#20671.
Centril added a commit to Centril/rust that referenced this issue Oct 19, 2019
…asper

Use structured suggestion for restricting bounds

When a trait bound is not met and restricting a type parameter would
make the restriction hold, use a structured suggestion pointing at an
appropriate place (type param in param list or `where` clause).

Account for opaque parameters where instead of suggesting extending
the `where` clause, we suggest appending the new restriction:
`fn foo(impl Trait + UnmetTrait)`. Fix rust-lang#64565, fix rust-lang#41817, fix rust-lang#24354,
cc rust-lang#26026, cc rust-lang#37808, cc rust-lang#24159, fix rust-lang#37138, fix rust-lang#24354, cc rust-lang#20671.
@cjgillot
Copy link
Contributor

cjgillot commented Mar 5, 2022

The report now correctly type-checks.

@cjgillot cjgillot closed this as completed Mar 5, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-associated-items Area: Associated items (types, constants & functions) A-typesystem Area: The type system C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-lang Relevant to the language team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

6 participants