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

type parameters of trait functions and impl selection combine in confusing ways #5221

Closed
Kimundi opened this issue Mar 4, 2013 · 11 comments
Closed
Labels
A-type-system Area: Type system

Comments

@Kimundi
Copy link
Member

Kimundi commented Mar 4, 2013

It started with this error:

pub trait VideoDriver {
    static fn init() -> Self;
}

pub trait Platform {
    static fn init<D: VideoDriver>() -> Self;
    static fn foo() -> bool;
}

pub fn run<P: Platform, D: VideoDriver>() {
    let platform: P = Platform::init::<D>();

}
---------------------------------------------------------------------------------------------
trait_generic_method.rs:11:19: 11:38 error: not enough type parameters provided for this item
trait_generic_method.rs:11     let platform: P = Platform::init::<D>();
                                              ^~~~~~~~~~~~~~~~~~~~~~
trait_generic_method.rs:11:19: 11:38 error: cannot determine a type for this bounded type parameter: unconstrained type
trait_generic_method.rs:11     let platform: P = Platform::init::<D>();
                                              ^~~~~~~~~~~~~~~~~~~~~~

Which is confusing because the init() method is just defined on one type parameter.
However if I change the line to let platform: P = Platform::init::<P, D>(); it compiles, which is confusing for the same reasons.

The cause for this is that you can specify the type of an trait impl by appending an ::<T> to the call of an function like this: let is_foo = Platform::foo::<int>(), which is fine as long as the function itself has no specific trait bounds. Combined though it's a mess, as it's not even clear in which order the parameters go.

As the type selection really belongs to the trait, and not to an function of that trait, I propose that the syntax should get changed to let platform = Platform::<P>::init::<D>().
More linenoise, but at least it's not confusing.

@bstrie
Copy link
Contributor

bstrie commented Mar 4, 2013

Or, since Rust has already diverged from C++ in this area, perhaps it's time to think of a less-hideous way to specify types at use sites. :)

@Kimundi
Copy link
Member Author

Kimundi commented Mar 4, 2013

@bstrie sure, but how? ^^

@bstrie
Copy link
Contributor

bstrie commented Mar 4, 2013

Putting aside syntax for the moment, I still don't understand the error here. In the line:

Platform::init::<P, D>()

what, exactly, is P, and why is it necessary?

@Kimundi
Copy link
Member Author

Kimundi commented Mar 4, 2013

@bstrie: The P there means 'use the implementation of Platform for type P'. It should be inferred because P is already given as type of the variable, but apparently it is required if you want to give any other specific types.

@nikomatsakis
Copy link
Contributor

Yes, we need to integrate type parameters into paths in a better way.

@catamorphism
Copy link
Contributor

Still a bug. Since this potentially involves changing syntax, I'm nominating for milestone 1, well-defined.

@graydon
Copy link
Contributor

graydon commented May 23, 2013

accepted for well-defined milestone

@graydon
Copy link
Contributor

graydon commented May 23, 2013

accepted for backwards-compatible milestone

@graydon
Copy link
Contributor

graydon commented May 23, 2013

relative of #5527

@emberian
Copy link
Member

triage bump

@catamorphism
Copy link
Contributor

This is done.

bors added a commit to rust-lang-ci/rust that referenced this issue May 2, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-type-system Area: Type system
Projects
None yet
Development

No branches or pull requests

6 participants