4 ms·
I've been digging more into Rust, and things not working because I forgot to import the trait drives me bonkers. Like, you create a struct, you build an impleme
by camgunz 5y ago
I've been digging more into Rust, and things not working because I forgot to import the trait drives me bonkers. Like, you create a struct, you build an implementation, you implement a trait on it, you try and use it in another module, you can't, you feel like you must have goofed something, you hack around for an hour, oh you remember you forgot to import the trait you already implemented, you open up HN in a fury.... Is there a really important reason rustc doesn't know what traits are implemented on what structs? It can't be a dependency graph thing, it has to know about the struct in the first place.
- deleted 5y ago[deleted]
- wyager 5y agoHaskell automatically imports all typeclass definitions (equivalent to traits) when you import a module, so you sometimes see lines like `import Foo.Bar ()` Which looks like it's just importing nothing at all (`()`) but is actually pulling in some traits and nothing else. You don't see this often because "orphan instances" (instances defined in a file besides the location of the trait definition or the type definition) are discouraged, but they do occur.
- tome 5y agoFYI that pattern is useful even in the absence of orphans.
- wyager 5y agoInteresting, where?
- tome 5y agoI use it in test suites, where the tests are simply to check that something compiles, not its behaviour, for example https://github.com/tomjaguarpaw/product-profunctors/blob/faf52f0a134099ed8adb6b29ea822d48920e7ac3/Test/Main.hs#L1 https://github.com/tomjaguarpaw/product-profunctors/blob/faf... I had also thought that there was a reason one could need that pattern to import instances even in the absence of orphans, but on reflection I think I was mistaken.
- mplanchard 5y agoIf you’re using rust-analyzer in your editor of choice, it will often suggest and auto-import traits when you try to use their methods with the trait not in scope. It knows, based on the dependency graph and your own code, all of the traits that could provide a method. I use rust-analyzer in emacs, but it’s available in any editor that supports language servers. With my setup, I’ll start typing a method, get a completion for the trait method I want with the trait indicated, and select the completion. The trait is then automatically imported and the method is completed.
- camgunz 5y agorust-analyzer is a language server, which (along with autocomplete and maybe infuriatingly) I'm not into. I think this mostly reinforces Eli's point, which is broadly that you need a lot of editor support to use Rust reasonably ergonomically.
- mplanchard 5y agoI think the sibling comment pointing out that the compiler errors tell you exactly what trait you need is for you then! You can get them with just a `cargo check`, no language server required.
- veber-alex 5y agoI suggest you start reading the compiler error messages as they say exactly what trait is missing, no need to waste an hour. For example for this code: trait Foo { fn foo(&self) {} } struct Bar; impl Foo for Bar {} mod test { use super::Bar; fn test() { Bar.foo(); } } 22 | Bar.foo(); | ^^^ method not found in `Bar` | = help: items from traits can only be used if the trait is in scope help: the following trait is implemented but not in scope; perhaps add a `use` for it: | 20 | use crate::Foo; |
- camgunz 5y agoA less condescending way to say what you said is, "oh they're pretty clear in the compiler output, are they buried or something?" And then I would say that in the linter in Vim, you only get the "method not found in Bar" which could be all kinds of things.
- mplanchard 5y agoThis seems like you’re using a relatively uncommon tooling setup (no language server, some kind of inline vim errors rather than the command line), and expecting that to “just work.” As a user of arcane tools, it seems to me a slightly unreasonable expectation. If you’re not going to go down the “golden path” of using rust—analyzer, you’ll need to assume that your editor’s support for the language may be incomplete out of the gate and figure out how to supplement it. Even with rust-analyzer, the source of truth is always `cargo check` and friends, so I recommend getting super familiar with them on the command line, regardless of your editor setup.
- camgunz 5y agoYeah no you're definitely right, I'm definitely not in the golden path for Rust dev. I guess my quibbles (which I would cop to being quibbles... I think anyway) are: - I'm already using 'cargo check' as my linter (rustc doesn't understand modules, seemingly). - My setup works for JavaScript/React/Svelte, SQL, C/C++, Python, and Go. - It can't be the case that (Neo)Vim + Ale [0] is arcane. Also the link in "Tools" from rust-lang.org goes to the rust.vim repo, which defaults to Syntastic, which I'm pretty sure has the same issue. I don't necessarily think I should extrapolate from my experience to a broader "Rust is different for little/no gain" critique I've made in the past, but I sure want to haha. And to kind of anticipate a little, I wouldn't blame Ale here because--again--it works for everything else. But anyway, yeah I've mostly given up on linting and I just run 'cargo check' in a terminal buffer now. It's probably something as simple as adding a command-line argument to... idk cargo or rustc to make the additional "help" format a little more amenable to Ale? Maybe I'll take a crack at it when I get some time. [0]: https://github.com/dense-analysis/ale https://github.com/dense-analysis/ale