Rust Internals - Latest posts https://internals.rust-lang.org Latest posts Just `mut` alongside `let mut` I imagine many people rely on lints (e.g., clippy::shadow_unrelated) to detect or prevent shadowing, and I'd guess it wouldn't be that difficult to expand existing lints to detect such code or add new lints that would detect it.

Such lints already fire in the absence of let when dealing with function/closure parameters:

#[expect(clippy::shadow_unrelated, reason = "example")]
fn foo() -> u32 {
    let x = 3u32;
    x + Some(0u32)
        .map(|mut x| {
            x += 1;
            x
        })
        .unwrap_or_default()
}
]]>
https://internals.rust-lang.org/t/just-mut-alongside-let-mut/24084#post_9 Mon, 16 Mar 2026 15:40:52 +0000 internals.rust-lang.org-post-151696
Just `mut` alongside `let mut` Without a leading let it will be harder to detect shadowing in your code:

let foo = "foo";

...

mut foo = "bar";
]]>
https://internals.rust-lang.org/t/just-mut-alongside-let-mut/24084#post_8 Mon, 16 Mar 2026 14:53:28 +0000 internals.rust-lang.org-post-151695
Could borrow checking with origins unblock sound specialization
bjorn3:

Because it would require needlessly duplicating functions for every instantiation

No, it wouldn't. Under refined proposal (dropping same origin dispatch), the solver makes the specialization decision before lifetime erasure and bakes it into MIR as a direct function call. Codegen never looks at lifetimes to decide anything.

No function body is ever duplicated based on lifetimes. If a generic function has T: 'static in its where clause, the solver picks the specialized impl for every call into that function, because every T entering it is 'static by construction. One copy per concrete type, same as today. If the function doesn't have the bound, the solver falls back to the default. Also one copy. There's no case where the monomorphizer produces two copies differing only in lifetime. @robofinch raised valid point though that this would "expose" internal workings of the borrow checker to the actual code execution.

It is compatible: inside takes_callback(f: for<'a> fn(&'a u8)), the solver sees for<'a>, which means "must work for all lifetimes." There's no 'static bound, no concrete lifetime visible. The solver falls back to the default impl which is one function body. The HRTB case is just another instance of "generic context where the solver doesn't have the information, so it uses the default." The single function pointer is never asked to behave differently for different lifetimes.

Just to reiterate:

Or did I miss something?

]]>
https://internals.rust-lang.org/t/could-borrow-checking-with-origins-unblock-sound-specialization/24079#post_8 Mon, 16 Mar 2026 14:21:39 +0000 internals.rust-lang.org-post-151694
Introduce a way to construct Range from start + length Thank you for the enlightenment, I wasn't aware of the ACP process.

]]>
https://internals.rust-lang.org/t/introduce-a-way-to-construct-range-from-start-length/24073?page=2#post_29 Mon, 16 Mar 2026 13:50:13 +0000 internals.rust-lang.org-post-151691
Idea: Add an option to set the mode to fs::copy
jrose:

fclonefileat operates on a directory descriptor + basename for the destination

Thanks for the clarification, I didn't read the code closely enough to notice that.

]]>
https://internals.rust-lang.org/t/idea-add-an-option-to-set-the-mode-to-fs-copy/24080#post_11 Mon, 16 Mar 2026 13:45:01 +0000 internals.rust-lang.org-post-151690
Could borrow checking with origins unblock sound specialization
Serhii:

But is this really the case? Specializing on 'static seems like a perfectly valid use case. 'static is not an origin computed by the borrow checker, it's a property of the data itself. No borrow checker upgrade will change whether a string literal or an owned type is 'static. T: 'static is already a bound the solver understands.

Because it would require needlessly duplicating functions for every instantiation. And it is incompatible with HRTB (for<'a> fn(&'a ()) might need different codegen for when it is passed an &'static () or a &'notstatic (), but it represents only a single function pointer that needs to be valid for both lifetime instantiations)

]]>
https://internals.rust-lang.org/t/could-borrow-checking-with-origins-unblock-sound-specialization/24079#post_7 Mon, 16 Mar 2026 13:29:22 +0000 internals.rust-lang.org-post-151689
How can we solve the problem of unmerged RFCs after their FCP? So theoretically after it fixes the file we could give RFCbot merge permissions and have it automatically merge?

