
Introducing Rust Language Server - JoshTriplett
https://internals.rust-lang.org/t/introducing-rust-language-server-source-release/4209
======
hetman
I think the most astonishing thing to me about the Rust language project is
not the language it self (sure it's innovative but there's also still a lot of
work to be done to make it get out of your way). It's the speed and tenacity
with which the project has managed to push development of the supporting
tooling. The development tools surrounding a language can often be more
important for productivity than the language itself, and it feels like the
Rust team and community really get that.

~~~
JoshTriplett
I think that's a side effect of making a welcoming community a priority. The
Rust Language Server grew out of feedback from the Rust Language Survey, in
which many people responded that they wanted good IDE support.

That isn't a glamorous task to work on, especially if you're already
comfortable with the level of editor support you have, but it helps bring more
people into the community, which has a multiplicative effect.

~~~
theossuary
I think it's a side effect of having a punishing language. Coding Rust is
always described as fighting with the compiler, I don't think Rust would have
ever taken off if there weren't great tools to fight the compiler with. I
think that's a part of it, anyway.

~~~
fabrice_d
I don't think "fighting the compiler" is an accurate description of the Rust
coding experience. There is a learning curve during which you feel like you
fight the borrow checker a lot, but once you get it you will find that the
compiler is actually helpful.

~~~
iopq
There's plenty of fighting the compiler.

    
    
        error[E0281]: type mismatch: the type `fn(_) -> _ {tool::second::<_>}` implements the trait `std::ops::FnMut<(_,)>`, but the trait `for<'r> std::ops::FnMut<(&'r _,)>` is required (expected concrete lifetime, found bound lifetime parameter )
    
         --> src\lib.rs:53:11
           |
        53 |            .filter(apply(second, i))
           |                    ^^^^^
           |
           = note: required by `apply`
    
        error[E0271]: type mismatch resolving `for<'r> <fn(_) -> _ {tool::second::<_>} as std::ops::FnOnce<(&'r _,)>>::Output == _`
          --> src\lib.rs:53:11
           |
        53 |            .filter(apply(second, i))
           |                    ^^^^^ expected bound lifetime parameter , found concrete lifetime
           |
           = note: concrete lifetime that was found is lifetime '_#11r
           = note: required by `apply`
    
        error: aborting due to 2 previous errors
    

I now know why I'm getting this error. Would you?

~~~
lmm
I suspect I would - I'll happily guess if I can take a look at the code (or at
least the signatures of "filter", "apply", "second" and "i").

~~~
iopq
I put the whole code in a separate branch for you:

[https://bitbucket.org/iopq/fizzbuzz-in-
rust/src/920bd2bd1267...](https://bitbucket.org/iopq/fizzbuzz-in-
rust/src/920bd2bd1267d4bb495d114db6dbf396106962d4/src/lib.rs?at=error&fileviewer=file-
view-default)

this doesn't work, so I want you to tell me why

~~~
lmm
Hmm fair enough, harder than I thought (I don't know Rust, the error just
sounded sensible). It reads like the function you're passing into filter is
supposed to be "lifetime-generic" taking a parameter whose lifetime comes from
the for, but the function returned by apply has a fixed lifetime. But I can't
see where it's getting the lifetime for that from, or what to do about it. I
guess at that point I'd try adding an explicit lifetime to the return type of
apply (or maybe an IDE could show it without having to write it)?

~~~
iopq
The problem is with the function `second` that I get from the other crate. If
I replace the `second` function with my own implementation it works. But for
the `second` implementation from tool.rs to work, Rust needs better higher
ranked lifetime support.

It would also work with a closure, but I wrote my code this way to avoid
closures in the first place (I was going for point-free style).

I basically just have to write my own function:

