Question: <del> Subproject commit 2adc17a5442614dbe34626fdd9b32de7c07b8086 </del> <ins> Subproject commit 1d5d0e8b0e3134dc781adb98057e38ffdf200df2 </ins>

The feature gate for the issue is . Tracking issues are used to record the overall progress of implementation. They are also uses as hubs connecting to other relevant issues, e.g., bugs or open design questions. A tracking issue is however not meant for large scale discussion, questions, or bug reports about a feature. Instead, open a dedicated issue for the specific matter and add the relevant feature gate label. [ ] Adjust documentation ([see instructions on rustc-dev-guide][doc-guide]) [ ] Stabilization PR ([see instructions on rustc-dev-guide][stabilization-guide]) [stabilization-guide]: https://rustc-dev- [doc-guide]: https://rustc-dev- Initial implementation ()
FWIW, here is a full-featured API provided by an external crate:
I wonder how this API relates to . It would be great if there was some safe API that wrapped around the use of to access a 's spare capacity, then updated based on the s .
Maybe we should follow that example and generalize to return ?
has implemented that, albeit as a private function. Sounds like a good idea to me.
Since exists now I think is redundant.
That's not actually true due to pointer invalidation, see and
I think it would be better to have this feature sooner rather than later. I'm starting to notice instances where people are doing things that are probably or definitely UB because they want this functionality. So I think this API falls squarely into the standard library's mission to provide pre-built and correct implementations of things that are subtle or difficult to get right.   (originally posted on but per Ralf's comments there, it is probably better to have this method for the above use cases)
I agree. I've been using this in my code and found it to be very useful. Even though is more general, I've never had a need for it and I feel that is useful on its own. The API being stabilized is: merge
Team member has proposed to merge this. The next step is review by the rest of the tagged team members: [x] [x] [x] [x] [x] [ ] No concerns currently listed. Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!


Question: <del> Subproject commit 2adc17a5442614dbe34626fdd9b32de7c07b8086 </del> <ins> Subproject commit 1d5d0e8b0e3134dc781adb98057e38ffdf200df2 </ins>

See for info about what commands tagged team members can give me.
while waiting for this feature to be stabilized, you should suggest that and use one of the convenience methods in:
:bell: This is now entering its final comment period, as per the . :bell:
Ralf mentioned this on , mostly rewording with my own opinion: I would prefer not to recommend that function, because even if you just want access to the spare region, under SB, these interfaces invalidate all pointers to the initialized region. I think that's too much of a footgun for codebases where people are already writing code that is rejected by Miri.
I wonder how many people do keep outstanding pointers to the initialized part while toying with the extra part 's implementation is already better than their 0-elems slices that get -ly converted into non-empty slices (and currently better than the stdlib one since it doesn't involve a 12-week delay for stable Rust). Anyhow, I've just released a new version () with a dedicated adapter: , for extra good measure.
To be clear, my concern is that the splitting interfaces are adding a landmine for the future. If I'm sending someone a PR I'll make sure it passes Miri at the time, but that's a hard condition to maintain. Especially because the two aforementioned codebases have dependencies that do int-ptr casts, an operation that Miri just doesn't understand at the moment, so it would be hard to advocate Miri in CI.
The final comment period, with a disposition to merge, as per the , is now complete. As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed. This will be merged soon.


Question: None => continue, }; <del> // Filter away "empty import canaries" and ambiguous imports. </del> <ins> // Filter away ambiguous and gensymed imports. Gensymed imports // (e.g. implicitly injected `std`) cannot be properly encoded in metadata, // so they can cause name conflict errors downstream. </ins> let is_good_import = binding.is_import() && !binding.is_ambiguity() && <del> binding.vis != ty::Visibility::Invisible; </del> <ins> !(ident.name.is_gensymed() && ident.name != "_"); </ins> if is_good_import || binding.is_macro_def() { let def = binding.def(); if def != Def::Err {

The error happens on latest stable and nightly. Steps to reproduce: ; : : returns error: The error only happens if the module is named (for instance, and work without error). The error is not produced if doesn't use in any way. If doesn't contain imports but uses the library directly (e.g. ), the error is produced. always succeeds. I don't know if this is supposed to be forbidden but the error message seems to be misleading.
The second instance is injected implicitly. The error could be better, yes.
Where exactly is injected - in the library or in the test? Why does the library work on its own? Why does conflict with in the test?
Ok, it turns out this is a legitimate bug, I misinterpreted it as a more commonly reported diagnostic issue. is injected into both the library and the test, but only the first one causes the error. If you set in , then you'll see the error immediately while compiling - conflicts with . On 2018 edition, however, is injected in more subtle way, as where is some unique symbol that still has the string representation , but doesn't clash with anything in the same crate. Unfortunately, turns into "just " after encoding into metadata in the compiled library (this is the bug). So, when we load that library from the test it looks like the library defines two conflicting items.
The solution is to either encode gensyms/hygiene into metadata properly (this is a large task and a long standing issue), or come up with some hack preventing the injected specifically from being encoded (it doesn't really need to be encoded).
Fixed in


Question: })), }; <del> f(RefMutL(put_back_on_drop.value.as_mut().unwrap())) </del> <ins> f(put_back_on_drop.value.as_mut().unwrap()) </ins> } /// Sets the value in `self` to `value` while running `f`.

() As you can see, calling directly doesn't instantiate the HRTB (even though it needs to AFAIK) or if it does it doesn't normalize the resulting bound, whereas going through normalizes the instantiated argument types of , while 's definition can be type-checked as-is. EDIT: you can also get an ICE by uncommenting the use in : cc (this might be a duplicate)
Duplicate of (at least the ICE case)? A lot of analysis wad did in the other issue. Maybe it would help. I doubt that, in such cases the associate type do normalize at all. My assumption is: In the case that you marked as "working", it is just delayed the normalization to the later stage. So if the later stage consider this is dead code it is passed and compile, otherwise, when it really need to normalize it, run into ICE. So when called explicitly like , the compiler have no choice but to normalize with . If you instead though, the compiler checked that the requirement to match the argument can in theory fullfill, but the lifetime parameter was not free in the function body so it can consider this is a late bound. So the normalization is not happen right away. Later on, when you add the code in to call , the compiler have to do normalization again, but it is already in codegen (see the backtrace messages) phase, so normalization is unexpected and ICE occurs. Given all that, I guess a proper solution is to add a "late normalization" pass to normalize any postponed normalization like this.
This is a probably a duplicate of and/or ?
closing as duplicate of , which is where I will try to track future instances of this field of ICE.


Question: <ins> // When build the suggesttion take in consideration the `:?` // https://github.com/rust-lang/rust/issues/100648 #![deny(warnings)] fn main () { println!("hello {:?}", world = "world"); //~^ ERROR named argument `world` is not used by name //~| HELP use the named argument by name to avoid ambiguity //~| SUGGESTION world } </ins>

The suggestion that rustc gives is incorrect and seems to not take into account what characters are in the format argument. I tried this code: I expected to see this happen: Instead, this happened: Using beta.2/nightly : <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
label -C-bug +A-diagnostics +T-compiler
claim


Question: ///     Ok(()) /// } /// ``` <del> #[unstable(feature = "rw_exact_all_at", issue = "51984")] </del> <ins> #[stable(feature = "rw_exact_all_at", since = "1.33.0")] </ins> fn read_exact_at(&self, mut buf: &mut [u8], mut offset: u64) -> io::Result<()> { while !buf.is_empty() { match self.read_at(buf, offset) {

The and traits contain convenience methods and wrapping and . This issue tracks addition of similar methods to trait's and . This is implemented in .
if this is a tracking issue, maybe it should have the label
We should eventually add similar methods to .
I know nothing about developing on Windows so I can't do it myself but I guess a PR would be accepted. Can we stabilize this? Is there anything that still needs to be done?
Seems reasonable to me! fcp merge
Team member has proposed to merge this. The next step is review by the rest of the tagged teams: [ ] [x] [x] [x] [x] [ ] No concerns currently listed. Once a majority of reviewers approve (and none object), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See for info about what commands tagged team members can give me.
:bell: This is now entering its final comment period, as per the . :bell:
The final comment period, with a disposition to merge, as per the , is now complete.
What's the next step? Should I make a PR to stabilize? Sorry but I don't fully understand how things work yet.
indeed that should be all that's necessary! If you'd like to make the PR you're also more than welcome to do so!


Question: //! call `next()` on your iterator, until it reaches `None`. Let's go over that //! next. //! <ins> //! Also note that `Iterator` provides a default implementation of methods such as `nth` and `fold` //! which call `next` internally. However, it is also possible to write a custom implementation of //! methods like `nth` and `fold` if an iterator can compute them more efficiently without calling //! `next`. //! </ins> //! # for Loops and IntoIterator //! //! Rust's `for` loop syntax is actually sugar for iterators. Here's a basic

From : It's easy, according to implement my own ` implementation for free. In retrospect it makes sense, but it was not obvious to me at all just from reading the docs. It is not mentioned in , or the docs for . And as the link in my post suggests, trying to work my way around the ownership of the APIs led me quite far afield. Admittedly it's not the most common case, but I think it would save others time if the standard library at least mentioned this somewhere. EDIT: fixed forum link which changed its name when I marked it solved.
A section about "you should consider overloading these things" definitely sounds good. should also be on that list. (In the future or in nightly is in that list too, .)
Your forum link is broken.
The docs do say However, I do like 's suggestion, about talking about which methods you may want to override.
Such hints should be non-normative though to allow the implementations, especially specializations, to use different approaches in the future.
Agreed, I was picturing more which methods to consider overloading, not specifically which things use them. (Or, contrapositively, which things there's usually no reason to overload, like , because the default implementation is generally as good as it gets because it's a trivial wrapper.)
So basically this issue is about adding some documentation on which methods you might want to override right? Which methods do you think are best to mention? Or did I misinterpret the discussion?
That's correctly, probably under or near For now my inclination would be to mention and -- once stable it should be instead, but IIRC we don't mention unstable in the broader docs until it stabilizes.
What about adding this line of text at the end of the "Implementing Iterator" section? which call internally. However, it is also possible to write a custom implementation of methods such as and if an iterator is able to compute them more efficiently without calling . Feel free to adjust the text or make something up yourself :) If you agree I will create a PR for this.
I think it would also be nice to add something to the documentation. How about this? Rather than overriding this method directly, instead override the method.
in case it wasn't clear or you are not watching your GitHub notifications, I approve of both your and suggestions. I look forward to the PR!