Should the FCP start before the changes are made? That doesn't seem right to me. I could be wrong though

]]>
https://internals.rust-lang.org/t/how-can-we-solve-the-problem-of-unmerged-rfcs-after-their-fcp/24083#post_9 Mon, 16 Mar 2026 07:37:24 +0000 internals.rust-lang.org-post-151688
Idea: Add an option to set the mode to fs::copy The Mac fclonefileat operates on a directory descriptor + basename for the destination, not a file descriptor. Which makes sense, since it is modifying directory entries rather than file contents. That said, I'm also not sure it can modify permissions atomically with the clone—the manpage suggests you can choose "same as original, if permitted" or "reset to the default for the destination directory". Which means changing the fs API wouldn't be able to provide atomicity anyway.

EDIT: …and copyfile now has a COPYFILE_CLONE flag, so maybe fclonefileat is a distraction anyway.

]]>
https://internals.rust-lang.org/t/idea-add-an-option-to-set-the-mode-to-fs-copy/24080#post_10 Mon, 16 Mar 2026 04:43:18 +0000 internals.rust-lang.org-post-151687
How can we solve the problem of unmerged RFCs after their FCP? Yes, most of the time this is about someone taking the procedural steps to do this, which takes a few minutes, but they are a manual few minutes that don't involve just pushing a merge button.

Occasionally, the problem is also that we FCPed an RFC while saying it needs a couple of changes, and the changes haven't been made yet.

]]>
https://internals.rust-lang.org/t/how-can-we-solve-the-problem-of-unmerged-rfcs-after-their-fcp/24083#post_8 Sun, 15 Mar 2026 22:10:44 +0000 internals.rust-lang.org-post-151679
How can we solve the problem of unmerged RFCs after their FCP?
RalfJung:

one also has to fix up the filename and potentially the "rendered" link and maybe more

This, at least, should be better now as the bot will IIRC do the rename when the PR is initially opened now.

]]>
https://internals.rust-lang.org/t/how-can-we-solve-the-problem-of-unmerged-rfcs-after-their-fcp/24083#post_7 Sun, 15 Mar 2026 20:34:49 +0000 internals.rust-lang.org-post-151677
Just `mut` alongside `let mut`
nvijayap:

I am talking about the future - an enhancement to make the code elegant.

The core problem is that you're also, perhaps unknowingly, asking for

  • a giant argument about when it's better to use which form
  • a giant argument about whether everyone should have to move to the new form
  • a giant argument about how rustfmt should decide which to use
  • a bunch of confusion when people see older resources that weren't updated
  • a ton of churn on everyone with existing code to move to the new thing

It's just not worth it.

The rust philosophy for this is that it's fine to ask people to just accept the structured suggestion. I, for example, continually make the mistake of struct Foo { x: u32; y: u32 } -- a semicolon instead of a comma -- but the answer isn't "Rust should accept that"; it's "oops, I accepted the structured suggestion and it's fine now".

]]>
https://internals.rust-lang.org/t/just-mut-alongside-let-mut/24084#post_7 Sun, 15 Mar 2026 20:33:14 +0000 internals.rust-lang.org-post-151676
Just `mut` alongside `let mut` See also: Frequently Requested Changes - The Rust Language Design Team

Frequently Requested Changes

This page documents some of those ideas, along with the concerns that argue against them.

If something appears on this page, that doesn’t mean Rust would never consider making any similar change. It does mean that any hypothetical successful proposal to do so would need to address at a minimum all of these known concerns, whether by proposing a new and previously unseen approach that avoids all the concerns, or by making an extraordinary case for why their proposal outweighs those concerns.

Hopeful proposers of any of these ideas should document their extensive research into the many past discussions on these topics and ensure they have something new to offer.

[…]

Fundamental changes to Rust syntax

This includes proposals such as changing the generic syntax to not use </>, changing block constructs to not require braces, changing function calls to not require parentheses, and many other similar proposals. These also include proposals to add “alternative” syntaxes, in addition to those that replace the existing syntax. Many of these proposals come from people who also write other languages. Arguments range from the ergonomic (“I don’t want to type this”) to the aesthetic (“I don’t like how this looks”).

Changes that would break existing Rust code are non-starters. Even in an edition, changes this fundamental remain extremely unlikely. The established Rust community with knowledge of existing Rust syntax has a great deal of value, and to be considered, a syntax change proposal would have to be not just better, but so wildly better as to overcome the massive downside of switching.

In addition, such changes often go against one or more other aspects of Rust’s design philosophy. For instance, we don’t want to make changes that make code easier to write but harder to read, or changes that make code more error-prone to modify and maintain.

