> Cargo couldn’t fetch the index from crates.io if you were using an older Windows without having applied security fixes.
Why are developers (since this is an issue that shows up with cargo) running Windows 7 without security patches installed? Especially since the issue only shows up on Windows 7 installs that haven't received security patches since June 2016.
> libgit2 created a fix, using the WinHTTP API to request TLS 1.2. On master, we’ve updated to fix this, but for 1.24.1 stable, we’re issuing a warning, suggesting that they upgrade their Windows version.
That's really a neat and responsible way of handling this.
Although developers should know and do better, I think a big part of why they aren't doing it is because Microsoft has made it so hard to update Windows 7 since a year or two ago, all in the name of forcing people to switch to Windows 10.
You now have to visit and manually download the updates from Microsoft's Update Catalog website. Oh, and that website only works on Internet Explorer.
>Why are developers (since this is an issue that shows up with cargo) running Windows 7 without security patches installed? Especially since the issue only shows up on Windows 7 installs that haven't received security patches since June 2016.
The issue shows up on patched machines. The patch does not enable TLS 1.2 by default. You have to add reg keys for it.
> Why are developers (since this is an issue that shows up with cargo) running Windows 7 without security patches installed? Especially since the issue only shows up on Windows 7 installs that haven't received security patches since June 2016.
Enterprise. It’s only recently
I’ve stopped seeing XP boxes around, but Windows 7 is everywhere.
Because unlike most other programming languages, Rust is well-engineered and seeks to both provide the most general abstractions possible and to make the code generated by them as efficient as possible.
In particular, for this task, this requires to:
1. Return references to subranges of the original string, rather than copying them, so that no copy happens if you only need to examine the component instead of storing it
2. Not use reference counting to do so, but rather statically checked references with lifetimes, to avoid unnecessary instructions to update the reference count and lack of a static finalization point
3. Provide a way to get components one by one, so that if you only need e.g. the first two, time is not wasted to split the whole string
4. Provide that through a generic Iterator trait, so that it may be passed to generic methods (like one that collects the result into a vector)
5. Dispatch that generic trait statically rather than using an indirect call as that would destroy performance
6. Make the state manipulated by such an interface into a first-class object, and allow to put them in a data structure (like an array) while still doing static dispatch, so that you can, for instance, split multiple strings into components and interleave them without ever making an indirect call.
The combination of these essential requirements results in the creation of the SplitWhitespace<'a> data type, which represents the state of a parser splitting a string into 'a-lifetime references to whitespace-separated its components one by one, implementing the Iterator trait, and usable in a data structure.
> Why would you create a special data type to represent a string split by Whitespace?
Big chunks of Rust are build around iterators, and `split_whitespace` returns an iterator of type `SplitWhitespace`. Because this is a concrete type, the Rust compiler and LLVM will then work to together to completely inline it, and they will generate code that looks like a hand-rolled loop.
There are some downsides to this system—it usually takes me about 10 minutes to write custom iterators for a new data structure—but iterators are very nice to program with and they go fast.
There's a new 'impl Trait' feature scheduled for later this year which will eliminate the need to export a custom struct like this. And it will eliminate the 10 minutes I spend writing iterators. Of course, it adds a new language feature. Nothing's free.
> Rust gives me a headache. I want to like it, but it just seems so... overengineered
I admit, Rust does sometimes have a "heavy industry" feeling to it. But this has some nice benefits, too:
1. I can write cross-platform CLI tools that Just Work on Linux, MacOS and Windows, because Rust has good abstractions for paths, files, threads, etc.
2. I can write multi-threaded code that does things like, "Read an arbitrary stream of bytes in a background thread, compress it, break it into 5MB chunks, and upload each of those chunks to S3 in parallel, using no more than N worker threads and applying backpressure, and do all this in the background while I work on something else." And thanks to Rust's threading rules, all this will work on the first try, with no nightmarish threading bugs.
3. In general, if my Rust code actually compiles, there's about an 85% chance that it will work flawlessly on the first try.
Personally, these are benefits that I'm willing to pay for. And Rust does require some familiarity both with how processors work, and with functional programming. And of course, everybody has different tradeoffs. But for certain kinds of work, Rust really hits the sweet spot.
I wrote in another comment that I don't think the SplitWhitespace type is an example of overengineering. And I don't.
However, thinking about this more, I think I understand what you mean and I, sort of, agree.
What I believe is going on is that Rust exposes a lot of its engineering. This can be either good or bad depending on where you're coming from. If you're working at a low level then this is usually a good thing. If you're working at a high level then this can be quite annoying.
What I think you'll find is that this is largely a point in time thing. Rust is still relatively young and there is substantial work in flight under the banner of ergonomics. Even though this is more engineering, I'm pretty confident that the net effect will be to make the language feel less engineered. It probably won't completely get there this year but I don't think it'll be long.
As implied by other commenters, the problem is that Rust cannot currently abstract out a concrete return type without indirection of some sort. More formally, it’s not possible to existentially quantify over a trait bound; in other words, to say that whatever the actual type that is returned, all the caller needs to know is that it implements a certain trait or traits.
Note that it’s exactly the same in other major statically-typed languages like Java or C++: there are no existential types without indirection (which in the case of Java and similar managed languages is implicit and mandatory).
Rust is in the progress of adding existential trait bounds in the form of the `impl trait` feature. It’s already available in nightly.
I would call that underengineered. This could be more generic, both in what it operates on (why only strings and not any sequence of value items?) and what it separates on (why only Unicode whitespace? It could be used as return value from a call that iterates over CSV fields in a line or that finds regex matches in a string).
... why not create a new type. As noted by a sibling comment, there are some good reasons to do it.
And there's actually very little chance that you, as the developer, are ever going to explicitly specify that type - there's pretty good type inference. As a rust user, I don't care that it's another type because I don't need to care about it in order to write code.
It depends on what software world you come from. In many places "stringly typed" code is frowned upon: http://wiki.c2.com/?StringlyTyped
Yes, it's convenient, but using data types can help with many things, from implicit documentation, to optimizations to enforcing a code contract/interface.
This is an interesting demonstration how fiddly and UB-happy FFI boundaries can be... Fortunately the UB → abort change will land in the future, it will be for the better.
[+] [-] mkj|8 years ago|reply
"There are only Copy types on the rust stack frame being jumped over."
https://github.com/rust-lang/rust/issues/48251
[+] [-] stmw|8 years ago|reply
[+] [-] Freak_NL|8 years ago|reply
Why are developers (since this is an issue that shows up with cargo) running Windows 7 without security patches installed? Especially since the issue only shows up on Windows 7 installs that haven't received security patches since June 2016.
> libgit2 created a fix, using the WinHTTP API to request TLS 1.2. On master, we’ve updated to fix this, but for 1.24.1 stable, we’re issuing a warning, suggesting that they upgrade their Windows version.
That's really a neat and responsible way of handling this.
[+] [-] mtgx|8 years ago|reply
You now have to visit and manually download the updates from Microsoft's Update Catalog website. Oh, and that website only works on Internet Explorer.
[+] [-] Arnavion|8 years ago|reply
The issue shows up on patched machines. The patch does not enable TLS 1.2 by default. You have to add reg keys for it.
https://github.com/rust-lang/cargo/issues/5065#issuecomment-...
[+] [-] mstade|8 years ago|reply
Enterprise. It’s only recently I’ve stopped seeing XP boxes around, but Windows 7 is everywhere.
[+] [-] ogoffart|8 years ago|reply
[+] [-] HumanDrivenDev|8 years ago|reply
https://doc.rust-lang.org/std/str/struct.SplitWhitespace.htm...
Why would you create a special data type to represent a string split by Whitespace? Lunacy
[+] [-] devit|8 years ago|reply
In particular, for this task, this requires to:
1. Return references to subranges of the original string, rather than copying them, so that no copy happens if you only need to examine the component instead of storing it
2. Not use reference counting to do so, but rather statically checked references with lifetimes, to avoid unnecessary instructions to update the reference count and lack of a static finalization point
3. Provide a way to get components one by one, so that if you only need e.g. the first two, time is not wasted to split the whole string
4. Provide that through a generic Iterator trait, so that it may be passed to generic methods (like one that collects the result into a vector)
5. Dispatch that generic trait statically rather than using an indirect call as that would destroy performance
6. Make the state manipulated by such an interface into a first-class object, and allow to put them in a data structure (like an array) while still doing static dispatch, so that you can, for instance, split multiple strings into components and interleave them without ever making an indirect call.
The combination of these essential requirements results in the creation of the SplitWhitespace<'a> data type, which represents the state of a parser splitting a string into 'a-lifetime references to whitespace-separated its components one by one, implementing the Iterator trait, and usable in a data structure.
[+] [-] ekidd|8 years ago|reply
Big chunks of Rust are build around iterators, and `split_whitespace` returns an iterator of type `SplitWhitespace`. Because this is a concrete type, the Rust compiler and LLVM will then work to together to completely inline it, and they will generate code that looks like a hand-rolled loop.
There are some downsides to this system—it usually takes me about 10 minutes to write custom iterators for a new data structure—but iterators are very nice to program with and they go fast.
There's a new 'impl Trait' feature scheduled for later this year which will eliminate the need to export a custom struct like this. And it will eliminate the 10 minutes I spend writing iterators. Of course, it adds a new language feature. Nothing's free.
> Rust gives me a headache. I want to like it, but it just seems so... overengineered
I admit, Rust does sometimes have a "heavy industry" feeling to it. But this has some nice benefits, too:
1. I can write cross-platform CLI tools that Just Work on Linux, MacOS and Windows, because Rust has good abstractions for paths, files, threads, etc.
2. I can write multi-threaded code that does things like, "Read an arbitrary stream of bytes in a background thread, compress it, break it into 5MB chunks, and upload each of those chunks to S3 in parallel, using no more than N worker threads and applying backpressure, and do all this in the background while I work on something else." And thanks to Rust's threading rules, all this will work on the first try, with no nightmarish threading bugs.
3. In general, if my Rust code actually compiles, there's about an 85% chance that it will work flawlessly on the first try.
Personally, these are benefits that I'm willing to pay for. And Rust does require some familiarity both with how processors work, and with functional programming. And of course, everybody has different tradeoffs. But for certain kinds of work, Rust really hits the sweet spot.
[+] [-] lucozade|8 years ago|reply
However, thinking about this more, I think I understand what you mean and I, sort of, agree.
What I believe is going on is that Rust exposes a lot of its engineering. This can be either good or bad depending on where you're coming from. If you're working at a low level then this is usually a good thing. If you're working at a high level then this can be quite annoying.
What I think you'll find is that this is largely a point in time thing. Rust is still relatively young and there is substantial work in flight under the banner of ergonomics. Even though this is more engineering, I'm pretty confident that the net effect will be to make the language feel less engineered. It probably won't completely get there this year but I don't think it'll be long.
[+] [-] jayflux|8 years ago|reply
Basically the same as calling .split(‘ ‘) on a string in JavaScript
You can find a list of Rusts primitive types here: https://doc.rust-lang.org/std/#primitives
[+] [-] Sharlin|8 years ago|reply
Note that it’s exactly the same in other major statically-typed languages like Java or C++: there are no existential types without indirection (which in the case of Java and similar managed languages is implicit and mandatory).
Rust is in the progress of adding existential trait bounds in the form of the `impl trait` feature. It’s already available in nightly.
[+] [-] the_mitsuhiko|8 years ago|reply
Because it's an iterator. A bespoke iterator type is also created behind the scenes in many other languages. How else would you do it?
[+] [-] Someone|8 years ago|reply
[+] [-] swsieber|8 years ago|reply
And there's actually very little chance that you, as the developer, are ever going to explicitly specify that type - there's pretty good type inference. As a rust user, I don't care that it's another type because I don't need to care about it in order to write code.
So lots of benefits, very low cost/impact.
[+] [-] oblio|8 years ago|reply
Yes, it's convenient, but using data types can help with many things, from implicit documentation, to optimizations to enforcing a code contract/interface.
[+] [-] GolDDranks|8 years ago|reply
[+] [-] _binder|8 years ago|reply
[+] [-] ilurkedhere|8 years ago|reply