Question: //! call `next()` on your iterator, until it reaches `None`. Let's go over that //! next. //! <ins> //! Also note that `Iterator` provides a default implementation of methods such as `nth` and `fold` //! which call `next` internally. However, it is also possible to write a custom implementation of //! methods like `nth` and `fold` if an iterator can compute them more efficiently without calling //! `next`. //! </ins> //! # for Loops and IntoIterator //! //! Rust's `for` loop syntax is actually sugar for iterators. Here's a basic

Sorry for the late reply! I apparently don't get notifications for thumbs ups and the like! I will hopefully be able to create a PR somewhere this midday.


Question: let prefix = default_path(&builder.config.prefix, "/usr/local"); let sysconfdir = prefix.join(default_path(&builder.config.sysconfdir, "/etc")); <ins> // Sanity check for the user write access on prefix and sysconfdir assert!( is_dir_writable_for_user(&prefix), "User doesn't have write access on `install.prefix` path in the `config.toml`.", ); assert!( is_dir_writable_for_user(&sysconfdir), "User doesn't have write access on `install.sysconfdir` path in `config.toml`." ); </ins> let datadir = prefix.join(default_path(&builder.config.datadir, "share")); let docdir = prefix.join(default_path(&builder.config.docdir, "share/doc/rust")); let mandir = prefix.join(default_path(&builder.config.mandir, "share/man"));

In the followup discussion on , we discovered that their original problem was because they had chosen a path under their home directory for , but they had not changed the default . So most things installed fine, but they didn't have permission to write . Bootstrap could sanity check this when starting an install, seeing that is writable by the current user but the absolute is not. (A relative goes under , which should be fine.) This should also take into account as a further prefix on all installation paths.
I have just updated to version 1.71.0, and now I'm receiving the terminal warning: In my previous setup, I the line to my file.
yeah, made that effectively . That was reverted in , and now proposed for stable and beta backports. So you could add for now, but it will be going back to the way it was.


Question: #[unstable(feature = "context_ext", issue = "123392")] #[rustc_const_unstable(feature = "const_waker", issue = "102012")] pub const fn ext(&mut self) -> &mut dyn Any { <del> match &mut self.ext { </del> <ins> // FIXME: this field makes Context extra-weird about unwind safety // can we justify AssertUnwindSafe if we stabilize this? do we care? match &mut *self.ext { </ins> ExtData::Some(data) => *data, ExtData::None(unit) => unit, }

https://crater-
I'll need to re-check later but this seems to bisect to somehow.
The UI test changes from that PR appear to back this up, as confusing as it is.
I'm not sure what's going on in that crate, if it built successfully by mistake, or how that PR interacts with it, so let's cc the PR author and reviewer for validation.
After , no longer implements and , because the context now contains a which doesn't implement those traits. So this is an issue with the standard library and not the crate being built. Repro: label -T-compiler +T-libs +S-has-mcve
WG-prioritization assigning priority (). Noticing this on which says that was meant to be confined on nightly. Unsure about the fallout of this regression but for now marking as critical for tracking purposes. label -I-prioritize +P-critical
Revert up:
Isn't not unwind safe?
That line was by your PR, so while what you say is technically true, talking about what "already happened" when we are traveling back and forth through time via version control may be more confusing than helpful.
That line was already there. I the line below it though. Original PR:
Apologies, I guess I can't count numbers today? Hm, so, the full error of the regression is this: Note that it's trying to make a pointer implement . And for what it's worth, stable does indeed document is . Thus unfortunately that line you pointed to, as opposed to the one I thought you were referring to, is effectively just documenting that all are , and that will include regardless of whether it is is . And confusingly, , unlike .
I have opened as an alternative.


Question: <del> // ---------------------------------------------------------------------------- // // Inno Setup Ver:	5.4.2 // Script Version:	1.4.1 // Author:			Jared Breland <jbreland@legroom.net> // Homepage:		http://www.legroom.net/software // License:			GNU Lesser General Public License (LGPL), version 3 //						http://www.gnu.org/licenses/lgpl.html // // Script Function: //	Allow modification of environmental path directly from Inno Setup installers // // Instructions: //	Copy modpath.iss to the same directory as your setup script // //	Add this statement to your [Setup] section //		ChangesEnvironment=true // //	Add this statement to your [Tasks] section //	You can change the Description or Flags //	You can change the Name, but it must match the ModPathName setting below //		Name: modifypath; Description: &Add application directory to your environmental path; Flags: unchecked // //	Add the following to the end of your [Code] section //	ModPathName defines the name of the task defined above //	ModPathType defines whether the 'user' or 'system' path will be modified; //		this will default to user if anything other than system is set //	setArrayLength must specify the total number of dirs to be added //	Result[0] contains first directory, Result[1] contains second, etc. //		const //			ModPathName = 'modifypath'; //			ModPathType = 'user'; // //		function ModPathDir(): TArrayOfString; //		begin //			setArrayLength(Result, 1); //			Result[0] := ExpandConstant('{app}'); //		end; //		#include "modpath.iss" // ---------------------------------------------------------------------------- procedure ModPath(); var oldpath:	String; newpath:	String; updatepath:	Boolean; pathArr:	TArrayOfString; aExecFile:	String; aExecArr:	TArrayOfString; i, d:		Integer; pathdir:	TArrayOfString; regroot:	Integer; regpath:	String; begin // Get constants from main script and adjust behavior accordingly // ModPathType MUST be 'system' or 'user'; force 'user' if invalid if ModPathType = 'system' then begin regroot := HKEY_LOCAL_MACHINE; regpath := 'SYSTEMCurrentControlSetControlSession ManagerEnvironment'; end else begin regroot := HKEY_CURRENT_USER; regpath := 'Environment'; end; // Get array of new directories and act on each individually pathdir := ModPathDir(); for d := 0 to GetArrayLength(pathdir)-1 do begin updatepath := true; // Modify WinNT path if UsingWinNT() = true then begin // Get current path, split into an array RegQueryStringValue(regroot, regpath, 'Path', oldpath); oldpath := oldpath + ';'; i := 0; while (Pos(';', oldpath) > 0) do begin SetArrayLength(pathArr, i+1); pathArr[i] := Copy(oldpath, 0, Pos(';', oldpath)-1); oldpath := Copy(oldpath, Pos(';', oldpath)+1, Length(oldpath)); i := i + 1; // Check if current directory matches app dir if pathdir[d] = pathArr[i-1] then begin // if uninstalling, remove dir from path if IsUninstaller() = true then begin continue; // if installing, flag that dir already exists in path end else begin updatepath := false; end; end; // Add current directory to new path if i = 1 then begin newpath := pathArr[i-1]; end else begin newpath := newpath + ';' + pathArr[i-1]; end; end; // Append app dir to path if not already included if (IsUninstaller() = false) AND (updatepath = true) then newpath := newpath + ';' + pathdir[d]; // Write new path RegWriteStringValue(regroot, regpath, 'Path', newpath); // Modify Win9x path end else begin // Convert to shortened dirname pathdir[d] := GetShortName(pathdir[d]); // If autoexec.bat exists, check if app dir already exists in path aExecFile := 'C:AUTOEXEC.BAT'; if FileExists(aExecFile) then begin LoadStringsFromFile(aExecFile, aExecArr); for i := 0 to GetArrayLength(aExecArr)-1 do begin if IsUninstaller() = false then begin // If app dir already exists while installing, skip add if (Pos(pathdir[d], aExecArr[i]) > 0) then updatepath := false; break; end else begin // If app dir exists and = what we originally set, then delete at uninstall if aExecArr[i] = 'SET PATH=%PATH%;' + pathdir[d] then aExecArr[i] := ''; end; end; end; // If app dir not found, or autoexec.bat didn't exist, then (create and) append to current path if (IsUninstaller() = false) AND (updatepath = true) then begin SaveStringToFile(aExecFile, #13#10 + 'SET PATH=%PATH%;' + pathdir[d], True); // If uninstalling, write the full autoexec out end else begin SaveStringsToFile(aExecFile, aExecArr, False); end; end; end; end; // Split a string into an array using passed delimiter procedure Explode(var Dest: TArrayOfString; Text: String; Separator: String); var i: Integer; begin i := 0; repeat SetArrayLength(Dest, i+1); if Pos(Separator,Text) > 0 then	begin Dest[i] := Copy(Text, 1, Pos(Separator, Text)-1); Text := Copy(Text, Pos(Separator,Text) + Length(Separator), Length(Text)); i := i + 1; end else begin Dest[i] := Text; Text := ''; end; until Length(Text)=0; end; procedure ModPathCurStepChanged(CurStep: TSetupStep); var taskname:	String; begin taskname := ModPathName; if CurStep = ssPostInstall then if IsTaskSelected(taskname) then ModPath(); end; procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep); var aSelectedTasks:	TArrayOfString; i:				Integer; taskname:		String; regpath:		String; regstring:		String; appid:			String; begin // only run during actual uninstall if CurUninstallStep = usUninstall then begin // get list of selected tasks saved in registry at install time appid := '{#emit SetupSetting("AppId")}'; if appid = '' then appid := '{#emit SetupSetting("AppName")}'; regpath := ExpandConstant('SoftwareMicrosoftWindowsCurrentVersionUninstall'+appid+'_is1'); RegQueryStringValue(HKLM, regpath, 'Inno Setup: Selected Tasks', regstring); if regstring = '' then RegQueryStringValue(HKCU, regpath, 'Inno Setup: Selected Tasks', regstring); // check each task; if matches modpath taskname, trigger patch removal if regstring <> '' then begin taskname := ModPathName; Explode(aSelectedTasks, regstring, ','); if GetArrayLength(aSelectedTasks) > 0 then begin for i := 0 to GetArrayLength(aSelectedTasks)-1 do begin if comparetext(aSelectedTasks[i], taskname) = 0 then ModPath(); end; end; end; end; end; function NeedRestart(): Boolean; var taskname:	String; begin taskname := ModPathName; if IsTaskSelected(taskname) and not UsingWinNT() then begin Result := True; end else begin Result := False; end; end; </del>