That said, we are open to proposals that involve new syntax, especially for new features, or to improve an existing fundamental feature. The bar for new syntax (e.g. new operators) is high, but not insurmountable. But the bar for changes to existing syntax is even higher.

]]>
https://internals.rust-lang.org/t/just-mut-alongside-let-mut/24084#post_6 Sun, 15 Mar 2026 20:19:22 +0000 internals.rust-lang.org-post-151675
Just `mut` alongside `let mut` It is certainly possible to add this feature. The question is, will the benefit of the code being more concise, only, be worth the cost of the compiler, and human readers, learning another single-purpose piece of syntax? That is the argument you must make, not merely that is it possible and would be shorter.

]]>
https://internals.rust-lang.org/t/just-mut-alongside-let-mut/24084#post_5 Sun, 15 Mar 2026 16:35:40 +0000 internals.rust-lang.org-post-151673
Just `mut` alongside `let mut` I know how things stand currently with let mut.

I am talking about the future - an enhancement to make the code elegant.

Let me drill-down a bit ...

During the Lexing & Parsing step of the compiler, can the term set (which can be introduced in the future) get replaced by let mut?

FUTURE ==> Code will then be elegant with let and set <== FUTURE

FUTURE ==> Coders can then use these interchangeably - let mut and set <== FUTURE

Thanks,

Naga Vijayapuram

]]>
https://internals.rust-lang.org/t/just-mut-alongside-let-mut/24084#post_4 Sun, 15 Mar 2026 15:35:17 +0000 internals.rust-lang.org-post-151672
Just `mut` alongside `let mut` Also note that let mut isn’t an atomic thing that can be shortened.

Instead the sequence “let mut” appears in let statement containing mut x-style identifier pattern. The mut is part of the pattern.

let mut x = 123;

is technically composed of let, followed by mut x, not let mut followed by x.

Like, you could think of it as bracketing; let (mut x) not (let mut) x. [Note that let (mut x) = 123; is even valid Rust syntax.]

Hence, it’s also the case that

// error
let mut _ = 123;

is illegal syntax, and

let (mut x, mut y) = (1, 2);

is not written like this:

// error
let mut (x, y) = (1, 2);
]]>
https://internals.rust-lang.org/t/just-mut-alongside-let-mut/24084#post_3 Sun, 15 Mar 2026 14:45:09 +0000 internals.rust-lang.org-post-151671
Just `mut` alongside `let mut` The fact that let mut is longer than let is intentional. The language designers wanted to encourage people to use let as the "default", not overuse let mut unnecessarily.

]]>
https://internals.rust-lang.org/t/just-mut-alongside-let-mut/24084#post_2 Sun, 15 Mar 2026 14:03:43 +0000 internals.rust-lang.org-post-151670
Just `mut` alongside `let mut` Hi,

I suggest/recommend support for just the mut keyword for mutable variables alongside existing let mut

If we cannot accommodate mut, can we think of a new 3-character keyword that rhymes with let - from soundex or other criteria?

Some suggestions ...

tel - the reverse of let

cut

set - highly recommended for clarity - (clean, clear, crisp) !

Naga Vijayapuram

]]>
https://internals.rust-lang.org/t/just-mut-alongside-let-mut/24084#post_1 Sun, 15 Mar 2026 13:46:07 +0000 internals.rust-lang.org-post-151669
How can we solve the problem of unmerged RFCs after their FCP? [RFC2603] Extend `<const>` to include `str` and structural constants. by eddyb · Pull Request #3161 · rust-lang/rfcs · GitHub seems not obvious, I would be hesistant to merge it in its current status. Looks like [RFC2603] Extend `<const>` to include `str` and structural constants. by eddyb · Pull Request #3161 · rust-lang/rfcs · GitHub there are some concerns / unresolved questions.

]]>
https://internals.rust-lang.org/t/how-can-we-solve-the-problem-of-unmerged-rfcs-after-their-fcp/24083#post_6 Sun, 15 Mar 2026 11:48:46 +0000 internals.rust-lang.org-post-151668
How can we solve the problem of unmerged RFCs after their FCP? Yeah this has been a gap in our process since forever -- the process is manual and requires more than just pressing the merge button (one also has to fix up the filename and potentially the "rendered" link and maybe more). And apparently nobody is in charge of doing that. For my own RFCs I just kept pinging members of the team that approved the PR until someone figured out how to merge it...

]]>
https://internals.rust-lang.org/t/how-can-we-solve-the-problem-of-unmerged-rfcs-after-their-fcp/24083#post_5 Sun, 15 Mar 2026 11:20:20 +0000 internals.rust-lang.org-post-151667
How can we solve the problem of unmerged RFCs after their FCP? Agreed, but it's not just that rfc. There's also #3161 and #3641 (the latter even having a comment asking for timeline for merging). I think that this is an issue that should not occur at all.

