Question: &ccx.int_type); let llfn = decl_cdecl_fn(ccx, "main", llfty, ty::mk_nil()); <ins> // FIXME: #16581: Marking a symbol in the executable with `dllexport` // linkage forces MinGW's linker to output a `.reloc` section for ASLR if ccx.sess().targ_cfg.os == OsWindows { unsafe { llvm::LLVMRustSetDLLExportStorageClass(llfn) } } </ins> let llbb = "top".with_c_str(|buf| { unsafe { llvm::LLVMAppendBasicBlockInContext(ccx.llcx, llfn, buf)

This should be as simple as passing to the linker for both libraries and executables. However, the necessary relocations are never generated by MinGW or MinGW-w64 for executables so nothing is actually randomized without also passing . The switch is also broken and results in a messed up entry point, but it may not actually be required.
Hi, I found this issue while looking for an old reference, but I thought you might be interested in a possible fix. We needed for Tor's hardening options and after some back and forth settled on a working binutils patch which is here (works for 2.24 and is being submitted upstream shortly): This patch has not been reviewed at all, since no one at Tor feels sufficiently capable. Hopefully the binutils folks will have something to say, but as language developers you might too. (edit: fix link to patch)
We ended up working around it for the time being by doing a dllexport of main in order to force it to output a relocation section, since the executable counts as a library. I would really like to have this fixed properly though so I'll look into it some more when I have time.
Needs to be disabled again due to .
Note that recent binutils may have support for high entropy ASLR. ( was accepted last year. See ) It would be good to check if mingw-w64 would contain the patch when we re-enable ASLR.
Triage: not sure if anything has changed here, but I don't think so.
Triage: same as in 2016


Question: <ins> error[E0425]: cannot find value `a` in this scope --> $DIR/format-args-capture-issue-102057.rs:2:18 | LL |     format!("x7Ba}"); |                  ^ not found in this scope error[E0425]: cannot find value `a` in this scope --> $DIR/format-args-capture-issue-102057.rs:4:18 | LL |     format!("x7Bax7D"); |                  ^ not found in this scope error[E0425]: cannot find value `b` in this scope --> $DIR/format-args-capture-issue-102057.rs:9:22 | LL |     format!("x7Ba} {b}"); |                      ^ help: a local variable with a similar name exists: `a` error[E0425]: cannot find value `b` in this scope --> $DIR/format-args-capture-issue-102057.rs:11:25 | LL |     format!("x7Bax7D {b}"); |                         ^ help: a local variable with a similar name exists: `a` error[E0425]: cannot find value `b` in this scope --> $DIR/format-args-capture-issue-102057.rs:13:25 | LL |     format!("x7Ba} x7Bb}"); |                         ^ help: a local variable with a similar name exists: `a` error[E0425]: cannot find value `b` in this scope --> $DIR/format-args-capture-issue-102057.rs:15:28 | LL |     format!("x7Bax7D x7Bb}"); |                            ^ help: a local variable with a similar name exists: `a` error[E0425]: cannot find value `b` in this scope --> $DIR/format-args-capture-issue-102057.rs:17:28 | LL |     format!("x7Bax7D x7Bbx7D"); |                            ^ help: a local variable with a similar name exists: `a` error: aborting due to 7 previous errors For more information about this error, try `rustc --explain E0425`. </ins>

I tried this code: I expected to see this happen: a "no value found" error pointing at the token Instead, this happened: a "no value found" error pointing at the : <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
This doesn't seem to be an issue on stable, interestingly.
Yep, it works fine on 1.63.0, but has the problem on 1.65.0-beta.1 and the latest nightly.
claim