The .exe installer tries to install to "C:Program Files (x86)Rust", even though it's the 64-bit version. It then fails to create the destination directory due to a permission error. The .msi installer correctly defaults to "C:Program FilesRust <channel<version", and has no problems with permissions, I would expect the .exe installer to have the same behaviour.
Rust should install to , just like Ant, Python, and many others. is the place for developer tools that have a known folder. is badly named (compare to ), poorly suited for command line tools, and clutters the already hideous PATH more than .
/cc
Neither Ant nor Python install to C:tools by default, and searching I can't find any reference to C:tools even being a thing? Both Python and Ant install to C:Python<Versionand C:ant, which is incredibly annoying, so please don't do that!
I might be mistaken, but installing both through stuck them in for me. I'd recommend anyone with a machine running Vista or later use chocolatey. And there's a trend in chocolatey to have packages extract to when they aren't self-contained enough for .
For an OS without much filesystem hierarchy, is a decent place for developer and command-line packages, similar to on some unices. But I'd much rather see a that actually obeyed chocolatey's conventions and extracted an archive to , with no installer/registry involvement. But Rust only and installers for windows. : And all packages that do this reduce PATH clutter, since chocolatey symlinks their executables into .
The idea was to deprecate the .exe installer once .msi is known to be working satisfactory.
Can we have a zip release too, that contains Rust and Cargo like the others? Linux and OS X have an archive release. Those are preferred in chocolatey because they don't involve the registry or any other Windows components.
We do produce tarballs for windows.
Seems like we should probably just stop producing the .exe's. That fix would go in
I don't see a cargo+rustc nightly tarball for windows, although I do see ones for linux and osx.
triage: We do not link to the .exe installer anymore, but we still produce them.


Question: <del> // ---------------------------------------------------------------------------- // // Inno Setup Ver:	5.4.2 // Script Version:	1.4.1 // Author:			Jared Breland <jbreland@legroom.net> // Homepage:		http://www.legroom.net/software // License:			GNU Lesser General Public License (LGPL), version 3 //						http://www.gnu.org/licenses/lgpl.html // // Script Function: //	Allow modification of environmental path directly from Inno Setup installers // // Instructions: //	Copy modpath.iss to the same directory as your setup script // //	Add this statement to your [Setup] section //		ChangesEnvironment=true // //	Add this statement to your [Tasks] section //	You can change the Description or Flags //	You can change the Name, but it must match the ModPathName setting below //		Name: modifypath; Description: &Add application directory to your environmental path; Flags: unchecked // //	Add the following to the end of your [Code] section //	ModPathName defines the name of the task defined above //	ModPathType defines whether the 'user' or 'system' path will be modified; //		this will default to user if anything other than system is set //	setArrayLength must specify the total number of dirs to be added //	Result[0] contains first directory, Result[1] contains second, etc. //		const //			ModPathName = 'modifypath'; //			ModPathType = 'user'; // //		function ModPathDir(): TArrayOfString; //		begin //			setArrayLength(Result, 1); //			Result[0] := ExpandConstant('{app}'); //		end; //		#include "modpath.iss" // ---------------------------------------------------------------------------- procedure ModPath(); var oldpath:	String; newpath:	String; updatepath:	Boolean; pathArr:	TArrayOfString; aExecFile:	String; aExecArr:	TArrayOfString; i, d:		Integer; pathdir:	TArrayOfString; regroot:	Integer; regpath:	String; begin // Get constants from main script and adjust behavior accordingly // ModPathType MUST be 'system' or 'user'; force 'user' if invalid if ModPathType = 'system' then begin regroot := HKEY_LOCAL_MACHINE; regpath := 'SYSTEMCurrentControlSetControlSession ManagerEnvironment'; end else begin regroot := HKEY_CURRENT_USER; regpath := 'Environment'; end; // Get array of new directories and act on each individually pathdir := ModPathDir(); for d := 0 to GetArrayLength(pathdir)-1 do begin updatepath := true; // Modify WinNT path if UsingWinNT() = true then begin // Get current path, split into an array RegQueryStringValue(regroot, regpath, 'Path', oldpath); oldpath := oldpath + ';'; i := 0; while (Pos(';', oldpath) > 0) do begin SetArrayLength(pathArr, i+1); pathArr[i] := Copy(oldpath, 0, Pos(';', oldpath)-1); oldpath := Copy(oldpath, Pos(';', oldpath)+1, Length(oldpath)); i := i + 1; // Check if current directory matches app dir if pathdir[d] = pathArr[i-1] then begin // if uninstalling, remove dir from path if IsUninstaller() = true then begin continue; // if installing, flag that dir already exists in path end else begin updatepath := false; end; end; // Add current directory to new path if i = 1 then begin newpath := pathArr[i-1]; end else begin newpath := newpath + ';' + pathArr[i-1]; end; end; // Append app dir to path if not already included if (IsUninstaller() = false) AND (updatepath = true) then newpath := newpath + ';' + pathdir[d]; // Write new path RegWriteStringValue(regroot, regpath, 'Path', newpath); // Modify Win9x path end else begin // Convert to shortened dirname pathdir[d] := GetShortName(pathdir[d]); // If autoexec.bat exists, check if app dir already exists in path aExecFile := 'C:AUTOEXEC.BAT'; if FileExists(aExecFile) then begin LoadStringsFromFile(aExecFile, aExecArr); for i := 0 to GetArrayLength(aExecArr)-1 do begin if IsUninstaller() = false then begin // If app dir already exists while installing, skip add if (Pos(pathdir[d], aExecArr[i]) > 0) then updatepath := false; break; end else begin // If app dir exists and = what we originally set, then delete at uninstall if aExecArr[i] = 'SET PATH=%PATH%;' + pathdir[d] then aExecArr[i] := ''; end; end; end; // If app dir not found, or autoexec.bat didn't exist, then (create and) append to current path if (IsUninstaller() = false) AND (updatepath = true) then begin SaveStringToFile(aExecFile, #13#10 + 'SET PATH=%PATH%;' + pathdir[d], True); // If uninstalling, write the full autoexec out end else begin SaveStringsToFile(aExecFile, aExecArr, False); end; end; end; end; // Split a string into an array using passed delimiter procedure Explode(var Dest: TArrayOfString; Text: String; Separator: String); var i: Integer; begin i := 0; repeat SetArrayLength(Dest, i+1); if Pos(Separator,Text) > 0 then	begin Dest[i] := Copy(Text, 1, Pos(Separator, Text)-1); Text := Copy(Text, Pos(Separator,Text) + Length(Separator), Length(Text)); i := i + 1; end else begin Dest[i] := Text; Text := ''; end; until Length(Text)=0; end; procedure ModPathCurStepChanged(CurStep: TSetupStep); var taskname:	String; begin taskname := ModPathName; if CurStep = ssPostInstall then if IsTaskSelected(taskname) then ModPath(); end; procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep); var aSelectedTasks:	TArrayOfString; i:				Integer; taskname:		String; regpath:		String; regstring:		String; appid:			String; begin // only run during actual uninstall if CurUninstallStep = usUninstall then begin // get list of selected tasks saved in registry at install time appid := '{#emit SetupSetting("AppId")}'; if appid = '' then appid := '{#emit SetupSetting("AppName")}'; regpath := ExpandConstant('SoftwareMicrosoftWindowsCurrentVersionUninstall'+appid+'_is1'); RegQueryStringValue(HKLM, regpath, 'Inno Setup: Selected Tasks', regstring); if regstring = '' then RegQueryStringValue(HKCU, regpath, 'Inno Setup: Selected Tasks', regstring); // check each task; if matches modpath taskname, trigger patch removal if regstring <> '' then begin taskname := ModPathName; Explode(aSelectedTasks, regstring, ','); if GetArrayLength(aSelectedTasks) > 0 then begin for i := 0 to GetArrayLength(aSelectedTasks)-1 do begin if comparetext(aSelectedTasks[i], taskname) = 0 then ModPath(); end; end; end; end; end; function NeedRestart(): Boolean; var taskname:	String; begin taskname := ModPathName; if IsTaskSelected(taskname) and not UsingWinNT() then begin Result := True; end else begin Result := False; end; end; </del>

I don't have access to windows at the moment to check if this bug has been resolved, but it's been a long time...
Grabbing the Windows download link from and swapping the for yields a functional link to the , which is nice. Testing on win7-x64, the MSI extracts with lessmsi, but the directory structure is somewhat unusual so there's no one-liner to get the Rust folder out. The best I came up with was: This yields a Rust install rooted at . However now that exists, multiple targets aren't really an issue anymore. Someone should make a Chocolatey package for
Can someone with access to Windows check what happens here today?
The latest version installs to instead, which works, but is a terrible default.
Triage: ! This seems... fine. I'm not sure if this should stay open or not; I'll let the relevant team (infra? compiler?) decide.


Question: config.out = absolute(&config.out).expect("can't make empty path absolute"); } <ins> if cargo_clippy.is_some() && rustc.is_none() { println!( "WARNING: Using `build.cargo-clippy` without `build.rustc` usually fails due to toolchain conflict." ); } config.initial_cargo_clippy = cargo_clippy; </ins> config.initial_rustc = if let Some(rustc) = rustc { if !flags.skip_stage0_validation { config.check_stage0_version(&rustc, "rustc");

I'm pretty sure it is possible to set custom paths for , & in but not for clippy.
label +T-bootstrap


Question: [platform-support]: https://forge.rust-lang.org/platform-support.html <del> ## Installing on Linux or Mac </del> <ins> ## Installing Rust </ins> <del> If we're on Linux or a Mac, all we need to do is open a terminal and type this: </del> <ins> All you need to do on Unix systems like Linux and macOS is open a terminal and type this: </ins> ```bash <del> $ curl -sSf https://static.rust-lang.org/rustup.sh | sh </del> <ins> $ curl https://sh.rustup.rs -sSf | sh </ins> ``` <del> This will download a script, and start the installation. If it all goes well, you’ll see this appear: </del> <ins> It will download a script, and start the installation. If everything goes well, you’ll see this appear: </ins> ```text <del> Rust is ready to roll. </del> <ins> Rust is installed now. Great! </ins> ``` <del> From here, press `y` for ‘yes’, and then follow the rest of the prompts. </del> <ins> Installing on Windows is nearly as easy: download and run [rustup-init.exe]. It will start the installation in a console and present the above message on success. </ins> <del> ## Installing on Windows </del> <ins> For other installation options and information, visit the [install] page of the Rust website. </ins> <del> If you're on Windows, please download the appropriate [installer][install-page]. [install-page]: https://www.rust-lang.org/install.html </del> <ins> [rustup-init.exe]: https://win.rustup.rs [install]: https://www.rust-lang.org/install.html </ins> ## Uninstalling <del> Uninstalling Rust is as easy as installing it. On Linux or Mac, run the uninstall script: </del> <ins> Uninstalling Rust is as easy as installing it: </ins> ```bash <del> $ sudo /usr/local/lib/rustlib/uninstall.sh </del> <ins> $ rustup self uninstall </ins> ``` <del> If we used the Windows installer, we can re-run the `.msi` and it will give us an uninstall option. </del> ## Troubleshooting If we've got Rust installed, we can open up a shell, and type this:

Specifically at , and recommend for Windows too, right? We've , but in the meantime, the old book should recommend the new recommended toolchain :) If it's too soon to do this because isn't stable enough yet, consider this a reminder issue to make this change once it is :)
wants to wait a bit, and we'd need to then make sure to update the website in sync (see )
Maybe the big red warning "this is beta software" should be removed from the website?
This will be fixed by


Question: } } <ins> #[cfg(target_arch = "x86_64")] fn f128() { const_assert!((1f128).to_bits(), 0x3fff0000000000000000000000000000); const_assert!(u128::from_be_bytes(1f128.to_be_bytes()), 0x3fff0000000000000000000000000000); const_assert!((12.5f128).to_bits(), 0x40029000000000000000000000000000); const_assert!(u128::from_le_bytes(12.5f128.to_le_bytes()), 0x40029000000000000000000000000000); const_assert!((1337f128).to_bits(), 0x40094e40000000000000000000000000); const_assert!(u128::from_ne_bytes(1337f128.to_ne_bytes()), 0x40094e40000000000000000000000000); const_assert!((-14.25f128).to_bits(), 0xc002c800000000000000000000000000); const_assert!(f128::from_bits(0x3fff0000000000000000000000000000), 1.0); const_assert!(f128::from_be_bytes(0x3fff0000000000000000000000000000u128.to_be_bytes()), 1.0); const_assert!(f128::from_bits(0x40029000000000000000000000000000), 12.5); const_assert!(f128::from_le_bytes(0x40029000000000000000000000000000u128.to_le_bytes()), 12.5); const_assert!(f128::from_bits(0x40094e40000000000000000000000000), 1337.0); assert_eq!(f128::from_ne_bytes(0x40094e40000000000000000000000000u128.to_ne_bytes()), 1337.0); const_assert!(f128::from_bits(0xc002c800000000000000000000000000), -14.25); // Check that NaNs roundtrip their bits regardless of signalingness // 0xA is 0b1010; 0x5 is 0b0101 -- so these two together clobbers all the mantissa bits // NOTE: These names assume `f{BITS}::NAN` is a quiet NAN and IEEE754-2008's NaN rules apply! const QUIET_NAN: u128 = f128::NAN.to_bits() | 0x0000_AAAA_AAAA_AAAA_AAAA_AAAA_AAAA_AAAA; const SIGNALING_NAN: u128 = f128::NAN.to_bits() ^ 0x0000_5555_5555_5555_5555_5555_5555_5555; const_assert!(f128::from_bits(QUIET_NAN).is_nan()); const_assert!(f128::from_bits(SIGNALING_NAN).is_nan()); const_assert!(f128::from_bits(QUIET_NAN).to_bits(), QUIET_NAN); if !has_broken_floats() { const_assert!(f128::from_bits(SIGNALING_NAN).to_bits(), SIGNALING_NAN); } } </ins> fn main() { <ins> #[cfg(target_arch = "x86_64")] { f16(); f128(); } </ins> f32(); f64(); }

