13 ms·
Rust 1.x seems to not always be backward compatible in practice
- choeger 5y agoIf the problem really comes from incorrect code in Firefox then I don't think that backwards compatibility is even possible. Consider the possibility that it was actually a bug in the Rust compiler that let this code pass. What should the compiler developers do if not fix this bug? If, on the other hand, the code was correct, then backwards compatibility is definitely expected. The same holds for the format of the cargo files, btw. changing something like this during one major (or minor, depending on the release cycle) release is bad form IMO. The mentioned case of C compilers and their warnings is an interesting grey area. Presumably it would still compile just fine, but as a developer you want -Werror and -Wall. In practice this often makes certain libraries incompatible after a compiler upgrade.
- dathinab 5y agoThere had been a few cases where bugs in Rust had been fixed which did cause breakage, but fixes where rolled out slowly spread over multiple versions. This included: - Soundness issues around Self: Sized bound requirements and traits. (Big breakage bout early one in rust lifetime.) - Soundness issues around something related to match statements and guards I don't remember. - Something related to accepting invalid inputs, I think this included Cargo accepting invalid Cargo.toml files. There was also a very small bit of accidental breakage which counted as a bug but affected close to no one so no one ever invested time to fix. For example a bug which only affects people running multiple tightly linked rust crates on older editions and doing unusual stuff wrt. macro imports and re-exports which where only valid for I think 1-2 rust version. Then there was a bit of accidental stabilization, where things which should not be doable on stable where doable. If not found very early this was normally kept stable if possible, but I think there was at least one time where this "stabilization bug" needed to be fixed. Anyway to cut it short: 1) Compilers are not perfect, this is also true for C/C++. 2) At least serve bugs (e.g. soundness bugs) are not treated as "de-facto" standardized/stabilized but are fixed (something I prefer). ---- As a side note Firefox is a bad example as they used some tricks to use some definitely not stable options on stable rust which is basically guaranteed to cause breakage at some point and not covered by any stability guarantees. As another side note `#[deny(warnings)]` is also not covered by stability guarantees, the compiler is free to add new warnings any time (but will do so with a lot of care, e.g. preferably only with new rust editions, which also may make some warnings errors). --- Also: -`rustup` supports setting overrides, no reason to fear updates, just pin a older rust version in your create using overrides (if you need to). - Idk. about his problems but I have yet to see a case where any breakage wasn't reasonable straight forward to fix (weather unintentional, intentional to fix soundness or due to an edition change triggered by me).
- gpderetta 5y agoThese days upgrades go much more smoothly, but on the first decade of the millennium upgrading your C++ compiler was always a major hassle as each version would fix many bugs, increase its standard compliance and start rejecting erroneous code.
- aseipp 5y agoIt still happens today, but nowhere near as badly. I package FoundationDB for my linux distribution, and around GCC 6.x the build broke for version FDB 6.0. Why? Because the code used 'log' unqualified in their code (for logging), and some rearrangement of the libstdc++ headers to be more correct and caused the 'log' (math function) to come into scope. (The libstdc++ changes were the correct course of action, in my reading.) Of course, FDB also changed their code in the mean time so newer versions 6.1+ didn't hit this, so it was an old regression in an old version from a mishap in the standard library that had been a bug for like, years and years. Tons of regressions like this happen all the time in the GCC/LLVM world. Every time we do a bump of the default C compiler, you can bet it will take 4-8 weeks while regressions -- from "This random thing enabled -Werror, again" to "Someone used a new feature but scoped the #ifdef wrong" to "Actual segfaults in libstdc++" -- are sorted out.
- indianboy42 5y agoI would love to know what the errors actually were, maybe a deeper dive into what and why compatibility was supposedly broken. Did the rust developers know that they were breaking compatibility? Firefox is a pretty big high profile user of rust, a breaking change couldn't have just snuck by.
- dathinab 5y agoFirefox only cares about Firefox working with the specific rust versions they intend to support. They also use some hidden non document rust flags to use unstable rust options/features on stable (but increasingly less, the flag exists only for bootstraping rust itself and isn't meant to be used by anything else). Which is fine for Firefox itself. Just a problem for anyone forking of Firefox. (Or for other reasons trying to build it with a different rust version.)
- heftig 5y agoFirefox might be a pretty bad example here. IIRC it was only recently they stopped using the undocumented RUSTC_BOOTSTRAP to enable unstable nightly features in stable Rust.
- gpm 5y agoIt looks like they still use that in a bunch of places? https://github.com/mozilla/gecko-dev/search?q=RUSTC_BOOTSTRAP https://github.com/mozilla/gecko-dev/search?q=RUSTC_BOOTSTRA... Specific example: https://github.com/mozilla/gecko-dev/blob/d36cf98aa85f24ceefd07521b3d16b9edd2abcb7/taskcluster/docker/image_builder/Dockerfile#L73 https://github.com/mozilla/gecko-dev/blob/d36cf98aa85f24ceef...
- heftig 5y agoOh, I see. I only vaguely remembered some changeset regarding it. I must have been mistaken, then, and it's still in use. In any case, sneakily using nightly features can make using a different Rust version problematic, since these features are free of any stability guarantees. Arch Linux carries a rather large patch updating some vendored dependency in order to make Firefox 78 compile with a newer Rust. https://github.com/archlinux/svntogit-packages/tree/packages/js78/trunk https://github.com/archlinux/svntogit-packages/tree/packages...
- kzrdude 5y agopacked_simd is accounting for the diff there, and it is still a nightly-only (meaning experimental features) crate, so looks like it's still using that.
- deleted 5y ago[deleted]
- kzrdude 5y agoWhat a confusing codebase. https://github.com/mozilla/gecko-dev/tree/d36cf98aa85f24ceefd07521b3d16b9edd2abcb7/third_party/rust/xmldecl https://github.com/mozilla/gecko-dev/tree/d36cf98aa85f24ceef... This package documents a "minimum supported rust version" then goes on to set RUSTC_BOOTSTRAP (cirumventing, enabling experimental features). Very mixed signals - I'm pretty disappointed to see documentation say one thing and then the code do another. I would suspect the developers are maybe not entirely in tune with the Rust ecosystem, and that would make sense, they have more important stuff to do, like building Firefox, than playing with Rust. :)
- chippiewill 5y agoIs this maybe related to not accounting for Rust editions? https://doc.rust-lang.org/edition-guide/editions/index.html https://doc.rust-lang.org/edition-guide/editions/index.html
- heftig 5y agoNo, editions require explicit activation and the "default" edition will remain forever at 2015, i.e. Rust 1.0. This is in contrast to C and C++ compilers like GCC and Clang, where the default "std" setting is often updated with new releases.
- cesarb 5y ago> No, editions require explicit activation and the "default" edition will remain forever at 2015, i.e. Rust 1.0. With the slight caveat that this is the "default if not specified", but the default when creating a new project with "cargo new" is to specify the currently latest version on the generated Cargo.toml file. That is, there are two defaults: the default for pre-edition projects (forever 2015), and the default for creating a new project (sets the project to what was the latest edition when the "cargo new" was run).
- dathinab 5y agoI believe it's not a caveat at all. I mean you can mix and match dependencies of different editions, and there are (IMHO) very few reasons to start a new project with an old editions. For that (IMHO) very few reasons you tend to be aware of you intentionally wanting to use a old version and as such it's not a problem. Through I would say there is no real default rust editions, it's more appropriate to say crates/libraries "keep" the rust edition they where created with until explicitly changed.
- gpderetta 5y agoWell, AFAIK rust versions are not backward compatible, while C and C++ standars for the most part are.
- joosters 5y ago...any performance measurements from before this transition aren't compatible with those after it, since I'm building different things with a different toolchain. Yes, but this would have been true even if there had been no rust errors or incompatibilities. You upgraded your rust compiler, so you're no longer comparing like with like.
- gpm 5y agoUnless of course your goal is to benchmark the difference between rust compilers, or maybe between software built with up to date compilers in general.
- seoaeu 5y agoThe author insinuates that the breakage is intentional, but I'm not convinced that it is. For instance, one of the cited issues is that newer cargo versions cannot parse the old Cargo.toml. However, as far back as 2016 cargo was maintaining backwards compatibility when making bug fixes to its TOML parsing. [1] [1]: https://github.com/rust-lang/cargo/pull/2680 https://github.com/rust-lang/cargo/pull/2680
- dralley 5y ago>The author insinuates that the breakage is intentional, but I'm not convinced that it is. The author seems to do this a lot. https://news.ycombinator.com/item?id=27385818 https://news.ycombinator.com/item?id=27385818
- mjw1007 5y agoWhen Rust 1.0 was released, the stated stability commitment had three documented caveats: « We reserve the right to fix compiler bugs, patch safety holes, and change type inference in ways that may occasionally require new type annotations. » See https://blog.rust-lang.org/2014/10/30/Stability.html https://blog.rust-lang.org/2014/10/30/Stability.html
- simias 5y agoI definitely had to add type annotations when compiling "old" Rust code with a modern version, but it wasn't a huge deal in practice. While Rust's handling of backcompat isn't perfect, I think it's very good given how young and fast-moving the language is. I usually have more trouble dealing with old C++ code on newer versions of G++/LLVM than Rust. Admittedly that C++ code often predates the very existence of Rust, but still, you'd expect a higher standard of backward-compatibility from such an old and widespread language.
- bfrog 5y agoI've seen minor version bumps in GCC break C++
- superkuh 5y agoRust is just too young and moves to fast to be used for software projects you want other people to be able to compile. In addition to the backwards compatibility problems it suffers even more serious forwards compatibility problems due to the type of dev culture currently associated with it. They always use $latest and what is in $latest changes so fast even if your rustc is 4 months old it already can't compile code written in $latest. If you're only shipping binaries it's okay. And in the future I bet Rust will be pretty nice. But right now it's painful and full of pitfalls.
- dathinab 5y ago> Rust is just too young and moves to fast to be used for software projects you want other people to be able to compile. Except many people doing exactly that and it working fine. > backwards compatibility problems Which aren't really a problem in practice. Definitely not worse then in any other language, yes there was some intentional breakage (soundness bug fixes) and unintentional breakage (compiler bugs) but most of this was in the very early stable rust versions since then accidental breakage which isn't caught and fixed before stable has become quite rare. As far as I know rust does more to find accidental breakage then many other languages. > They always use $latest and what is in $latest changes so fast even if your rustc is 4 months old it already can't compile code written in $latest. What is the problem with requiring a up-to date build chain? Slow long release cycles with a lot of patch back-porting is a software development model which for many (most?) projects has been deemed to not work well and has been replaced with something more in the direction of CI. Let's be honest even if we assume slow long releases are better for compilers, they still put quite an additional burden one the compiler development process which a is feasible if you have a lot of payed devs from large companies, but not really if only your core devs are payed (by the foundation and/or companies) but a lot of relevant contributions come from people not directly payed to work on rust. > But right now it's painful and full of pitfalls. I don't think so, but I guess we both can agree that thinks are improving, for me to make it even better and for you to maybe make it usable for the things you currently treat it as not suited for. ;-)
- superkuh 5y ago
- urschrei 5y agoOK, I'll say it because nobody else seems to want to: the sensible approach would be to ask for some help on one of the several official avenues that are open to you: users.rust-lang.org to begin with, and then the Discord (if you're comfortable with Discord). Aside from the high quality of help available to anyone, of any proficiency level, there's a pretty good chance you can describe your problem to someone who worked on Rust in Firefox. But why bother with that when you can write passive-aggressive blog posts that are devoid of useful information about the errors that were encountered instead.
- xyproto 5y agoRust+cargo not being as backward compatible as expected is different to the author wanting to solve one specific problem.
- vlang1dot0 5y agoFirefox has explicitly used unstable Rust features for years. Their build system opts into this behavior knowing these features are not guaranteed to be stable in future versions. It's 100% unsurprising that using unstable features means your code might break with a future compiler.
- nextaccountic 5y agoThe backwards compatibility guarantee of Rust applies only to stable releases. Firefox is weird in that it is enabling nightly features in an unnoficial compiler build that, for some odd reason, they want to tag as "stable". But it isn't.
- gpm 5y agoTechnically I believe that they're using the official compiler build, just using an unsupported and undocumented backdoor to enable nightly features in that official stable build.
- deleted 5y ago[deleted]
- HugoDaniel 5y agoSimilar things happen in a lot of other languages, sometimes it is not even a matter of a changing/evolving spec. (like TypeScript, or any other language that improves type checking or compile/interpretation validations at each minor version - breaking old code because it no longer type-checks/validates). Sometimes I feel that C is the only language that can benefit from compound gains over time, their spec is tight and sees sparse nuanced improvements in wide intervals of time.
- dathinab 5y agoThis is actually not a problem of spec but one of: - firefox "secretly" relying on unstable things while using stable rust (using some magical undocumented rust flags meant to be only used for bootstrapping rust). - the older firefox release relying/touching on some "bug" in rust which was fixed (e.g. accidentally accepting malformed config files, or soundness issues). - a bug in the compiler no one put resources to fix in yet (as e.g. close to no one is affected by it and there are more relevant bugs to work on). This can happen to you in C or C++, too. For any larger and more complicated projects some bugs "popping out" when using newer compilers due to either compiler bugs or code bugs "somehow passing by" in earlier compiler versions is totally a thing. Through due to how long the C standard stood still it's not that often happening in C, I guess? Hm, I wonder if Linux kernel devs might disagree??
- amluto 5y agoThe Linux build regularly breaks on new Clang versions. GCC is better in this regard, but we still have issues. The most common ones (that I’ve noticed, anyway) are codegen related — Linux makes assumptions about gcc’s output that break, even if gcc continues to accept the source code.
- loeg 5y ago> Through due to how long the C standard stood still it's not that often happening in C, I guess? Back in the GCC 4 timeframe (~2005), the compiler started taking a more strict view of the C standard in a way that produced additional warnings/errors relative to the GCC 3.x series. Compiler upgrades do regularly break some subset of packages in distro repositories; breaking C++ happens a lot more than C, but it happens.
- pilif 5y agoOne thing I ran into when I was trying to compile something after it wasn’t touched for a year or so is that cargo doesn’t in-fact look at its lock file what minor versions is concerned. This caused cargo to install different minor versions than it would have a year ago despite a lock file being present. These minor version updates were relying on newer rust version features and then failed to build on the old version of the rust compiler I was using. Updating rust made the build work again, but now with additional warnings (where the code I was compiling did shady things which old rust wouldn’t detect but new one did), but it did finally produce a usable binary. Still, I was a bit miffed by cargos behavior of ignoring minor versions locks in the lock file and installing later versions than what was locked. What good is a package lock file if it isn’t respected?
- steveklabnik 5y agoThat very very very much sounds like a bug, one that I’ve never heard of before. You don’t happen to have that project lying around, do you?
- dochtman 5y agoI think I’ve noticed that cargo install would pick up newer semver-compatible versions than what was in the lockfile unless I passed —-locked explicitly, which seemed surprising to me.
- steveklabnik 5y agoAh yeah if we’re talking about cargo install, then sure. That would make sense. Both behaviors can be surprising. We picked one. It happens. I am not sure myself if it was the right choice or not.
- follower 5y agoIt sounds little bit like the (known) situation around cargo where it doesn't default to `--locked` and so results in surprising behaviour for many people. This particular issue is in regard to `cargo install`: https://github.com/rust-lang/cargo/issues/7169 https://github.com/rust-lang/cargo/issues/7169 Oh, or, I guess, it might be how the version is specified--guess we need some more details on what "compile something after it wasn’t touched for a year" entailed.
- losvedir 5y agoSince rust does a "crater run" with each release, where it builds (all?) many known crates, it has stats with how many break. I vaguely remember a comment by Steve Klabnik here in HN one time (which I sadly cannot find now) that said over the course of a year, something like 95% of unupdated crates compile still compile on the newest version. I think that's pretty good, especially for such a young language with some ongoing significant changes. And I think that's stable enough for a production environment where there's an expectation of minimal ongoing maintenance. It means you rarely have to touch your code through updates, but occasionally will need to tweak something. But it does add up, and something 5 years old is decently likely to not compile. I personally ran into something like that digging up an old project, and the problem is it's hard to incrementally fix it, since at that point all the dependencies are quite old, too. And there's a complex relationship between the dependencies snapshotted at that moment, and so probably you can just update them all to the very newest version and they'll be compatible, but somewhere in the middle is hard.
- dilap 5y agojust checked: the first Go code i ever wrote, over 8 years ago, still compiles flawlessly. obviously the world is filled with trade-offs, but my oh my is it nice to use a language that doesn't break old code.
- Uther 5y agoI'm not sure you can compare the code base of you first program in Go, that is probably small and straightforward, with something as huge and complex as Firefox.
- dilap 5y agoFair point! (But also I will say the relative smallness of my projects in other languages has proved no defense against code breakage w/ time :-)
- temac 5y agoHave you ever seen a big codebase build 100% of the time after arbitrary toolchain, env, deps upgrade? There are some project more focused on that but even them eventually give up on supporting all versions of their deps. Likewise for compilers, pretty much regardless of the language. I mean the only way to stay perfectly compatible with random codebase is to keep the compiler even bug compatible with older ones, which is not particularly interesting... gcc seems to not always be backward compatible in practice. clang too. msvc too.
- tialaramex 5y agoUsers (and this is what the blog's author is here, they aren't developing Firefox they just want a benchmark activity) aren't very interested in solving technical problems and so, as seen here, they won't tell you what the error was. They definitely won't admit to any suspicion that it's in any way their fault. It's your fault. From their perspective, who cares what the error is? They formed an intent, and then your stupid computer software instead of fulfilling their intent did something else. This is your fault. For example maybe I wanted to delete the old data, and I typed "rm new-data". Don't tell me that deletes the new data, I can see that now, it's your fault that the new data is deleted, I wanted to delete the old data. For a UX point of view, where possible try to offer "Undo". The user doesn't care that shooting themselves in the face was a bad idea, and they definitely don't care that you made them click "Yes, really, in my face, I understand this will hurt" three times first, now that they've done it, and it hurts, they want to undo it. Adding a forth confirmation step will not reduce the complaints. Sometimes it will be hard to "undo". But you should periodically revisit decisions about that over the lifetime of a piece of software as resources increase. If you have 64KB bytes of RAM it's understandable if I can't undo "fill circle" in v1 of your Freeware art program. It's much less understandable in version 16 of the $100 program on a 16GB PC... Would it make sense to be able to "undo" a Rustup even though that's difficult? Maybe. It's worth at least considering. And yes, it is nice that Rust has a helpful community who might try to help you fix problems if you explain what the problem is, but this isn't really about Rust, it's about Users.
- steveklabnik 5y agoAn "undo" in Rustup barely makes sense, because it is almost virtually a stateless thing. However, maybe in this case, it would have; the author hasn't provided enough detail to truly say.
- ChrisSD 5y agoBut in that case they're Firefox "users", not Rust users. This distinction matters because the use of Rust is just a technical detail which ultimately the user doesn't really care about. They're benchmarking Firefox, not Rust. Therefore the onus is on Firefox to provide a good user experience.
- midjji 5y agoIts almost like fixing compiler bugs means no language is truly ever backwards compatible for long...
- thesuperbigfrog 5y agoWhat you are saying is true in the Hyrum's Law (https://www.hyrumslaw.com/ https://www.hyrumslaw.com/) sense, but should not be true for a mature programming language which maintains backward compatibility. The question then is how does someone define backward compatibility? The answer is a formal definition of what the expected behaviors and expectations of the programming language in question. This usually means a language specification or extensive unit tests that effectively define what the programming language should or should not do for a given set of circumstances.
- aseipp 5y agoRust already does this, they have extensive testing of new releases via e.g. crater. "Run the new compiler on every public piece of code possible" is actually a very unsurprising strategy these days and communities beyond Rust use this tactic, and this is all on top of the probably ~thousands of unit tests in their suite (not that users go looking at unit tests to decide what's "valid" Rust or not.) As someone who's invested a lot of time in PLT and even at one point had their name on a draft of the Haskell standard, the unfortunate reality is that language specifications are very often not useful to the wide majority of people, while being quite laborious to produce and maintain and work with over time. The culture of computer programming, at large, is part of this, it's not some mathematical fact, but a social one. At the end of the day, what constitutes "Rust the language" in any formal capacity doesn't matter; "Rust the language" is a social construct in that sense, a guarantee Rust will still be Rust even if some minor bugs are fixed that they let slip by. This is how most people think of it, when you get down to the nitty gritty. I'll also say that tons of regressions happen in mature languages with backwards compatibility. Ask any Linux distro maintainer! I don't even keep track of all the weird reasons regressions happen anymore; it's like counting sand on a beach. It's not a happy fact of life, but it is what it is, and regressions do happen, no matter if your language is stable for 5 years or 50.
- SomaticPirate 5y agoThe Rust apologists are numerous in these threads. Several people have told OP he should have reached out to ask the Rust community for help rather than writing a “passive aggressive” blog post. Is pointing out an undesirable behavior of Rust passive aggressive? I had the same experience trying to use older versions of Rust or trying to use newer versions of rustc on older crates. It doesn’t “just” work. For many of us this coming from Go, this seems like a step backwards. I’m thankful OP had the courage to post this note about his experience. I’m also disappointed to see members of the Rust community to suggest its a failing on OP’s part that they were not able to get Firefox to build and that bringing up this difficulty is something OP was wrong to do.
- michaelmrose 5y agoHe wrote a blog post about a language and tools that he doesn't personally use or understand that he was trying to use to stress test his system. From reading the responses it seems that he may have misunderstood Firefox specific issues as being rust issues by virtue of having insufficient understanding to disambiguate. Had he communicated he probably would have been able to derive this understanding easier from conversation thus the exhortation that he ought to have do so sees to be productive and correct. I don't think its apt to call the people critiquing the critique "apologists" when the entire original blog post seems to be misunderstanding on the part of the blogger. Posts that critique things the poster do not understand tend to themselves generate critical feedback which seems fairly measured to me.
- zinekeller 5y ago> I had the same experience trying to use older versions of Rust or trying to use newer versions of rustc on older crates. It doesn’t “just” work. For many of us this coming from Go, this seems like a step backwards. I have read the blogpost... and this isn't really the substance of the complaint? It is Mozilla's fault really to be honest, they should be sticking to a nightly if they want to use weird and non-standard features. I personally think the only similarly between yours and the authors' is the (supposed) unmet promises of backwards compatibility - guess what, I code in different languages (including Go) and I can see breakages regularly, mostly not due to breaking a "backwards compatible" promise but because the broken code has been always there, just not being enforced by the compiler. Specifically in Rust, the backwards compatibility promise wasn't Microsoft's "everything including undocumented features" backwards compatibility: it was only limited to documented features used properly. This can surprise people who relies on the Microsoft definition of backwards compatibility.