3 ms·
Rust generally uses lexical scoping, and each function/closure has a unique (possibly anonymous) type per definition, not a type per call. I would therefore exp
by GrantMoyer 2y ago
Rust generally uses lexical scoping, and each function/closure has a unique (possibly anonymous) type per definition, not a type per call. I would therefore expect local types to be per definition too, so the behavior seems fine to me.
- noelwelsh 2y agoI disagree. If I define two modules mod one { struct Cat { name: String } } and mod two { struct Cat { name: String } } I have two distinct types called Cat which are not equivalent. one::Cat != two::Cat // doesn't compile but illustrates the point, I hope Similarly, when I call a function I create a new environment (think, stack frame) for each call which contains values that are distinct from all other calls. I would expect the same to hold for types defined within a function.
- masklinn 2y ago> Similarly, when I call a function I create a new environment (think, stack frame) for each call which contains values that are distinct from all other calls. I would expect the same to hold for types defined within a function. Rust types are not runtime objects. Also just because a function call creates a new environment doesn't mean everything is part of that environment. `static` items are singletons, even if defined within a function (which is a common case when the function should be the only thing directly interacting with the static).
- GrantMoyer 2y agoI don't think the analogy to modules is quite right. I think that maps better to: fn foo() {struct Cat;} fn bar() {struct Cat;} and foo::Cat != bar::Cat. Whereas the a single function with a local type maps better to: mod foo {struct Cat;} mod bar {pub use ::foo::Cat;} mod baz {pub use ::foo::Cat;} and bar::Cat does equal baz::Cat. But maybe I only think that construct maps better because I'm predisposed to the interpetation I described. I do see what your saying, and agree that Rust could work that way; I'm just not convinced it's a bug that it doesn't. The behavior you describe would be more surprising to me than the existing behavior, but clearly that's not a universal sentiment, and I'm not sure which behavior would be less surprising to most people.
- noelwelsh 2y agoSeems reasonable to me. I was thinking more of closures, which capture their environment, but those are of course a distinct type in Rust.
- ulbu 2y agoa stack frame is a runtime object, while a type exists only to the compiler. the suggestion to create it in a call just makes no sense. a type is a definition, not an instance.
- tialaramex 2y agoWhy "possibly anonymous" ? I don't think we can ever name any of these types. Rust's Existential types exist so that we can say we return such a thing, without being able to name it.
- GrantMoyer 2y agoYou're right, and I was being imprecise. All closure and "function item" types are unnameable; only function pointer types can be named, for example `fn(int) -> int`[1]. [1]: https://doc.rust-lang.org/reference/types/function-item.html https://doc.rust-lang.org/reference/types/function-item.html