Question: self.draw_line( &mut buffer, <del> &unannotated_line, </del> <ins> &replace_tabs(&unannotated_line), </ins> annotated_file.lines[line_idx + 1].line_index - 1, last_buffer_line_num, width_offset,

The code that truncates long lines doesn't take (hard) tabs into account, so the lines printed are off. Example code: Gives the following error: If you use four spaces instead of each tab it works as expected: cc and cc <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
I thought we were already accounting for tabs, but looking we rely on which considers to not have a width, which we then assume to be 1.
claim


Question: LifetimeRibKind::Item | LifetimeRibKind::AnonymousReportError | LifetimeRibKind::ElisionFailure => Some(LifetimeUseSet::Many), <del> // An anonymous lifetime is legal here, go ahead. LifetimeRibKind::AnonymousCreateParameter { .. } => { Some(LifetimeUseSet::One { use_span: ident.span, use_ctxt }) } </del> <ins> // An anonymous lifetime is legal here, and bound to the right // place, go ahead. LifetimeRibKind::AnonymousCreateParameter { binder: anon_binder, .. } => Some(if binder == anon_binder { LifetimeUseSet::One { use_span: ident.span, use_ctxt } } else { LifetimeUseSet::Many }), </ins> // Only report if eliding the lifetime would have the same // semantics. LifetimeRibKind::Elided(r) => Some(if res == r {

<!-- 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: explanation suggestion compiles: Instead, this happened: explanation Suggestion does not compile: ` <!-- 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. --:


Question: }; ExprKind::Cast { source } <ins> } else { // Default to `ExprKind::Cast` for all explicit casts. // MIR building then picks the right MIR casts based on the types. ExprKind::Cast { source: self.mirror_expr(source) } </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: it compiles, since raw pointer casts should be allowed even for completely different types. Instead, this happened: it fails with: It looks like for some reason the compiler creates a lifetime obligation here. Strangely, it works with : .
I've looked into this. The issue is that typeck considers this cast to be a "coercion cast", because typeck thinks that you could replace the function body with just since the types are the same (it also triggers the lint (allow-by-default)). HIR typeck isn't aware of lifetimes. So then THIR building and MIR building build MIR that doesn't contain a cast but instead just assigns one to the other. The borrow checker is rightfully not pleased. The bug here is that the THIR does not contain an explicit cast anymore. I'm not sure how to best fix this, as the current logic for "is this a no-op cast (called coercion cast in the code)" is just "try to coerce the types in the same way that happens on coercion sites and if it works it has to be useless". Which is wrong in the presence of lifetimes. It seems like the current strategy works this way because it reuses some code in THIR building. Thinking about it a little more, this is very special to pointer casts, because only pointer casts are allowed to change the type like this. Maybe THIR building should just special case pointer casts to always be emitted?
Unfortunately due to this bug there is that should be turned into a raw pointer cast, but we cannot.
I think that's a different case, these are boxes and not raw pointers, and box-box casts are not allowed to do arbitrary changes (and are in fact coercion casts, so the doesn't actually do anything). The error there is correct and this needs a transmute.
I'd like to replace the transmutes by raw pointer casts, which IMO is much preferable, similar to But this bug is in the way of that.


Question: <del> // check-pass </del> // aux-build:import_crate_var.rs #[macro_use] extern crate import_crate_var; fn main() { m!(); <del> //~^ WARN `$crate` may not be imported //~| NOTE `use $crate;` was erroneously allowed and will become a hard error </del> <ins> //~^ ERROR `$crate` may not be imported </ins> }

The warning was introduced in to avoid breakage from .
Presumably the next step is to make this an error by default.
Triage: Digging through all the linked issues is tough, and it's not clear to me exactly what this warning is or does. can you maybe elaborate a little?
This needs to be turned into an error, i.e. behave like basically:
Relevant code is here: Should be easy to turn that into and then do a crater run.


Question: ); // print the suggestion draw_col_separator(&mut buffer, row_num, max_line_num_len + 1); <del> buffer.append(row_num, line, Style::NoStyle); </del> <ins> buffer.append(row_num, &replace_tabs(line), Style::NoStyle); </ins> row_num += 1; }


Question: <ins> fn main() { let str::<{fn str() { let str::T>>::as_bytes; }}, T>::as_bytes; //~^ ERROR expected a pattern, found an expression //~| ERROR cannot find type `T` in this scope //~| ERROR type and const arguments are not allowed on builtin type `str` //~| ERROR expected unit struct, unit variant or constant, found associated function `str<, T>::as_bytes` } </ins>

<!-- ICE: Rustc '' 'error: internal compiler error: node HirId(DefId(0:32 ~ 787F2C645D84C34B503984769364221101FF5A50720AF027A7CACDC71EA4474E[c98a]::insideconstgenericarguments::{constant}::checktrybindstighter).22) (pat ) cannot be placed in TypeckResults with hirowner DefId(0:22 ~ 787F2C645D84C34B503984769364221101FF5A50720AF027A7CACDC71EA4474E[c98a]::insideconstgenericarguments)', 'error: internal compiler error: node HirId(DefId(0:32 ~ 787F2C645D84C34B503984769364221101FF5A50720AF027A7CACDC71EA4474E[c98a]::insideconstgenericarguments::{constant}::checktrybindstighter).22) (pat ) cannot be placed in TypeckResults with hirowner DefId(0:22 ~ 787F2C645D84C34B503984769364221101FF5A50720AF027A7CACDC71EA4474E[c98a]::insideconstgenericarguments)' File: --auto-reduced (treereduce-rust): <details<summary<strongoriginal code</strong</summary<poriginal: </p</detailsVersion 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: [typeck] type-checking [analysis] running analysis passes on this crate --
This bisects to cc


Question: use rustc_middle::mir::ConstraintCategory; use rustc_middle::traits::query::OutlivesBound; use rustc_middle::ty::{self, RegionVid, Ty}; <del> use rustc_span::{Span, DUMMY_SP}; </del> <ins> use rustc_span::{ErrorGuaranteed, Span, DUMMY_SP}; </ins> use rustc_trait_selection::traits::query::type_op::{self, TypeOp}; use std::rc::Rc; use type_op::TypeOpOutput;

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
Regression in cc :sweat_smile:
I knew this was a source of ICEs Most of these should already be reachable if they are in the body of a constant used in an array length. If you want to try fuzzing by sticking code into a const body...


Question: <ins> // Copyright 2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. fn blah() -> int { //~ ERROR not all control paths return a value 1i ; //~ NOTE consider removing this semicolon: } fn main() { } </ins>

Here is the error Here is the code that generates the error My system is x86_64 archlinux. The rust compiler version is Let me know if you guys need anything else. (The code is really short so it shouldn't be hard to just type it in to duplicate the bug)
It only needs one line for me
Workaround (in the sense that the compiler no longer ICE's): I think there is some unfortunate interaction here with the way we attempt to infer which kind of numeric literals are in the array (, , etc) and other code not being prepared to handle the that results when you don't have that information available.
This is almost certainly a duplicate of (but maybe the integer inference codepath is slightly different?).
This also causes the same ICE -
Similarly:
Looks like it's been fixed.


Question: <ins> // Copyright 2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. fn blah() -> int { //~ ERROR not all control paths return a value 1i ; //~ NOTE consider removing this semicolon: } fn main() { } </ins>

Swapping the order of the branches compiles fine. cc
Just checked: this fails with a normal closure too, not just a proc.
Compiles fine now but potentially needs a test.


Question: <ins> // Copyright 2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. fn blah() -> int { //~ ERROR not all control paths return a value 1i ; //~ NOTE consider removing this semicolon: } fn main() { } </ins>

Versions: Code to reproduce the ICE: Compilation output:
Seems to be fine now but potentially needs a test.
Nope, still failing. An updated example:
That code example fails to compile, but it's because the function signature for is wrong. It should be: When you make that change and make the struct fields public, the code compiles fine. Without the change I also didn't see any internal compiler errors. Rust Version: 0.12.0-pre-nightly, , Linux x8664
Yeah, I think this can be closed.
Flagging as needstest (not sure if one is checked in already)


Question: <ins> // Copyright 2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. fn blah() -> int { //~ ERROR not all control paths return a value 1i ; //~ NOTE consider removing this semicolon: } fn main() { } </ins>

It gives
cc
Looks like it no longer causes an ICE.
I agree, it is fixed, I close it.


Question: } fn test_argument_position(x: impl for<'a> Trait<'a, Assoc = impl Copy + 'a>) {} <del> //~^ ERROR `impl Trait` can only mention lifetimes bound at the fn or impl level </del> <ins> //~^ ERROR `impl Trait` can only mention lifetimes from an fn or impl </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
minimized
Bisected to :sweatsmile:


Question: let debugger_visualizers = stat!("debugger-visualizers", || self.encode_debugger_visualizers()); <del> // Encode exported symbols info. This is prefetched in `encode_metadata` so we encode // this as late as possible to give the prefetching as much time as possible to complete. </del> <ins> // Encode exported symbols info. This is prefetched in `encode_metadata`. </ins> let exported_symbols = stat!("exported-symbols", || { self.encode_exported_symbols(tcx.exported_symbols(LOCAL_CRATE)) });

<!-- 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
another one


Question: let debugger_visualizers = stat!("debugger-visualizers", || self.encode_debugger_visualizers()); <del> // Encode exported symbols info. This is prefetched in `encode_metadata` so we encode // this as late as possible to give the prefetching as much time as possible to complete. </del> <ins> // Encode exported symbols info. This is prefetched in `encode_metadata`. </ins> let exported_symbols = stat!("exported-symbols", || { self.encode_exported_symbols(tcx.exported_symbols(LOCAL_CRATE)) });

I just tried out the new parallelization feature of the compiler and it randomly panicked because a deadlock was detected. I tried a couple of times and could not reproduce it unfortunately. : <details<summary<strongBacktrace</strong</summary<p</p</details
Could you provide the minimal example causes the ICE?
The project I compiled was huge and I was not able to consistently reproduce it so reducing my case to a minimal example might take forever. Buy I noticed the issue you linked already contains a fairly small example code so it's probably alright to close my ticket since it seems to be a duplicate of that other ticket anyway.
Can you reproduce this bug using the latest nightly version to get the new error output?
Yes. It appears to be the same issue (albeit while compiling a different dependency but that probably doesn't matter):
BTW with the latest nightly the compiler always and immediately panics and produces multiple back traces. version: nightly-aarch64-apple-darwin unchanged - rustc 1.76.0-nightly ( 2023-12-05) <details<summarycompiler error</summary</details
It would be fixed by


Question: let debugger_visualizers = stat!("debugger-visualizers", || self.encode_debugger_visualizers()); <del> // Encode exported symbols info. This is prefetched in `encode_metadata` so we encode // this as late as possible to give the prefetching as much time as possible to complete. </del> <ins> // Encode exported symbols info. This is prefetched in `encode_metadata`. </ins> let exported_symbols = stat!("exported-symbols", || { self.encode_exported_symbols(tcx.exported_symbols(LOCAL_CRATE)) });

<!-- 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. --I have tried to measure on a 32 core machine and got this ice after several tries. Steps to reproduce: I have got it 2 times in a row, so it should be reproducible. <!-- 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. --:
searched nightlies: from nightly-2023-11-03 to nightly-2023-11-09 regressed nightly: nightly-2023-11-07 searched commit range: regressed commit: <details<summarybisected with <a href=''cargo-bisect-rustc</av0.6.7</summaryHost triple: x86_64-unknown-linux-gnu Reproduce with: </details
modify labels: +A-parallel-queries
modify labels: +WG-compiler-parallel
Can you reproduce this bug using the latest nightly version to get the new error output?
I can build rustc from the sources if you need to check something.
That's all right. It's a same error with other issues


Question: <ins> #![feature(optin_builtin_traits)] // Test for issue #56934 - that it is impossible to redundantly // implement an auto-trait for a trait object type that contains it. // Negative impl variant. auto trait Marker1 {} auto trait Marker2 {} trait Object: Marker1 {} // A supertrait marker is illegal... impl !Marker1 for dyn Object + Marker2 { }   //~ ERROR E0371 // ...and also a direct component. impl !Marker2 for dyn Object + Marker2 { }   //~ ERROR E0371 // But implementing a marker if it is not present is OK. impl !Marker2 for dyn Object {} // OK // A non-principal trait-object type is orphan even in its crate. impl !Send for dyn Marker2 {} //~ ERROR E0117 // And impl'ing a remote marker for a local trait object is forbidden // by one of these special orphan-like rules. impl !Send for dyn Object {} //~ ERROR E0321 impl !Send for dyn Object + Marker2 {} //~ ERROR E0321 fn main() { } </ins>

Code gives the same error as , giving (dyn Xyz + Abc + 'static)XyzCode passes coherence, but wfcheck fails because of the confusion:


Question: /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn lock(&self) -> StdoutLock<'_> { <ins> self.lock_any() } // Locks this handle with any lifetime. This depends on the // implementation detail that the underlying `ReentrantMutex` is // static. fn lock_any<'a>(&self) -> StdoutLock<'a> { </ins> StdoutLock { inner: self.inner.lock() } } <ins> /// Consumes this handle to the standard output stream, locking the /// shared global buffer associated with the stream and returning a /// writable guard. /// /// The lock is released when the returned lock goes out of scope. The /// returned guard also implements the [`Write`] trait for writing data. /// /// It is often simpler to directly get a locked handle using the /// [`io::stdout_locked`] function instead, unless nearby code also /// needs to use an unlocked handle. /// /// # Examples /// /// ```no_run /// #![feature(stdio_locked)] /// use std::io::{self, Write}; /// /// fn main() -> io::Result<()> { ///     let mut handle = io::stdout().into_locked(); /// ///     handle.write_all(b"hello world")?; /// ///     Ok(()) /// } /// ``` #[unstable(feature = "stdio_locked", issue = "none")] pub fn into_locked(self) -> StdoutLock<'static> { self.lock_any() } </ins> } #[stable(feature = "std_debug", since = "1.16.0")]

Given the following code: The current output is: I think it's typical for a newcomer to want to get a iterator by chaining method calls like . There's no obvious reason why that shouldn't work. The examples in the documentation do typically show being assigned to a variable prior to calling its method, but don't explain why that's necessary. I think the "borrow" terminology is misleading, but there might not be a concise way to describe what's actually going on to the user. The "temporary value is freed at the end of this statement" is probably correct. The "creates a temporary which is freed while still in use" is probably more correctly "creates a temporary that is required to outlive (or live exactly as long as) the result of...", followed by a pointer to the method invocation, with text of " method call". Maybe it should also point out the lifetime argument in the return type. I tried and failed to find a satisfactory explanation of what exactly was borrowing from the temporary value produced by . When I looked through the library source code, the only references in were those created by locking a , and the in question is static. I'm guessing the existence of a borrow is assumed rather than inferred from analyzing the function body of . The assumption might be the result of the anonymous lifetime argument on the output type from , which imposes a requirement that the doesn't outlive (or has the same lifetime as?) the value that is the receiver of . The correct fix might be to change the locked stdin handles to all use lifetimes, but I will probably file that as a separate issue.
label +A-borrow-checker +A-lifetimes +D-confusing +D-incorrect +D-newcomer-roadblock
IMO the intent is clear here. Without changing the API, why exactly is Rust unable to lift 'a &'static X to 'static & 'static X, if X also contains only 'static lifetimes? I don't think raw references have a meaningful dropper; borrowck is able to freely resolve any derived lifetimes on impls that don't depend on anything else to 'static; I'm pretty sure under current rules we should be able to substitute latter for earlier and get exactly the same behaviour.
This is due to .


Question: /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn lock(&self) -> StdoutLock<'_> { <ins> self.lock_any() } // Locks this handle with any lifetime. This depends on the // implementation detail that the underlying `ReentrantMutex` is // static. fn lock_any<'a>(&self) -> StdoutLock<'a> { </ins> StdoutLock { inner: self.inner.lock() } } <ins> /// Consumes this handle to the standard output stream, locking the /// shared global buffer associated with the stream and returning a /// writable guard. /// /// The lock is released when the returned lock goes out of scope. The /// returned guard also implements the [`Write`] trait for writing data. /// /// It is often simpler to directly get a locked handle using the /// [`io::stdout_locked`] function instead, unless nearby code also /// needs to use an unlocked handle. /// /// # Examples /// /// ```no_run /// #![feature(stdio_locked)] /// use std::io::{self, Write}; /// /// fn main() -> io::Result<()> { ///     let mut handle = io::stdout().into_locked(); /// ///     handle.write_all(b"hello world")?; /// ///     Ok(()) /// } /// ``` #[unstable(feature = "stdio_locked", issue = "none")] pub fn into_locked(self) -> StdoutLock<'static> { self.lock_any() } </ins> } #[stable(feature = "std_debug", since = "1.16.0")]

