I thought ATPIT would make this code compile?

#![feature(impl_trait_in_assoc_type)]

pub trait Args {
    type F;

    fn call(self, f: &Self::F);
}

impl Args for () {
    type F = impl Fn();
    
    fn call(self, f: &Self::F) {
        (f)();
    }
}

(Playground)

Errors:

   Compiling playground v0.0.1 (/playground)
error: unconstrained opaque type
  --> src/lib.rs:10:14
   |
10 |     type F = impl Fn();
   |              ^^^^^^^^^
   |
   = note: `F` must be used in combination with a concrete type within the same impl

error: could not compile `playground` (lib) due to 1 previous error

*IT*s require some sort of defining use site(s), and being an argument isn't a definiing use site. I haven't kept up on which way the wind is blowing lately, but here's one of the main issues on the topic (for TAIT).

(Edit: Mentioning the alias in an argument does make the function body a potential definition site, see @kpreid's post below.)

But the details aren't very important for your example; there's nothing that could be a defining use there.

Here's a modification that does contain a defining use.

4 Likes

Thank you very much for the answer! It filled the missing gaps which the original error message failed to convey :slight_smile:

It can be if you constrain the type in the body. This code compiles:

#![feature(impl_trait_in_assoc_type)]

pub trait Foo {
    type F;

    fn call(self, f: &Self::F);
}

impl Foo for () {
    type F = impl std::fmt::Display;
    
    fn call(self, f: &Self::F) {
        let _: &String = f;
    }
}

This is not very useful by itself, though, because there's no way (I think) to call that function; you need a return-position usage to be able to create a value of the opaque type.

3 Likes

Thanks for the correction.

You can get access to an opaque type through other means than a return-position usage.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.