Closed jake-87 closed 5 months ago
Apologies, I do not know how to assign tags. I believe this proposal should at least have T-lang
.
Would this also allow using type parameters from an outer function inside the inner function's body, even when they do not appear in the inner function's signature? E.g.,
fn outer<T: Default>() {
fn inner() {
let _ = T::default();
}
}
This would mean that the compiler has to inspect inner
's body before being able to tell that it's generic. Also, one of the main uses of nested inner functions is for deliberately avoiding separate monomorphizations; this change could make it easier to accidentally introduce genericity when it's not desired.
Also, how does this interact with attributes that require a non-generic function, like #[export_name]
and #[no_mangle]
?
Finally, should const
or static
items also be able to use generic parameters from the outer function?
No, I am not proposing to allow that example, for the exact reasons you've raised.
I'm unsure what you mean by "interacting with #[export_name]
and #[no_mangle]
" - if there's no generic parameters, you can't use this feature.
With regards to static
and const
, They already cannot, and I see no reason to change that. In those two examples, it's quite reasonable that they cannot use a generic parameter.
I'm unsure what you mean by "interacting with
#[export_name]
and#[no_mangle]
" - if there's no generic parameters, you can't use this feature.
I believe they meant something like this:
fn foo<T>(x: T) -> T {
// This attribute requires `bar` to not be generic, but this then requires determining that doesn't use `T`
#[no_mangle]
fn bar(y: i32) -> i32 {
y
}
// This cannot be allowed, but notice how it has the same signature as `bar`!
#[no_mangle]
fn baz(y: i32) -> i32 {
T::some_function(y)
}
bar(x)
}
With regards to
static
andconst
, They already cannot, and I see no reason to change that. In those two examples, it's quite reasonable that they cannot use a generic parameter.
IMO it would be confusing if functions can use generic parameters declared outside and static
/const
can't. Also, what about struct
s, trait
s and impl
s?
I would propose to reject both of your examples, noting the same reasoning that @Jules-Bertholet provided. Whether a function can be #[no_mangle]
(or similar) should be determinable from the type signature, which it will still be - simply an occurs check.
Correct me if i'm wrong, but static
and const
should not be able to as there is no way to obtain a static
/const
value without arbitrary code execution, rending this useless anyway due to the generic nature of the type. Perhaps the error message could be changed from E0401 to something more informative.
Structs being able to utilize this seems reasonable (although perhaps not productive? may encourage longer functions using more internal structs - happy to take further comment on this one)
However, traits and impls would probably not benefit from this, and further complicating trait resolution seems a fool's errand. I do not want to "half-arse" this feature, but these two seem much more work then they're worth (I've also never seen a local trait)
I would propose to reject both of your examples, noting the same reasoning that @Jules-Bertholet provided.
It might be helpful to add the examples and rationale to the RFC. It could go in the rationale and alternatives section, but I'm not sure if that's the best place.
I will, yes - I've ran into some busyness, but I'll do it when I find the time.
Allow type parameters to be used in nested functions. Removes E0401.
This error was first introduced (at the latest) in 2015. After almost ten years of development and changes in Rust, I believe it's time to reconsider it. TLDR: Allow the below.
Rendered