"can't use type parameters from outer function" - why not?

struct Foo<T>;
fn test<T>() {
    type F = Foo<T>; // type alias for brevity

produces: “error: can’t use type parameters from outer function; try using a local type parameter instead [E0401]”.

The --explain output does a good enough job stating the rule: “Items inside functions are basically just like top-level items, except that they can only be used from the function they are in.” But it doesn’t state any reason why this should be the case, and I can’t think of any other than implementation limitations: the semantics of allowing such references would be straightforward. While nested fns can be replaced with closures, that doesn’t work for type aliases and structs, leaving a choice between repeating type parameters (potentially a lot of them) everywhere the type is used, or creating a verbose boilerplate helper function or struct.

Worth creating a RFC over?


I would be very happy to see an RFC about this. I find the current behavior rather annoying when using nested fns because I usually have to repeat many of the (potentially quite large) where clauses.


@comex Did you ever create an RFC about this?


I’m in favor of doing this for type aliases and consts, because they are erased at compile time, but not for other kinds of items which have a compiled representation. I do think it is valuable that they behave just like top level items from a trans perspective.


Having one for structs is also useful for declaring transient objects like Serde-style visitors.


This is extremely annoying.


I thought this was just an implementation limitation to be fixed after the queryfication of the compiler is done…


We might not be able to do it without breaking a lot of code - extra parametrization isn’t free and we can’t even do it for array lengths (e.g. fn foo<T: Trait>() -> [T; T::N]) yet because not even libcore compiles then (cyclical dependencies).

Querification doesn’t fully solve the ordering problem, but rather restates it in terms of dependencies, which must form a DAG.

The solution is believed to be the introduction of even more indirection aka “lazy normalization” - deferring the evaluation of types or values until the result is actually needed.