(I didn't include the mitigation enforcement RFC because it is comparatively recent.)

The main problem I have with this is the finality of FCPs (final comment periods) not being entirely representative. After a final comment period, where the community has the time to raise objections, the RFC should be merged as a decision has already been made and all concerns arealready answered. So after the final comment period, IMO RFCs should be merged as soon as possible (immediately?) but they aren't always.

]]>
https://internals.rust-lang.org/t/how-can-we-solve-the-problem-of-unmerged-rfcs-after-their-fcp/24083#post_4 Sun, 15 Mar 2026 02:02:32 +0000 internals.rust-lang.org-post-151661
How can we solve the problem of unmerged RFCs after their FCP? Someone should probably re-submit it as an ACP to get it moving forward.

]]>
https://internals.rust-lang.org/t/how-can-we-solve-the-problem-of-unmerged-rfcs-after-their-fcp/24083#post_3 Sun, 15 Mar 2026 01:52:20 +0000 internals.rust-lang.org-post-151660
How can we solve the problem of unmerged RFCs after their FCP? Fixed link RFC: map_or_default in Option and Result by orlp · Pull Request #3148 · rust-lang/rfcs · GitHub

]]>
https://internals.rust-lang.org/t/how-can-we-solve-the-problem-of-unmerged-rfcs-after-their-fcp/24083#post_2 Sun, 15 Mar 2026 00:07:31 +0000 internals.rust-lang.org-post-151658
How can we solve the problem of unmerged RFCs after their FCP? RFCs like #3148 have been sitting in the background for about 10 months now, with no clear sign of getting merged even though they have finished their final comment period. Is there a way that we can perhaps clear them? Perhaps by giving RFCbot merge permissions?

Edit:oops, hand-typed the link. Thanks @dlight!

]]>
https://internals.rust-lang.org/t/how-can-we-solve-the-problem-of-unmerged-rfcs-after-their-fcp/24083#post_1 Sat, 14 Mar 2026 23:52:56 +0000 internals.rust-lang.org-post-151656
Cargo project config unification I understand you to be saying that there are a bunch of existing .cargo/config.toml parameters that are problematic to set in the context of a workspace or package, and you (the Cargo team) don't want to be seen as endorsing their use in that context, by making them usable from Cargo.toml. Is that an accurate summary of what you're trying to communicate?

Assuming so, first, let me explain in somewhat more detail where I'm coming from. What I care about is getting to a place where no project ever needs to ship a .cargo/config.toml in their source tree, as expeditiously as possible. Right now, sometimes people have to do that; for example, I know of software that has to be built with -C target-feature=+crt-static -C relocation-model=static or it won't link. The only way to accomplish that, as of the last time the project I'm thinking of was updated,[1] was to set rustflags in .cargo/config.toml.

But it's bad that people have to do that, and I hope you agree with that at least in principle. Many developers don't even know you can put a .cargo/config.toml in a workspace or package, and so it's a potential source of confusion for people new to a project. It might even be a place where someone could hide underhanded tricks, in the style of the xz exploit. Both these issues are made worse by .cargo/config.toml being a hidden file.

Furthermore, it seems to me that any setting that would be problematic in a Cargo.toml is equally problematic in a workspace or package .cargo/config.toml, only, because it's much less visible in .cargo/config.toml, the problems are exacerbated. That's why I can't get behind your plan to sort out the problems and then only move the settings that aren't problematic. I think a world in which all those problematic settings can appear in Cargo.toml, but Cargo throws deprecation warnings on the mere existence of package- or workspace-scope .cargo/config.toml, is strictly better than the world we have now. I also think that doing the file-level deprecation first and then going back to the problematic settings case by case is a better overall strategy for getting the whole job done in a reasonable amount of time.


  1. it's been on ice for a bit more than a year, so the situation may well have changed ↩︎

]]>
https://internals.rust-lang.org/t/cargo-project-config-unification/24082#post_5 Sat, 14 Mar 2026 23:37:54 +0000 internals.rust-lang.org-post-151655
Introduce a way to construct Range from start + length Clone is called in all kinds of situations involving Step, so it's not really surprising

]]>
https://internals.rust-lang.org/t/introduce-a-way-to-construct-range-from-start-length/24073?page=2#post_28 Sat, 14 Mar 2026 23:18:24 +0000 internals.rust-lang.org-post-151654
Idea: Add an option to set the mode to fs::copy Yes.

]]>
https://internals.rust-lang.org/t/idea-add-an-option-to-set-the-mode-to-fs-copy/24080#post_9 Sat, 14 Mar 2026 23:15:00 +0000 internals.rust-lang.org-post-151653
Idea: Add an option to set the mode to fs::copy
chrisd:

