[HN Gopher] Rust 1.56.0 and Rust 2021
___________________________________________________________________
Rust 1.56.0 and Rust 2021
Author : steveklabnik
Score : 333 points
Date : 2021-10-21 14:59 UTC (8 hours ago)
(HTM) web link (blog.rust-lang.org)
(TXT) w3m dump (blog.rust-lang.org)
| mjw1007 wrote:
| In 2017 or so when Rust editions were invented, the notion was
| that editions were primarily a "rallying point" (a way to make
| Rust's continuous release process feel more like Java's or
| C++'s), and only secondarily an (opt-in) change to the language
| itself.
|
| See for example the summary at the top of https://rust-
| lang.github.io/rfcs/2052-epochs.html
|
| It seems to to me that that aspect has now been dropped: TFA
| simply says "Editions are a mechanism for opt-in changes that may
| otherwise pose backwards compatibility risk."
|
| I'm not sure this change of direction has been officially
| announced anywhere, though.
|
| (I think this is a good change: last time I saw cases of people
| asking questions like "How do I do foo in Rust 2018", and getting
| a mix of answers like "Nothing in Rust 2018 affects foo" and
| "Since Rust 1.20 you've been able to use std::foo::bar to do
| that".)
| nicoburns wrote:
| The 2018 was widely considered to be overly pressured (contrary
| to the usual Rust approach of shipping it when it's ready),
| which led to burnt out compiler devs, and a bunch of people
| with unmet expectations. I think the approach to decouple Big
| Bang features from editions has been made in response to that.
| mjw1007 wrote:
| It's hard to tell how much of the trouble with 2018 was due
| to the concept of having a major release with several things
| being updated together, and how much was due to the mistake
| of setting too early a deadline (by pre-announcing that it
| would be "Rust 2018" rather than "Rust 2019").
| kzrdude wrote:
| 2021 was explicitly a "nothing new" edition, at least.
| pornel wrote:
| It created confusion, because:
|
| * lumping marketing of cool features with an announcement of a
| few incompatible changes was easily misinterpreted as all new
| features requiring a new incompatible edition (while in fact
| almost all marketed features were already available in the old
| edition).
|
| * celebration of features developed in recent years under one
| big event sounded like all these features were brand new and
| released at once.
|
| For people who didn't follow Rust development, the announcement
| sounded like Rust suddenly made a lot of incompatible changes.
| steveklabnik wrote:
| It was discussed as part of the 2021 Edition RFC.
| tialaramex wrote:
| Interesting. It mentions stuff like the library and
| documentation.
|
| When IntoIterator for arrays first stabilized (with the hack
| hiding into_iter() for backwards compatibility) I considered
| making all the documentation changes to use natural arrays in
| standard library examples, which of course would now be the
| obvious way to write it whereas previously it was ugly.
|
| I didn't do it (and now I have a job keeping me too busy) and I
| haven't gone back to look at examples to see if all/ most /
| some were updated to use arrays in the now natural way.
| Fiahil wrote:
| It's not written in the announcement, but I am under the
| impression that Rust 1.56 compiles a bit faster. Is that right ?
| Macha wrote:
| Here's some compile benchmarks from the LLVM update which is
| the main reason for compile time changes:
|
| https://perf.rust-lang.org/compare.html?start=ef9549b6c0efb7...
|
| Some things compile decently faster (~ 10%), some things
| compile a little faster or slower (~ +/- 3%), some things have
| a bigger perf hit but not as many as had a bigger perf gain (~
| -10%).
|
| So it's faster on average but the data is muddy enough that you
| probably wouldn't stick it front and center on your release
| notes.
| dralley wrote:
| Does anyone know what change was responsible for the big
| improvement from a few days ago?
|
| https://perf.rust-lang.org
|
| It's less of a universal improvement than the pass manager,
| but for most of the benchmarks that it does impact it seems
| just as large, or larger.
| kzrdude wrote:
| From the graph, it points out this commit. And from the
| description, I think it's exactly that commit and not just
| one close to it. I heard it was a big improvement.
|
| https://github.com/rust-lang/rust/commit/63cc2bb
|
| > Enable new pass manager with LLVM 13
|
| > https://github.com/rust-lang/rust/pull/88243
| benschulz wrote:
| I believe this is mostly due to the switch to LLVM 13[1].
|
| [1]: https://twitter.com/ryan_levick/status/1443202538099073027
| eska wrote:
| That seems to have been a mixed bag. But they also enabled
| PGO (or was it LTO?) and that was mentioned to be a bigger
| improvement.
| woodruffw wrote:
| PGO requires a runtime profile, so I doubt they've enabled
| that by default :-)
|
| Rust has had LTO for quite a while, and it's normally a
| source of _longer_ compilation times rather than shorter
| ones (since LTO in LLVM-world involves mashing all of the
| bitcode together and (re-)running a lot of expensive
| analyses to further optimize across translation unit
| boundaries.
|
| OTOH they've been making continuous improvements to the
| incremental compilation mode since 1.51/2, so that's
| probably among the sources of improvements here.
| nicoburns wrote:
| I believe the new pass manager isn't due to be enabled by
| default until the next version (1.57)
| runevault wrote:
| Yeah the significant improvements from 13 will require that
| last I heard.
| eska wrote:
| Finally a nice way to init hash maps and all other kinds of
| collections! The former was really unattractive to Rust newbies!
| stusmall wrote:
| I love the concept of editions. I haven't anything like it in
| other languages. Having the ability to have one project made up
| of crates of many different editions is brilliant. It makes
| breaking language changes that would otherwise be a nonstarter
| become minor and easy to manage. Love it
| remram wrote:
| Lots of languages have opt-in features/extensions/pragmas,
| which are more granular but somewhat similar. Like Python's
| __future__, Haskell's #LANGUAGE, and Rust's #![feature].
|
| Adding 20 lines of #[!feature(...)] to every project would get
| old quick.
| steveklabnik wrote:
| While there's nothing exactly like it yet, we did consider the
| ways that many similar systems work. There's a lot of
| similarities, even though I do think Editions end up being
| meaningfully distinct.
|
| As an example, here's a comment of mine on the original RFC
| (which was called "epochs"): https://github.com/rust-
| lang/rfcs/pull/2052#issuecomment-315... (the part with "Some
| language development comparisons")
| avgcorrection wrote:
| > I think the main problem here is semver.
|
| Maybe it's ironic that semver (machine-readable versioning)
| ended up being a liability due to interpretation by people
| (i.e. we can't release a 2.0 because it would "send the wrong
| message").
| steveklabnik wrote:
| While semver was _intended_ as machine-readable versioning,
| and still mostly is, given that sevmer does not say what an
| "api" is in any way means that it's still defined by humans
| at the end of the day.
|
| I think I'm in agreement :)
| stouset wrote:
| Of course there's always Hyrum's Law[1], which can be
| summed up as
|
| > All observable behaviors of your system will be
| depended on by somebody.
|
| Even minor bugfixes will at some point invariably break
| somebody who depended upon the broken behavior. So semver
| really boils down to a human assessment of whether any
| potential breakage is incidental or intended.
|
| [1]: https://www.hyrumslaw.com/
| tialaramex wrote:
| Hyrum's Law reminds me of Frank Borman's "A superior
| pilot uses his superior judgement to avoid situations
| which require the use of his superior skill". On the user
| side Hyrum's law is a situation where you're going to
| need superior skill to fix it. You should instead have
| used superior judgement to avoid this situation
| altogether.
|
| As a library author I don't feel there's any value in
| considering Hyrum's Law. I can't help those poor fools,
| for all I know they're relying on me not updating the
| documentation to warn them they shouldn't rely on
| undocumented behaviour I'm about to change... Rust
| provides a pretty clear line in the sand on API changes
| we can use to choose semver policy. If your program has a
| proc macro to copy-paste sections of my source code into
| yours so you can access my non-public functions, I can't
| see that from where I am and you're lucky it ever worked,
| I am under no obligation to ensure it magically stays
| working in my next bugfix release.
| avgcorrection wrote:
| And I agree with you on the solution: version the
| language (or whatever other more conceptual thing) by
| year and the program by semver. It's the only thing that
| makes sense given the constraints.
| emteycz wrote:
| ES(year) for JavaScript
| nicoburns wrote:
| A better JavaScript example would be strict mode, which is
| opt-in with "use strict" and changes quite a bit of the
| semantics of the code while being completely interoperable
| with non-strict JS code.
| Macha wrote:
| Yeah, and the "use" statements for this came from Perl
| which is probably the originator of this pattern here.
| RussianCow wrote:
| Newer versions of JavaScript do not break compatibility with
| older versions, whereas different editions of Rust break
| compatibility in various ways while still allowing
| interoperability between libraries written in different
| editions. That makes the two approaches very different.
| bee_rider wrote:
| Although if they hit Rust version 2.XX.Y this might add some
| (probably brief) confusion.
| RussianCow wrote:
| I remember reading somewhere that Rust will never have a v2,
| but now I can't find a source.
| nicoburns wrote:
| There are currently no plans, but I don't think it's a hard
| never. I'd probably be willing to bet it'll be at least 10
| years though.
| nivertech wrote:
| Solidity (a PL in which Ethereum's so called "smart
| contracts"[1] are developed) has version pragmas [2] at the top
| of each file.
|
| That's necessary b/c there are lots of breaking changes between
| language/compiler versions[3].
|
| --
|
| [1] they are more like DB triggers than contracts
|
| [2] https://docs.soliditylang.org/en/develop/layout-of-source-
| fi...
|
| [3] https://docs.soliditylang.org/en/develop/050-breaking-
| change...
| woodruffw wrote:
| Version pragmas themselves aren't new -- even Perl has
| them[1]. What makes Rust's implementation nice (and somewhat
| unique) is its commitment to backwards compatibility while
| _allowing_ codebases to incrementally move towards a new
| edition.
|
| [1]: https://perldoc.perl.org/functions/use
| tialaramex wrote:
| From one your links:
|
| > It just instructs the compiler to check whether its version
| matches the one required by the pragma. If it does not match,
| the compiler issues an error.
|
| This is very different from Rust where your Rust 1.56.0
| compiler will cheerfully compile Rust 2015, Rust 2018 and
| Rust 2021 code, into the same program even. Rust editions are
| _not_ about the compiler version, they 're about the
| _language_ and every Rust compiler will compile every
| language edition it knows about.
| cygx wrote:
| _> I haven 't anything like it in other languages_
|
| Perl can do it not only at module level, but at block level
| within a single source file.
| xamolxix wrote:
| > I haven't anything like it in other languages
|
| Is that different from compiling one lib with --std=c++11 and
| another with --std=c++17?
| EdSchouten wrote:
| Yes, in that in C++ it would break if one library used a
| modern language feature as part of its public header files.
| chc wrote:
| Surely the difference there is that Rust doesn't have
| header files.
| masklinn wrote:
| Not necessarily, you could imagine a system where the
| header file specifies its edition.
| dralley wrote:
| But don't header files generally get concatenated
| together due to the way "dumb" textual includes work?
| cpeterso wrote:
| A header file can check #if __STDC_VERSION__ or
| __cplusplus versions to make some code conditionally
| available for, say, C11 or C++11. #if
| __STDC_VERSION__ >= 201112L // C11 feature
| #endif #if __cplusplus >= 201103L //
| C++11 feature #endif
| [deleted]
| hiccuphippo wrote:
| Can't you compile libraries to object files independently
| with whatever version of c++ they require and then link
| them together?
| int_19h wrote:
| You'd still need the header that describes the public
| interface of such a separately compiled object file.
|
| Also, this doesn't work with templates, and modern
| idiomatic C++ tends to be template-heavy.
| tialaramex wrote:
| Yes. If the only value the library brings to you is that
| it generates a particular object file, you can divorce
| that object file from your chosen language version
| entirely.
|
| If you have libraries that you don't care if they're C or
| Pascal or a Lisp implemented in raw machine code, then
| this works just fine and you needn't care about Rust's
| editions feature. Rust will also cheerfully consume these
| libraries although of course everything about them is by
| definition Unsafe in Rust terms.
|
| But most people want their C++ libraries to deliver a bit
| more than "Here is some machine code, and here are some
| symbol names that map to the machine code or to raw
| binary data". Like maybe they want to be able to
| _implement_ an Interface the library describes, or they
| want to use a Concept the library names. You can 't do
| those things using language-independent object files.
|
| Rust library A, from edition 2021 can implement a Trait
| from library B (edition 2018) on its thin wrapper of a
| type from library C (edition 2015) and then you can
| consume the resulting type, with its trait
| implementation, from your Rust 2018 program.
| MaulingMonkey wrote:
| The problem is a C++ library's headers must be compiled
| with the settings, context, and flags of every downstream
| thing that depends on them, rather than separately.
|
| Which isn't such a big problem if your C++ library
| exposes a minimal C-like API from it's headers, with most
| of the meat of the library hidden away in source files,
| but might be a very big problem if your C++ library is a
| miserable little pile of ~~secrets~~ _templates_ , a la
| boost.
| heftig wrote:
| If the application is using C++17, wouldn't the headers of
| the C++11 lib then be compiled as C++17, potentially breaking
| things?
|
| PS: The other way around is more obviously broken, with the
| C++17 lib headers getting compiled using C++11.
| pjmlp wrote:
| Or you make use of the preprocessor or if constexpr, and
| then have the specific code for each language version.
| int_19h wrote:
| The maintainers would have to do it for every new
| language version that breaks them, though. The edition
| system keeps old stuff working without any effort.
| pjmlp wrote:
| I don't want to start this discussion thread yet again,
| but I am a firm believer that edition system only appears
| to work right now because:
|
| 1 - Rust is still quite young and doesn't have 30 years
| of accumulated editions
|
| 2 - There is still only one major Rust compiler
|
| 3 - Editions are designed only to work when compiling the
| whole project, including 3rd party dependencies, from
| source code within a single build
|
| 4 - So far the editions don't have semantic breaking
| changes across editions, where behaviour changes across
| the edition border
|
| 5 - There is no plan to ever have editions work across
| ABIs
|
| So "The edition system keeps old stuff working without
| any effort." might not be true when Rust achieves an
| adoption scale similar to C and C++, in about 20 years,
| with several accumulated editions, and a couple of
| compilers in use.
|
| I might be proven wrong, but that is how I see it today.
| tialaramex wrote:
| It's certainly true that if C++ library maintainers are
| up for the ever-growing maintenance burden, they can all
| individually deliver the same promise Rust gets out of
| the box.
|
| This is in practice what the maintainers of the three
| standard libraries have to do, perhaps one or more of
| them will offer their opinion about that experience?
| orra wrote:
| I don't know what guarantees your typical C++ compiler gives
| you that those can link together?
|
| Regardless, at the very least, you would need to write the
| headers to be interoperable.
| masklinn wrote:
| Aside from the header issue, it doesn't allow for or support
| backwards-incompatible changes.
|
| Because editions are opt-in (and library-level source
| metadata) the language itself can be modified in non-
| backwards-compatible ways.
|
| So for instance a C++ with editions could make ctors
| `explicit` by default, or it could entirely change the
| automatic member generation (by removing it for instance). As
| long as the ABI and API remain compatible, that's fine.
| neandrake wrote:
| It's probably worth noting that the backwards compatibility
| breaking changes I think only applies to the language and
| not the standard library. I'm unable to look up the details
| right now but I believe there's a trait function defined in
| stdlib which is deprecated, supersede, but can't be removed
| even as part of an Edition, or it would break older code.
| masklinn wrote:
| That is correct, editions are mostly about language-level
| syntactic changes, the APIs have to be compatible between
| editions. The only place where that isn't the case is the
| standard prelude (the "builtins" you don't have to
| import).
| tialaramex wrote:
| The ability to replace the prelude does mean that you can
| imagine if somebody invents a much better thing than,
| say, Rust's iterators Rust 2050 can have a prelude that
| brings in std::better::Iterator instead of
| std::iter::Iterator and then most coders will end up
| using the new better iterators, just because that's the
| kind you get out of the box.
|
| Anybody who literally refers to std::iter::Iterator gets
| the old ones of course as does any library code from
| prior editions, but the documentation could lead those
| few people in the right direction. And presumably
| std::better::Iterator politely implements
| std::iter::IntoIterator because why not.
|
| I would be interested to understand if they're allowed to
| replace the macros. The standard macros aren't actually
| from the prelude, but instead if you aren't no_std you
| get all the standard macros anyway. Are they allowed to
| change those in a future edition? Or not?
| stormbrew wrote:
| Personally I'd kinda like it if preludes were decoupled
| from editions in some way. Like, fine to have a default
| per-edition but there are times I would _really_ like to
| have a prelude without all the `impl <T> X for T`s
| included.
|
| You can kinda do this now with `#[no_implicit_prelude]` I
| think but it has somewhat odd semantics. It applies to
| all submodules, unlike most attributes, and then if you
| define your own prelude you need to use it in every
| submodule because they won't all have their own.
|
| If it's gonna have global effect I think it'd be better
| if it was: #[prelude] mod
| my_prelude { use std::whatever::*; }
|
| and then my_prelude would be included in all submodules
| by default.
| nicoburns wrote:
| Seems like it ought to new possible to rename
| std::iter::Iterator to std::iter::OldIterator, add
| std::iter::NewIterator, and then vary which iterator
| std::iter::Iterator points to based on edition.
|
| Maybe that would be considered too confusing though.
| pornel wrote:
| Yes, because C versions are frozen in time, and editions
| aren't. Today Rust added brand new features to Rust 2015 and
| Rust 2018, and will continue to expand them forever (every
| new feature lands in all editions whenever possible).
|
| Rust editions are closer to source code parsing modes. More
| like enabling trigraphs in C or "use strict" in JS.
|
| Additionally, textual header inclusion in C makes mixing
| versions tricky. Rust has properly isolated crates, and
| tracks edition per AST node (so that even cross-crate macros
| work correctly with mixed editions).
| alerighi wrote:
| C compilers usually backport features in older standards as
| well (I know, they are breaking the standard). One example
| are C++ style comments, that are in the standard only from
| C99, but basically every compiler supports them even in
| ANSI/C90 mode.
|
| By the way the difference is that Rust is not a standard,
| thus is easier to evolve (the process is much shorter). On
| the other side, the fact that a language changes slowly
| it's something good in a way, it means that you don't have
| to continue to change the way you do things, and update
| older projects.
|
| That to everyone that has to maintain code for decades it's
| important. And every serious software project (not hobby
| stuff) does stay in production decades really. I don't use
| Rust, or even C++, for that reason.
| nicoburns wrote:
| > On the other side, the fact that a language changes
| slowly it's something good in a way, it means that you
| don't have to continue to change the way you do things,
| and update older projects.
|
| Isn't the point of Rust editions that this is also true
| for Rust? Don't want to update to a new edition? Then...
| don't. The old ones are maintained.
| Luker88 wrote:
| Wonderful, but still disappointed that easy strict-type-wrapping
| is not a thing yet.
|
| There have been a few RFC trying to work on deriving a type from
| another, and while I agree it's much more complex than it sounds,
| I also find it's a huge missing point.
|
| If I have to reimplement a wrapper myself for all Traits, I most
| likely won't bother, leading to less typesafety, leading to more
| bugs :(
| pjmlp wrote:
| Finally here! Congratulations to everyone.
| yakubin wrote:
| I'm eagerly awaiting the Cargo feature "named profiles"[1]. It's
| already merged, but not yet announced to be planned for any
| specific Cargo version. It will allow users to create custom
| profiles with different build parameters from the standard ones,
| so you can e.g. create a "profiling" profile which is based on
| the "release" profile, so that it has all the nice optimizations,
| but with debug information included, so that it works well with
| _cargo-flamegraph_ : [profile.profiling]
| inherits = "release" debug = true
|
| [1]: <https://github.com/rust-lang/cargo/pull/9943>
|
| And then there's the less fireworky, but still appreciated,
| _Iterator::map_while_ [2], which is going to be in Rust 1.57.
|
| [2]: <https://github.com/rust-lang/rust/pull/89086>
| steveklabnik wrote:
| Unless something is special about this feature, new features
| generally aren't "planned" for specific versions in general.
| Since this landed two weeks ago, that means that it should land
| in the beta version of Cargo once that branches for this
| release (I didn't check if it has yet or not), which would
| place it to be stable in the next release of Rust, 1.57.0.
| yakubin wrote:
| Thanks for the clarification. I just went by what's specified
| in the sidebar on GitHub in the "Milestone" section.
| steveklabnik wrote:
| Any time. Cargo doesn't use the Milestone feature of GitHub
| at all, so that's why that's empty :)
| nynx wrote:
| Woot woot, transmute is const now
| orra wrote:
| Curious what the applications are. Collections? Would you write
| a lot of "unsafe" const code, given the chance?
| brink wrote:
| It's useful for handling data that came from outside Rust.
|
| If you have a byte array that you've received over a network
| connection that represents an array of floats, or you need to
| convert a 32bit RGBA pixel buffer that you got from some
| clang ffi binding to a byte pixel buffer without having to
| split/copy to a new vector.
| kzrdude wrote:
| Happy that the const subset of the language grows
| luizfelberti wrote:
| I will shamefully admit to using transmute in very sinful
| ways, such as having enums that are repr(u16) or something
| like that at multiple numeric ranges such as:
| #[repr(u16)] enum Foo { A = 0, B }
| #[repr(u16)] enum Bar { A = 3200, B }
| struct FooOrBar(u16);
|
| And then proceeding to violate all of the unwritten rules of
| Rust by wrangling casts across these types like a goddamn
| wizard
|
| I'm not proud of this...
| lilyball wrote:
| This sounds like a great example of where you might want a
| union (https://doc.rust-
| lang.org/1.56.0/reference/items/unions.html)
| luizfelberti wrote:
| Ooh I forgot the language had those!
|
| I still feel like this trick has it's place though, as an
| example take a look at where I stole this trick from, by
| matklad [0] and tell me what you think :)
|
| [0] https://github.com/rust-
| analyzer/rowan/blob/d2c7843858da9d9e...
| nynx wrote:
| I can't think of an example now, but it has come up before
| when working on collections and other things.
| steveklabnik wrote:
| One thing that's come up a couple times are... well, what
| transmute is, that is, two types that have the same
| representation, and you want to cast between them. For
| example, the "try Rust out in the Linux kernel" code has a
| function that turns a byte slice into a &Cstr via a
| transmute. Those kinds of conversions can be useful inside of
| const fns.
| ishanjain28 wrote:
| Hi Steve,
|
| I came across this post which presents an example using
| rust's transmute and it's incorrect behavior when the
| alignment is different.
| https://andrewkelley.me/post/unsafe-zig-safer-than-unsafe-
| ru...
|
| Is this issue still present? I tried to figure it out the
| other day using latest rust's nightly but the llvm ir
| output has so much going on that I didn't _really_
| understand what was going on
| steveklabnik wrote:
| I am unsure about the specific details about IR that's
| emitted (though at first glance it seems we do emit the
| alignment attribute now, I think?), but transmute is, as
| the documentation says, "incredibly" unsafe:
|
| > Because transmute is a by-value operation, alignment of
| the transmuted values themselves is not a concern. As
| with any other function, the compiler already ensures
| both T and U are properly aligned. However, when
| transmuting values that point elsewhere (such as
| pointers, references, boxes...), the caller has to ensure
| proper alignment of the pointed-to values.
|
| This code is doing the latter incorrectly, and therefore
| invokes UB, as far as I can tell. To be honest, I don't
| use transmute very often and so I don't have every single
| last corner case about it memorized.
|
| It's not so much an "issue" as it is "Here's an API
| that's extremely sharp in Rust, and a similar, but less
| sharp API in Zig."
| MaulingMonkey wrote:
| Per transmute's docs @ https://doc.rust-
| lang.org/std/mem/fn.transmute.html:
|
| > Because transmute is a by-value operation, alignment of
| the transmuted values themselves is not a concern. As
| with any other function, the compiler already ensures
| both T and U are properly aligned. However, when
| transmuting values that point elsewhere (such as
| pointers, references, boxes...), the caller has to ensure
| proper alignment of the pointed-to values.
|
| The post you've linked transmutes a _reference_ , and as
| the caller fails to explicitly ensure proper alignment,
| it explicitly risks invoking undefined behavior - I would
| consider the code buggy. The easiest way to prove it's
| broken would be to create an reference that's more likely
| to be unaligned (&array[1] instead of &array[0]?) and run
| the code on a less misalignment-tolerant platform (ARM?).
|
| Here are some 100% sound alternatives using bytemuck (no
| unsafe required!) and core::ptr::{read,write}_unaligned
| (unsafe required):
|
| https://play.rust-
| lang.org/?version=stable&mode=debug&editio...
| jarpadat wrote:
| That discussion is a bit strange. In that example Foo is
| implicitly #[repr(Rust)] meaning it has an undefined
| layout. In particular, a,b is unordered, and even if you
| don't care which order you get, there is the question of
| padding (a reasonable compiler will tightly pack a,b but
| that's not required).
|
| For this reason, we never reach the question of alignment
| because we know neither i32, u8, nor any other type has
| the same layout as Foo (undefined layout).
|
| It is certainly true that unsafe Rust is _veeeeery_
| unsafe, as perhaps evidenced by me being the first person
| to point out the repr issue. On the other hand this
| scheme has a lot of advantages for writing safe Rust.
| jjice wrote:
| Really excited for the reserved prefixes. Lots of possibilities
| there. I'm really rooting for f-strings to stream line format!
| calls.
| mbStavola wrote:
| I'm so excited to finally have disjoint captures in closures;
| many papercuts on that one when I worked heavily with Amethyst a
| while back as there were a few closure-based APIs.
|
| Thanks to all the contributors for getting us to the 2021
| edition!
| k__ wrote:
| That's the stuff Rust needs more of!
| dthul wrote:
| Love the 2021 edition changes and also the fact that they are so
| minor!
| nayuki wrote:
| I'm confused about the bullet point "IntoIterator for arrays". I
| thought this was added already in Rust 1.53.0. Did something else
| happen?
|
| See https://blog.rust-
| lang.org/2021/06/17/Rust-1.53.0.html#whats...
| steveklabnik wrote:
| There's an explanation at the bottom of the section; this
| landed as a hack in previous editions, but works via the normal
| mechanisms in Rust 2021.
|
| "Since this special case for .into_iter() is only required to
| avoid breaking existing code, it is removed in the new edition,
| Rust 2021, which will be released later this year."
|
| As a user, you're right that there's not really an external-
| facing change here.
| davisoneee wrote:
| To follow Steve's comment:
|
| > Until Rust 1.53, only references to arrays implement
| IntoIterator. This means you can iterate over &[1, 2, 3] and
| &mut [1, 2, 3], but not over [1, 2, 3] directly.
|
| ...now, you can also iterate over [1, 2, 3] etc.
|
| https://doc.rust-lang.org/edition-guide/rust-2021/IntoIterat...
| steveklabnik wrote:
| Right, but the point is that you can do that as of 1.53.0,
| you didn't have to wait until this release and the edition to
| do it.
| tialaramex wrote:
| You know all this, but while _some_ obvious things work in
| 1.53.0 one important thing causes scary warnings because it
| is shadowed by the back compat hack.
|
| "for x in myArray" works fine, just like "for x in
| myVector" but whereas "myVector.into_iter().foo()" does
| what you expect, "myArray.into_iter().foo() is actually
| giving foo an iterator over the references just as it would
| have in 2017 and now produces a warning about this into the
| bargain.
|
| In Rust 2021 myArray.into_iter() does what a modern Rust
| programmer expects it to do, provide an iterator over
| myArray itself.
|
| The warning does explain how you can get that iterator in
| 1.53.0 of course, but you need to write some ugly syntax
| whereas in Rust 2021 the obvious syntax just does what you
| expect as if arrays had always been IntoIterator.
___________________________________________________________________
(page generated 2021-10-21 23:01 UTC)