[https://bitbucket.org/iopq/fizzbuzz-in-
rust/src/58bfa4c58c80...](https://bitbucket.org/iopq/fizzbuzz-in-
rust/src/58bfa4c58c803b04451ae60fe06da4450aef9658/src/lib.rs?at=master&fileviewer=file-
view-default#lib.rs-66:68)

this compiles, but it seems kind of pointless since I can only use this
particular function in my case (because of the extra levels of references)

if I could use the tool.rs version, it would automatically generate all the
implementations I need using macros

------
favorited
For anyone interested in similar tools, Microsoft recently published a
protocol[1] for this type of service, and an implementation[2] of it for
VSCode+NodeJS.

Swift also has a library[3] called SourceKit which does the same thing for
Swift – it can run as an out-of-process daemon, and people have written
integrations for Atom, Emacs, etc. to get autocomplete, syntax highlighting,
def links, etc.

[1][https://github.com/Microsoft/language-server-
protocol](https://github.com/Microsoft/language-server-protocol)
[2][https://github.com/Microsoft/vscode-languageserver-
node](https://github.com/Microsoft/vscode-languageserver-node)
[3][https://github.com/apple/swift/tree/master/tools/SourceKit](https://github.com/apple/swift/tree/master/tools/SourceKit)

~~~
wbond
If it really pushes syntax highlighting to another process and uses JSON for
serialization, that is going to impose a cap on editor performance.

~~~
pcwalton
Rust's JSON serializer is _really_ fast (~300 MB/s).
[http://erickt.github.io/blog/2014/12/13/performance-
digressi...](http://erickt.github.io/blog/2014/12/13/performance-digression/)

~~~
wbond
I'm imaging more along the lines of serializing editor state with each key
press, encoding it, sending it to another process, having that process
unserialize it, lex it, encode all of the cascading token changes and
information about those tokens back into JSON, sending it back to the editor
process which then has to decode the JSON and apply all of the token
information to the in-memory representation as real overhead.

It's great that Rust will decode and encode the JSON quickly (I've been
keeping an eye on Rust's MSVC progress before I consider using it for a real-
world project), but the project I work on cares about optimizations on the
level of in-memory data layout and memory allocations. Moving syntax
highlighting into a pluggable system would be a huge performance regression.

~~~
steveklabnik
There was a talk at RustConf by Raph Levien about his editor, Xi. It almost
entirely uses JSON-RPC to communicate through a distributed architecture, and
next-level speed is one of his design goals:
[https://confreaks.tv/videos/rustconf2016-a-modern-editor-
bui...](https://confreaks.tv/videos/rustconf2016-a-modern-editor-built-in-
rust)

> I've been keeping an eye on Rust's MSVC progress before I consider using it
> for a real-world project

The latest builds of MSVC claim to have native Rust syntax highlighting and
autocomplete, I have not yet tried it myself:
[https://www.visualstudio.com/news/releasenotes/vs15-relnotes](https://www.visualstudio.com/news/releasenotes/vs15-relnotes)

~~~
wbond
I'm referring to the MSVC "backend" for Rust, not Visual Studio.

~~~
steveklabnik
Ah! What things are you looking for in its maturity? In some ways, it's
actually the most mature backend; stack probes work with it, for example.
Windows isn't my personal area of expertise though.

~~~
wbond
I've been following [https://github.com/rust-
lang/rfcs/issues/1061](https://github.com/rust-lang/rfcs/issues/1061) for a
while. It seems that high-level pieces are there, but that certain elements
useful in day-to-day software engineering still need some more time.

~~~
retep998
Yay, someone actually follows that issue.

If you have the time, you should really consider helping to improve the Rust
experience on Windows. There's a huge shortage of Windows developers in the
Rust community.

~~~
wbond
Unfortunately I am already overcommitted with open source projects. For now I
am content to wait and see how it all plays out. It will be great to have
another language where Windows support is really first-rate.

------
beliu
This is awesome. The best languages are the ones with strong tools.

Side note: really looking forward to rolling this into Rust support for
Sourcegraph (Sourcegraph team member here) to make any Rust library as easy to
explore as
[https://sourcegraph.com/github.com/gorilla/websocket/-/blob/...](https://sourcegraph.com/github.com/gorilla/websocket/-/blob/client.go#L39)
and
[https://sourcegraph.com/github.com/staltz/xstream@master/-/b...](https://sourcegraph.com/github.com/staltz/xstream@master/-/blob/src/extra/flattenSequentially.ts#L68)
are for Go and TypeScript. Thanks for making and open-sourcing this!

------
JoshTriplett
I saw the demo of this at RustConf, and it was incredible. See the video
linked from the post:
[https://www.youtube.com/watch?time_continue=2405&v=pTQxHIzGq...](https://www.youtube.com/watch?time_continue=2405&v=pTQxHIzGqFI)

I look forward to seeing support for this integrated with vim.

------
joostdevries
Compilers that have a language service api are awesome. The Typescript
compiler does and it makes for high quality low latency refactoring, code
completion, show expression type etc across ediors and IDEs. Since my other
day to day language is Scala I was glad to find out that the upcoming Dotty
Scala compiler will also feature a language service api. Yay.

------
k4rtik
I recently learned how modern IDE's provide the kind of features Rust LS is
targeting. For anyone else interested, here is a great video explaining the
same: [https://channel9.msdn.com/Blogs/Seth-Juarez/Anders-
Hejlsberg...](https://channel9.msdn.com/Blogs/Seth-Juarez/Anders-Hejlsberg-on-
Modern-Compiler-Construction)

------
haberman
I've wanted this for a long time. But I don't see why it has to be language-
specific. Maybe some of the fancy parts do, but why can't
make/cmake/ninja/etc. support this in a language independent way? Just basic
queries/commands like:

    
    
       1. run any build steps that directly depend on file X
       2. run any build steps that directly or indirectly depend on file X
       3. get whether the build of X succeeded or failed, and console output
    

These alone would go so far towards making Vim/Emacs/etc more user-friendly.

~~~
steveklabnik
This is what
[https://news.ycombinator.com/item?id=12739817](https://news.ycombinator.com/item?id=12739817)
is about, and I agree it's a great idea! In that sense, it's not language-
specific.

------
avodonosov
Is it something like swank for common lisp?

------
jayflux
There's some talk of getting this into Sublime Text
[https://github.com/jonathandturner/rustls/issues/18](https://github.com/jonathandturner/rustls/issues/18)

------
denfromufa
This most likely originated from TypeScript, which actually went further with
compiler and code analysis integrated

~~~
steveklabnik
We've been planning this for a while, and it's largely been a joint effort
between Jonathan and Nick; Jonathan _did_ work on TypeScript before coming to
work on Rust, though.

