54

impl Traits can be used as function arguments. Are there differences between this and a generic function with a trait constraint?

trait Foo {}

fn func1(_: impl Foo) {}

fn func2<T: Foo>(_: T) {}
0

2 Answers 2

46

impl Traits as function arguments are desugared to an anonymous generic parameter. See the RFC, which says:

Expand impl Trait to allow use in arguments, where it behaves like an anonymous generic parameter.

There's also an example in the RFC:

// These two are equivalent
fn map<U>(self, f: impl FnOnce(T) -> U) -> Option<U>
fn map<U, F>(self, f: F) -> Option<U> where F: FnOnce(T) -> U

However, one difference is that impl Trait arguments cannot have their types explicitly specified:

fn foo<T: Trait>(t: T)
fn bar(t: impl Trait)

foo::<u32>(0) // this is allowed
bar::<u32>(0) // this is not

The Motivation for expanding to argument position section explains why additional syntax was added for an existing feature. In short, it's for having similar syntax as impl traits in function return position, which improves learnability, and to improve ergonomics.

Sign up to request clarification or add additional context in comments.

4 Comments

Hm, thanks. I did not read the RFC; I only saw the link to the github issue from "this week in Rust".
@Boiethios RFCs, even merged RFCs, aren't always accurate to the current version of Rust -- they may be not-yet-implemented, implemented-with-changes, or superseded -- so it's still a fair question. However, in this case the RFC is accurate.
(When changes have been made since the RFC was merged, you'd hope to find that in the tracking issue for the RFC.)
bar::<u32>(0) // this is not I've seen this in the docs as well. Why would I need it though? I can fully specify it by using bar::(0u32)
9

Both produce identical assembly, at least with the following simple test case:

trait Foo {}

struct Bar;

impl Foo for Bar {}

fn func1(_: impl Foo) {}

fn func2<T: Foo>(_: T) {}

fn main() {
    let x = Bar;

    let y = func1(x); // or func2(x);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.