Unexpected trait behavior with default_type_params

9cac30f
Opened by Carl Lerche at 2023-05-23 11:15:35

This seems more like an error message issue than anything, but I was very confused for a while. Here is a repro:

#![feature(unboxed_closures)]
#![feature(default_type_params)]

pub trait Invoke<A, R = ()> {
    fn invoke(&mut self, args: A) -> R;
}

impl<A, R, F: Send + FnMut(A) -> R> Invoke<A, R> for F {
    fn invoke(&mut self, args: A) -> R {
        self.call_mut((args,))
    }
}

pub struct Foo;


impl Invoke<uint, uint> for Foo {
    fn invoke(&mut self, args: uint) -> uint {
        args
    }
}

fn repro<A, I: Invoke<A>>(_: I) {
    unimplemented!();
}

pub fn main() {
    repro(Foo);
}

output:

repro.rs:28:5: 28:10 error: the trait `core::ops::Fn<(_,), ()>` is not implemented for the type `Foo`
repro.rs:28     repro(Foo);
                ^~~~~
repro.rs:28:5: 28:10 note: the trait `core::ops::Fn` must be implemented because it is required by `repro`
repro.rs:28     repro(Foo);
                ^~~~~
error: aborting due to previous error
  1. cc me

    Niko Matsakis at 2014-11-08 11:08:55

  2. Triage: updated code:

    #![feature(unboxed_closures)]
    #![feature(default_type_params)]
    
    pub trait Invoke<A, R = ()> {
        fn invoke(&mut self, args: A) -> R;
    }
    
    impl<A, R, F: Send + FnMut(A) -> R> Invoke<A, R> for F {
        fn invoke(&mut self, args: A) -> R {
            self.call_mut((args,))
        }
    }
    
    pub struct Foo;
    
    
    impl Invoke<usize, usize> for Foo {
        fn invoke(&mut self, args: usize) -> usize {
            args
        }
    }
    
    fn repro<A, I: Invoke<A>>(_: I) {
        unimplemented!();
    }
    
    pub fn main() {
        repro(Foo);
    }
    

    same error.

    Steve Klabnik at 2016-02-02 22:02:02

  3. Triage: updated code

    #![feature(fn_traits)]
    #![feature(default_type_params)]
    
    pub trait Invoke<A, R = ()> {
        fn invoke(&mut self, args: A) -> R;
    }
    
    impl<A, R, F: Send + FnMut(A) -> R> Invoke<A, R> for F {
        fn invoke(&mut self, args: A) -> R {
            self.call_mut((args,))
        }
    }
    
    pub struct Foo;
    
    
    impl Invoke<usize, usize> for Foo {
        fn invoke(&mut self, args: usize) -> usize {
            args
        }
    }
    
    fn repro<A, I: Invoke<A>>(_: I) {
        unimplemented!();
    }
    
    pub fn main() {
        repro(Foo);
    }
    

    updated error:

    error[E0277]: expected a `std::ops::FnMut<(_,)>` closure, found `Foo`
      --> src/main.rs:28:5
       |
    28 |     repro(Foo);
       |     ^^^^^ expected an `FnMut<(_,)>` closure, found `Foo`
       |
       = help: the trait `std::ops::FnMut<(_,)>` is not implemented for `Foo`
       = note: required because of the requirements on the impl of `Invoke<_>` for `Foo`
    note: required by `repro`
      --> src/main.rs:23:1
       |
    23 | fn repro<A, I: Invoke<A>>(_: I) {
       | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    

    Steve Klabnik at 2018-09-24 17:53:40