is declared as follows: Because there is only one input lifetime (the elided lifetime of ), it is assigned to the output lifetime , which is why the lock can live at most as long as the temporary.
Thanks. I think this might be a bug in libstd (using instead of as the return type), but I'll file that separately. What I think is a diagnostic inaccuracy is that the error message refers to a borrow, when, by inspection of the library source code, no borrow is taking place in . (Unless I'm missing something?) What I think is happening is that the compiler is enforcing that lives no longer than the temporary produced by , and is misleadingly calling that a borrow in the error message.
As a simplified example: The error message refers to a borrow even when the output type of does not refer to at all!
that's because of the elision rules: on the declaration you're implicitly telling the compiler that the lifetime of the borrow matches the lifetime of the type. .
Thanks. I think the error messages could use a little more detail about how something that the borrow checker sees as a borrow may be an artifact of lifetime constraints in a function signature rather than an actual borrow in the function body. It certainly surprised me the first time I ran into it. (Maybe only in the explanatory text in the compiler error index. It looks like E0597 could also benefit from that detail, because it's a similar case, and an example in E0716 produces E0597.)
Shorter example, probably better suited for an example in the compiler error index:


Question: pub fn print_tts(&mut self, tts: &[ast::TokenTree]) -> IoResult<()> { try!(self.ibox(0)); <ins> let mut suppress_space = false; </ins> for (i, tt) in tts.iter().enumerate() { <del> if i != 0 { </del> <ins> if i != 0 && !suppress_space { </ins> try!(space(&mut self.s)); } try!(self.print_tt(tt)); <ins> // There should be no space between the module name and the following `::` in paths, // otherwise imported macros get re-parsed from crate metadata incorrectly (#20701) suppress_space = match tt { &ast::TtToken(_, token::Ident(_, token::ModName)) | &ast::TtToken(_, token::MatchNt(_, _, _, token::ModName)) | &ast::TtToken(_, token::SubstNt(_, token::ModName)) => true, _ => false } </ins> } self.end() }

Macro definitions encoded to the metadata do not preserve the identifier style, thus certain paths break down.
Nice catch. I was afraid something like this would happen... Really a bug in pretty printing, as it doesn't preserve the ident style. This is what we get for hacking contextual lexer information into the token stream...
The original example now compiles fine, but then I'm not sure about tomaka/android-rs-glue. is this issue still relevant?
I didn't test myself, but reported that it's fixed.
Yeah it looks like this has been fixed, yay!


Question: hir_analysis_invalid_union_field_sugg = wrap the field type in `ManuallyDrop<...>` <ins> hir_analysis_late_bound_const_in_apit = `impl Trait` can only mention const parameters from an fn or impl .label = const parameter declared here hir_analysis_late_bound_lifetime_in_apit = `impl Trait` can only mention lifetimes from an fn or impl .label = lifetime declared here hir_analysis_late_bound_type_in_apit = `impl Trait` can only mention type parameters from an fn or impl .label = type parameter declared here </ins> hir_analysis_lifetimes_or_bounds_mismatch_on_trait = lifetime parameters or bounds on {$item_kind} `{$ident}` do not match the trait declaration .label = lifetimes do not match {$item_kind} in trait


Question: } key!(is_builtin, bool); <del> key!(endian = "target_endian"); key!(c_int_width = "target_c_int_width"); </del> <ins> key!(endian = "target-endian"); key!(c_int_width = "target-c-int-width"); </ins> key!(os); key!(env); key!(vendor);

Hello everyone, this is my first Issue on the Rust project, let me know if I'm doing anthing wrong ! I am in the process of building a library/runtime for the Wii fully written in Rust. To acheive this goal, I need to cross-compile my library to a custom target I named . The json file contains and along other lines to define the architecture. Normally, the build completes without an issue. On the latest nighlty, the compiler fails and return: Of course, is set to in the file, so this shouldn't happen. It most recently worked on: : It fails on this nightly, currently latest at the time of writing: : I can provide any file or other precision if necessary ! Thanks for reading my report !
I was also having the some issue and tracked it to this: That commit broke the equivalence between "target_endian" and "target-endian" by adding a case to the macro without the replace line for it.
cc
I'll fix this today.
Fixed in
I hope this gets merged asap :-)
(Reopening because isn't merged yet.)


Question: LL |     let _: &dyn const Trait; |                 ^^^^^^^^^^^ <del> error: aborting due to 1 previous error </del> <ins> error: `~const` is not allowed here --> $DIR/const-trait-bounds-trait-objects.rs:9:17 | LL |     let _: &dyn ~const Trait; |                 ^^^^^^ | = note: trait objects cannot have `~const` trait bounds error: const trait bounds are not allowed in trait object types --> $DIR/const-trait-bounds-trait-objects.rs:14:25 | LL | const fn handle(_: &dyn const NonConst) {} |                         ^^^^^^^^^^^^^^ error: `~const` is not allowed here --> $DIR/const-trait-bounds-trait-objects.rs:16:23 | LL | const fn take(_: &dyn ~const NonConst) {} |                       ^^^^^^ | = note: trait objects cannot have `~const` trait bounds error: aborting due to 4 previous errors </ins>

<!-- ICE: Rustc '' 'thread 'rustc' panicked at 'assertion failed'', 'thread 'rustc' panicked at 'assertion failed'' 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: [fnsig] computing function signature of [collectmoditemtypes] collecting item types in top-level module [analysis] running analysis passes on this crate --
bisects to


Question: without modifying the original"] #[stable(feature = "unicode_case_mapping", since = "1.2.0")] pub fn to_uppercase(&self) -> String { <del> let out = convert_while_ascii(self.as_bytes(), u8::to_ascii_uppercase); // Safety: we know this is a valid char boundary since // out.len() is only progressed if ascii bytes are found let rest = unsafe { self.get_unchecked(out.len()..) }; // Safety: We have written only valid ASCII to our vec let mut s = unsafe { String::from_utf8_unchecked(out) }; </del> <ins> let (mut s, rest) = convert_while_ascii(self, u8::to_ascii_uppercase); </ins> for c in rest.chars() { match conversions::to_upper(c) {

I'm looking into the performance of / on mostly ascii strings, using a small microbenchmark to . Using linux perf tooling I see that the hot part of the code is the following large loop, which despite heavy use of sse2 instructions only seems to process 32 bytes per iteration. I don't see an easy way to improve the autovectorization of this code, but it should be relatively easy to explicitly vectorize it using , and I would like to prepare such a PR if there are no objections. As far as I know, is already in use inside , for example by .
The way the loop ors the bits for the is-ascii check into a single usize doesn't seem ideal for vectorization. keeping the lanes independent should yield better autovectorization results.
Thanks for the suggestion. I already started with a simd implementation, but now checked again if the autovectorization could be improved. With the following main loop The assembly and performance is indeed better, but there is still some weird shuffling and shifting going on: The explicit simd version looks a bit better, mostly because the ascii check directly translates to a : Do you have a preference here between autovectorization and explicit simd?
If the SIMD impl results in reasonable code across architectures, including some without SIMD then that should be fine. I think it would be the first time where we use portable simd unconditionally, so it could use some additional scrutiny. If it's only meant to target x86 with SSE2 then that'd mean having multiple paths and in that case we'd still have to tweak the generic path anyway. At that point we might as well just optimize the latter further. You can probably get rid of those too by keeping multiple bools in a small array. That way the optimizer will more easily see that it can shove them into independent simd lanes. Increasing the unroll count might help too to fit better into simd registers. We do get pretty decent autovectorization in other places in the standard library by massaging things into a state that basically looks like arrays-instead-of-SIMD-types. E.g.
It seems llvm is too "smart" for this trick, on its own that generates the exact same code. The trick does work, although it seems a bit fragile.


Question: without modifying the original"] #[stable(feature = "unicode_case_mapping", since = "1.2.0")] pub fn to_uppercase(&self) -> String { <del> let out = convert_while_ascii(self.as_bytes(), u8::to_ascii_uppercase); // Safety: we know this is a valid char boundary since // out.len() is only progressed if ascii bytes are found let rest = unsafe { self.get_unchecked(out.len()..) }; // Safety: We have written only valid ASCII to our vec let mut s = unsafe { String::from_utf8_unchecked(out) }; </del> <ins> let (mut s, rest) = convert_while_ascii(self, u8::to_ascii_uppercase); </ins> for c in rest.chars() { match conversions::to_upper(c) {

The following creates a instruction just like the simd version, but a slightly different alternative with a array and comparing against 0 does not. It only needs to be better than the autovectorized version on those platforms ;) My initial idea was to gate the simd code on either SSE2 or Neon (possibly also Altivec and RiscV). I'd also add a scalar loop for the non-multiple-of-N remainder, so all-ascii strings are fully handled by specialized code. Currently this remainder goes through the generic and code path. On other platforms, only the scalar loop would be used, since I assume the autovectorization would also generate suboptimal code. But I agree that if similar code quality can be achieved with autovectorization, that would be preferable. I'll open a PR after a little bit more polishing the code.


Question: t1.next().is_none() && t2.next().is_none() } <ins> // See comments in `interpolated_to_tokenstream` for why we care about // *probably* equal here rather than actual equality // // This is otherwise the same as `eq_unspanned`, only recursing with a // different method. pub fn probably_equal_for_proc_macro(&self, other: &TokenStream) -> bool { let mut t1 = self.trees(); let mut t2 = other.trees(); for (t1, t2) in t1.by_ref().zip(t2.by_ref()) { if !t1.probably_equal_for_proc_macro(&t2) { return false; } } t1.next().is_none() && t2.next().is_none() } </ins> /// Precondition: `self` consists of a single token tree. /// Returns true if the token tree is a joint operation w.r.t. `proc_macro::TokenNode`. pub fn as_tree(self) -> (TokenTree, bool /* joint? */) {

This is minimized from the dramatic forum thread . The following code is fine in nightly-2018-04-12 but breaks with nightly-2018-04-15. Oddly, lots of minor perturbations make it succeed. For example remove the two characters and it works. Or remove the single quote in the string and it works.
Alrighty-roo. As everything these days with hygiene, there's a couple of bugs here. With this one though I think only two! Everything has to do here with basically. AKA anything that runs through that falls off The usual reasons we think you fall off the "happy path" are due to things like inner attributes, , macro expansion, etc. None of that's present here! It should be the case that above can be losslessly converted to a based on what we've cached. Turns out though had a bug in it (surprise surprise!). There we're using to compare the resulting two token streams which eventually bottoms out in . As it turns out this isn't quite what we want! The implementation is structural, but the token stream we get when stringifying is slightly different than what we parsed. Here in the example you're using the literal string , but rustc stringifies this token as . Similarly if you replaced the string with something like it'll be stringified as . This means that the tokens are not literally byte-for-byte equal, which means we fall off the happy path! tl;dr the token stream of is not equivalent to the token stream . This causes us to fall off the happy path and used a stringified token stream. OK so in the case above we're falling off the happy path when we didn't expect to, but even still there's some weird bad hygiene behavior when we're not on the happy path. There's still something to fix! It turns out that there's also a regression due to (found via bisection). Before that PR this example would compile just fine, afterwards though it's hitting this error. can you help diagnose this and see what's going on? The reduced test case I have right now is: (note the inner attribute on to force using a non-cached token stream)
I've posted a fix for the "happy path" at will actually fix example above.


Question: t1.next().is_none() && t2.next().is_none() } <ins> // See comments in `interpolated_to_tokenstream` for why we care about // *probably* equal here rather than actual equality // // This is otherwise the same as `eq_unspanned`, only recursing with a // different method. pub fn probably_equal_for_proc_macro(&self, other: &TokenStream) -> bool { let mut t1 = self.trees(); let mut t2 = other.trees(); for (t1, t2) in t1.by_ref().zip(t2.by_ref()) { if !t1.probably_equal_for_proc_macro(&t2) { return false; } } t1.next().is_none() && t2.next().is_none() } </ins> /// Precondition: `self` consists of a single token tree. /// Returns true if the token tree is a joint operation w.r.t. `proc_macro::TokenNode`. pub fn as_tree(self) -> (TokenTree, bool /* joint? */) {

