Erlich
Erlich

Reputation: 345

What is the rationale for not being able to use the outer type parameter within an inner function?

I'm trying to create a recursive inner function that will print all elements in a linked list:

fn print_stack(&self) {
    fn print_nodes(head: &Option<Box<Node<T>>>) {
        match head {
            Some(ref p) => {
                println!("{:?}",p.data);
                print_nodes(head.next);
            },
        }
    };
    print_nodes(&self.head);
}

The compiler generates the following error:

can't use type parameters from outer function; try using a local type parameter instead.

Why is this an error?

Upvotes: 10

Views: 5738

Answers (1)

user743382
user743382

Reputation:

From Rust Compiler Error Index:

E0401

Inner items do not inherit type parameters from the functions they are embedded in.

[...]

Items inside functions are basically just like top-level items, except that they can only be used from the function they are in.

There are a couple of solutions for this.

[...]

For a generic item, you can copy over the parameters:

[...]

I would conclude from this that items inside functions are also compiled as top-level items. Allowing references to the outer function type parameters would allow two different function definitions with the same name, without any type parameters on the function itself to disambiguate, so would require name mangling changes. Making a small test program confirms this:

struct Foo<T>(T);
impl <T> Foo<T> {
    pub fn bar() {
        fn baz() { }
        baz();
    }
}
fn main() {
    Foo::<i32>::bar();
    Foo::<u32>::bar();
}

Compiling this and calling nm on the generated output shows two definitions of bar, and a single definition of baz.

It's possible to change Rust in the way you expect, but it would need to be designed first, and the perceived benefits must outweigh the cost to implement it. Given the available workarounds, the perceived benefits may be small. In your case, as indicated on that page, the workaround is to specify the type parameters for the inner function as well.

Upvotes: 8

Related Questions