On Windows ... there's no single function to copy using file handles ... there are some low-level functions which can help, such as NtCopyFileChunk, but [it doesn't do the whole job and] doesn't work in all cases ...

Linux's copy_file_range also doesn't do the whole job and doesn't work in all cases; callers need to check for a "can't do it this time" error return and fall back to a manual copy loop. It sounds like the Windows implementation of io::copy might usefully be taught to use NtCopyFileChunk if it doesn't already, but fs::copy on Windows should keep using CopyFile, would you agree?

]]>
https://internals.rust-lang.org/t/idea-add-an-option-to-set-the-mode-to-fs-copy/24080#post_8 Sat, 14 Mar 2026 22:48:52 +0000 internals.rust-lang.org-post-151650
Idea: Add an option to set the mode to fs::copy As mentioned by zackw, io::copy definitely can do those. The implementation literally first tries a function called kernel_copy and falls back to generic copying if that doesn’t work. Specifically on Linux the docs note that

On Linux (including Android), this function uses copy_file_range(2) , sendfile(2) or splice(2) syscalls to move data directly between file descriptors if possible.

]]>
https://internals.rust-lang.org/t/idea-add-an-option-to-set-the-mode-to-fs-copy/24080#post_7 Sat, 14 Mar 2026 22:11:39 +0000 internals.rust-lang.org-post-151648
Introduce a way to construct Range from start + length True, but it at the least seems surprising that Clone would be called in such a situation.

]]>
https://internals.rust-lang.org/t/introduce-a-way-to-construct-range-from-start-length/24073?page=2#post_27 Sat, 14 Mar 2026 21:37:15 +0000 internals.rust-lang.org-post-151647
Idea: Add an option to set the mode to fs::copy On Windows you're correct, there's no single function to copy using file handles. You can implement this manually (which is essentially what CopyFile does) but that's more involved. There are some low-level functions which can help, such as NtCopyFileChunk, but that doesn't copy metadata itself and it doesn't work in all cases. Quoting from those docs:

NtCopyFileChunk is used internally by CopyFile for most forms of copy. Current exceptions include cloud copies, SMB offload and ODX.

]]>
https://internals.rust-lang.org/t/idea-add-an-option-to-set-the-mode-to-fs-copy/24080#post_6 Sat, 14 Mar 2026 19:32:00 +0000 internals.rust-lang.org-post-151644
Cargo project config unification
zackw:

What would be so bad about moving everything, and I really do mean everything, from .cargo/config.toml to Cargo.toml, right now, so that we can deprecate the existence of .cargo/config.toml in packages and workspaces as soon as possible?

I'd recommend actually looking at the config before making such broad statements

  • alias: there is no manifest lookup for these today
  • build: half of these are caller, machine, or user specific
  • credential-alias: user specific
  • doc: user or machine specific
  • env: unenumerable use case
  • future-incompat-report: user specific
  • cache: user or machine specific
  • cargo-new: user as the point is that you aren't in a repo
  • http: user or machine specific
  • install: caller, user, or machine specific
  • net: ditto
  • patch: already in manifest
  • profile: ditto
  • resolver: controlled by workspace.resolver. Maybe more can go in but design work is needed
  • registries: unsure
  • source: ditto
  • target links: overriding build scripts should likely not be in a static file
  • term: caller, user, or machine specific

Another problem is RUSTFLAGS is a raw escape hatch that users can shoot themselves in the foot with and so it needs a "here be dragons" rather than having a paved path in the manifest,

]]>
https://internals.rust-lang.org/t/cargo-project-config-unification/24082#post_4 Sat, 14 Mar 2026 18:35:59 +0000 internals.rust-lang.org-post-151643
Cargo project config unification
epage:

We will likely never directly support .cargo/config.toml fields in Cargo.toml. Instead, we will need to look at how they should be abstracted in Cargo.toml.

This plan means package/workspace .cargo/config.toml will continue to need to exist indefinitely. I don't like that.

What would be so bad about moving everything, and I really do mean everything, from .cargo/config.toml to Cargo.toml, right now, so that we can deprecate the existence of .cargo/config.toml in packages and workspaces as soon as possible?

