Skip to content

Incorrect "associated type must be specified" for trait objects #23856

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Closed
theemathas opened this issue Mar 30, 2015 · 11 comments
Closed

Incorrect "associated type must be specified" for trait objects #23856

theemathas opened this issue Mar 30, 2015 · 11 comments
Labels
A-associated-items Area: Associated items (types, constants & functions) C-bug Category: This is a bug.

Comments

@theemathas
Copy link
Contributor

theemathas commented Mar 30, 2015

Code:

trait MyIterator: Iterator<Item = char> {}

impl<T: ?Sized + Iterator<Item=char> + 'static> MyIterator for T {}

struct TestStruct {
    data: Box<MyIterator + 'static>,
}

fn new_struct(string: &'static str) -> TestStruct {
    TestStruct {
        data: Box::new(string.chars()) as Box<MyIterator + 'static>,
        //also does not compile
        //data: Box::new(string.chars()) as Box<MyIterator<Item=char> + 'static>,
    }
}

fn main() {}

Error:

<anon>:11:15: 11:39 error: the value of the associated type `Item` (from the trait `core::iter::Iterator`) must be specified [E0191]
<anon>:11         data: Box::new(string.chars()) as Box<MyIterator + 'static>,
                        ^~~~~~~~~~~~~~~~~~~~~~~~

playpen

I expect this code to compile without errors.

EDIT

This is the error on the current version:

   Compiling playground v0.0.1 (file:///playground)
error[E0191]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) must be specified
 --> src/main.rs:6:15
  |
6 |     data: Box<MyIterator + 'static>,
  |               ^^^^^^^^^^^^^^^^^^^^ missing associated type `Item` value

error: aborting due to previous error

error: Could not compile `playground`.

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

Changing line 6 to data: Box<MyIterator<Item=char> + 'static>, moves the error to line 11:

   Compiling playground v0.0.1 (file:///playground)
error[E0191]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) must be specified
  --> src/main.rs:11:47
   |
11 |         data: Box::new(string.chars()) as Box<MyIterator + 'static>,
   |                                               ^^^^^^^^^^^^^^^^^^^^ missing associated type `Item` value

error[E0308]: mismatched types
  --> src/main.rs:11:15
   |
11 |         data: Box::new(string.chars()) as Box<MyIterator + 'static>,
   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected trait `MyIterator<Item=char>`, found trait `MyIterator`
   |
   = note: expected type `std::boxed::Box<MyIterator<Item=char> + 'static>`
              found type `std::boxed::Box<MyIterator + 'static>`
   = help: here are some functions which might fulfill your needs:
           - .collect()
           - .product()
           - .sum()

error: aborting due to 2 previous errors

error: Could not compile `playground`.

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

However, commenting line 11 and uncommenting line 13 makes the code compile fine.

@steveklabnik
Copy link
Member

Very strange. I'd expect the Item=char version to compile.

@Twey
Copy link

Twey commented Dec 9, 2016

(comment copied from duplicate #36978 for locality purposes, since it contains a more-M WE)

Consider the following:

trait Foo { type FooT; }
trait Bar { }
trait FooBar: Foo<FooT=usize> + Bar { }
type BoxedFooBar = Box<FooBar>;

Since the value of FooT is known from the definition of FooBar, line 4 should be fine — if FB: FooBar then necessarily FB::FooT = usize. However, this fails to compile with rustc 1.12.0, with the error:

error[E0191]: the value of the associated type `FooT` (from the trait `Foo`) must be specified
 --> <anon>:4:24
  |
4 | type BoxedFooBar = Box<FooBar>;
  |                        ^^^^^^ missing associated type `FooT` value

To make it compile, one must duplicate the information at every use-site:

trait Foo { type FooT; }
trait Bar { }
trait FooBar: Foo<FooT=usize> + Bar { }
type BoxedFooBar = Box<FooBar<FooT=usize>>;

@Mark-Simulacrum Mark-Simulacrum added the C-bug Category: This is a bug. label Jul 22, 2017
@thanatos
Copy link
Contributor

thanatos commented Aug 3, 2017

Am I looking at an example of this, or something else entirely? Playground example; that fails to compile with the same error as above in this thread.

(Note that this example contains an error on my part: I intended to use the template parameter C, and write &mut C, and not have that trait object. If I correct that, it does compile.)

@Twey
Copy link

Twey commented Aug 4, 2017

Yes, this is the same thing.

@ExpHP
Copy link
Contributor

ExpHP commented Sep 4, 2017

Just ran into this today. As mentioned by @thanatos and in some linked duplicates, it appears to only impact trait objects. (if it impacted generic type parameters, I think there would be a lot more fuss over it!)

trait MyFunc: FnMut() {}
impl<F:FnMut()> MyFunc for F {}

// OK
fn takes_generic<F: MyFunc>(mut f: F) { f(); }
// Error: missing associated type `Output` value
fn takes_trait_object(f: &mut MyFunc) { f(); }

fn main() {}

Changing the trait object to a generic type parameter is a workaround in many, but not all, use cases.

@vorot93
Copy link

vorot93 commented Feb 6, 2018

Just ran into this bug while trying to mix Box with Stream and Sink supertraits from futures crate. Very annoying!

@theemathas theemathas changed the title Incorrect "associated type must be specified" for supertrait Incorrect "associated type must be specified" for trait objects Feb 6, 2018
@bkchr
Copy link
Contributor

bkchr commented Feb 9, 2018

I ran into the same bug, in the same situation like @vorot93.

@Arignir
Copy link

Arignir commented Jun 11, 2018

I ran into that problem too, it's quite annoying. I hope a fix will pop soon.

@alexreg
Copy link
Contributor

alexreg commented Oct 10, 2018

Any progress on this lately?

pietroalbini added a commit to pietroalbini/rust that referenced this issue Nov 10, 2018
Take supertraits into account when calculating associated types

Fixes rust-lang#24010 and rust-lang#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 rust-lang#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
@Imxset21
Copy link

I think this issue has been resolved as of PR #55687, correct? The linked playgrounds no longer fail to compile, at least on a cursory inspection. Could we close this issue out?

@Twey
Copy link

Twey commented Mar 21, 2019

Looks fixed to me.

@Centril Centril closed this as completed Mar 21, 2019
ExpHP added a commit to ExpHP/rsp2 that referenced this issue Apr 8, 2019
The workaround for rust-lang/rust#23856 can now be removed.
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
A-associated-items Area: Associated items (types, constants & functions) C-bug Category: This is a bug.
Projects
None yet
Development

No branches or pull requests