This file is only and : , but we should add the other float types to this test. The change should wait for since that changes some of these semantics (this PR is almost merged). There are probably a handful of tests that only check and but could use updates with the new types. <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
Okay will do that
FYI you can comment to assign yourself an issue
claim


Question: return Some(*c); } <del> let mut dist = dist.unwrap_or_else(|| cmp::max(lookup.len(), 3) / 3); </del> <ins> // `fn edit_distance()` use `chars()` to calculate edit distance, so we must // also use `chars()` (and not `str::len()`) to calculate length here. let lookup_len = lookup.chars().count(); let mut dist = dist.unwrap_or_else(|| cmp::max(lookup_len, 3) / 3); </ins> let mut best = None; // store the candidates with the same distance, only for `use_substring_score` current. let mut next_candidates = vec![];

In I noticed this surprising spelling suggestion: To me and don't seem like they would be similar enough to meet the threshold for showing such a suggestion. Can we calibrate this better for short idents? For comparison, even doesn't assume you mean . rustc 1.45.0-nightly ( 2020-05-23) Mentioning who worked on suggestions most recently in .
I debugged it a bit. is selected as the candidate because the edit distance is just 2 to . The code to fix is likely in or around . I tried some quick tricks but got ICEs and failing tests and gave up. One thing I didn't try that could perhaps work is to consider edit distance between characters of different alphabets/logogram sets as infinite, rather than 1, which is the case right now.
Thank you for investigating! Independent of what we do with different logogram sets (your suggestion sounds plausible), an edit distance of 2 for a string of length 2 should not meet the threshold for showing a suggestion, even within a single logogram set.
I think edit distance of 1 for a string of length 1 is reasonable (a lot of existing UI tests relies on it), but maybe an edit distance of 2 for a string of length 2 is not reasonable indeed. As you point out, with regular chars, the edit distance is still 2 but is not suggested. So maybe there is a simpler fix to be made for than looking at what alphabets/logogram sets characters belong to.


Question: fn f(a: u16, b: &str) {} fn main() { <del> f(0); //~ ERROR E0061 </del> <ins> f(0); //~^ ERROR E0061 //~| NOTE expected 2 parameters //~| NOTE the following parameter types were expected </ins> }

From: src/test/compile- Error E0061 needs a span_label, updating it from: To: Bonus: the types could be incorporated into the label rather than a note (though we may want to avoid types with long names in the label)
Planning on tackling the bonus here. Is there a prefered max length for output on the console. In the case it would exceed this should i truncate the typename or just not include?
- great point. If you want to work on truncation, feel free to add it, too. I'm not sure if the term crate will tell you the current terminal size, but it may.
I'm fixing and I noticed that it and this issue currently share the same code for generating this error, and adding code to add a to the message in would fix both.
Did you do the bonus as well? I can tackle that if you haven't.
I haven't yet - I can fix the issue (currently testing/fixing unit tests) and you can take on the bonus part of the issue.
Sounds great to me! Thanks.
- I opened up issue to track the bonus portion of the work for you.


Question: run: src/ci/scripts/install-wix.sh <<: *step <del> - name: install InnoSetup run: src/ci/scripts/install-innosetup.sh <<: *step </del> - name: ensure the build happens on a partition with enough space run: src/ci/scripts/symlink-build-dir.sh <<: *step


Question: run: src/ci/scripts/install-wix.sh <<: *step <del> - name: install InnoSetup run: src/ci/scripts/install-innosetup.sh <<: *step </del> - name: ensure the build happens on a partition with enough space run: src/ci/scripts/symlink-build-dir.sh <<: *step


Question: <ins> // Checks that naked functions are never inlined. // compile-flags: -O -Zmir-opt-level=2 // ignore-wasm32 #![crate_type = "lib"] #![feature(asm)] #![feature(naked_functions)] #[inline(always)] #[naked] #[no_mangle] pub unsafe extern "C" fn f() { // Check that f has naked and noinline attributes. // // CHECK:       define void @f() unnamed_addr [[ATTR:#[0-9]+]] // CHECK-NEXT:  start: // CHECK-NEXT:    call void asm asm!("", options(noreturn)); } #[no_mangle] pub unsafe fn g() { // Check that call to f is not inlined. // // CHECK-LABEL: define void @g() // CHECK-NEXT:  start: // CHECK-NEXT:    call void @f() f(); } // CHECK: attributes [[ATTR]] = { naked noinline{{.*}} } </ins>

Currently, the compiler is allowed to inline naked functions if it wants to. For a normal function, inlining is fine because the compiler can remove the function prologue/epilogue and the remaining will behave as expected. However for naked functions, the developer provides the prologue/epilogue and those aren't removed by the compiler. This almost surely will result in incorrect behavior. Accordingly I think it would make sense for the compiler to not inline naked functions unless the developer explicitly opted-in.
In the other thread, alistair23 found that
Yes, functions should imply .


Question: // through and constrain Pi. let mut subcomponents = smallvec![]; let mut subvisited = SsoHashSet::new(); <del> compute_components_recursive(tcx, ty.into(), &mut subcomponents, &mut subvisited); </del> <ins> compute_alias_components_recursive(tcx, ty, &mut subcomponents, &mut subvisited); </ins> out.push(Component::EscapingAlias(subcomponents.into_iter().collect())); } }

Another regresssion of with a different failure path: It should be fixed by ignoring non-captured lifetimes in: cc label regression-from-stable-to-stable C-bug T-compiler T-types A-impl-trait
Note that fixing this issue is necessary for , but might not be sufficient. I'll investigate more...
WG-prioritization assigning priority (). label -I-prioritize +P-high


Question: // through and constrain Pi. let mut subcomponents = smallvec![]; let mut subvisited = SsoHashSet::new(); <del> compute_components_recursive(tcx, ty.into(), &mut subcomponents, &mut subvisited); </del> <ins> compute_alias_components_recursive(tcx, ty, &mut subcomponents, &mut subvisited); </ins> out.push(Component::EscapingAlias(subcomponents.into_iter().collect())); } }

Some regressions of that I previously reported in , but they were missed: I guess the way to fix this is to ignore non-captured lifetimes of opaque types here cc label C-bug regression-from-stable-to-stable T-types T-compiler A-impl-trait
WG-prioritization assigning priority (). label -I-prioritize +P-high


Question: pub fn report_error_if_loans_conflict(&self, old_loan: &Loan<'tcx>, <del> new_loan: &Loan<'tcx>) { </del> <ins> new_loan: &Loan<'tcx>) -> bool { </ins> //! Checks whether `old_loan` and `new_loan` can safely be issued //! simultaneously.

Ran into this when running a fauly tt muncher with ~100 items. We can now compete with C++ in the compiler spew area as well! :-P
Ran into this while demonstrating why you need raw pointers to do a singly-linked-queue: 66 Borrow check errors in this test.


Question: fn method(&self) -> impl Trait<Type = impl Sized + '_>; } <ins> trait Trait2 { type Type; fn method(&self) -> impl Trait2<Type = impl Trait2<Type = impl Sized + '_> + '_>; } </ins> fn main() {}

<!-- Thank you for finding an Internal Compiler Error! If possible, try to provide a minimal verifiable example. You can read "Rust Bug Minimization Patterns" for how to create smaller examples. --<!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</details
probably Regression in searched nightlies: from nightly-2023-02-15 to nightly-2023-03-16 regressed nightly: nightly-2023-02-20 searched commit range: regressed commit: <details<summarybisected with <a href=''cargo-bisect-rustc</av0.6.5</summaryHost triple: x86_64-unknown-linux-gnu Reproduce with: </details
It's actually
Or at least, the logic broke because of , so the ICE message probably changed in that PR from some other message, to this one in the title.
label +S-bug-has-mcve


Question: <ins> // Traits in scope are collected for doc links in field attributes. // check-pass // aux-build: assoc-field-dep.rs extern crate assoc_field_dep; pub use assoc_field_dep::*; #[derive(Clone)] pub struct Struct; pub mod mod1 { pub struct Fields { /// [crate::Struct::clone] pub field: u8, } } pub mod mod2 { pub enum Fields { V { /// [crate::Struct::clone] field: u8, }, } } </ins>

Here is a complete (minimized) reproducer: It can be reproduced with a workspace with two crates "a" and "b" where: The crate "a" depends on the public () crate and its code is: . The crate "b" depends on the workspace crate and its code is: With that setup, the command rightfully succeeds using the stable toolchain. But fails when using the latest (2022-04-25) nightly toolchain. The bug is observable on nightly only (works fine on stable, and beta) : <details<summary<strongBacktrace</strong</summary<p</p</details
Fixed in


Question: } } <ins> /// A call to a `panic()` lang item where the first argument is _not_ a `&str`. #[derive(Debug)] pub struct PanicNonStr; impl NonConstOp for PanicNonStr { fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> { ccx.tcx.sess.struct_span_err( span, "argument to `panic!()` in a const context must have type `&str`", ) } } </ins> #[derive(Debug)] pub struct RawPtrComparison; impl NonConstOp for RawPtrComparison {