That PR does not, however, fix the regression from which is still reproducible with the example I gisted.
Any idea why my repro case above is fixed if you remove the tokens? It seems like should fall off the happy path just as much.
If you remove the tokens we're still on the stringification path (aka not the happy path). For whatever reason though the hygiene bug goes away. That's likely caused from a subtelty introduced in (or at least so I'm hoping). I don't know much about , so I'm hoping will be able to look at this and know what's going on!
I don't know much about , so I'm hoping will be able to look at this and know what's going on! I'll investigate.
is the commit causing the regression. Further investigation is in progress.
An issue recently popped up on Rocket () that appears to be identical to this one and is not resolved in any recent nightly. It's possible that the root cause is , however.


Question: impl EmptyTrait2 for HasEmptyTraits {} #[doc(cfg(feature = "some-feature"))] impl EmptyTrait3 for HasEmptyTraits {} <ins> mod macros; pub use macros::*; </ins>

Hey! Ran into what appears to be a bug - crate's exported macros each appear twice in the left sidebar: ! Toolchain versions (per log): rustc 1.60.0-nightly ( 2022-02-09), docsrs 0.6.0 ( 2022-02-01) Please let me know if I can provide additional info.
Thank you for the report! This is definitely not an issue with itself, but with rustdoc. is this known? Should a rustdoc issue be created?
Not known afaik. Please do file an issue (or transfer this one)!
Seems similar to
Thanks for transferring the issue. One difference between this and - both macros are exported using a wildcard in crate root (not rename):
Well, just another reexport issue. It's common around here. :laughing: I'll try to take a look in the next days.
This is what I have on currently nightly: ! So I guess it's fixed?
Trying locally with the latest nightly (, more current than that of issue open) I get the same initial landing page for but if I click on one of the macros listed (e.g. "drill down") duplicates still appear on the sidebar: ! So the tiny bug is still there, just deeper/hidden on the latest nightly?
Ah indeed! I can also reproduce it now. Will take another look tomorrow then.


Question: <ins> // This test ensures that there is no macro duplicates in the sidebar. goto: file://|DOC_PATH|/test_docs/macro.a.html // Waiting for the elements in the sidebar to be rendered. wait-for: ".sidebar-elems .others .macro" // Check there is only one macro named "a" listed in the sidebar. assert-count: ( "//*[@class='sidebar-elems']//*[@class='others']/*[@class='block macro']//li/a[text()='a']", 1, ) // Check there is only one macro named "b" listed in the sidebar. assert-count: ( "//*[@class='sidebar-elems']//*[@class='others']/*[@class='block macro']//li/a[text()='b']", 1, ) </ins>


Question: let parent = tcx.map.get_parent(param.id); <del> if space != TypeSpace && default.is_some() { </del> <ins> if !allow_defaults && default.is_some() { </ins> if !tcx.sess.features.borrow().default_type_parameter_fallback { tcx.sess.add_lint( lint::builtin::INVALID_TYPE_PARAM_DEFAULT,

If I understand correctly, type parameter defaults have no effect in the block . Just like in PR , this should have a warning and then an error. Example cc
Argh, I guess I failed to cover those?
Nominating for triage.
triage: P-high


Question: <ins> // force-host // no-prefer-dynamic #![crate_type = "proc-macro"] extern crate proc_macro; use proc_macro::TokenStream; #[proc_macro_derive(ICE)] pub fn derive(_: TokenStream) -> TokenStream { r#"#[allow(missing_docs)] struct X { }"#.parse().unwrap() } </ins>

<!-- 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. --I encountered an ICE while incorrectly inserting a outer attribute above deriving or inside of a proc-macro. This did not happen with any other derive I tried. <!-- 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
can you please also provide the configuration to reproduce an for your issue? thanks
Sure, sorry for forgetting, here is the mcve: But incase you dont want to see the entire project the for the macro was just: And the of the project to use the macro (and trigger the ICE) was:
Cool, thank you! Here's the result of a bisection: seems to point to PR cc searched nightlies: from nightly-2021-01-01 to nightly-2021-08-11 regressed nightly: nightly-2021-04-12 searched commits: from to regressed commit: <details<summarybisected with <a href=''cargo-bisect-rustc</av0.6.0</summaryHost triple: x86_64-unknown-linux-gnu Reproduce with: </details
Assigning priority as discussed in the of the Prioritization Working Group. label -I-prioritize +P-medium


Question: //~^^^ ERROR: function takes 1 generic argument but 2 generic arguments were supplied //~^^^^ ERROR: unconstrained generic constant //~^^^^^ ERROR: unconstrained generic constant `{const expr}` <ins> //~^^^^^^ ERROR: unconstrained generic constant `{const expr}` </ins> } fn main() {}

we should change the following function to use a instead of Using a walker causes the control-flow to be a lot more complicated and given that this code is soundness-critical, we should make sure it's as easy to understand as possible <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim


Question: }); if check_params && let Some(args) = path.segments.last().unwrap().args { let params_in_repr = tcx.params_in_repr(def_id); <del> for (i, arg) in args.args.iter().enumerate() { </del> <ins> // the domain size check is needed because the HIR may not be well-formed at this point for (i, arg) in args.args.iter().enumerate().take(params_in_repr.domain_size()) { </ins> if let hir::GenericArg::Type(ty) = arg && params_in_repr.contains(i as u32) { find_item_ty_spans(tcx, ty, needle, spans, seen_representable); }

<details<summary<strongFull output including backtrace</strong</summary<p</p</detailsRegression from () <details<summaryBisection details</summarybisected with <a href=''cargo-bisect-rustc</av0.6.4 searched nightlies: from nightly-2022-10-06 to nightly-2022-10-28 regressed nightly: nightly-2022-10-09 searched commit range: regressed commit: Host triple: x8664-apple-darwin </details<!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOT_END --
this function call crash for the assertion fail, from the log, is with count = 1, and is also 1 when crashing. Do you have any clue? is implemented at here, I'm still not quite familar with the query part:
It looks like the parens are parsed as generic parameters for a type that doesn't have generic parameters? The simple fix is just check .
I think a reasonable fix is modifying the API for , It reasonable to add assertion for , but it's better to return false for outside of expected range?
Have a test on C++'s , which also has this assertion: emm, it's better to keep it for .
claim
I'd be curious to know if we can maintain an invariant in the HIR that it does not contain generics that do not align with . That was what I assumed when writing that code, but that may be too optimistic.
I considered removing the assert too, but I think it's better to have it since it exposes invalid assumptions as in this case.
We should (replacing the assertion) -- that's probably fine as long as it's understood why the does not line up here, and it's understood why we can't fix it somewhere upstream (e.g. in parsing or lowering instead)
I have a general question for , why we just exit when we find a fatal error in parsing (which can not recover by simply autofix).


Question: }); if check_params && let Some(args) = path.segments.last().unwrap().args { let params_in_repr = tcx.params_in_repr(def_id); <del> for (i, arg) in args.args.iter().enumerate() { </del> <ins> // the domain size check is needed because the HIR may not be well-formed at this point for (i, arg) in args.args.iter().enumerate().take(params_in_repr.domain_size()) { </ins> if let hir::GenericArg::Type(ty) = arg && params_in_repr.contains(i as u32) { find_item_ty_spans(tcx, ty, needle, spans, seen_representable); }

I have a real Dev experience when working on , I was editing an file with 3k+ lines of code, and I forgetted remove an extra '{', then the compiler give about 20+ errors, the first two are from parsing: But there are many many other errors from later phases... I need to scroll up several pages to the beginning of error to find the rootcause.
If we can not get valid AST in parsing, later phases such as analysising will report out extra (mostly unhelpful) errors?
The assertion is inside of the data structure. I generally expect data structures to simply assert on pre-conditions. We could put a delay-bug before the call, but that also seems like overkill since that is already on the error-reporting path. I agree there are cases where rustc should quit sooner. But in general I think we have to err on the side of recover-and-continue if there is some possibility that more helpful errors may be emitted.
This can happen. The parser should be more realistic on what it recovers and avoid errors from later passes that do not make sense. A few years back we would stop as soon as any error occurred in a given pass and avoid trying any further evaluation, and that was also a usability issue, because people would get a false sense of "how much work is left to fix". We shouldn't have a blanket evaluation stop, but maybe be more aggressive about pruning the AST when multiple parse errors have occurred.
do you want to take over this issue? I currently don't have any clue about the rootcause. Or we give it an simple fix now.
I can take a look.


Question: builder.info(&format!("Assembling stage{} compiler ({})", stage, host)); // Link in all dylibs to the libdir <ins> let stamp = librustc_stamp(builder, build_compiler, target_compiler.host); let proc_macros = builder .read_stamp_file(&stamp) .into_iter() .filter_map(|(path, dependency_type)| { if dependency_type == DependencyType::Host { Some(path.file_name().unwrap().to_owned().into_string().unwrap()) } else { None } }) .collect::<HashSet<_>>(); </ins> let sysroot = builder.sysroot(target_compiler); let rustc_libdir = builder.rustc_libdir(target_compiler); t!(fs::create_dir_all(&rustc_libdir)); let src_libdir = builder.sysroot_libdir(build_compiler, host); for f in builder.read_dir(&src_libdir) { let filename = f.file_name().into_string().unwrap(); <del> if is_dylib(&filename) { </del> <ins> if is_dylib(&filename) && !proc_macros.contains(&filename) { </ins> builder.copy(&f.path(), &rustc_libdir.join(&filename)); } }

do you have the component installed? That adds a bunch more crates to the sysroot.
I believe these are required in rustc-dev as part of the need for (). I'll admit, I still don't fully understand the need for that, as it is quite mind-bending.
They are included in both rustc component and rustc-dev component. The latter are definitely used for example to build clippy, but I don't see reason for inclusion in rustc.


Question: <ins> // Copyright 2017 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. struct A; impl A { fn take_mutably(&mut self) {} } fn identity<T>(t: T) -> T { t } // Issue 46095 // Built-in indexing should be used even when the index is not // trivially an integer // Overloaded indexing would cause wrapped to be borrowed mutably fn main() { let mut a1 = A; let mut a2 = A; let wrapped = [&mut a1, &mut a2]; { wrapped[0 + 1 - 1].take_mutably(); } { wrapped[identity(0)].take_mutably(); } } </ins>

Hello, today we've found some weird behaviour of array indexing. Here is the Code snippet: The question is, why is the indexing operator behaves depending on whether we evaluate in place or not.
Highly related question :
Moreover, does not compile too.
points to this being a difference in how builtin indexing works vs overloaded indexing. My cleaned up version of the transcript: Highly related to , which will cause these types of situations to occur more frequently.
As a workaround, you can write an explicit type of which will then allow builtin indexing to happen:


Question: <ins> // Copyright 2017 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. struct A; impl A { fn take_mutably(&mut self) {} } fn identity<T>(t: T) -> T { t } // Issue 46095 // Built-in indexing should be used even when the index is not // trivially an integer // Overloaded indexing would cause wrapped to be borrowed mutably fn main() { let mut a1 = A; let mut a2 = A; let wrapped = [&mut a1, &mut a2]; { wrapped[0 + 1 - 1].take_mutably(); } { wrapped[identity(0)].take_mutably(); } } </ins>

It appears that when it's not obvious the index type is , we fall back to overloaded indexing: Fails in constant checking, : And also with the new MIR-based constant checker, :


Question: code_offset: usize, margin: Margin, ) { <ins> // Tabs are assumed to have been replaced by spaces in calling code. assert!(!source_string.contains('t')); </ins> let line_len = source_string.len(); // Create the source line we will highlight. let left = margin.left(line_len);

The code that truncates long lines doesn't take (hard) tabs into account, so the lines printed are off. Example code: Gives the following error: If you use four spaces instead of each tab it works as expected: cc and cc <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
I thought we were already accounting for tabs, but looking we rely on which considers to not have a width, which we then assume to be 1.
claim


Question: // #55810: Type check patterns first so we get types for all bindings. let scrut_span = scrut.span.find_ancestor_inside(expr.span).unwrap_or(scrut.span); for arm in arms { <del> self.check_pat_top(&arm.pat, scrutinee_ty, Some(scrut_span), true); </del> <ins> self.check_pat_top(&arm.pat, scrutinee_ty, Some(scrut_span), Some(scrut)); </ins> } // Now typecheck the blocks.

<!-- 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. If you cannot produce a minimal reproduction case (something that would work in isolation), please provide the steps or even link to a repository that causes the problematic output to occur. --Given the following code: The current output is: <!-- The following is not always necessary. --Ideally the output should suggest to the user that they need to initialize the enum variant's value in order to use the . <!-- If the problem is not self-explanatory, please provide a rationale for the change. --<!-- If dramatically different output is caused by small changes, consider also adding them here. 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. The output might also be different depending on the Edition. --<!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
Can you give the output of what it should look like?
It should probably look similar to the suggestion given for and So I guess sth. like: Edit: Or instead of saying “to instantiate this tuple variant” we could say “to call this function” like it's done for the erroneous snippet (where is a ).
claim
commit the fix


Question: <ins> // GVN may create indirect constants with higher alignment than their type requires. Verify that we // do not ICE during codegen, and that the LLVM constant has the higher alignment. // // compile-flags: -Zmir-opt-level=0 -Zmir-enable-passes=+GVN // compile-flags: -Cno-prepopulate-passes // only-64bit struct S(i32); struct SmallStruct(f32, Option<S>, &'static [f32]); // CHECK: @0 = private unnamed_addr constant // CHECK-SAME: , align 8 fn main() { // CHECK-LABEL: @_ZN20overaligned_constant4main // CHECK: [[full:%_.*]] = alloca %SmallStruct, align 8 // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[full]], ptr align 8 @0, i64 32, i1 false) // CHECK: %b.0 = load i32, ptr @0, align 4, // CHECK: %b.1 = load i32, ptr getelementptr inbounds ({ i32, i32 }, ptr @0, i32 0, i32 1), align 4 let mut s = S(1); s.0 = 3; // SMALL_VAL corresponds to a MIR allocation with alignment 8. const SMALL_VAL: SmallStruct = SmallStruct(4., Some(S(1)), &[]); // In pre-codegen MIR: // `a` is a scalar 4. // `b` is an indirect constant at `SMALL_VAL`'s alloc with 0 offset. // `c` is the empty slice. // // As a consequence, during codegen, we create a LLVM allocation for `SMALL_VAL`, with // alignment 8, but only use the `Option<S>` field, at offset 0 with alignment 4. let SmallStruct(a, b, c) = SMALL_VAL; } </ins>

Error: That's this: The GVN MIR diff is this: searched nightlies: from nightly-2023-06-01 to nightly-2023-11-08 regressed nightly: nightly-2023-10-30 searched commit range: regressed commit: <details<summarybisected with <a href=''cargo-bisect-rustc</av0.6.7</summaryHost triple: x86_64-unknown-linux-gnu Reproduce with: </details
This issue is a bit old but I've now minimized the reproducer, it's in the description. the assertion that's failing here looks to me like it is simply too picky, and it should be checking if the alignment of the allocation is the alignment of the type we're reading from it, instead of exactly equal. Do you agree that this is just a too-picky assertion?
I agree the assertion is just too picky. I expect the subtlety of needing to pass the larger alignment for the llvm constant.
I can't figure out what you mean here. What LLVM constant? Why is there subtelty? Maybe I just don't understand what's going on with GVN here, I'm assuming that GVN has merged two constants together so that we're now loading part of a more-aligned constant to get a less-aligned one. Is that wrong?
I mean, this is codegen code. It creates a constant for llvm. That constant has some alignment. We need to pick the right one, between the lhs and rhs of the assert.
Where are we picking an alignment? Is it down here?
smaller repro: <!-- ICE: Rustc '-Zmir-opt-level=5 -Cdebuginfo=2 -ooutputfile -Zdump-mir-dir=dir' 'thread 'rustc' panicked at 'assertion failed'', 'thread 'rustc' panicked at 'assertion failed'' File: --auto-reduced (treereduce-rust): <details<summary<strongoriginal code</strong</summary<poriginal: </p</detailsVersion 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: --
I don't really know.


Question: <ins> // GVN may create indirect constants with higher alignment than their type requires. Verify that we // do not ICE during codegen, and that the LLVM constant has the higher alignment. // // compile-flags: -Zmir-opt-level=0 -Zmir-enable-passes=+GVN // compile-flags: -Cno-prepopulate-passes // only-64bit struct S(i32); struct SmallStruct(f32, Option<S>, &'static [f32]); // CHECK: @0 = private unnamed_addr constant // CHECK-SAME: , align 8 fn main() { // CHECK-LABEL: @_ZN20overaligned_constant4main // CHECK: [[full:%_.*]] = alloca %SmallStruct, align 8 // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[full]], ptr align 8 @0, i64 32, i1 false) // CHECK: %b.0 = load i32, ptr @0, align 4, // CHECK: %b.1 = load i32, ptr getelementptr inbounds ({ i32, i32 }, ptr @0, i32 0, i32 1), align 4 let mut s = S(1); s.0 = 3; // SMALL_VAL corresponds to a MIR allocation with alignment 8. const SMALL_VAL: SmallStruct = SmallStruct(4., Some(S(1)), &[]); // In pre-codegen MIR: // `a` is a scalar 4. // `b` is an indirect constant at `SMALL_VAL`'s alloc with 0 offset. // `c` is the empty slice. // // As a consequence, during codegen, we create a LLVM allocation for `SMALL_VAL`, with // alignment 8, but only use the `Option<S>` field, at offset 0 with alignment 4. let SmallStruct(a, b, c) = SMALL_VAL; } </ins>

TBH, the simplest solution is a codegen test, and check that the generated constant has the right over-alignment.
I don't have confidence in my ability to do that, so I think it would unblock you faster if you took this issue. I feel like just this diff is a fix for this ICE: But I don't understand why the assertion was exact in the first place, or what the hazard would be from over-aligning the allocation.


Question: <ins> // revisions: cfail #![feature(const_generics, const_evaluatable_checked)] #![allow(incomplete_features)] // regression test for #79251 #[derive(Debug)] struct Node<K, const D: usize> where SmallVec<K, { D * 2 }>: , { keys: SmallVec<K, { D * 2 }>, } impl<K, const D: usize> Node<K, D> where SmallVec<K, { D * 2 }>: , { fn new() -> Self { panic!() } #[inline(never)] fn split(&mut self, i: usize, k: K, right: bool) -> Node<K, D> { let mut node = Node::new(); node.keys.push(k); //~^ error: no method named node } } #[derive(Debug)] struct SmallVec<T, const D: usize> { data: [T; D], } impl<T, const D: usize> SmallVec<T, D> { fn new() -> Self { panic!() } } fn main() {} </ins>

<!-- 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. --I'm creating this issue mainly because it seems to be a different one than the ones listed in <!-- 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
What command are you running? I tried this code , but I encountered an error that doesn't have a method.
how strange, for me just causes the ice and it doesn't even come to notice that the function is missing. I just ran , and with the newest rustc () I still get the same error as above (in a new cargo project with the code copied from the playground link above).
Just ran again today and still get an ICE. Made the example a bit smaller: Output of (build also fails with the same message): Considering the rustc versions it should be the same that is currently on the playground, however there it does not cause an ICE. Maybe someone could try to reproduce this in a local environment?
can reproduce this locally, not sure why it doesn't ICE on the playground
cc -- it ICEs locally, but not on the playground
Try with ?
That indeed removes the ICE, let me just check which one of the options it is. Adding to the (or profile.release in release mode) section causes the ice to disappear.
That's even weirder. Seems like this is partly an incr-comp bug then.
Note that the ICE occurs in the incr-comp hasher (ICH): So this seems to be an incr-comp bug.
Reposting : So I removed .


Question: <ins> // revisions: cfail #![feature(const_generics, const_evaluatable_checked)] #![allow(incomplete_features)] // regression test for #79251 #[derive(Debug)] struct Node<K, const D: usize> where SmallVec<K, { D * 2 }>: , { keys: SmallVec<K, { D * 2 }>, } impl<K, const D: usize> Node<K, D> where SmallVec<K, { D * 2 }>: , { fn new() -> Self { panic!() } #[inline(never)] fn split(&mut self, i: usize, k: K, right: bool) -> Node<K, D> { let mut node = Node::new(); node.keys.push(k); //~^ error: no method named node } } #[derive(Debug)] struct SmallVec<T, const D: usize> { data: [T; D], } impl<T, const D: usize> SmallVec<T, D> { fn new() -> Self { panic!() } } fn main() {} </ins>

<!-- 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<details<summary<strongQuery Stack</strong</summary<p</p</details
modify labels to +requires-nightly
The following snippet gives the same ICE. The types are intentionally wrong. <details<summary<strongBacktrace</strong</summary<p</p</details<details<summary<strongQuery Stack</strong</summary<p</p</details
Triage: This is now fixed on the recent nightly, marking as E-needs-test.


Question: <ins> // aux-build:issue-89971-outer-attr-following-inner-attr-ice.rs #[macro_use] extern crate issue_89971_outer_attr_following_inner_attr_ice; fn main() { Mew(); X {}; } #![deny(missing_docs)] //~^ ERROR an inner attribute is not permitted in this context #[derive(ICE)] #[deny(missing_docs)] struct Mew(); </ins>


Question: <ins> error: using function pointers as const generic parameters is forbidden --> $DIR/issue-72352.rs:6:42 | LL | unsafe fn unsafely_do_the_thing<const F: fn(&CStr) -> usize>(ptr: *const i8) -> usize { |                                          ^^^^^^^^^^^^^^^^^^ error: aborting due to previous error </ins>

I've tried reducing this but wasn't really able to so far. I might try again some other time. The code below currently ICEs on Nightly (). When trying to reproduce locally for the backtrace, I had an older Nightly first () where this actually didn't crash the compiler, so it's apparently a regression. <details<summary<strongBacktrace</strong</summary<p</p</details
This is my first time using cargo-bisect-rustc and it's fantastic. It identified the regression as... searched nightlies: from nightly-2020-02-13 to nightly-2020-05-14 regressed nightly: nightly-2020-03-20 searched commits: from to regressed commit: <details<summarybisected with <a href=''cargo-bisect-rustc</av0.5.2</summaryHost triple: x86_64-unknown-linux-gnu Reproduce with: </details
is a rollup commit. The only PR which was part of that and (to me) looks like it could have caused this issue is .
Triage: the feature was removed by and the ICE no longer occurs with the latest nightly.


Question: <ins> error: using function pointers as const generic parameters is forbidden --> $DIR/issue-72352.rs:6:42 | LL | unsafe fn unsafely_do_the_thing<const F: fn(&CStr) -> usize>(ptr: *const i8) -> usize { |                                          ^^^^^^^^^^^^^^^^^^ error: aborting due to previous error </ins>

produces: <details</detailsIt should not be possible to access the type parameter in the type of the const parameter. cc Thanks to for .
Hi, I am new to rust compiler development and have decided to try to fix this issue to get started. If I understand the const-generics RFC correctly, type parameters can not be used in a const generic parameter because it cannot be ensured that the actual types have the "structural match" property. However, checking reveals that fn pointers (as well as raw pointers and empty arrays) always support structural matching, regardless of the types used within. My question is: is there another reason why const generic parameters are not allowed to use type parameters? If so, I think an additional check has to be to .
Actually, I think I may have interpreted. It looks like this example is intended to work to me. cc just to clarify.
Triage: the feature was removed by and the ICE no longer occurs with the latest nightly.


Question: <ins> error: using function pointers as const generic parameters is forbidden --> $DIR/issue-72352.rs:6:42 | LL | unsafe fn unsafely_do_the_thing<const F: fn(&CStr) -> usize>(ptr: *const i8) -> usize { |                                          ^^^^^^^^^^^^^^^^^^ error: aborting due to previous error </ins>

<!-- 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
Probably related to
Triage: the feature was removed by and the ICE no longer occurs with the latest nightly.


Question: <ins> error: using function pointers as const generic parameters is forbidden --> $DIR/issue-72352.rs:6:42 | LL | unsafe fn unsafely_do_the_thing<const F: fn(&CStr) -> usize>(ptr: *const i8) -> usize { |                                          ^^^^^^^^^^^^^^^^^^ error: aborting due to previous error </ins>

<!-- 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
Depends on const generics in type dependent paths afaict. See for more info. EDIT: Also depends on const generics with generic types. Merging does not close this issue
Triage: the feature was removed by and the ICE no longer occurs with the latest nightly.
Adding the following as a test might still be useful, even if it only errors with "using function pointers as const parameters is forbidden":


Question: <ins> // run-rustfix // Regression test for changes introduced while fixing #54505 // This test uses non-literals for Ranges // (expecting no parens with borrow suggestion) use std::ops::RangeBounds; // take a reference to any built-in range fn take_range(_r: &impl RangeBounds<i8>) {} fn main() { take_range(std::ops::Range { start: 0, end: 1 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &std::ops::Range { start: 0, end: 1 } take_range(::std::ops::Range { start: 0, end: 1 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &::std::ops::Range { start: 0, end: 1 } take_range(std::ops::RangeFrom { start: 1 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &std::ops::RangeFrom { start: 1 } take_range(::std::ops::RangeFrom { start: 1 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &::std::ops::RangeFrom { start: 1 } take_range(std::ops::RangeFull {}); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &std::ops::RangeFull {} take_range(::std::ops::RangeFull {}); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &::std::ops::RangeFull {} take_range(std::ops::RangeInclusive::new(0, 1)); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &std::ops::RangeInclusive::new(0, 1) take_range(::std::ops::RangeInclusive::new(0, 1)); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &::std::ops::RangeInclusive::new(0, 1) take_range(std::ops::RangeTo { end: 5 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &std::ops::RangeTo { end: 5 } take_range(::std::ops::RangeTo { end: 5 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &::std::ops::RangeTo { end: 5 } take_range(std::ops::RangeToInclusive { end: 5 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &std::ops::RangeToInclusive { end: 5 } take_range(::std::ops::RangeToInclusive { end: 5 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &::std::ops::RangeToInclusive { end: 5 } } </ins>

is an incorrect suggestion because has higher precedence than . It should suggest .
If someone wants to tackle this issue, it should be straightforward to fix. In: there should be another branch for , where the path of the call is . This code is a good reference: This issue affects the other range syntaxes too, so those should also be fixed (although these are not — look at for clues).
Hi I'd like to tackle this and take the plunge into the Rust compiler code :)
great! Let me know if you hit any snags or need any more tips. You'll want to add tests for these (in ). The is a good place for general information about the compiler. When you're done, include in the pull request and I'll review it!
you've anticipated most of my newbie questions already :) Thanks for that info, very useful! I'm now in the process of stressing my PC with lots of compiling to actually get started. Skimming the test code I'm really impressed by how easy it is to add "UI" tests for these sorts of things (compile this, expect this error on this line). Snazzy! That's all great, but do you anticipate I should also add "deeper" tests? I guess I'm trying to understand if the scope of this is just pure UI or do I need to touch some syntax parsing/immediate representations, since you mentioned code in . Because the compiler is emitting a syntax suggestion, we might want to assert that the suggestion is correct syntax in the first place. I don't know if that's how deep the rabbit hole goes and if there's a facility to help out, but my hunch is that since we have all of the compiler at hand, why not use it to validate the suggestion syntax? EDIT: OK, reading up on adding new tests to the compiler I encountered mention of , and it seems to be sort-of what I was after.
The issue here is just a diagnostic issue, so checking that we're getting the updated hint is enough. The code in is just helpful to see what ranges like and are desugared into, so you can catch them in — you shouldn't need to modify anything (apart from the test) outside of . It would technically be possible to do something like this, but it would probably be more trouble than it's worth.


Question: <ins> // run-rustfix // Regression test for changes introduced while fixing #54505 // This test uses non-literals for Ranges // (expecting no parens with borrow suggestion) use std::ops::RangeBounds; // take a reference to any built-in range fn take_range(_r: &impl RangeBounds<i8>) {} fn main() { take_range(std::ops::Range { start: 0, end: 1 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &std::ops::Range { start: 0, end: 1 } take_range(::std::ops::Range { start: 0, end: 1 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &::std::ops::Range { start: 0, end: 1 } take_range(std::ops::RangeFrom { start: 1 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &std::ops::RangeFrom { start: 1 } take_range(::std::ops::RangeFrom { start: 1 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &::std::ops::RangeFrom { start: 1 } take_range(std::ops::RangeFull {}); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &std::ops::RangeFull {} take_range(::std::ops::RangeFull {}); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &::std::ops::RangeFull {} take_range(std::ops::RangeInclusive::new(0, 1)); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &std::ops::RangeInclusive::new(0, 1) take_range(::std::ops::RangeInclusive::new(0, 1)); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &::std::ops::RangeInclusive::new(0, 1) take_range(std::ops::RangeTo { end: 5 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &std::ops::RangeTo { end: 5 } take_range(::std::ops::RangeTo { end: 5 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &::std::ops::RangeTo { end: 5 } take_range(std::ops::RangeToInclusive { end: 5 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &std::ops::RangeToInclusive { end: 5 } take_range(::std::ops::RangeToInclusive { end: 5 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &::std::ops::RangeToInclusive { end: 5 } } </ins>

(I'm not aware of a facility to do this easily already.) I think manually going through the possible s and checking that the parenthesisation behaviour is correct in each case would be a lot simpler: if we handle the different s in an exhaustive now (it's likely that if the ranges were handled incorrectly, there could be some others that are also missed at the moment), then this should be a one-time fix and the tests should prevent it regressing. A simple UI test should be sufficient here: will generate the output files, which will include all the relevant notes.
There was a similar problem with the suggestions, and it was fixed in . Further use of the operator precedence list can be seen in (which introduced the error fixed in the other PR).
Thanks for your guidance and much appreciated. I have dug into HIR and built-in ranges a bit more. Decided to check all the built-in range types and concluded they are all indeed affected by this problem. The following test I came up with demonstrates my intended fix (fails with nightly as well as stage 1 compiled from master): None of the fix suggestions, when applied, constitute valid syntax. My test checks for syntax I believe should be suggested by the compiler. I'm keen to tackle all of the range types at once in the scope of this issue. The problem I see though is just how wildly different each of the range types is represented in HIR. Adding a call just above this line: Revealed the following: for isfor isfor isfor isfor isfor is I'm quite bewildered by this non-uniformity and I guess I need some help unifying all of these into a elegant condition to tell "is this a built-in range?". I could probably brute-force it in a with explicit checks for , but maybe we can do better. Thanks in advance! EDIT realized that this non-uniformity was actually mentioned in the second comment from , but my plea still stands. Thanks for your patience.
I think you can match on all of these with something along the lines of (pseudocode):
Right, that's what I had in mind, but was also wondering if something like a check for  trait would work better. I guess we want to match against built-in range literals though, and explicitly.


Question: <ins> // run-rustfix // Regression test for changes introduced while fixing #54505 // This test uses non-literals for Ranges // (expecting no parens with borrow suggestion) use std::ops::RangeBounds; // take a reference to any built-in range fn take_range(_r: &impl RangeBounds<i8>) {} fn main() { take_range(std::ops::Range { start: 0, end: 1 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &std::ops::Range { start: 0, end: 1 } take_range(::std::ops::Range { start: 0, end: 1 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &::std::ops::Range { start: 0, end: 1 } take_range(std::ops::RangeFrom { start: 1 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &std::ops::RangeFrom { start: 1 } take_range(::std::ops::RangeFrom { start: 1 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &::std::ops::RangeFrom { start: 1 } take_range(std::ops::RangeFull {}); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &std::ops::RangeFull {} take_range(::std::ops::RangeFull {}); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &::std::ops::RangeFull {} take_range(std::ops::RangeInclusive::new(0, 1)); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &std::ops::RangeInclusive::new(0, 1) take_range(::std::ops::RangeInclusive::new(0, 1)); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &::std::ops::RangeInclusive::new(0, 1) take_range(std::ops::RangeTo { end: 5 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &std::ops::RangeTo { end: 5 } take_range(::std::ops::RangeTo { end: 5 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &::std::ops::RangeTo { end: 5 } take_range(std::ops::RangeToInclusive { end: 5 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &std::ops::RangeToInclusive { end: 5 } take_range(::std::ops::RangeToInclusive { end: 5 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &::std::ops::RangeToInclusive { end: 5 } } </ins>

Here's how I rationalize it: because they are parsed and desugared by the compiler, the check needs to be explicit and hardcode all paths to builtin ranges. Handle a special case with a special case.
Yes, this is where the lowering code comes in handy, because you can see exactly how the different syntax is desugared differently, to make sure you really are catching all the cases. Yes, I agree. It'd be nice if there was a more uniform way to handle them, but it's not convenient at the moment. You could include a reference back to in a comment to where the desugaring takes place, which will provide some motivation for matching in .
All clear now, thanks. I have succeeded in matching all range types and getting the test to pass. Needs some cleanups, but hopefully should be ready for PR soon. I have a few more questions before that though :smile: I have noticed that most of my code would actually be irrelevant if I re-used functions and constants defined in , e.g.: Can't deny that I have used these as inspiration / guideline (albeit I did not do a stupid copy-paste). What's the policy on using clippy code (clippy is a submodule of main repo)? This is purely in the interest of pursuing . The diff is not that big (52 new lines to , fairly specific to matching paths) -- but still, my clean code sense tingles because of possible DRY violation. Another conundrum I have is whether we should address and paths (and if so, how to work out we're not using at compile time)?
Unfortunately, there's not much sharing from clippy to rustc. I wouldn't worry about it. If you can encapsulate it easily, it's possible that clippy could make use of the code in rustc instead. The function in picks the correct path for / — you should be able to use that.
Thanks for the suggestion for , unfortunately I can't really make the association of and . It seems to me they are disjoint -- in : lowering happens in , whereas typechecking happens in . in takes : The it uses needs an awful lot of things to be instantiated. Not sure if I can get the hold of it all in .


Question: <ins> // run-rustfix // Regression test for changes introduced while fixing #54505 // This test uses non-literals for Ranges // (expecting no parens with borrow suggestion) use std::ops::RangeBounds; // take a reference to any built-in range fn take_range(_r: &impl RangeBounds<i8>) {} fn main() { take_range(std::ops::Range { start: 0, end: 1 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &std::ops::Range { start: 0, end: 1 } take_range(::std::ops::Range { start: 0, end: 1 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &::std::ops::Range { start: 0, end: 1 } take_range(std::ops::RangeFrom { start: 1 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &std::ops::RangeFrom { start: 1 } take_range(::std::ops::RangeFrom { start: 1 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &::std::ops::RangeFrom { start: 1 } take_range(std::ops::RangeFull {}); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &std::ops::RangeFull {} take_range(::std::ops::RangeFull {}); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &::std::ops::RangeFull {} take_range(std::ops::RangeInclusive::new(0, 1)); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &std::ops::RangeInclusive::new(0, 1) take_range(::std::ops::RangeInclusive::new(0, 1)); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &::std::ops::RangeInclusive::new(0, 1) take_range(std::ops::RangeTo { end: 5 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &std::ops::RangeTo { end: 5 } take_range(::std::ops::RangeTo { end: 5 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &::std::ops::RangeTo { end: 5 } take_range(std::ops::RangeToInclusive { end: 5 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &std::ops::RangeToInclusive { end: 5 } take_range(::std::ops::RangeToInclusive { end: 5 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &::std::ops::RangeToInclusive { end: 5 } } </ins>

Another problem I encountered while writing tests is that the changes I have made will affect suggestions for code like this: With my changes, the suggestion would be . I believe the correct suggestion would not involve the needless parentheses. This is due to not differentiating between "de-sugared" form coming from and between these de-sugared forms being supplied explicitly as input source code. With this in mind, I think current code is not PR worthy just yet. If of interest, here's the branch:
Left a couple of comments on possible approaches on that commit. The code looks fine.


Question: { hidden_ty } <ins> // FIXME(RPITIT): This can go away when we move to associated types ty::Projection(proj) if def_id.to_def_id() == proj.item_def_id && substs == proj.substs => { hidden_ty } </ins> _ => ty, }, lt_op: |lt| lt,

Here's a MVCE: I expected to see this happen: compilation fails because I'm clearly returning an instead of a Instead, this happened: bad codegen ("async fn resumed after completion") :
This is specifically a bug with default body in traits, this doesn't happen in s. I'll check it out, it's probably a very simple fix.


Question: <ins> // regression test for #67609. // check-pass static NONE: Option<String> = None; static NONE_REF_REF: &&Option<String> = { let x = &&NONE; x }; fn main() { println!("{:?}", NONE_REF_REF); } </ins>

root: gb2260-0.1.1: v. root: imperative - 3 (1 gh, 2 ) detected crates which regressed due to this <detailscommitted-0.1.11: v. imperative-1.0.1: v. epage/committed: v. </detailscc (likely MIR borrowck related, though not the transition itself as that happened last cycle)
Probably a result of the soundness fixes in
This is a change in promotion. cc
Minimized:
Maybe ?
or . No, it's neither of these.
It's , likely .


Question: /// /// # NaN bit patterns /// <del> /// This section defines the possible NaN bit patterns returned by non-"bitwise" floating point /// operations. The bitwise operations are unary `-`, `abs`, `copysign`; those are guaranteed to /// exactly preserve the bit pattern of their input except for possibly changing the sign bit. </del> <ins> /// This section defines the possible NaN bit patterns returned by floating-point operations. </ins> /// <del> /// A floating-point NaN value consists of: /// - a sign bit /// - a quiet/signaling bit </del> <ins> /// The bit pattern of a floating-point NaN value is defined by: /// - a sign bit. /// - a quiet/signaling bit. Rust assumes that the quiet/signaling bit being set to `1` indicates a ///   quiet NaN (QNaN), and a value of `0` indicates a signaling NaN (SNaN). In the following we ///   will hence just call it the "quiet bit". </ins> /// - a payload, which makes up the rest of the significand (i.e., the mantissa) except for the <del> ///   quiet/signaling bit. /// /// Rust assumes that the quiet/signaling bit being set to `1` indicates a quiet NaN (QNaN), and a /// value of `0` indicates a signaling NaN (SNaN). In the following we will hence just call it the /// "quiet bit". /// /// The following rules apply when a NaN value is returned: the result has a non-deterministic sign. /// The quiet bit and payload are non-deterministically chosen from the following set of options: /// /// - **Preferred NaN**: The quiet bit is set and the payload is all-zero. /// - **Quieting NaN propagation**: The quiet bit is set and the payload is copied from any input ///   operand that is a NaN. If the inputs and outputs do not have the same payload size (i.e., for ///   `as` casts), then ///   - If the output is smaller than the input, low-order bits of the payload get dropped. ///   - If the output is larger than the input, the payload gets filled up with 0s in the low-order ///     bits. /// - **Unchanged NaN propagation**: The quiet bit and payload are copied from any input operand ///   that is a NaN. If the inputs and outputs do not have the same size (i.e., for `as` casts), the ///   same rules as for "quieting NaN propagation" apply, with one caveat: if the output is smaller ///   than the input, droppig the low-order bits may result in a payload of 0; a payload of 0 is not ///   possible with a signaling NaN (the all-0 significand encodes an infinity) so unchanged NaN ///   propagation cannot occur with some inputs. /// - **Target-specific NaN**: The quiet bit is set and the payload is picked from a target-specific ///   set of "extra" possible NaN payloads. The set can depend on the input operand values. ///   See the table below for the concrete NaNs this set contains on various targets. </del> <ins> ///   quiet bit. /// /// The rules for NaN values differ between *arithmetic* and *non-arithmetic* (or "bitwise") /// operations. The non-arithmetic operations are unary `-`, `abs`, `copysign`, `signum`, /// `{to,from}_bits`, `{to,from}_{be,le,ne}_bytes` and `is_sign_{positive,negative}`. These /// operations are guaranteed to exactly preserve the bit pattern of their input except for possibly /// changing the sign bit. /// /// The following rules apply when a NaN value is returned from an arithmetic operation: /// - The result has a non-deterministic sign. /// - The quiet bit and payload are non-deterministically chosen from ///   the following set of options: /// ///   - **Preferred NaN**: The quiet bit is set and the payload is all-zero. ///   - **Quieting NaN propagation**: The quiet bit is set and the payload is copied from any input ///     operand that is a NaN. If the inputs and outputs do not have the same payload size (i.e., for ///     `as` casts), then ///     - If the output is smaller than the input, low-order bits of the payload get dropped. ///     - If the output is larger than the input, the payload gets filled up with 0s in the low-order ///       bits. ///   - **Unchanged NaN propagation**: The quiet bit and payload are copied from any input operand ///     that is a NaN. If the inputs and outputs do not have the same size (i.e., for `as` casts), the ///     same rules as for "quieting NaN propagation" apply, with one caveat: if the output is smaller ///     than the input, droppig the low-order bits may result in a payload of 0; a payload of 0 is not ///     possible with a signaling NaN (the all-0 significand encodes an infinity) so unchanged NaN ///     propagation cannot occur with some inputs. ///   - **Target-specific NaN**: The quiet bit is set and the payload is picked from a target-specific ///     set of "extra" possible NaN payloads. The set can depend on the input operand values. ///     See the table below for the concrete NaNs this set contains on various targets. </ins> /// /// In particular, if all input NaNs are quiet (or if there are no input NaNs), then the output NaN /// is definitely quiet. Signaling NaN outputs can only occur if they are provided as an input

Pointed out by in the float docs are using the term "arithmetic" operations in a few places, but that term is never defined. Furthermore, the new NaN docs probably should use that term as well when discussing which operations the NaN rules apply to (instead of "non-bitwise floating point operations" which they use currently). By "arithmetic operations", the docs likely mean all operations except for unary , , , , , and .


Question: let Some(rcvr_ty) = self.node_ty_opt(rcvr.hir_id) else { continue; }; let rcvr_ty = rcvr_ty.fold_with(&mut fudger); let Ok(method) = <del> self.lookup_method(rcvr_ty, segment, DUMMY_SP, parent_expr, rcvr, args) </del> <ins> self.lookup_method_for_diagnostic(rcvr_ty, segment, DUMMY_SP, parent_expr, rcvr) </ins> else { continue; }; let ideal_rcvr_ty = rcvr_ty.fold_with(&mut fudger); let ideal_method = self <del> .lookup_method(ideal_rcvr_ty, segment, DUMMY_SP, parent_expr, rcvr, args) </del> <ins> .lookup_method_for_diagnostic(ideal_rcvr_ty, segment, DUMMY_SP, parent_expr, rcvr) </ins> .ok() .and_then(|method| { let _ = self.at(&ObligationCause::dummy(), self.param_env)

<!-- 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. --No user code, just trying to compile my project. The is <!-- 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. --:
Do you mind checking if this still ICEs on the most recent nightly?
I just did that now, and it looks like the issue is fixed on the latest nightly. (sorry should have tried that in first place!)
That's weird, because I can repro it (cross-compiling for from linux if it matters).
on the latest nightly?
yep: Also the version of winit from the report () is not the latest . I'm working on bisecting and reducing now
Wait, this actually ICEs on stable too and I didn't notice because rustc emitted a bunch of errors after the ICE (?!)
I've reduced it down to this (which is no longer macOS or aarch64 dependent): (The assignment to was of course something more reasonable in the original code, but now I can't seem to replace it without making the ICE go away) This failed to compile without ICE on 1.69: Regression in () searched nightlies: from nightly-2023-03-06 to nightly-2023-04-19 regressed nightly: nightly-2023-04-15 searched commit range: regressed commit: <details<summarybisected with <a href=''cargo-bisect-rustc</av0.6.6</summaryHost triple: x86_64-unknown-linux-gnu Reproduce with: </details label regression-from-stable-to-stable
Whoops, I seemed to have caused it I'll look into it!
WG-prioritization assigning priority (). label -I-prioritize +P-medium


Question: <del> use crate::io::{self, ErrorKind, Read, Write}; </del> <ins> use super::{BufWriter, ErrorKind, Read, Result, Write, DEFAULT_BUF_SIZE}; </ins> use crate::mem::MaybeUninit; /// Copies the entire contents of a reader into a writer.

I was using std::io::copy from an SSD to memory using , which reported an eye-raising 30 MB/s. Wrapping it in a BufReader (either as the outer or middle layer) made no real difference. So I googled around a bit and found the recommended size was 64KB according to some random Microsoft article, so I decided to copy-paste the std::io::copy implementation and increase the buffer size. This got up to 600 MB/s at about 256KB which sounded a lot more it continued going upwards from there past the point of believability (unless the files were being pulled from RAM as a consequence of my repeated accesses). With a 10MB Vec, I got 228.36 GB/s . Unrealistic values aside, has anybody checked the buffer value to make sure there isn't some huge low-hanging fruit for std::io::copy speeds?
You mention windows. This may be platform-specific behavior. On unix systems I would fadvise on the input file for copying. Googling tells me that the windows equivalent is . Have you tried that?
After a coarse overview, my intuition is that there is some funny business going on with the length determined by and the subsequent calls on the , that could explain the unrealistic results.
It’s possible. The actual times did increase dramatically from the std::io::copy default though - my suspicion is that there is probably some caching to RAM going on or something as cold runs were generally slower than hot runs. This was for some work code that I’m no longer actively developing. I’ll leave this email marked as unread for awhile in case I have some spare time to write a benchmark. I don’t think the other flag that was mentioned is accessible with the default open file api, but in any case it at least appears there’s some low hanging fruit wrt to std::io::copy perf
I tried benchmarking on Windoze before and after changing to (instead of the original ) and the results were slightly worse (up to ~3%) with the modified setup, both on HDD and SSD. However, I'm not sure if my benchmarks were good enough - I was having a hard time tweaking them so that I could see any difference between results for different file sizes.