You could still migrate these settings to a better schema within Cargo.toml, later, probably on a setting-by-setting basis. It seems to me it would go more smoothly overall.

]]>
https://internals.rust-lang.org/t/cargo-project-config-unification/24082#post_3 Sat, 14 Mar 2026 16:14:05 +0000 internals.rust-lang.org-post-151642
Idea: Add an option to set the mode to fs::copy On Unixy systems, at the system call level, "filesystem cloning or kernel-space-only copying" is still an operation on a pair of file descriptors, not a pair of pathnames. On all supported Unixy systems except MacOS, fs::copy already just calls io::copy, and, skimming the code, I don't see a good reason why the MacOS implementation of fs::copy couldn't be pushed down into io::copy.

On Windows, the CopyFile family of functions really does operate on pathnames, not file handles. I wasn't able to find an equivalent that operates on file handles in a couple minutes skimming MSDN, but that doesn't mean there isn't one. However, CopyFile doesn't appear to allow you to control the ACL of the destination file, either, so the feature you want may not be possible to implement for Windows. (People who know more about low-level Windows programming than I do, please correct me if I'm wrong about anything in this paragraph.)

Therefore, I think the Right Thing would be to push the MacOS-specific fs::copy down into io::copy, make a documented guarantee that io::copy will use copy_file_range or equivalent primitive whenever possible, and also document in fs::copy that if you want to control the ownership, permissions, or other metadata of the destination file, create it yourself and use io::copy.

]]>
https://internals.rust-lang.org/t/idea-add-an-option-to-set-the-mode-to-fs-copy/24080#post_5 Sat, 14 Mar 2026 16:02:01 +0000 internals.rust-lang.org-post-151641
Could borrow checking with origins unblock sound specialization No, 'static bounds are also computed by the borrow checker, just like other T: 'a lifetime bounds. I could modify my above example to make n_ref a 'static reference, meaning that better control flow analysis in the borrow checker could result in another_ref later being recognized as a 'static reference when it’s used in result.

Specializing on some compiler-implemented HasNoLifetimeParameters trait could be reasonable, though. I believe that

struct Foo(&'static str);

could implement HasNoLifetimeParameters, while &'static str would not, in order to avoid relying on context to determine whether a given string is “really genuinely guaranteed to always be 'static”, “always 'static in the current rustc version, but not explicitly annotated as 'static so this might surprise the user”, or “only sometimes 'static”.

]]>
https://internals.rust-lang.org/t/could-borrow-checking-with-origins-unblock-sound-specialization/24079#post_6 Sat, 14 Mar 2026 15:45:12 +0000 internals.rust-lang.org-post-151640
Idea: Add an option to set the mode to fs::copy
jrose:

fs::copy can do filesystem cloning or kernel-space-only copying that io::copy can't,

This is the issue we came across while trying to implement the cp utility.

Do you think that the permissions need solving?

]]>
https://internals.rust-lang.org/t/idea-add-an-option-to-set-the-mode-to-fs-copy/24080#post_4 Sat, 14 Mar 2026 15:25:23 +0000 internals.rust-lang.org-post-151639
Idea: Add an option to set the mode to fs::copy No, fs::copy can do filesystem cloning or kernel-space-only copying that io::copy can't, it really is its own operation. I'm not sure adding a mode set here is the right choice, but substituting io::copy is a behavior change and potential pessimization.

]]>
https://internals.rust-lang.org/t/idea-add-an-option-to-set-the-mode-to-fs-copy/24080#post_3 Sat, 14 Mar 2026 14:47:08 +0000 internals.rust-lang.org-post-151638
Could borrow checking with origins unblock sound specialization
robofinch:

we further don't want to allow specialization on lifetimes at all.

But is this really the case? Specializing on 'static seems like a perfectly valid use case. 'static is not an origin computed by the borrow checker, it's a property of the data itself. No borrow checker upgrade will change whether a string literal or an owned type is 'static. T: 'static is already a bound the solver understands.

]]>
https://internals.rust-lang.org/t/could-borrow-checking-with-origins-unblock-sound-specialization/24079#post_5 Sat, 14 Mar 2026 14:40:32 +0000 internals.rust-lang.org-post-151637
Idea: Add an option to set the mode to fs::copy It seems to me that fs::copy is a convenience function for the simplest, most quick-n-dirty use case, and as the documentation notes, you'll probably want io::copy if you need more control over file creation or platform-dependent stuff like permissions.

]]>
https://internals.rust-lang.org/t/idea-add-an-option-to-set-the-mode-to-fs-copy/24080#post_2 Sat, 14 Mar 2026 14:25:11 +0000 internals.rust-lang.org-post-151636
Idea: Add an option to set the mode to fs::copy Currently in fs::copy, there is no way to set the mode of the file you are creating. This seems like something that would be quite intuitive to have, especially when building lower level utilities, and it also provides, perhaps at first hidden, security benefits.