The panic payload of the macro (as passed on to ) is generic, but the CTFE panic support assumes it will always be an . This leads to ICEs: Cc
I guess we could support this, but we'd have to find some way to render the errors. Maybe we need to wait for const traits so we can require const Debug?
Alternatively constck could require the argument to have type .
also requires a
Yeah, the libcore panic machinery does not support non-format-string panics.
Aye, left out the latter of my message. is likely the most common argument to , and it's not unusual with e.g. ; so I agree that waiting for const traits before supporting any other arguments is reasonable.
Im hitting this ICE on stable without feature flag:
Hm indeed, that is interesting: any idea why we go on here after seeing an error? Does this kind of behavior mean any part of CTFE is reachable on stable somehow?
yes. We're not gating CTFE on whether there were stability (or any other static checks) failing. I've been abusing this since 1.0 to demo things on the stable compiler and never got around to fixing it. I don't even know if we have a tracking issue for it.
:rofl: So what would be a possible approach here? Replace such consts by early enough that their MIR never actually gets evaluated? We might as well use this issue, IMO...
That would require us to mutate all MIR and potentially even HIR. Other possible solutions: poison the mir Body if const checks fail (by adding a field like or by just nuking the body by replacing it with ) and thus make allow const evaluation to check if the mir Body failed the checks and bail out before doing anything make the have an field similar to
On second thought, let's leave this issue for the ICE, and make a new one for "we can trigger nightly-only const code on stable because we don't abort compilation early enough":
Given that this ICE is pre-existing, as shown by , can we un-block ? I'd really like to see const_panic stabilized, and this seems like a minor issue to be blocking on.
That comment is an example of accidentally partially exposing an unstable feature on stable -- a separate bug tracked in I don't see how that's an argument for shipping that feature on stable when it is broken.


Question: } } <ins> /// A call to a `panic()` lang item where the first argument is _not_ a `&str`. #[derive(Debug)] pub struct PanicNonStr; impl NonConstOp for PanicNonStr { fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> { ccx.tcx.sess.struct_span_err( span, "argument to `panic!()` in a const context must have type `&str`", ) } } </ins> #[derive(Debug)] pub struct RawPtrComparison; impl NonConstOp for RawPtrComparison {

In particular, applies to all unstable const features. Fixing this bug here is not even that hard I think: somewhere around here there needs to be a check that the argument has type . Re: , AFAIK that one is also blocked on figuring out how the diagnostics should look like, and a further concern (though maybe not blocking) is .
I guess that might make this a non-issue, where it is proposed also would require as first argument.
For reference: , which was recently merged. The plan is to fix the behaviour of in the Rust 2021 edition. Given that this ICE is listed as a blocker for , does this mean that stabilizing that will have to wait for the next edition?
No, because breaking changes are allowed to be made to unstable features without moving to a new edition; that's kinda the whole idea. The 2021 edition will effectively just extend the same restriction to all invocations, const context or not.
I'd like to tackle this but I'm not very experienced with the CTFE code. I get that we need to check from the that we've matched on in this branch and we need to match on the enum, but: For the first question, I see and that we probably want to check that the type of the tuple and that there's variants of that are , but do we stop the iteration when we get one that is a type? Is the projection list always guaranteed to terminate in a variant of that has a ? And once we have an instance of , do we just check that there's any_ projection in the list that has a ?
you can use to get the type of the . Then you can test its to be .


Question: /// /// In other words, it zips two iterators together, into a single one. /// <del> /// When either iterator returns [`None`], all further calls to [`next`] /// will return [`None`]. </del> <ins> /// If either iterator returns [`None`], [`next`] will return [`None`]. </ins> /// /// # Examples ///

[][zip] says: However, it is not always true; it actually returns after when the source iterator is not fused. [Playground] [zip]: [Playground]:


