Scope of Associated Types in Traits, type (as Alias) and Functions generics

I just started playing with Rust a little bit, I'm enjoying it so far, but a few things aches my brain.
While playing with Traits I found something that I can really reason about:

is there any reason Why I can't do something like this (Line 3):

fn sigma<T:Int, F:Fn(T)->T>(xs:&[T], f:&F) -> T {
    match xs {
        []        => T::zero(),   
        //[3] Why is T only the Function Signature valid and not inside the Function?
        // I'd wait to be able to right T::zero() instead of Int::zero()
        [x, xs..] => f(x) + sigma(xs, f)
    }
}

or when I implement the Add trait for example, why can't I use the Output as Return type?

impl Add for Point {
    type Output = Point;
    fn add(self, other: Point) -> Output {  // this doesn't work I have to use Point
        ...
    }
}

specially in this case, it got really confusing for me
given this function:

fn id(input:isize) -> isize {
   ...
}
type Identifier = isize
let numbe:Identifier = 42
id(number)
// this code works, but using type in traits acts different.

I might be overseeing the reason for that. But it is something that still confusing me.

thanks,
DL

2 Likes

It is a long standing bug/feature request to be able to call static methods on type parameters/type aliases. Solving it is part of the motivation for UFCS. For now, the correct approach is Int::zero() or sometimes <T as Int>::zero() if there are ambiguity errors.

It's an as-yet unimplemented part of the associated items RFC.

1 Like

Hm, this looks like an inconsistency between type parameters and T::foo-like method calls:

struct T;

impl T {
    fn foo() { println!("Foo"); }
}

fn foo<T>() {
    T::foo(); // this prints `Foo`, showing that T is referring
              // to the struct T
    let x: T = T; // but this is a type mismatch, showing that the
                  // first T refers to the type parameter T
}

fn main() {}

Does anyone know if this is intentional/known or bug-report-worthy?

@huon thank you very much for the information provided :+1:

I'll be following the status of this bugs/features.

Not inconsistent. See: Rust Playground

What you're showing is an impl for a type, so the methods are scoped to the type, while type parameters can only be known to have impls for various traits they implement. Since the impls are on traits, the methods are scoped to the trait, and merely overloaded for each distinct combination of type parameters (including the Self type). If/when we have Type::method syntax when method belongs to a trait, it'll be there merely as convenient sugar for UFCS (<Type as Trait>::method) where Trait can be inferred, not as something that is logically required by the structure of the language.