The lack of an option to set a mode during copying has resulted in inelegant hacks like this (by yours truly) in software that needs to set file permissions before copying data over (to avoid permission races).

What do people think about this? I don't think it would be a very significant change, but I do think it could have quite positive effects on security.

]]>
https://internals.rust-lang.org/t/idea-add-an-option-to-set-the-mode-to-fs-copy/24080#post_1 Sat, 14 Mar 2026 11:35:28 +0000 internals.rust-lang.org-post-151635
Introduce a way to construct Range from start + length
jhpratt:

but now you no longer have the start value to store.

Step has Clone as a supertrait.

]]>
https://internals.rust-lang.org/t/introduce-a-way-to-construct-range-from-start-length/24073?page=2#post_26 Sat, 14 Mar 2026 08:45:10 +0000 internals.rust-lang.org-post-151634
Introduce a way to construct Range from start + length That actually wouldn't work. To utilize Step, you'd have to pass by ownership internally, as the methods take Self by value. That's the only way you'd know what the end value is, but now you no longer have the start value to store.

]]>
https://internals.rust-lang.org/t/introduce-a-way-to-construct-range-from-start-length/24073?page=2#post_25 Sat, 14 Mar 2026 06:32:13 +0000 internals.rust-lang.org-post-151633
Introduce a way to construct Range from start + length I think it'd be reasonable for the length to be a usize and the start to be anything implementing Step, with a panicking version and an Option version.

]]>
https://internals.rust-lang.org/t/introduce-a-way-to-construct-range-from-start-length/24073?page=2#post_24 Sat, 14 Mar 2026 05:55:51 +0000 internals.rust-lang.org-post-151632
Pre-feature request: suppress unused variable warning for unit-type arguments When writing a lot of code I frequently encounter unused warnings, pointing out that I forgot to implement some piece of logic. They're really helpful, even for zsts. I don't about about Copy though.

Maybe you can pr with some warn by default lint about Copy ZSTs and we'll see how many decide to switch it to allow?

]]>
https://internals.rust-lang.org/t/pre-feature-request-suppress-unused-variable-warning-for-unit-type-arguments/24065#post_17 Sat, 14 Mar 2026 02:27:49 +0000 internals.rust-lang.org-post-151631
Introduce a way to construct Range from start + length
scottmcm:

How about just a function? Range::from_start_and_len(start, length) would be fine, no new type.

I'll ask again: what is the type signature of from_start_and_len? Are both T? If so, what of the signed types and negative length? Perhaps T and Into<T::Unsigned> to at least remove the negative-ness concern? Should there be a try_ variant that catches that and overflow? If it is "just" Add-gated, what about floating point types? What is f32::Unsigned if that path is chosen? Or perhaps this only makes sense for usize at all?

]]>
https://internals.rust-lang.org/t/introduce-a-way-to-construct-range-from-start-length/24073?page=2#post_23 Sat, 14 Mar 2026 02:01:54 +0000 internals.rust-lang.org-post-151630
Could borrow checking with origins unblock sound specialization We just don't want codegen to depend on lifetimes, though; we don't merely want specialization on lifetimes to not be unsound, we further don't want to allow specialization on lifetimes at all. Whether or not a given reference is 'static can be somewhat unpredictable due to const promotion (e.g., let x = &1_u8) or reborrowing. Further, specialization on lifetimes can try to specialize on two references having the same lifetime, which seems even more unpredictable.

Also, consider the following:

let n: u8 = 0;
let n_ref = &n;
{
    let other: u8 = 1;
    let another_ref = n_ref;
    // Fairly sure that `if false { .. }` would have the same effect.
    if random_u32().is_multiple_of(2) {
        another_ref = &other;
        // Conditional early return of a borrow.
        return another_ref;
    }

    // Under the current borrow checker, I'm fairly sure the origins are:
    // {shared(n)} and {shared(n), shared(other)}, not the same.
    // Under Polonius, I'm fairly sure the origins are:
    // {shared(n)} and {shared(n)}, the same.
    let result = (n_ref, another_ref).merge();
}