Question: <ins> trait T<'x> { type V; } impl<'g> T<'g> for u32 { type V = u16; } fn main() { (&|_|()) as &dyn for<'x> Fn(<u32 as T<'x>>::V); //~^ ERROR: type mismatch in closure arguments //~| ERROR: type mismatch resolving } </ins>

Binder(<[type error] as ToBytes) This only happens if there are two erroneous functions, if I take out it works fine. It seems like I was trying to do this wrong in the first place since the first function gives an error . Not sure what the right way to do this is. <details<summaryTraceback</summary</details
Tried to reduce it and found a similar case with the same ICE:
Compiler triage: Seems likely to be caused by the need for lazy norm. Marking as p-medium for now.
The ICE doesn't appear on the latest nightly, marked as E-needstest


Question: ObligationCauseCode::VariableType(hir_id) => { let parent_node = self.tcx.hir().get_parent_node(hir_id); match self.tcx.hir().find(parent_node) { <ins> Some(Node::Local(hir::Local { ty: Some(ty), .. })) => { err.span_suggestion_verbose( ty.span.shrink_to_lo(), "consider borrowing here", "&", Applicability::MachineApplicable, ); err.note("all local variables must have a statically known size"); } </ins> Some(Node::Local(hir::Local { init: Some(hir::Expr { kind: hir::ExprKind::Index(_, _), span, .. }), ..

I tried compiling this code: which resulted in the following output of rustc: So the compiler says So I tried adding a borrow and recompiling the code: which resulted in: so the compiler says and so I'm stuck in a loop. The compiler can't decide whether I should borrow or not. As a newbie to Rust, this is very frustrating and the opposite of helpful, it just confuses me further. Please fix this indecisiveness :) :
For reference, what you likely want to do is one of the following which means they cannot be the type of a local binding. You can give a binding a slice type (), because that's morally equivalent to a pointer (with sizing info), which has a compile time determined size, as all borrows are .
Current output: After :


Question: <ins> error[E0425]: cannot find value `读文` in this scope --> $DIR/non_ascii_ident.rs:3:13 | LL |     let _ = 读文; |             ^^^^ not found in this scope error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0425`. </ins>


Question: plugin_registrar, plugins, pointer, <ins> pointer_trait, pointer_trait_fmt, </ins> poll, position, post_dash_lto: "post-lto",

I tried this code: I expected to see this happen: The compilation succeed or guide me to (1) cast the to with . (2) borrow the : . But in this case the addresses printed are the same (what?). Instead, this happened*: Cryptic error message: There is : . It took me minutes before I found the workaround. But it still surprised me. : <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOT_END --
This creates a reference-to-function-pointer (type ), a double indirection. So it is not what you want. The error could possibly be improved, and the entire situation documented better, but I think getting an error is expected here. is not a function pointer, it is an anonymous ) (of size 0) indicating exactly the function it was created from. This type coerces to a function pointer, but cannot know what type to coerce it to. Printing function pointers is easy (well, if they are not polymorphic via ), but printing these function singleton ZSTs is hard.
It might also be worth linting against .
helps with the docs. But to close this issue, it would probably make sense to write a lint against where is the name of a function. That should be a matter of adding a new in which checks all expressions for being . That path we can pass to to get a . Now we just need to check if that refers to a function: pass the to . At least I hope that makes sense, someone stop me if this is all wrong. ;)
I'd like to help write this lint. The default level for the lint should be right? claim
Yeah, feels like a reasonable start.
Nominated for lang team discussion. It seems we usually ask for lints to be approved before shipping them, so let's get that process started. sorry for this, I wasn't aware of this part of the process. You can still go ahead and implement this if you want, but depending on what the lang team decides, we should submit this lint to clippy instead of the compiler itself. That might require minor adjustments, but the main work you are putting in and the testcases will be useful either way.


Question: plugin_registrar, plugins, pointer, <ins> pointer_trait, pointer_trait_fmt, </ins> poll, position, post_dash_lto: "post-lto",

:)
As a point of interest, this would have been extremely useful in helping debug a segfault in The original code used , not .
Without the cast, this should not compile as transmute checks that the sizes match. I assume what you describe happens when using , i.e., not just remove the but also add a .
Unfortunately I never committed the broken code so I'm not sure what I had originally ... the closest thing is which doesn't compile. Sorry for the noise.
no worries. I already have the lint implemented, but in that case I'll wait until they discuss to write the tests
I think should compile. That's no noise, it seems very relevant. :)
poll T-lang Should we add a lint for taking a reference to a fn?
Team member has asked teams: T-lang, for consensus on: [x] [x] [x] [ ] [x] [ ]
I think I agree here, but to confirm: this isn't actually about linting the taking of a reference to a place of type, but just about using on the voldemort-typed function name constants, right?
Yes.
Discussed in a (rather small) meeting today: Those present felt a lint would make sense. If somebody wanted to go ahead and try to author one, please feel free and nominate the resulting PR for discussion.
all right, so if you want to open a PR, everything is settled for that. :)


Question: <del> // compile-flags: --error-format pretty-json -Zunstable-options // build-pass (FIXME(62277): could be check-pass?) </del> <ins> // compile-flags: --error-format json -Zunstable-options </ins> // run-rustfix // The output for humans should just highlight the whole span without showing

Update test file to use + annotations instead of (see https://rust-) The files need to update are: - <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --This issue has been assigned to via . <!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
is the correct file name , not ? And what about this comment?
Is the problem fixed ? If not, I would like to work on it !
WIP PR has been closed due to inactivity so you can work on this.
I would like to be assigned to this issue. Am I supposed to do a new pull request ?
claim Go ahead!
Error: Parsing assign command in failed: claim Please let know if you're having trouble with this bot.
claim
Error: Parsing assign command in failed: claim Please let know if you're having trouble with this bot.
Hmm, it's odd, anyway, you can assign the issue to yourself by comment Ah, I mistaken the command, the collect one is , sorry.
claim
If I understood well the problem: I must replace all the by just , even if comment exist ? Because the output changes, I should modify the .stderr version I must change with in , and as should raise an error we add why add in the version ?


Question: || abi == SpecAbi::RustIntrinsic || abi == SpecAbi::PlatformIntrinsic { <del> let fixup = |arg: &mut ArgAbi<'tcx, Ty<'tcx>>| { </del> <ins> let fixup = |arg: &mut ArgAbi<'tcx, Ty<'tcx>>, is_ret: bool| { </ins> if arg.is_ignore() { return; }

Rust should pass more structs in registers. Consider these examples: ideally, both functions would execute entirely in registers and wouldn't touch memory: Rust, as of a recent 1.2.0-dev nightly, is unable to pass either of these in registers (see LLVM IR and ASM below). It would be pretty safe to pass and return small structs (ones that fit into <=2 registers) in registers, and is likely to improve performance on average. This is what the System V ABI does. It would also be nice to exploit Rust's control over aliasing, and where possible also promote reference arguments to registers, i.e. put the values in registers for the following functions: In the case, this would mean passing two values in registers as function parameters, and returning two values in registers as the return values (ideally we'd arrange for the parameter registers to match the return registers). Uniqueness of makes this optimization valid, although we may have to give up on this optimization in cases such as when there are raw pointers present. Here's a more realistic example where I've wanted Rust to do this: This function is too large to justify inlining. I'd like the begin and end pointers of to be kept in registers across the function call. Probably not surprising to the compiler team, but for completeness here is the LLVM IR of the above snippets, as of today's Rust (1.2.0-dev), compiled in release mode / opt-level=3: and here is the ASM:
For fat pointers this has been fixed in Am 22.06.2015 07:58 schrieb "Reiner Pope"
On etc. this is currently impossible because the address of references is significant (you can e.g. print it with ).
- yes, the ability to take addresses prevents doing this for all functions. But you could see doing this as an optimization: make the compiler check whether a function uses the address of a reference, and if not then change its calling convention. The compiler can use the worker/wrapper technique (as in GHC) to support call sites which aren't aware of this change in calling convention, by splitting the function into two:
Don't do this. You will break FastISel. Fix LLVM if it's not doing the optimizations you want.
what exactly would break FastISel?


Question: || abi == SpecAbi::RustIntrinsic || abi == SpecAbi::PlatformIntrinsic { <del> let fixup = |arg: &mut ArgAbi<'tcx, Ty<'tcx>>| { </del> <ins> let fixup = |arg: &mut ArgAbi<'tcx, Ty<'tcx>>, is_ret: bool| { </ins> if arg.is_ignore() { return; }

Pretty sure that since work on niche-filling optimisation, and use a pair of registers for the argument and the return value, respectively. Cc
didn't solve this?
Yes, this appears to be fixed. The following Rust code (): generates and
Ah no, I see that this issue also suggests: We don't do that yet: . FWIW Maybe it is worth to split this issue into two. One part has been closed already AFAICT. The other part (passing as a register containing a ) is... a suggestion at most. This issue does not suggest how to do this. already raised the issue that this breaks if the address is inspected. It probably needs to handle writes through (e.g. due to ) and somehow as well, etc. So I'm skeptic that this can work.
Here's another slightly more complex example, where ABI seems to be more efficient than :
A related thread:
is this fixed? Linked code is still bigger on Rust 1.48.
my example is fixed, the return value is no longer via stack: The difference is that rust abi version now uses a vectorized add, which seems like a win?
Hi all. I've traced back the cause of 'P-high' issue to two pulls that relate to this issue, namely and . Basically, these commits break auto-vectorization post Rust version 1.48 in a way that is not easily worked around. In short, if we take: 47 yields an efficient: 48 yields an awkward: 50 yields an even more awkward cascade effect: There are other examples in . My overly simplistic analysis, I'm no expert, is . In summary, if I rebuild Rust with the above pulls neutered, auto-vectorization appears to return to normal, as per 1.47.


Question: <ins> error[E0080]: it is undefined behavior to use this value --> $DIR/issue-51559.rs:4:1 | LL | pub const FOO: usize = unsafe { BAR as usize }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain (non-pointer) bytes | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior error: aborting due to previous error For more information about this error, try `rustc --explain E0080`. </ins>

Some people were of the opinion that this shouldn't work, but it currently does. : cc
cc
it's just super scary. EDIT: it should not and does not work. If we allowed this, various surprising things can happen, especially around implicit promotion. If you want to store pointers and integers, you can use a raw pointer.
For my own education, can you elaborate on why function pointers are ok? I'd thought that the runtime addresses of things -- including functions -- shouldn't be accessible at const-time since we don't know where they'll live at runtime. Could I make a const array that usize long?
When compiling to LLVM, the real function handle or pointer address is obtained. If you try doing anything weird with pointers at compile time, you will quickly notice that you are not at runtime. For example, you cannot divide such a usize by anything. You can add or subtract integers, because that's just pointer offsetting, but you can't inspect the address in any way. This also means that no, you cannot use this usize for array lengths or enum discriminants. This is due to the fact that miri pointers are not just addresses, but abstract pointers that are in a separate layer from the bytes of normal memory like the one of integers.
Thanks for the explanation. I guess that means that such a couldn't be passed to a const generic either?
The thing is const generics don't know where the usize comes from, so they could try to do something with it that is not allowed if it is just a pointer address. Until monomorphization we can't know if there is an issue. Note that converting a pointer to an usize and back just to be able to put it in const, statics, or use it with const generics, is a real pain. We would be better off in this case with an type, such that I can write and avoid the conversion to usize. For const generics, C++ accepts function pointers at the type level and that works just fine with clang, so I expect to work fine as well.
How would work? is disallowed but and work? that seems very weird and special cased (especially for fn types that involve higher rank lifetimes, as in my example) or is ~= ?


Question: <ins> error[E0080]: it is undefined behavior to use this value --> $DIR/issue-51559.rs:4:1 | LL | pub const FOO: usize = unsafe { BAR as usize }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain (non-pointer) bytes | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior error: aborting due to previous error For more information about this error, try `rustc --explain E0080`. </ins>

then is a double indirection and to use it you need to worry about managing the memory it points to (which contains the )
I haven't thought this through beyond having used the atomic pointers in the C++ standard library: One way to implement this could be where we provide blanket impls for , , , , , , , ... or use some compiler magic to achieve a similar effect...
This is a bit offtopic, but regarding , mentioned at least once the possibility of introducing some new type, to make sugar for . I guess it can't entirely be "sugar", because of existing impls, but at least both could work the same.
Hehe, this is cute. :) And I agree it is working as intended. (Nice that the translation to LLVM actually gets this right, should there be a testcase to make sure it stays that way? :D )
So... other than testing this, all we need is a PR that adds -casts in constants under a feature gate (and makes those casts unsafe in constants and )
I've opened to brainstorm how to either add an type or retrofit to support items.
These kind of operations are now unsafe in contexts (impl PR: )
So do we have a test that you cannot use such usize as array length? :D
hmm... apparently not... Test-instructions: (via the feature gate) to turn various kinds of references and function pointers into these expressions in array length, repeat lengths and enum discriminant initializers (e.g. ) Note: Do not use items, everything needs to be inline in the use site to be properly tested
this is no longer allowed by any means:
Yes that is intended. This issue is for adding a regression test testing what happens when you use a pointer casted to a usize in an array length.


Question: ast_passes_bound_in_context = bounds on `type`s in {$ctx} have no effect <del> ast_passes_const_and_async = functions cannot be both `const` and `async` .const = `const` because of this .async = `async` because of this .label = {""} </del> ast_passes_const_and_c_variadic = functions cannot be both `const` and C-variadic .const = `const` because of this .variadic = C-variadic because of this <ins> ast_passes_const_and_coroutine = functions cannot be both `const` and `{$coroutine_kind}` .const = `const` because of this .coroutine = `{$coroutine_kind}` because of this .label = {""} </ins> ast_passes_const_bound_trait_object = const trait bounds are not allowed in trait object types ast_passes_const_without_body =

() Reproduces on the playground using . label +D-incorrect +F-gen_blocks +requires-nightly


Question: <ins> error[E0425]: cannot find function `foo` in module `to_reuse` --> $DIR/ice-issue-124342.rs:7:21 | LL |     reuse to_reuse::foo { foo } |                     ^^^ not found in `to_reuse` error[E0425]: cannot find value `foo` in this scope --> $DIR/ice-issue-124342.rs:7:27 | LL |     reuse to_reuse::foo { foo } |                           ^^^ | help: you might have meant to refer to the associated function | LL |     reuse to_reuse::foo { Self::foo } |                           ++++++ error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0425`. </ins>

<!-- ICE: Rustc '' 'thread 'rustc' panicked at 'no entry found for key'', 'thread 'rustc' panicked at 'no entry found for key'' File: --auto-reduced (treereduce-rust): original: Version information ` Command: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongProgram output</strong</summary<p</p</details<!-- query stack: [resolverforlowering_raw] getting the resolver for lowering --
this probably crashes since but I haven't verified that yet
smaller
even smaller


Question: } let tcx = self.tcx(); let mut pred = cache_fresh_trait_pred.skip_binder(); <del> param_env = param_env.with_constness(pred.constness.and(param_env.constness())); </del> <ins> pred.remap_constness(tcx, &mut param_env); </ins> if self.can_use_global_caches(param_env) { if let Some(res) = tcx.selection_cache.get(&param_env.and(pred), tcx) {

<!-- Thank you for filing a regression report! A regression is something that changed between versions of Rust but was not supposed to. Please provide a short summary of the regression, along with any information you feel is relevant to replicate it. --I tried this code: I expected to see this happen: print (from Debug impl) Instead, this happened: E0277, trait impl not found This was found by CI in the Ruffle Project: The issue is caused by the effective anti-bound of Drop, introduced by the manual impl of the trait, as well as the PR which introduced bounds for a number of functions in . It most recently worked on: rustc 1.59.0-nightly ( 2021-12-18) : modify labels: +regression-from-stable-to-nightly -regression-untriaged
cc


Question: } } <del> pub fn is_async(self) -> bool { matches!(self, CoroutineKind::Async { .. }) } pub fn is_gen(self) -> bool { matches!(self, CoroutineKind::Gen { .. }) </del> <ins> pub fn as_str(self) -> &'static str { match self { CoroutineKind::Async { .. } => "async", CoroutineKind::Gen { .. } => "gen", CoroutineKind::AsyncGen { .. } => "async gen", } </ins> } pub fn closure_id(self) -> NodeId {


Question: use rustc_middle::ty; <ins> // Please change the public `use` directives cautiously, as they might be used by external tools. // See issue #120130. </ins> pub use self::drop_flag_effects::{ drop_flag_effects_for_function_entry, drop_flag_effects_for_location, move_path_children_matching, on_all_children_bits, on_lookup_result_bits, }; pub use self::framework::{ <del> fmt, lattice, visit_results, Analysis, AnalysisDomain, Direction, GenKill, GenKillAnalysis, JoinSemiLattice, MaybeReachable, Results, ResultsCursor, ResultsVisitable, ResultsVisitor, </del> <ins> fmt, graphviz, lattice, visit_results, Analysis, AnalysisDomain, Backward, Direction, Engine, Forward, GenKill, GenKillAnalysis, JoinSemiLattice, MaybeReachable, Results, ResultsCursor, ResultsVisitable, ResultsVisitor, SwitchIntEdgeEffects, </ins> }; <del> use self::framework::{Backward, SwitchIntEdgeEffects}; </del> use self::move_paths::MoveData; pub mod debuginfo;

has made it impossible to import some structures in when implementing dataflow analyses in external tools. When implementing for a custom dataflow problem, we can no longer import the or direction. is the source code of such an implementation. is needed to set the type of the trait. Previously, it under the export, but for now it is . The default implementation of the , so I can simply use the default value as a workaround. However, if I need to write a backward analysis, I must rewrite some parts of the framework in our source code because they cannot be imported. There are other tools in the ecosystem that use that API, e.g.: These changes will make problems if they decide to update to the recent toolchain. Could you please take a look at this matter? Are these changes intentional? Could we make some of the exports public again? cc
Feel free to send in a PR to make it public again. Please add a comment on the items saying they're used by external tools.
I will double-check which of the removed imports might be beneficial for external tools and will send a PR if there are no objections.


Question: let _ = &packed2.y; // ok, has align 2 in packed(2) struct let _ = &packed2.z; // ok, has align 1 } <ins> unsafe { struct U16(u16); impl Drop for U16 { fn drop(&mut self) { println!("{:p}", self); } } struct HasDrop; impl Drop for HasDrop { fn drop(&mut self) {} } #[allow(unused)] struct Wrapper { a: U16, b: HasDrop, } #[allow(unused)] #[repr(packed(2))] struct Wrapper2 { a: U16, b: HasDrop, } // An outer struct with more restrictive packing than the inner struct -- make sure we // notice that! #[repr(packed)] struct Misalign<T>(u8, T); let m1 = Misalign( 0, Wrapper { a: U16(10), b: HasDrop, }, ); let _ref = &m1.1.a; //~ ERROR reference to packed field //~^ previously accepted let m2 = Misalign( 0, Wrapper2 { a: U16(10), b: HasDrop, }, ); let _ref = &m2.1.a; //~ ERROR reference to packed field //~^ previously accepted } </ins> }

I tried this code: I expected to see this happen: The reference is aligned Instead, this happened: : label I-unsound A-mir
We have a pass to add moves for drops in packed structs, but it doesn't fire in this case. That's because there's a bug - this computation cannot just take into account the innermost field, it needs to compute a minimum of some sort.
is this a regression? What did you exactly expected the output to be? (I'd like to run a bisection). thanks.
This was right in . Getting a consistent reproduction of this is slightly difficult because the reference might happen to align correctly by accident. In other words, the fact that the example above prints a pointer that is not 2-aligned means that something is certainly wrong. However, if the address were to be 2-aligned that could either be because the bug is fixed or because we happened to get lucky. The consistent way to check this is by looking at . In 1.52.0 the MIR contains which is correct (the move ensures that the resulting place is aligned) while 1.53.0 contains Note that there is no move.
WG-prioritization assigning priority (). label -I-prioritize +P-high E-needs-bisection
I have run a bisection with on your . The bisection could not pinpoint a single commit, maybe it sinked into a rollup merge. But if it helps, the regression should be in and coming from one of these PRs do you see in any of those a possible culprit? (I don't have the context to)
Yeah, it's , cc
Not sure how would have an effect here, it should be a NOP for with . Looks like something else is amiss as well and that PR surfaced the bug? Where is the logic that moves packed structs to a new place before dropping implemented? That's odd, I would have expected this to be inside ... after all calling on a packed struct also has to do this move. Why does MIR building adjust the caller to satisfy a requirement that the callee should be responsible for?
the pass is called or something like that.


Question: let _ = &packed2.y; // ok, has align 2 in packed(2) struct let _ = &packed2.z; // ok, has align 1 } <ins> unsafe { struct U16(u16); impl Drop for U16 { fn drop(&mut self) { println!("{:p}", self); } } struct HasDrop; impl Drop for HasDrop { fn drop(&mut self) {} } #[allow(unused)] struct Wrapper { a: U16, b: HasDrop, } #[allow(unused)] #[repr(packed(2))] struct Wrapper2 { a: U16, b: HasDrop, } // An outer struct with more restrictive packing than the inner struct -- make sure we // notice that! #[repr(packed)] struct Misalign<T>(u8, T); let m1 = Misalign( 0, Wrapper { a: U16(10), b: HasDrop, }, ); let _ref = &m1.1.a; //~ ERROR reference to packed field //~^ previously accepted let m2 = Misalign( 0, Wrapper2 { a: U16(10), b: HasDrop, }, ); let _ref = &m2.1.a; //~ ERROR reference to packed field //~^ previously accepted } </ins> }

And this can't take place inside the callee because the callee receives a , and if that reference is unaligned then UB has already occurred and there's nothing the callee can do to fix things anymore
takes a raw pointer, so it could very well be the place where the packed struct alignment trouble is handled. And IMO it'd be a much more natural place than doing this by transforming caller MIR.
I don't understand the suggestion. The example above never calls for a packed struct. The offending drop in the MIR in the example above is . The type of that place is - but if were to be responsible for moving, then we would need to emit a move in literally every drop shim for a non-trivial alignment type.
Oh I see, I didn't quite read the example correctly. The problematic drop is the one that happens on field assignment, and we know it's a packed field because of the path we are accessing it with. EDIT: no wait this makes no sense. Now I am confused by your comment.
No what I just said makes no sense. What happens is that this is a partial drop -- one field has been moved out () and then the logic for dropping the remaining fields seems to be wrong. So is relevant because it changed . And it looks like somehow the change is wrong; here is also despite the reference being unaligned.
should fix this.


Question: #[start] fn main(_argc: isize, _argv: *const *const u8) -> isize { <del> let _x = box 1; </del> <ins> let _x = Box::new(1); </ins> 0 } #[lang = "eh_personality"] extern fn rust_eh_personality() {} <del> #[lang = "panic_impl"] extern fn rust_begin_panic(info: &PanicInfo) -> ! { unsafe { intrinsics::abort() } } </del> <ins> #[lang = "panic_impl"] extern fn rust_begin_panic(_info: &PanicInfo) -> ! { intrinsics::abort() } </ins> #[no_mangle] pub extern fn rust_eh_register_frames () {} #[no_mangle] pub extern fn rust_eh_unregister_frames () {} ```

There is no such thing as boxsyntax anymore :D <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOT_END --
does the same.
It probably makes sense to search across the repository (including submodules) any references to this removed feature and remove them
claim


Question: use _Unwind_VRS_DataRepresentation::*; pub const UNWIND_POINTER_REG: c_int = 12; <ins> pub const UNWIND_SP_REG: c_int = 13; </ins> pub const UNWIND_IP_REG: c_int = 15; #[cfg_attr(all(feature = "llvm-libunwind",

When I tested 1.40.0-beta.5 on , never completed on . When I run that test on arm directly, I get: The same happens when I use official builds of Rust 1.40-beta and 1.41-nightly, so it's not just a problem with Fedora's build of rustc or LLVM. This test didn't exist before , but running 1.39 on the current test just fails even earlier, as expected, "entered unreachable code: catch_unwind should not have caught foreign exception." I tried compiling the C++ part with GCC 9.2.1 and Clang 9.0.0, both with the same result. That's using libstdc++ either way though, because we don't have LLVM's libc++ available. cc
cc
PS: while I initially saw this on Fedora rawhide, my followup testing has been on stable Fedora 31.
That is very strange. And this behavior only occurs on ARM? I'm tempted to say that this is a bug in GCC's unwinder (in libgcc). Can you try this C++-only code to see if it has the same issue? a.cpp b.cpp This should print the message once and then fail with an uncaught exception.
Yes, the other arches completed and passed that test. Needs for , but then it works:
I tried stable 1.39 again commenting out the call to , then gets stuck in the same "caught foreign exception in catch" loop on the C++ side. In fact, this happens on every compiler I tried back to 1.13, which is the earliest I could get working at all! So at least it's not a new problem. Maybe we're generating bad unwind data, or maybe my libgcc has a bug in handling foreign exceptions, I don't know...
I think this might be a bug in the way the personality routine in libstdc++ (libsupc++ actually) handles foreign exceptions on ARM. Can you try using libc++ instead of libstdc++? Just change the linker args for rustc from to .
Oh, I found that Fedora does have libc++ packaged, and . But when I tried to use it simply as you indicate, foreign exceptions don't seem to be caught at all, in either direction.


Question: use _Unwind_VRS_DataRepresentation::*; pub const UNWIND_POINTER_REG: c_int = 12; <ins> pub const UNWIND_SP_REG: c_int = 13; </ins> pub const UNWIND_IP_REG: c_int = 15; #[cfg_attr(all(feature = "llvm-libunwind",

I see the binary still gets linked implicitly though, I think because adds it to std. I'll try to get a full build of rustc with just libc++ instead.
It's fine to link to , since that contains the libunwind implementation. The actual C++ personality functions are in libstd++/libc++abi. Can you post the test output with libc++?
Maybe this is obvious, but I have to compile the C++ part with clang++, not g++, or it gets "undefined reference to ". I wasn't sure whether to also use , but either way the C++ exception is not caught by Rust: So I commented out again to just try :
you may need to explicitly link libcxxabi depending on how libcxx was built. That should fix undefined reference error.
I did use -- do you mean more than that? If anyone else is interested in arm-linux, it would be great to get more hands on this, because that target is not a high priority for me. I will probably disable this test for arm in Fedora in the meantime.
I managed to reproduce this on Arch Linux with , so it's definitely not a Fedora-only issue.
no, that should be fine. Guess passing to the Clang (supported since 9.0.0) doesn't help either?
The link error was only when using g++ to compile That much was ok with clang++. I just tried adding to the clang command too, but got "argument unused during compilation".
I'm hitting this on Debian too. Running by itself does result in infinite-loop printing however the rust test suite is actually running . Directly running this however exits immediately, so I don't know why the test is hanging. I'll see if I can grab the environment from next time.
Ah nvmd, I just had to wrap the thing in single-quotes to reproduce the loop, the output of "pstree" is misleading.
Since this test is new in 1.40 I'll just for the time being in Debian.
Should be fixed by


Question: TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, }; use rustc_session::config::TraitSolver; <del> use rustc_span::def_id::{DefId, CRATE_DEF_ID}; </del> <ins> use rustc_span::{ def_id::{DefId, CRATE_DEF_ID}, DUMMY_SP, }; </ins> use rustc_trait_selection::traits; fn sized_constraint_for_ty<'tcx>(

<!-- Thank you for finding an Internal Compiler Error! If possible, try to provide a minimal verifiable example. You can read "Rust Bug Minimization Patterns" for how to create smaller examples. --<!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</details
probably Regression in searched nightlies: from nightly-2023-02-15 to nightly-2023-03-16 regressed nightly: nightly-2023-02-20 searched commit range: regressed commit: <details<summarybisected with <a href=''cargo-bisect-rustc</av0.6.5</summaryHost triple: x86_64-unknown-linux-gnu Reproduce with: </details
It's actually
Or at least, the logic broke because of , so the ICE message probably changed in that PR from some other message, to this one in the title.
label +S-bug-has-mcve


Question: <ins> - // MIR for `bitwise_not` before JumpThreading + // MIR for `bitwise_not` after JumpThreading fn bitwise_not() -> i32 { let mut _0: i32; let mut _1: i32; let mut _2: bool; let mut _3: i32; let mut _4: i32; scope 1 { debug a => _1; } bb0: { StorageLive(_1); _1 = const 0_i32; _1 = const 1_i32; StorageLive(_2); StorageLive(_3); StorageLive(_4); _4 = copy _1; _3 = Not(move _4); StorageDead(_4); _2 = Eq(move _3, const 0_i32); switchInt(move _2) -> [0: bb2, otherwise: bb1]; } bb1: { StorageDead(_3); _0 = const 1_i32; goto -> bb3; } bb2: { StorageDead(_3); _0 = const 0_i32; goto -> bb3; } bb3: { StorageDead(_2); StorageDead(_1); return; } } </ins>

<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. --I tried this code: I expected to see this happen: always panic Instead, this happened: only -Zmir-opt-level=2 panic For mir-opt-level 0, 1 and 3, they all normally return <!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
equals , so I think the panic case is incorrect?
Yeah, I think so.
Looks like it's JumpThreading that incorrectly removes the condition
I managed to create an example without panic, just wrong value
Most likely
ha, I found the bug. We're optimizing incorrectly in the jump threading code. Right now it's only written to handle bool correctly. I'll put up a fix claim


Question: } else { let args: Vec<_> = args .into_iter() <del> .map(|arg| unpack!(block = this.as_local_operand(block, arg))) </del> <ins> .map(|arg| unpack!(block = this.as_local_call_operand(block, arg))) </ins> .collect(); let success = this.cfg.start_new_block();

The following code fails on stable: When compiled in release mode, the assert is optimized out by LLVM even though it checks the exact same condition as the other assert, as can be verified by testing in debug mode. Note that it's theoretically possible for the stack to be aligned correctly such that the bug is suppressed, but that's not likely. The 256's can be replaced with larger alignments if that happens. The bug is caused by the impl of copying to the stack with the default alignment of 16. ()
and seem related
This is a soundness hole.
So... I guess the problem is that the that rustc emits for the unsized local doesn't use ? That's... kind of bad, because it doesn't look like even supports dynamically setting the alignment: If this is correct, the issue should be renamed to something like "unsized locals do not respect alignment".
A way to fix this would be to change the ABI for dynamic trait calls that take by value to always pass by address. When the trait object is created is where the trampoline function would be generated, so there is no additional cost for static calls.
This can also be fixed by not allowing dynamically-sized local variables with an alignment more than some maximum value and having all dynamically-sized locals use that maximum alignment unless optimizations can prove that a smaller alignment suffices.
Messing with the ABI wouldn't help with unsized locals in general (assuming is correct), since e.g. will also need an alloca with dynamic alignment in general. Given only a value, there is no static way to say anything about its alignment, so how would you distinguish whether calling a method on it is OK?
Can we call and then align the pointer for the local ourselves as a workaround until we come up with a good solution?
In clang there's a function which might or might not be useful in this case.
requires a constant alignment. Non constant alignments are . This matches semantics of LLVM instruction, so it's not helping, as alignment of value in is unknown at compile time when moving from .
I think that overallocating for unsized locals of unknown alignment may make sense. You can and then make use of to compute the offset. Sure, it increases stack requirements, but it seems acceptable for , and in most cases you end up with extra 7 bytes on stack or less. 256 alignment seems like an edge case where wasting 255 bytes doesn't matter.


Question: } else { let args: Vec<_> = args .into_iter() <del> .map(|arg| unpack!(block = this.as_local_operand(block, arg))) </del> <ins> .map(|arg| unpack!(block = this.as_local_call_operand(block, arg))) </ins> .collect(); let success = this.cfg.start_new_block();

if we keep setting as the default alignment we can skip the overallocating and offset dance for types with an alignment below that.
My idea was that rustc would prohibit coercing overaligned types to a dyn trait that takes by value. So:
The alignment is dynamically determined though, not sure if saving 15 bytes of stack space is worth the conditional branch?
Oh right. Yea that's probably not helpful.
Since , this would be backwards incompatible (at latest) once trait object upcasting is finally implemented: and trait objects would have to have the same alignment restriction (because you can upcast to ), but today you can freely create such objects with any alignment.
I was under the impression that calling didn't require dynamic , is that related to missing MIR optimizations, meaning we have unnecessary moves which end up duplicating the data on the stack using a dynamic ?
Correctness shouldn't rely on optimizations to fire...
Sure, I was just hoping we weren't relying on "unsized locals", only unsized parameters (i.e. ), for what we're exposing as stable. And I was hoping an optimization wouldn't need to be involved to get there. I wonder if it would even be possible to restrict "unsized locals" to the subset where we can handle it entirely through ABI, and not actually have dynamic s anywhere, since that would make me far more comfortable with 's implementation or even stabilization. Ironically, if that works, it's also the subset we could've implemented years earlier than we did, since most of the complexity, unknowns (and apparently bugs) are around dynamic s, not calling trait object methods on a dereference of .
That should be possible. I think everything that is necessary is performing the deref of the box as argument () instead of moving the box contents to a local first () That would also make it possible to call in cg_clif. Cranelift doesn't have alloca support, so the current MIR is untranslatable.
Hmm, but that's not trivially sound because it could lead to MIR calls where argument and return places overlap, which is UB. We'd potentially have to special-case it to derefs, but even then what's to stop someone from doing ? Maybe we could introduce a temporary for the return value instead, for these kinds of virtual calls? That should remove any potential overlap while allowing the call.


Question: } else { let args: Vec<_> = args .into_iter() <del> .map(|arg| unpack!(block = this.as_local_operand(block, arg))) </del> <ins> .map(|arg| unpack!(block = this.as_local_call_operand(block, arg))) </ins> .collect(); let success = this.cfg.start_new_block();

(Unrelatedly, I just realize we use a copying-out shim for vtable entries that take by value, even when would be passed as at the call ABI level. We would probably have to make computing the call ABI a query for this microopt to not be expensive)
That would result in being moved to a temp first before dropping and calling the boxed closure. If it wasn't moved first before the drop of , then borrowck would give an error. (I meant for this change to be done at mir construction level, not as an optimization pass, so borrowck should catch any soundness issues)
We can try it, I guess, but right now a lot relies on many redundant copies/moves being created by MIR building and may not catch edge cases like this. But also I don't think moving out of a moves the itself today. Me too, but I was going with the "correct by construction" approach of creating a redundant copy/move, just on the return side, instead of the argument side, of the call.
After revisiting on triage, removing nomination.
pre-triage: nominated for discussion in the next weekly meeting.
I just checked and, a function call roughly this (touched up for clarity): Some of my previous comments assumed the wasn't there and the call would use the destination directly, but given that there is a move, that simplifies my suggestion. <hr/For virtual by-value calls, we can skip one move when building the MIR, specifically the move out of the dereference of a for the argument. Given that we already move the result of the call, there should be no aliasing caused by this, but if we decide to change anything about how we build MIR calls, we'd need to be extra careful. We can also make this pattern be gated by a separate feature-gate (rather than ), and make sure the standard library only uses that feature-gate and not . This should solve any alignment issues might have, because we'd not be using dynamic unless the broader feature is used.
OK, if I understand what's being proposed here, it is to excerpt a subset of the "original unsized-locals plan" -- specifically, to permit locals with unsized types, but only in contexts where we can be guaranteed that we can point to the original storage and don't actually have to move any value (and hence we don't require variable size stack frames).


Question: } else { let args: Vec<_> = args .into_iter() <del> .map(|arg| unpack!(block = this.as_local_operand(block, arg))) </del> <ins> .map(|arg| unpack!(block = this.as_local_call_operand(block, arg))) </ins> .collect(); let success = this.cfg.start_new_block();

I'm in favor of this proposal, but I do think we want to be slightly careful to ensure we're not violating soundness. The main concern would be if there is some way to access or re-use the variable that was moved. I attempted to do so with this example () but it fails to compile: The error here arises because the closure would need to capture a to do anything, which prevents a later move. But maybe there is some kind of tricky example that can arise where we re-assign the value during argument evaluation?
compiles and does before , where is the result of .
Borrowck should prevent that, right?
borrowck may rely on MIR building creating extraneous copies, so we can't just assume it helps us. IMO we should limit it to functions taking unsized parameters and function calls passing such parameters or dereferences of es (any other pointer/reference doesn't support moving out of).
Well, I think is right that borrowck would catch violations of soundness in some strict sense, but I guess what I meant is that we might be breaking backwards compatibility.
The example that feels pretty relevant. If I understood your proposal, it would no longer compile. If I recall (thinking back), I had a plan to handle this by save the to an alternate location in the actual call, we pass ownership of and then do a shallow free of the This still seems like it would work, though I'm not sure how easy/elegant it is to formulate. In a sense we'd be rewriting to .
Isn't example dependent on doing a direct virtual call? My understanding is that you can't do this on stable with because the virtual call exists in one place, in libstd, and it doesn't do anything weird, so it would work with a restricted ruleset. EDIT: if it can work on stable, it's because calling 's will move the whole before the assignment is evaluated, which is fine, because the shallow drop is actually inside that , not its caller.
I agree that this code doesn't compile on stable today, but I'm not sure if that's the point. I guess you're saying it's ok for it to stop compiling? I think what I would like is that our overall behavior is as consistent as possible between Sized and Unsized parameters. I think we could actually do a more general change that doesn't special case Sized vs Unsized or anything else.