In other words, your proposal would make the exact behavior of the borrow checker load-bearing, and improving the borrow checker would be a breaking change.

]]>
https://internals.rust-lang.org/t/could-borrow-checking-with-origins-unblock-sound-specialization/24079#post_4 Sat, 14 Mar 2026 01:22:18 +0000 internals.rust-lang.org-post-151629
Cargo project config unification We will likely never directly support .cargo/config.toml fields in Cargo.toml. Instead, we will need to look at how they should be abstracted in Cargo.toml. This is being tracked in Tracking Issue: Support project-specific config in manifest · Issue #12738 · rust-lang/cargo · GitHub.

]]>
https://internals.rust-lang.org/t/cargo-project-config-unification/24082#post_2 Fri, 13 Mar 2026 21:32:37 +0000 internals.rust-lang.org-post-151628
Implement FusedIterator for core::iter::StepBy Sounds reasonable. Please send a libs-api ACP.

]]>
https://internals.rust-lang.org/t/implement-fusediterator-for-core-stepby/24074#post_5 Fri, 13 Mar 2026 20:07:45 +0000 internals.rust-lang.org-post-151626
Could borrow checking with origins unblock sound specialization You're right, I assumed that that having this infromation in codegen would unlock more optimizations. The idea was to use origin information at concrete call sites for lifetimes specialization. At a concrete call site like (&s, &s).merge(), the solver would use origin information to determine that both references share the same origin and pick the specialized impl. This is a type-checking time decision, before codegen runs.

In general one could imagine simpler case when codegen doesn't have knowledge of origins:

  1. Solver sees (&s, &s).merge() at a concrete call site
  2. Solver determines the origins are the same
  3. Solver picks the specialized impl
  4. Solver writes into MIR: "call this specific function" (the specialized one)
  5. Lifetimes get erased
  6. Codegen sees a direct function call and compiles it

Each call site gets its own resolution. So (&s, &s).merge() and (&a, &b).merge() become two different resolved function calls in MIR. By the time codegen runs, the decision is already made.

For specialization that depends on lifetime properties ('static, same-origin, outlives), anything that goes through a generic function can only be resolved if the relevant bounds are explicitly declared in the function signature. Without explicit bounds, the solver falls back to the default impl. For method-only specialization (where the return type doesn't change), monomorphization can pick the specialized code path for type-based properties like T: Copy, and for T: 'static on owned types where 'static is determinable from the type structure alone (e.g. u32, String). But for reference types like &str, the monomorphizer can't tell if it was &'static str or &'a str after lifetime erasure, so it falls back to the default.

If origin/lifetime information were preserved into codegen, it would unlock additional optimizations beyond what the solver can prove statically. Method-only specialization could be resolved at monomorphization time for cases like same-origin dispatch through generic functions, or 'static dispatch for reference types. But even without that, the proposal still stands. We'd just miss those optimizations, falling back to the default (slower) code path. The soundness story doesn't depend on codegen having origin information, only the optimization story does.

So in a way, we get proper full specialization for "concrete" types, but when lifetime shenanigans are involved, it becomes specialization only at the call-site level, or through explicitly declared bounds.

]]>
https://internals.rust-lang.org/t/could-borrow-checking-with-origins-unblock-sound-specialization/24079#post_3 Fri, 13 Mar 2026 19:14:32 +0000 internals.rust-lang.org-post-151625
Could borrow checking with origins unblock sound specialization
Serhii:

The trait solver and codegen see the same information. There's no "abstract during checking, concrete during codegen" split for origins.

I see no mention of this in Niko's blogpost and non reason why it would be the case.

]]>
https://internals.rust-lang.org/t/could-borrow-checking-with-origins-unblock-sound-specialization/24079#post_2 Fri, 13 Mar 2026 18:00:11 +0000 internals.rust-lang.org-post-151624
Introduce a way to construct Range from start + length
appleGun22:

Doesn't have a possibility to express an invalid (start > end) range

It still does, just via things like 200_u8 ..+ 100.

Unfortunately it works very poorly with general ranges in other places. "a".."b" works fine, and is even used in things like BTreeMap methods.

But if you had something like "a" ..+ 10, what does that mean? It clearly can't implement RangeBounds in std::ops - Rust, for example.

I think if you want the "counted" part, separating it out is useful. my_btree.range(start..).take(count), for example, works well.

How about just a function? Range::from_start_and_len(start, length) would be fine, no new type.

]]>
https://internals.rust-lang.org/t/introduce-a-way-to-construct-range-from-start-length/24073?page=2#post_22 Fri, 13 Mar 2026 17:33:47 +0000 internals.rust-lang.org-post-151623