Question: /// information. #[macro_export] #[allow_internal_unstable] <del> #[cfg(not(no_elf_tls))] </del> macro_rules! scoped_thread_local { (static $name:ident: $t:ty) => ( <del> #[cfg_attr(not(any(windows, target_os = "android", target_os = "ios", target_os = "openbsd", target_arch = "aarch64")), thread_local)] </del> static $name: ::std::thread::ScopedKey<$t> = <del> ::std::thread::ScopedKey::new(); </del> <ins> __scoped_thread_local_inner!($t); </ins> ); (pub static $name:ident: $t:ty) => ( <del> #[cfg_attr(not(any(windows, target_os = "android", target_os = "ios", target_os = "openbsd", target_arch = "aarch64")), thread_local)] </del> pub static $name: ::std::thread::ScopedKey<$t> = <del> ::std::thread::ScopedKey::new(); </del> <ins> __scoped_thread_local_inner!($t); </ins> ); } <ins> #[doc(hidden)] #[unstable(feature = "thread_local_internals", reason = "should not be necessary")] </ins> #[macro_export] #[allow_internal_unstable] #[cfg(no_elf_tls)] <del> macro_rules! scoped_thread_local { (static $name:ident: $t:ty) => ( static $name: ::std::thread::ScopedKey<$t> = ::std::thread::ScopedKey::new(); ); (pub static $name:ident: $t:ty) => ( pub static $name: ::std::thread::ScopedKey<$t> = ::std::thread::ScopedKey::new(); ); </del> <ins> macro_rules! __scoped_thread_local_inner { ($t:ty) => {{ static _KEY: ::std::thread::__ScopedKeyInner<$t> = ::std::thread::__ScopedKeyInner::new(); fn _getit() -> &'static ::std::thread::__ScopedKeyInner<$t> { &_KEY } ::std::thread::ScopedKey::new(_getit) }} } #[doc(hidden)] #[unstable(feature = "thread_local_internals", reason = "should not be necessary")] #[macro_export] #[allow_internal_unstable] #[cfg(not(no_elf_tls))] macro_rules! __scoped_thread_local_inner { ($t:ty) => {{ #[cfg_attr(not(any(windows, target_os = "android", target_os = "ios", target_os = "openbsd", target_arch = "aarch64")), thread_local)] static _KEY: ::std::thread::__ScopedKeyInner<$t> = ::std::thread::__ScopedKeyInner::new(); fn _getit() -> &'static ::std::thread::__ScopedKeyInner<$t> { &_KEY } ::std::thread::ScopedKey::new(_getit) }} </ins> } #[unstable(feature = "scoped_tls",

There is an  in the scoped TLS module, which allows for sharing of data that wasn't meant to be shared. An unqualified should only_ be used when provides some sort of threadsafe locking mechanism. and do not. This lets us, for example, clone an or between threads, in safe code: Here, we have clones from different threads being interleaved, which can cause unsafety if there's a race on the refcount. We could also cause unsafety with a , or any other non-Sync type. basically lets us share across threads even if . I put the sleeps in there because somehow without them the routines are run serially. Note that this is not a problem with the API. I'm using here because to exploit one needs to be able to share across threads, and has an additional bound which doesn't satisfy. Any usable API will probably have to make the assumption that . Nor is this a problem with , since it can be done with , too. Solution: Make it ... I think. I'm not familiar with this API, and I'm not sure why it's even in the first place.
cc
cc This seems concerning: this is designed to be thread-local, so that e.g. storing a works (which would be safe, if it were guaranteed to stay on one thread). However currently requires unconditionally, hence this overly-accepting impl.
Qualifying the impl with breaks scoped TLS for (see the associated PR); because becomes no longer and thus can't be stuffed inside a static.
I believe the only way statics can be safe is by requiring the absence of Sync. That may sound odd, but consider the following: - sending thread-local references across threads is memory unsafe even with no interior mutability a static with no interior mutability is almost entirely useless, certainly not a common case non- containers offering interior mutabilities are cheaper and preferred to ones, where they can be used The main issue is actually within the libstd TLS implementation: is a wrapper for getters so it's unaffected by it, but may live in a static or a global one, depending on whether the platform natively supports TLS or not. -ing a across threads is actually safe on the architectures which do not have native TLS support. However, allowing it on some architectures and not on others is undesirable. Should use an accessor model like ?


Question: /// information. #[macro_export] #[allow_internal_unstable] <del> #[cfg(not(no_elf_tls))] </del> macro_rules! scoped_thread_local { (static $name:ident: $t:ty) => ( <del> #[cfg_attr(not(any(windows, target_os = "android", target_os = "ios", target_os = "openbsd", target_arch = "aarch64")), thread_local)] </del> static $name: ::std::thread::ScopedKey<$t> = <del> ::std::thread::ScopedKey::new(); </del> <ins> __scoped_thread_local_inner!($t); </ins> ); (pub static $name:ident: $t:ty) => ( <del> #[cfg_attr(not(any(windows, target_os = "android", target_os = "ios", target_os = "openbsd", target_arch = "aarch64")), thread_local)] </del> pub static $name: ::std::thread::ScopedKey<$t> = <del> ::std::thread::ScopedKey::new(); </del> <ins> __scoped_thread_local_inner!($t); </ins> ); } <ins> #[doc(hidden)] #[unstable(feature = "thread_local_internals", reason = "should not be necessary")] </ins> #[macro_export] #[allow_internal_unstable] #[cfg(no_elf_tls)] <del> macro_rules! scoped_thread_local { (static $name:ident: $t:ty) => ( static $name: ::std::thread::ScopedKey<$t> = ::std::thread::ScopedKey::new(); ); (pub static $name:ident: $t:ty) => ( pub static $name: ::std::thread::ScopedKey<$t> = ::std::thread::ScopedKey::new(); ); </del> <ins> macro_rules! __scoped_thread_local_inner { ($t:ty) => {{ static _KEY: ::std::thread::__ScopedKeyInner<$t> = ::std::thread::__ScopedKeyInner::new(); fn _getit() -> &'static ::std::thread::__ScopedKeyInner<$t> { &_KEY } ::std::thread::ScopedKey::new(_getit) }} } #[doc(hidden)] #[unstable(feature = "thread_local_internals", reason = "should not be necessary")] #[macro_export] #[allow_internal_unstable] #[cfg(not(no_elf_tls))] macro_rules! __scoped_thread_local_inner { ($t:ty) => {{ #[cfg_attr(not(any(windows, target_os = "android", target_os = "ios", target_os = "openbsd", target_arch = "aarch64")), thread_local)] static _KEY: ::std::thread::__ScopedKeyInner<$t> = ::std::thread::__ScopedKeyInner::new(); fn _getit() -> &'static ::std::thread::__ScopedKeyInner<$t> { &_KEY } ::std::thread::ScopedKey::new(_getit) }} </ins> } #[unstable(feature = "scoped_tls",

Then the actual borrow of a static is an implementation detail and happens on the thread where the key is used, not where it was itself borrowed.
"I believe the only way #[threadlocal] statics can be safe is by requiring the absence of ." This is wrong, I think. For example, one might use thread local data for intrusive linked lists of hazard pointers. They would be thread local but might still be (one can guarantee existence with scoped threads or in certain circumstances where threads are bound to cores). That said you can obviously come up with other representations. In any case, I've mostly come around to believing that we need a separate lifetime (not just for this, but for things like ensuring that can't catch an error in a thread that changes thread local data, violating exception safety).
Based on what wrote, it seems like the TLS interface requires a that only allows non- data and is still accessible like one. One idea I had of how to enable this in todays Rust is to make generate a unit like struct instead of a . That struct would be and have a impl: According to this could also help with , but I'm not familiar enough with the TLS API in general to really reason about this.
I was expecting the impl to target an intermediary type, not the contents themselves. and have their own APIs to deal with. You would still be about to use the TLS API provided by libstd with thread-safe data, it's just the low-level which would have the requirement. Ideas of thread-local lifetimes predate the removal of from , and I'm not sure how relevant they are anymore. I'm also conflating thread-safe data access and thread lifetime... but how long does a thread live? What would unify with? Actually, there's an... easy solution for this. Somehow we were blinded by language semantics, but their details are fluid. It is trivial to make borrows of behave like borrows of an arbitrary rvalue, allowing the resulting reference to be passed down, but not returned. That would ensure that the the thread is just as alive for such borrows as it is for stack ones. would still require a like has, because it may not be when native TLS is supported. But both their APIs are compatible with such a change.
Wouldn't that limit the usability of thread locals in some cases, though?


Question: /// information. #[macro_export] #[allow_internal_unstable] <del> #[cfg(not(no_elf_tls))] </del> macro_rules! scoped_thread_local { (static $name:ident: $t:ty) => ( <del> #[cfg_attr(not(any(windows, target_os = "android", target_os = "ios", target_os = "openbsd", target_arch = "aarch64")), thread_local)] </del> static $name: ::std::thread::ScopedKey<$t> = <del> ::std::thread::ScopedKey::new(); </del> <ins> __scoped_thread_local_inner!($t); </ins> ); (pub static $name:ident: $t:ty) => ( <del> #[cfg_attr(not(any(windows, target_os = "android", target_os = "ios", target_os = "openbsd", target_arch = "aarch64")), thread_local)] </del> pub static $name: ::std::thread::ScopedKey<$t> = <del> ::std::thread::ScopedKey::new(); </del> <ins> __scoped_thread_local_inner!($t); </ins> ); } <ins> #[doc(hidden)] #[unstable(feature = "thread_local_internals", reason = "should not be necessary")] </ins> #[macro_export] #[allow_internal_unstable] #[cfg(no_elf_tls)] <del> macro_rules! scoped_thread_local { (static $name:ident: $t:ty) => ( static $name: ::std::thread::ScopedKey<$t> = ::std::thread::ScopedKey::new(); ); (pub static $name:ident: $t:ty) => ( pub static $name: ::std::thread::ScopedKey<$t> = ::std::thread::ScopedKey::new(); ); </del> <ins> macro_rules! __scoped_thread_local_inner { ($t:ty) => {{ static _KEY: ::std::thread::__ScopedKeyInner<$t> = ::std::thread::__ScopedKeyInner::new(); fn _getit() -> &'static ::std::thread::__ScopedKeyInner<$t> { &_KEY } ::std::thread::ScopedKey::new(_getit) }} } #[doc(hidden)] #[unstable(feature = "thread_local_internals", reason = "should not be necessary")] #[macro_export] #[allow_internal_unstable] #[cfg(not(no_elf_tls))] macro_rules! __scoped_thread_local_inner { ($t:ty) => {{ #[cfg_attr(not(any(windows, target_os = "android", target_os = "ios", target_os = "openbsd", target_arch = "aarch64")), thread_local)] static _KEY: ::std::thread::__ScopedKeyInner<$t> = ::std::thread::__ScopedKeyInner::new(); fn _getit() -> &'static ::std::thread::__ScopedKeyInner<$t> { &_KEY } ::std::thread::ScopedKey::new(_getit) }} </ins> } #[unstable(feature = "scoped_tls",

e.g., wouldn't that make it difficult to have a thread local point to another thread local? Maybe I just have to think about it. (BTW, I'm aware we're just talking about the low-level API :)).
in a , borrows are , I didn't even think of that. First off, a global static shouldn't be allowed to borrow a static. And in general, having borrows in a is going to be difficult to support, except for non- data, because they would be right now. We could disallow borrows or we could give some kind of scope to those borrows. Which makes me think, as a compromise between a lifetime and , there could be a pseudo-(rvalue)-scope. Combined with the ability to leave out in globals' type (or not having a type at all), the scope should bubble up into users of those statics. They would behave as if they were borrowed before everything else in the function where they're used, but still not (and they can't be returned from functions).
There's a few intertwined issues here at play, so I just want to quickly summarize the way I see things: This does not affect as it which has an , which while sound should be fixed, allowing removal of the block for . A borrow of a static should not yield something with the lifetime, as that is clearly not sound. I'm not sure I follow why we might require the types in a are not , I haven't quite followed that. Due the cross-platform requirements of std, however, I believe the best solution here is to use the same strategy as with an indirect accessor to ensure the semantics are the same across platforms that have and those that don't (where a normal is used).
triage: P-medium This is an unstable API so it's not super-high priority to fix, but we should defnitely fix!
requiring that a is not is an easy way to ensure that a borrow of it, while , cannot escape the current thread. I've changed my mind and prefer an rvalue borrow semantic for , but it still is the case that and use non- statics (ignoring the workarounds for ). If was supported everywhere, having rvalue borrow semantics wouldn't hurt the std TLS API (aside from stability issues with ), as the access patterns are already through anonymous lifetimes (references passed to closures).


Question: /// information. #[macro_export] #[allow_internal_unstable] <del> #[cfg(not(no_elf_tls))] </del> macro_rules! scoped_thread_local { (static $name:ident: $t:ty) => ( <del> #[cfg_attr(not(any(windows, target_os = "android", target_os = "ios", target_os = "openbsd", target_arch = "aarch64")), thread_local)] </del> static $name: ::std::thread::ScopedKey<$t> = <del> ::std::thread::ScopedKey::new(); </del> <ins> __scoped_thread_local_inner!($t); </ins> ); (pub static $name:ident: $t:ty) => ( <del> #[cfg_attr(not(any(windows, target_os = "android", target_os = "ios", target_os = "openbsd", target_arch = "aarch64")), thread_local)] </del> pub static $name: ::std::thread::ScopedKey<$t> = <del> ::std::thread::ScopedKey::new(); </del> <ins> __scoped_thread_local_inner!($t); </ins> ); } <ins> #[doc(hidden)] #[unstable(feature = "thread_local_internals", reason = "should not be necessary")] </ins> #[macro_export] #[allow_internal_unstable] #[cfg(no_elf_tls)] <del> macro_rules! scoped_thread_local { (static $name:ident: $t:ty) => ( static $name: ::std::thread::ScopedKey<$t> = ::std::thread::ScopedKey::new(); ); (pub static $name:ident: $t:ty) => ( pub static $name: ::std::thread::ScopedKey<$t> = ::std::thread::ScopedKey::new(); ); </del> <ins> macro_rules! __scoped_thread_local_inner { ($t:ty) => {{ static _KEY: ::std::thread::__ScopedKeyInner<$t> = ::std::thread::__ScopedKeyInner::new(); fn _getit() -> &'static ::std::thread::__ScopedKeyInner<$t> { &_KEY } ::std::thread::ScopedKey::new(_getit) }} } #[doc(hidden)] #[unstable(feature = "thread_local_internals", reason = "should not be necessary")] #[macro_export] #[allow_internal_unstable] #[cfg(not(no_elf_tls))] macro_rules! __scoped_thread_local_inner { ($t:ty) => {{ #[cfg_attr(not(any(windows, target_os = "android", target_os = "ios", target_os = "openbsd", target_arch = "aarch64")), thread_local)] static _KEY: ::std::thread::__ScopedKeyInner<$t> = ::std::thread::__ScopedKeyInner::new(); fn _getit() -> &'static ::std::thread::__ScopedKeyInner<$t> { &_KEY } ::std::thread::ScopedKey::new(_getit) }} </ins> } #[unstable(feature = "scoped_tls",

Maybe a combined strategy, where borrows of statics are iff the data is not (and rvalue-like otherwise), might work better and would require fewer changes to the std TLS implementation.
Right, but returning a borrow with a lifetime for a global is unsafe for other reasons (the lifetime of the thread is not ).
how can it be abused without sending it to a different thread?
The actual values themselves do not have a lifetime, so it can be a source of unsafety to advertise otherwise. For example you could stick a into a TLS value with a destructor, but when the destructor runs that pointer could be invalid.


Question: let unqualified_def = resolve_identifier_with_fallback(self, None); let qualified_binding = self.resolve_module_relative_path(span, segments, namespace); match (qualified_binding, unqualified_def) { <del> (Ok(binding), Some(ref ud)) if binding.def() == ud.def => { </del> <ins> (Ok(binding), Some(ref ud)) if binding.def() == ud.def && segments[0].identifier.name.as_str() != "$crate" => { </ins> self.session .add_lint(lint::builtin::UNUSED_QUALIFICATIONS, id,

When on latest rust nightly , you get an ICE when compiling .
Its a pretty recent regression, it can't be reproduced with .
Okay, managed to minimize it: Looks like a regression of . cc any ideas on this?
Yeah, this was caused by an oversight in -- fixed in .


Question: Future incompatibility report: Future breakage diagnostic: error: missing fragment specifier <del> --> $DIR/macro-match-nonterminal.rs:2:8 </del> <ins> --> $DIR/macro-match-nonterminal.rs:2:6 </ins> | LL |     ($a, $b) => { <del> |        ^ </del> <ins> |      ^^ </ins> | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #40107 <https://github.com/rust-lang/rust/issues/40107>

Here's some code incorrectly defining a macro, because it's missing a fragment specifier. Here's the error message rustc gives me: It's potentially confusing that the error points to the source after the name with the missing fragment specifier. Especially in a complicated macro, it would be better if it pointed to the item which was actually missing the fragment specifier. <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim
Some more context at


Question: let msg = "you might have meant to use `#![feature(trait_alias)]` instead of a  `type` alias"; if let Some(span) = self.def_span(def_id) { <del> err.span_help(span, msg); </del> <ins> if let Ok(snip) = self.r.session.source_map().span_to_snippet(span) { // The span contains a type alias so we should be able to // replace `type` with `trait`. let snip = snip.replacen("type", "trait", 1); err.span_suggestion(span, msg, snip, Applicability::MaybeIncorrect); } else { err.span_help(span, msg); } </ins> } else { err.help(msg); }

I managed to reproduce the problem with this snippet: The compiler yells E0404 at me, but fair enough I always ask it to a bit more about it :) However this time, it only says this: This is confusing because the snippet above doesn't involve the keyword so I didn't understand initially what I was doing wrong, then I read the error message again: I first tried this, and it worked, but having to repeat the whole syntax everywhere wasn't too compelling, hence the alias: The compiler error message makes it very clear that I can't alias a trait, but the E0404 explanation doesn't mention it at all. I hope the description could also include this use case as I've seen sometimes EXXXX explanations go over several facets of the same problem. That won't help me, but maybe others that may trip on the same problem. I would have submitted a pull request for the docs myself, but I have no idea why you can't use type aliases for traits so I can't it ;) I'm using stable Rust 1.19.0 (on Fedora).
One more thing, even though the compiler lets me create an alias for a trait, I don't know when I can use such an alias. Maybe this should be explained too.
Current output (in nightly):
Current output: No structured suggestion for the nightly feature (should be and the feature flag).


Question: // mir::Constant // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL // + literal: Const { ty: &i32, val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main[0]), const_param_did: None }, [], Some(promoted[1])) } <del> _13 = (_4.0: &i32);              // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL _15 = (_4.1: &i32);              // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageLive(_5);                 // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageLive(_6);                 // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL </del> <ins> StorageLive(_5);                 // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL _5 = (_4.0: &i32);               // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL _6 = (_4.1: &i32);               // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL </ins> StorageLive(_7);                 // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL <del> _7 = (*_13);                     // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL _6 = Eq(move _7, const 1_i32);   // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageDead(_7);                 // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL _5 = Not(move _6);               // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageDead(_6);                 // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL switchInt(_5) -> [false: bb1, otherwise: bb2]; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL </del> <ins> StorageLive(_8);                 // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageLive(_9);                 // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL _9 = (*_5);                      // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL _8 = Eq(move _9, const 1_i32);   // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageDead(_9);                 // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL _7 = Not(move _8);               // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageDead(_8);                 // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL switchInt(_7) -> [false: bb1, otherwise: bb2]; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL </ins> } bb1: { <del> StorageDead(_5);                 // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL </del> <ins> StorageDead(_7);                 // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageDead(_5);                 // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL </ins> _0 = const ();                   // scope 0 at $DIR/issue-73223.rs:1:11: 9:2 return;                          // scope 0 at $DIR/issue-73223.rs:9:2: 9:2 } bb2: { <del> (_9.0: &[&str]) = const main::promoted[0] as &[&str] (Pointer(Unsize)); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL </del> <ins> StorageLive(_11);                // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL _25 = const main::promoted[0] as &[&str] (Pointer(Unsize)); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL </ins> // ty::Const // + ty: &[&str; 3] // + val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main[0]), const_param_did: None }, [], Some(promoted[0])) // mir::Constant // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL // + literal: Const { ty: &[&str; 3], val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main[0]), const_param_did: None }, [], Some(promoted[0])) } <del> StorageLive(_11);                // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL (_12.0: &&i32) = &_13;           // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageLive(_14);                // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL _14 = &_15;                      // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL (_12.1: &&i32) = move _14;       // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL StorageDead(_14);                // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL _20 = (_12.0: &&i32);            // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL _23 = (_12.1: &&i32);            // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL _19 = <&i32 as Debug>::fmt as for<'r, 's, 't0> fn(&'r &i32, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error> (Pointer(ReifyFnPointer)); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL </del> <ins> StorageLive(_13);                // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL StorageLive(_15);                // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL _15 = _5;                        // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL (_14.0: &&i32) = &_15;           // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageLive(_16);                // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL _16 = &_6;                       // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL (_14.1: &&i32) = move _16;       // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL StorageDead(_16);                // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL _21 = (_14.0: &&i32);            // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL _24 = (_14.1: &&i32);            // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL _20 = <&i32 as Debug>::fmt as for<'r, 's, 't0> fn(&'r &i32, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error> (Pointer(ReifyFnPointer)); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL </ins> // mir::Constant // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL // + literal: Const { ty: for<'r, 's, 't0> fn(&'r &i32, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error> {<&i32 as std::fmt::Debug>::fmt}, val: Value(Scalar(<ZST>)) } <del> StorageLive(_18);                // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL _18 = transmute::<for<'r, 's, 't0> fn(&'r &i32, &'s mut Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>, for<'r, 's, 't0> fn(&'r core::fmt::Opaque, &'s mut Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>>(move _19) -> bb3; // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL </del> <ins> StorageLive(_19);                // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL _19 = transmute::<for<'r, 's, 't0> fn(&'r &i32, &'s mut Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>, for<'r, 's, 't0> fn(&'r core::fmt::Opaque, &'s mut Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>>(move _20) -> bb3; // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL </ins> // mir::Constant // + span: $SRC_DIR/core/src/fmt/mod.rs:LL:COL // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(for<'r, 's, 't0> fn(&'r &i32, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>) -> for<'r, 's, 't0> fn(&'r core::fmt::Opaque, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error> {std::intrinsics::transmute::<for<'r, 's, 't0> fn(&'r &i32, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>, for<'r, 's, 't0> fn(&'r core::fmt::Opaque, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>>}, val: Value(Scalar(<ZST>)) } } bb3: { <del> (_16.0: &core::fmt::Opaque) = transmute::<&&i32, &core::fmt::Opaque>(move _20) -> bb4; // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL </del> <ins> (_17.0: &core::fmt::Opaque) = transmute::<&&i32, &core::fmt::Opaque>(move _21) -> bb4; // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL </ins> // mir::Constant // + span: $SRC_DIR/core/src/fmt/mod.rs:LL:COL // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(&&i32) -> &core::fmt::Opaque {std::intrinsics::transmute::<&&i32, &core::fmt::Opaque>}, val: Value(Scalar(<ZST>)) } } bb4: { <del> (_16.1: for<'r, 's, 't0> fn(&'r core::fmt::Opaque, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>) = move _18; // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL StorageDead(_18);                // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL _22 = <&i32 as Debug>::fmt as for<'r, 's, 't0> fn(&'r &i32, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error> (Pointer(ReifyFnPointer)); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL </del> <ins> (_17.1: for<'r, 's, 't0> fn(&'r core::fmt::Opaque, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>) = move _19; // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL StorageDead(_19);                // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL _23 = <&i32 as Debug>::fmt as for<'r, 's, 't0> fn(&'r &i32, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error> (Pointer(ReifyFnPointer)); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL </ins> // mir::Constant // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL // + literal: Const { ty: for<'r, 's, 't0> fn(&'r &i32, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error> {<&i32 as std::fmt::Debug>::fmt}, val: Value(Scalar(<ZST>)) } <del> StorageLive(_21);                // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL _21 = transmute::<for<'r, 's, 't0> fn(&'r &i32, &'s mut Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>, for<'r, 's, 't0> fn(&'r core::fmt::Opaque, &'s mut Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>>(move _22) -> bb5; // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL </del> <ins> StorageLive(_22);                // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL _22 = transmute::<for<'r, 's, 't0> fn(&'r &i32, &'s mut Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>, for<'r, 's, 't0> fn(&'r core::fmt::Opaque, &'s mut Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>>(move _23) -> bb5; // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL </ins> // mir::Constant // + span: $SRC_DIR/core/src/fmt/mod.rs:LL:COL // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(for<'r, 's, 't0> fn(&'r &i32, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>) -> for<'r, 's, 't0> fn(&'r core::fmt::Opaque, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error> {std::intrinsics::transmute::<for<'r, 's, 't0> fn(&'r &i32, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>, for<'r, 's, 't0> fn(&'r core::fmt::Opaque, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>>}, val: Value(Scalar(<ZST>)) } } bb5: { <del> (_17.0: &core::fmt::Opaque) = transmute::<&&i32, &core::fmt::Opaque>(move _23) -> bb6; // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL </del> <ins> (_18.0: &core::fmt::Opaque) = transmute::<&&i32, &core::fmt::Opaque>(move _24) -> bb6; // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL </ins> // mir::Constant // + span: $SRC_DIR/core/src/fmt/mod.rs:LL:COL // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(&&i32) -> &core::fmt::Opaque {std::intrinsics::transmute::<&&i32, &core::fmt::Opaque>}, val: Value(Scalar(<ZST>)) } } bb6: { <del> (_17.1: for<'r, 's, 't0> fn(&'r core::fmt::Opaque, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>) = move _21; // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL StorageDead(_21);                // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL _11 = [move _16, move _17];      // scope 5 at $SRC_DIR/std/src/macros.rs:LL:COL </del> <ins> (_18.1: for<'r, 's, 't0> fn(&'r core::fmt::Opaque, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>) = move _22; // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL StorageDead(_22);                // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL _13 = [move _17, move _18];      // scope 5 at $SRC_DIR/std/src/macros.rs:LL:COL _12 = &_13;                      // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL _27 = move _12 as &[std::fmt::ArgumentV1] (Pointer(Unsize)); // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL StorageLive(_26);                // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL discriminant(_26) = 0;           // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL (_11.0: &[&str]) = move _25;     // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL (_11.1: std::option::Option<&[std::fmt::rt::v1::Argument]>) = move _26; // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL (_11.2: &[std::fmt::ArgumentV1]) = move _27; // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL StorageDead(_26);                // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL </ins> _10 = &_11;                      // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL <del> _25 = move _10 as &[std::fmt::ArgumentV1] (Pointer(Unsize)); // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL StorageLive(_24);                // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL discriminant(_24) = 0;           // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL (_9.1: std::option::Option<&[std::fmt::rt::v1::Argument]>) = move _24; // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL (_9.2: &[std::fmt::ArgumentV1]) = move _25; // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL StorageDead(_24);                // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL _8 = &_9;                        // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL begin_panic_fmt(move _8);        // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL </del> <ins> begin_panic_fmt(move _10);       // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL </ins> // mir::Constant // + span: $SRC_DIR/std/src/macros.rs:LL:COL // + literal: Const { ty: for<'r, 's> fn(&'r std::fmt::Arguments<'s>) -> ! {std::rt::begin_panic_fmt}, val: Value(Scalar(<ZST>)) }

This little matrix processing code shows miscompilation if compiled with: But it compiles correctly with: With:
Hmm, on first glance the replacement it performs looks correct: It replaces local () with the return place . Previously the return place was only used in the block by a copy statement, so this transformation should be correct. Maybe this part of the diff causes a problem? We're using our return place as the return destination for the inner call. It's possible that there's an undocumented (and maybe unintended) assumption that the return place is not reused like this, either in other MIR optimizations or in codegen. Haven't looked too deeply yet though.
Ah, there's this bad call in LLVM IR: It passes a reference to as both the return pointer, and the second (immutable) argument.
we have this corresponding MIR, where we already incorrectly pass a reference to as an argument, while also assigning the call result to it: The destination propagation pass already has code that prevents merging a call destination with one of the arguments, but here we pass a reference instead. Curiously, the was produced by merging with , which is not really something the pass should be doing since a reference is taken to , and we avoid touching any local that has its address taken.
The propagation is disabled only if both locals have their address taken. Changing that to be more conservative does fix this issue. Minimized:
Oof, this should have been an , not an
Thanks
Opened with a fix


Question: <ins> // run-pass #![allow(dead_code)] #![allow(improper_ctypes)] // ignore-wasm32-bare no libc to test ffi with #[derive(Copy, Clone)] pub struct QuadFloats { a: f32, b: f32, c: f32, d: f32 } mod rustrt { use super::QuadFloats; #[link(name = "rust_test_helpers", kind = "static")] extern { pub fn get_c_exhaust_sysv64_ints( _: *const (), _: *const (), _: *const (), _: *const (), _: *const (), _: *const (), _: *const (), h: QuadFloats, ) -> f32; } } fn test() { unsafe { let null = std::ptr::null(); let q = QuadFloats { a: 10.2, b: 20.3, c: 30.4, d: 40.5 }; assert_eq!( rustrt::get_c_exhaust_sysv64_ints(null, null, null, null, null, null, null, q), q.c, ); } } pub fn main() { test(); } </ins>

We encountered this with WebRender, where we exposed a method in Rust to the Gecko, and the last parameters supplied appeared random on the Rust side. I made a reduced test case adapted from it that you can grab at: It is a very simple test case where the C++ program puts all the parameters on the stack, prints the expected values of some of them, and calls the Rust method. The Rust method prints the values it received. We have enough parameters to fill up the registers used in the calling convention, and once we get to pushing things on the stack, it goes wrong. You can see from the output that they mismatch. ./build- && ./run- outputs c++ expect width=7 height=8 c++ expect slice=9 10 11 12 c++ expect outset=13. 13. 13. 13. c++ expect repeat h=0 v=0 got rust image 6 width 7 height 8 got rust slice SideOffsets { top: 9, right: 10, bottom: 11, left: 12 } got rust outset LayoutGeometry { top: 0.0, left: 0.0, width: 0.0, height: 0.0 } got rust repeat h=26 v=58 Note that the earlier parameters are correct, but the last 3 (outset, repeat h and repeat v) are all incorrect.
Is there an upstream issue in WebRender you can link? What platform is this happening on?
The Gecko side integrating with WebRender was disabled, and I have been working to re-enable this in You can find the code in question at: I intend to just work around this using structs for the moment as part of the aforementioned bug.
We're seeing this on all of our x64 platforms (win, mac, linux; all using clang). It looks like a pretty clear bug in our sysv callee ABI for x64 when there are lots of arguments.
<details<summaryrustc callee llvm-ir </summary</details<details<summaryclang caller llvm-ir </summary</detailsJust the signatures:
Note to self: can go negative from scalar integer arguments after the 6 integer registers have been exhausted and then is always true. Will try to fix soon (also I wonder if this is a stable-to-stable regression from years ago?).


Question: <ins> // run-pass #![allow(dead_code)] #![allow(improper_ctypes)] // ignore-wasm32-bare no libc to test ffi with #[derive(Copy, Clone)] pub struct QuadFloats { a: f32, b: f32, c: f32, d: f32 } mod rustrt { use super::QuadFloats; #[link(name = "rust_test_helpers", kind = "static")] extern { pub fn get_c_exhaust_sysv64_ints( _: *const (), _: *const (), _: *const (), _: *const (), _: *const (), _: *const (), _: *const (), h: QuadFloats, ) -> f32; } } fn test() { unsafe { let null = std::ptr::null(); let q = QuadFloats { a: 10.2, b: 20.3, c: 30.4, d: 40.5 }; assert_eq!( rustrt::get_c_exhaust_sysv64_ints(null, null, null, null, null, null, null, q), q.c, ); } } pub fn main() { test(); } </ins>

Looks like this was working circa 1.0, but has been broken at least since 1.12. Oof.
Do you need this fixed on beta as well, btw?
it would certainly be great if you uplifted this, but we have to work around it for the next few weeks anyway


Question: <ins> error: inconsistent resolution for an import --> $DIR/issue-62767.rs:24:5 | LL | use bar::bar; |     ^^^^^^^^ error[E0432]: unresolved import `Same` --> $DIR/issue-62767.rs:12:5 | LL | use Same::Same; |     ^^^^ `Same` is a variant, not a module error[E0432]: unresolved import `bar::bar` --> $DIR/issue-62767.rs:24:5 | LL | use bar::bar; |     ^^^^^^^^ no `bar` in `foo::bar::bar` error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0432`. </ins>

I tried this code: I expected to see this happen: Compilation error. This shadows one (glob-imported) with another . As far as I know, this should be forbidden. Instead, this happened: this code successfully compiled. : c.c. c.c.
Shadowing a glob import with a specific item is allowed and will unambiguously resolve to the specific one. This is also how the prelude works. The following compiles fine as well: .
To clarify, the problem is not shadowing, but time travel. We shadow identifier which have been already used to resolve another import, so we end up with meaning two things at the same time in the same scope.
This is a change from Rust 1.44, in Rust 1.43 this is an ICE "inconsistent resolution for an import". Possibly a consequence of
I'm not sure this is a bug. When resolving we are looking at all names in scope except for the names introduced by itself. Otherwise we'd have cycles even in trivial cases like where is a name from extern prelude. If you take this detail into consideration, then all paths seem to be resolved correctly.
cc (somewhat related)
I think, the difference with is that doesn't replace one resolution with another. We already have a name in the scope that is resolved to a particular extern crate. In my example, uses name from the scope, and then rebinds this name to another item. I can complicate my example a bit. What this program prints, "111" or "222"? It'd say, it depends on imports resolution order, but looks like it always prints "111".
It'd say, it depends on imports resolution order The intent for the resolution results is to never depend on internal resolution order. (cc , order-dependence can probably happen in practice due to the current not very principled implementation, but hopefully still can be eliminated in backward-compatible-in-practice way by rewriting the main resolution/expansion loop more carefully.) but looks like it always prints "111" That's what I'd expect. resolves to in resolves to (because non-globs shadow globs) first in resolves to (which the only in scope after excluding itself)
I'd still be ok with replacing the former ICE with an error though, since that's a more conservative choice.


Question: <ins> error: inconsistent resolution for an import --> $DIR/issue-62767.rs:24:5 | LL | use bar::bar; |     ^^^^^^^^ error[E0432]: unresolved import `Same` --> $DIR/issue-62767.rs:12:5 | LL | use Same::Same; |     ^^^^ `Same` is a variant, not a module error[E0432]: unresolved import `bar::bar` --> $DIR/issue-62767.rs:24:5 | LL | use bar::bar; |     ^^^^^^^^ no `bar` in `foo::bar::bar` error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0432`. </ins>

Actually enabling the property "name resolve to the same thing whether some items were excluded during its resolution to avoid cycles or not" may be useful for using something like "inference variables" for unresolved imports and making import resolution more like unification in type inference. That's an idea I had for quite some, but I hadn't realized that merging went against it.
Sigh, the issue already affects three stable releases - from 1.44 to 1.46. I'll try to prioritize it.
Addressed in
Assigning so this isn't lost. See the .
The fix caused some regressions -
The code in the issue produce no errors using Rust 1.67.1. Should we re-open the issue or is it not considered a bug now?
The fix was reverted due to breakage () and the current behavior is considered by design since then.
(Also it's not exactly a time travel - )


Question: hashbrown = { version = "0.4.0", features = ['rustc-dep-of-std'] } [dependencies.backtrace] <del> version = "0.3.25" </del> <ins> version = "0.3.29" </ins> default-features = false # don't use coresymbolication on OSX features = [ "rustc-dep-of-std", # enable build support for integrating into libstd

Every since a recent nightly update, both distributed nightlies and locally built produce backtraces where every level of the stack is represented only by their memory address and the label : Sadly I don't have a more specific repro case, but I can consistently reproduce locally. Older distributed nightlies do not present this behavior.
This happens consistently for me as well (also macOS).
I've been seeing this on Linux too, though it's been at least a week. (It also may have been fixed in a rustc newer than the one servo uses)
We should have tests for backtraces, so they don't regress again in the future.
this is certainly happening on master, and it's been happening for a while, but I assumed it was my env.
It just occurred to me that this might be related to the new symbol mangling (although I doubt it).
I've been experiencing this for about a week now (also on macOS). It definitely started prior to being merged. I also have the following in my :
has absolutely no changes if you don't use the flag, so it's not from there.
It's definitely , I tried before and after. It works if you enable the "coresymbolication" feature, though that's obviously not an option for distribution. I tried the latest master of , but it didn't help.
To confirm, is everyone only experiencing problems on OSX for rustc itself? Are there problems with other projects on OSX? can you please confirm or deny your experience from Linux? Throwing in a new platform here changes this quite a lot
Ok I believe I've found the issue for OSX, but if other platforms are still an issue that would be good to know
I've only experienced this with rustc itself on OSX. Things it builds seem ok, and linux/windows seem to be ok.
No, it's still happening on Linux as of yesterday (I can try again today). I also assumed it was my env.
I think the Linux issue is separate since it's been happening much longer than the OSX one
Hey, this seems to an issue on nightly for Windows (msvc) as well: This uses backtrace via :
if that's only using the crate and not using libstd, can you open an issue on the repository? The OSX issue should be fixed in , which I'd like to finish testing and then I'll send an update to libstd.


Question: hashbrown = { version = "0.4.0", features = ['rustc-dep-of-std'] } [dependencies.backtrace] <del> version = "0.3.25" </del> <ins> version = "0.3.29" </ins> default-features = false # don't use coresymbolication on OSX features = [ "rustc-dep-of-std", # enable build support for integrating into libstd

That could affect Linux as well but I doubt it, so if there are persisting Linux/Windows issues please feel free to let me know. If you can create an isolated problem which uses the crate rather than libstd that's even better!
Done: rust-lang/backtrace-rs


Question: <ins> error: using function pointers as const generic parameters is forbidden --> $DIR/issue-71611.rs:4:21 | LL | fn func<A, const F: fn(inner: A)>(outer: A) { |                     ^^^^^^^^^^^^ 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-71611.rs:4:21 | LL | fn func<A, const F: fn(inner: A)>(outer: A) { |                     ^^^^^^^^^^^^ 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-71611.rs:4:21 | LL | fn func<A, const F: fn(inner: A)>(outer: A) { |                     ^^^^^^^^^^^^ 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-71611.rs:4:21 | LL | fn func<A, const F: fn(inner: A)>(outer: A) { |                     ^^^^^^^^^^^^ 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: [true] `{$param_name}` *[false] `fn` parameter } has {$has_lifetime -> <del> [named] lifetime `{$lifetime}` *[anon] an anonymous lifetime `'_` </del> <ins> [true] lifetime `{$lifetime}` *[false] an anonymous lifetime `'_` </ins> } but calling `{$ident}` introduces an implicit `'static` lifetime requirement infer_ril_introduced_here = `'static` requirement introduced here

[ ] Previous Stable [ ] Current Stable [ ] Current Beta [X] Current Nightly No response <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim
This is another case for And except for the missing argument issue, there is an copy-paste bug in :


Question: GenericArg::Const(self.parse_const_arg()?) } else if self.check_type() { // Parse type argument. <del> let is_const_fn = self.look_ahead(1, |t| t.kind == token::OpenDelim(Delimiter::Parenthesis)); let mut snapshot = self.create_snapshot_for_diagnostic(); </del> <ins> // Proactively create a parser snapshot enabling us to rewind and try to reparse the // input as a const expression in case we fail to parse a type. If we successfully // do so, we will report an error that it needs to be wrapped in braces. let mut snapshot = None; if self.may_recover() && self.token.can_begin_expr() { snapshot = Some(self.create_snapshot_for_diagnostic()); } </ins> match self.parse_ty() { <del> Ok(ty) => GenericArg::Type(ty), </del> <ins> Ok(ty) => { // Since the type parser recovers from some malformed slice and array types and // successfully returns a type, we need to look for `TyKind::Err`s in the // type to determine if error recovery has occurred and if the input is not a // syntactically valid type after all. if let ast::TyKind::Slice(inner_ty) | ast::TyKind::Array(inner_ty, _) = &ty.kind && let ast::TyKind::Err = inner_ty.kind && let Some(snapshot) = snapshot && let Some(expr) = self.recover_unbraced_const_arg_that_can_begin_ty(snapshot) { return Ok(Some(self.dummy_const_arg_needs_braces( self.struct_span_err(expr.span, "invalid const generic expression"), expr.span, ))); } GenericArg::Type(ty) } </ins> Err(err) => { <del> if is_const_fn { match (*snapshot).parse_expr_res(Restrictions::CONST_EXPR, None) { Ok(expr) => { self.restore_snapshot(snapshot); return Ok(Some(self.dummy_const_arg_needs_braces(err, expr.span))); } Err(err) => { err.cancel(); } } </del> <ins> if let Some(snapshot) = snapshot && let Some(expr) = self.recover_unbraced_const_arg_that_can_begin_ty(snapshot) { return Ok(Some(self.dummy_const_arg_needs_braces( err, expr.span, ))); </ins> } // Try to recover from possible `const` arg without braces. return self.recover_const_arg(start, err).map(Some);

<!-- 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. --This is a much abbreviated version of the code from my experiments with adding a shuffle API to the stdsimd repo, it probably needs further reduction but I wanted to file this before I forgot: I expected to see this happen: it works, provides a useful error, or even just ICEs. Instead, this happened: I got a request to input a type instead! And no, that doesn't work either if you put it in, because instead you get: : <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
The fix is Due to parsing ambiguities generic arguments currently need to be put into braces, unless they are really simple (like or ), is not simple enough.
Oh, cool! That does compile! I knew about that but wasn't sure if that was the problem because I thought that was just for expressions? I guess that's technically an array expression? That is none of the errors I was presented with, though, which makes this a diagnostics problem I suppose?
I believe diagnostic for const generic (example taken from ) needs to be improved too before release, at least I thought that can be used instead, if one didn't know about then they need to search it up.
Arrays as const parameters still have bad error messages. same with tuples
claim


Question: <ins> // force-host // no-prefer-dynamic #![crate_type = "proc-macro"] extern crate proc_macro; use proc_macro::{Group, TokenStream, TokenTree}; // This macro exists as part of a reproduction of #61963 but without using quote/syn/proc_macro2. #[proc_macro_derive(DomObject)] pub fn expand_token_stream(input: TokenStream) -> TokenStream { // Construct a dummy span - `#0 bytes(0..0)` - which is present in the input because // of the specially crafted generated tokens in the `attribute-crate` proc-macro. let dummy_span = input.clone().into_iter().nth(0).unwrap().span(); // Define what the macro would output if constructed properly from the source using syn/quote. let output: TokenStream = "impl Bar for ((), Qux<Qux<Baz> >) { } impl Bar for ((), Box<Bar>) { }".parse().unwrap(); let mut tokens: Vec<_> = output.into_iter().collect(); // Adjust token spans to match the original crate (which would use `quote`). Some of the // generated tokens point to the dummy span. for token in tokens.iter_mut() { if let TokenTree::Group(group) = token { let mut tokens: Vec<_> = group.stream().into_iter().collect(); for token in tokens.iter_mut().skip(2) { token.set_span(dummy_span); } let mut stream = TokenStream::new(); stream.extend(tokens); *group = Group::new(group.delimiter(), stream); } } let mut output = TokenStream::new(); output.extend(tokens); output } </ins>

One of the many new (or newly enabled by default) warnings in Servo in today’s Nightly: The suggestion is wrong, which means also fails and therefore does not apply fixes for (the many) other warnings where the suggestion is correct.
Triage: Preliminarily assigning P-high before Felix reviews this.
Also cc since iirc you did some macro related work here.
Possible solution: when a warning’s span is exactly a macro invocation, don’t emit a “suggested fix” that is likely wrong. (But still emit a warning.)
We have that check for most suggestions, but it might be missing for . Was this in latest nightly? I know a couple of these have been fixed in the past few weeks.
This is in rustc 1.37.0-nightly ( 2019-06-18). works around this and allows ’ing the rest of the warnings (namely old syntax for inclusive ranges) or warnings in other crates.
Oh. I just noticed the suggestion. I’d missed it in that blob of text.
Apologies for the time this has taken - I've struggled to find time to dig in to this. So far, I've managed to make a smaller example (it still depends on , and ) that reproduces the issue, you can find it in (run in the directory).
Thanks to some help from I've now got a minimal test case w/out any dependencies that outputs the same tokens that the reduced example from servo did (you can see it in ). When inspecting the span that the lint is emitted for, it isn't marked as coming from a macro expansion, and it appears that it was created that way during the macro expansion. I'd appreciate any opinions on what the correct fix is here - is it a bug in / that they output what appears to be incorrect spans? Should rustc be able to handle this case? If so, where should I be looking to mark the span or what check should I be performing to identify it as a result of macro expansion?
cc
I believe this is a compiler bug, not something that needs a fix in syn or quote. is a call_site span. It is the span of tokens in macro output that are not attributable to any particular input token. Usually that will be most of the tokens in any macro output; diagnostics need to take this into account.


Question: ty_op: |ty| match *ty.kind() { // We can't normalize associated types from `rustc_infer`, // but we can eagerly register inference variables for them. <del> ty::Projection(projection_ty) if !projection_ty.has_escaping_bound_vars() => { </del> <ins> // FIXME(RPITIT): Don't replace RPITITs with inference vars. ty::Projection(projection_ty) if !projection_ty.has_escaping_bound_vars() && tcx.def_kind(projection_ty.item_def_id) != DefKind::ImplTraitPlaceholder => { </ins> self.infer_projection( param_env, projection_ty,

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> error[E0080]: evaluation of constant value failed --> $DIR/issue-88434-removal-index-should-be-less.rs:10:5 | LL | const _CONST: &[u8] = &f(&[], |_| {}); |                        -------------- inside `_CONST` at $DIR/issue-88434-removal-index-should-be-less.rs:4:24 ... LL |     panic!() |     ^^^^^^^^ |     | |     the evaluated program panicked at 'explicit panic', $DIR/issue-88434-removal-index-should-be-less.rs:10:5 |     inside `f::<[closure@$DIR/issue-88434-removal-index-should-be-less.rs:4:31: 4:37]>` at $SRC_DIR/std/src/panic.rs:LL:COL | = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error For more information about this error, try `rustc --explain E0080`. </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. --code from glacier <!-- 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<!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
This one also crashes beta and stable release channel.
Huh, why was this not detected earlier if it was tracked in glacier as fixed?
If you add a annotation to the trait bound on , then it no longer ICEs. Here's the code: Output: And if you add the two feature attributes the above messages ask you to enable, it still does not ICE, but correctly errors with "evaluation of constant value failed." Based on some debugging which I , I think this ICE has to do with the lifetime in the bound , although I'm not exactly sure how. I am new to the Rust compiler, and I just chose this issue because it seemed like a good first issue to work on, so I will read the (thanks to for sharing this) and try to further debug this.
If you plan to work on this issue, I recommend claiming it so other people know that and don't start working on it too. You can claim the issue by commenting with . More details about how to use rustbot are . You may also want to read the of the guide.
claim


Question: <ins> // build-pass trait X<const N: i32> {} fn hello<T: X<{ fn hello() -> ! { loop {} } 1 }>>() {} fn main() {} </ins>

I tried this code: I expected to see this happen: “error[E0658]: the type is experimental” Instead, this happened: Successful compilation, as long as I'm using a nightly compiler, but the error when on stable 1.75. This is incorrect because nightly features should always require attributes on nightly (until they're stabilized, which hasn't happened yet for ). <!-- 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. --: label +F-never_type +requires-nightly
searched nightlies: from nightly-2023-11-11 to nightly-2024-02-01 regressed nightly: nightly-2024-01-27 searched commit range: regressed commit: <details<summarybisected with <a href=''cargo-bisect-rustc</av0.6.5</summaryHost triple: x86_64-unknown-linux-gnu Reproduce with: </detailsThen, bisecting Manually verified that reverting (as ) restored the error. cc
Not sure to understand why fixing the visitor implementation introduced this bug. Maybe it highlighted a limitation? Gonna check.
Ok I think I know why: implementation of the not calling the equivalent function. Checking where it is used.
WG-prioritization assigning priority (). label -I-prioritize +P-high
Fix was already approved in . Waiting for CI to be unlocked.


Question: <ins> /// Some doc comment. struct X; // ignore-license // Copyright 2012-2013 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. // pp-exact // Test that rust can properly pretty print a doc comment if it's the first line in a file.  some fn main() { let x = X; } </ins>

This code: When run with produces this invalid code because it's losing a newline: With , however, it produces this syntactically correct code:
Moving this bug over to syntex:
Oops, closed the wrong ticket.


Question: io.into_raw_handle(); ret }, <del> Err(..) => unsafe { Ok(Handle::from_raw_handle(c::INVALID_HANDLE_VALUE)) }, </del> <ins> // If no stdio handle is available, then propagate the null value. Err(..) => unsafe { Ok(Handle::from_raw_handle(ptr::null_mut())) }, </ins> }, Stdio::MakePipe => {

<!-- 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: App P: App C: Build this in Windows. Since has "windows" subsystem, it will create no console window (i.e. no process). Since is a console app, when the process is created, I expect to see one console window that prints "Hello World" infinitely. App creates its console window but no text is printed. In Windows, spawn() eventually calls to with a , whose  is hard coded to . Additionally, it also with , and set them to the . Since app uses "windows" subsystem, it does not have console. stdout is always . Combining with in causes the unexpected behavior. If I make a call to with same parameters except a "zeroed" , it exhibits the correct behavior. spawn() should only conditionally set the flag if it can obtain those device handles, and never set any of those handles . Like this (pseudo code): <!-- 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. --:
I think this will need a T-libs-api decision as the current documentation for  (and stdin/stderr) is: I would guess that this "inherit by default" is why it's implemented the way it is. But perhaps there's some wiggle room with what it means to inherit handles that don't exist so we can change it. In either case it would be good to have some way to use platform default behaviour here. label -T-libs +T-libs-api
That's exactly my point. If there is nothing to inherit in the first place, just inherit nothing. The current behavior () is simply wrong. I believe fixing it doesn't violate the current specification.
Basically, currently there are only two options when handling the stdout/stderr: inherit or pipe. I think there should be a third option: isolated - make the child handle its console by itself. For example, if user calls and , he basically says "the parent process doesn't care about the child's output". It is the same as the "windows" subsystem case above. In this case, the flag should never be set, regardless if or is called.


Question: io.into_raw_handle(); ret }, <del> Err(..) => unsafe { Ok(Handle::from_raw_handle(c::INVALID_HANDLE_VALUE)) }, </del> <ins> // If no stdio handle is available, then propagate the null value. Err(..) => unsafe { Ok(Handle::from_raw_handle(ptr::null_mut())) }, </ins> }, Stdio::MakePipe => {

More importantly, this is de facto the default way of how a process is created in Windows. Defaulting to really makes me confused before reading the internal source code.
Not always. Parent process can still set those handles to something other than . For example, if you launch App P from IntelliJ it actually prints "Hello World!" in a loop but not in the spawned console which is empty, but in IntelliJ internal terminal. returns non invalid handle. This solution would make behaviour different depending on how you launch your app. Also, you can explicitly ask to create new console with even if your app already uses console subsystem. In this case you also likely want to avoid inheriting handles because you want output of the spawned process to be displayed in the new console, not in the existing one. This solution doesn't help with this.
I can't verify your statements since I don't have IntelliJ atm, but even it's true, isn't it IntelliJ setting up the console with maybe some special debugging API? How to you modify the code of P to achieve the same? And realistically speaking, do people actually do that with GUI apps? I think in this case, it's impossible to be 100% sure where the user wants the output at. New option might be the way to go.
Your prediction was dead-on, as it came true in While we can do this, as is proposing, it seems best here that we create a function, or set of functions, that explicitly handle this kind of situation rather than guessing.
Even with new APIs, we still need reasonable default behaviour. And the Command API is documented as inheriting handles by default. However, currently the API neglects the "no handle set" case entirely as that's not really a thing in POSIX or ISO C (well, you can close stdio but that's usually considered a Bad Thing unless you're being very very careful).


Question: 0, ); if stackp == MAP_FAILED { <del> panic!("failed to allocate an alternative stack"); </del> <ins> panic!("failed to allocate an alternative stack: {}", io::Error::last_os_error()); </ins> } let guard_result = libc::mprotect(stackp, page_size(), PROT_NONE); if guard_result != 0 { <del> panic!("failed to set up alternative stack guard page"); </del> <ins> panic!("failed to set up alternative stack guard page: {}", io::Error::last_os_error()); </ins> } stackp.add(page_size()) }

There is too little confidence in this mistake, why not return to errno. The mmap interface provides the errno, such as the ENOMEM and SIGSEGV interfaces. panic!("failed to allocate an alternative stack")
!
Please try again your code latest nightly Rust version. Also could you paste the ICE backtrace? label E-needs-mcve I-ICE
This is not a ICE This issue propose printing errno on this :
Probably we want this then: label: -I-ICE, -T-compiler, +T-libs


Question: <ins> // error-pattern: `#[panic_handler]` function required, but not found // Regression test for #54505 - range borrowing suggestion had // incorrect syntax (missing parentheses). // This test doesn't use std // (so all Ranges resolve to core::ops::Range...) #![no_std] #![feature(lang_items)] use core::ops::RangeBounds; #[cfg(not(target_arch = "wasm32"))] #[lang = "eh_personality"] extern fn eh_personality() {} #[cfg(target_os = "windows")] #[lang = "eh_unwind_resume"] extern fn eh_unwind_resume() {} // take a reference to any built-in range fn take_range(_r: &impl RangeBounds<i8>) {} fn main() { take_range(0..1); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &(0..1) take_range(1..); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &(1..) take_range(..); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &(..) take_range(0..=1); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &(0..=1) take_range(..5); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &(..5) take_range(..=42); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &(..=42) } </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> // error-pattern: `#[panic_handler]` function required, but not found // Regression test for #54505 - range borrowing suggestion had // incorrect syntax (missing parentheses). // This test doesn't use std // (so all Ranges resolve to core::ops::Range...) #![no_std] #![feature(lang_items)] use core::ops::RangeBounds; #[cfg(not(target_arch = "wasm32"))] #[lang = "eh_personality"] extern fn eh_personality() {} #[cfg(target_os = "windows")] #[lang = "eh_unwind_resume"] extern fn eh_unwind_resume() {} // take a reference to any built-in range fn take_range(_r: &impl RangeBounds<i8>) {} fn main() { take_range(0..1); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &(0..1) take_range(1..); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &(1..) take_range(..); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &(..) take_range(0..=1); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &(0..=1) take_range(..5); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &(..5) take_range(..=42); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &(..=42) } </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> // error-pattern: `#[panic_handler]` function required, but not found // Regression test for #54505 - range borrowing suggestion had // incorrect syntax (missing parentheses). // This test doesn't use std // (so all Ranges resolve to core::ops::Range...) #![no_std] #![feature(lang_items)] use core::ops::RangeBounds; #[cfg(not(target_arch = "wasm32"))] #[lang = "eh_personality"] extern fn eh_personality() {} #[cfg(target_os = "windows")] #[lang = "eh_unwind_resume"] extern fn eh_unwind_resume() {} // take a reference to any built-in range fn take_range(_r: &impl RangeBounds<i8>) {} fn main() { take_range(0..1); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &(0..1) take_range(1..); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &(1..) take_range(..); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &(..) take_range(0..=1); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &(0..=1) take_range(..5); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &(..5) take_range(..=42); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &(..=42) } </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> // error-pattern: `#[panic_handler]` function required, but not found // Regression test for #54505 - range borrowing suggestion had // incorrect syntax (missing parentheses). // This test doesn't use std // (so all Ranges resolve to core::ops::Range...) #![no_std] #![feature(lang_items)] use core::ops::RangeBounds; #[cfg(not(target_arch = "wasm32"))] #[lang = "eh_personality"] extern fn eh_personality() {} #[cfg(target_os = "windows")] #[lang = "eh_unwind_resume"] extern fn eh_unwind_resume() {} // take a reference to any built-in range fn take_range(_r: &impl RangeBounds<i8>) {} fn main() { take_range(0..1); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &(0..1) take_range(1..); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &(1..) take_range(..); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &(..) take_range(0..=1); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &(0..=1) take_range(..5); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &(..5) take_range(..=42); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &(..=42) } </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: use rustc_ast::{self as ast, NodeId, CRATE_NODE_ID}; use rustc_ast::{AngleBracketedArg, Crate, Expr, ExprKind, GenericArg, GenericArgs, LitKind, Path}; use rustc_ast_lowering::{LifetimeRes, ResolverAstLowering}; <del> use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap}; </del> <ins> use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet}; </ins> use rustc_data_structures::intern::Interned; use rustc_data_structures::sync::Lrc; use rustc_errors::{Applicability, DiagnosticBuilder, ErrorGuaranteed};

The resolver gathers a list of possibly unused trait imports in . This list is passed to resolver outputs, into the query. This query takes a and returns whether the import is possibly unused. This is used by the post-typeck unused import check in . This query iterates over all the statements in the crate, checks whether they may be unused trait imports, and warns if they are indeed unused. As there are typically very few unused trait imports compared to the number of items in a crate, it would make sense to directly iterate on . Steps: make an both in and , this will ensure a deterministic iteration order; rename query and give it the signature , and adapt the call site; we do not want to access directly, as this would prevent the query system from detecting that the set has not changed; in , inline and replace the loop over by a loop over ; the filter over there can be removed too (or replaced by a debug-assertion): the set may only point to use statements. Extra: investigate why we check for , and the consequences of removing that check; investigate the impact on perf of converting the to a simple when producing from . I am available on Zulip for any question. <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOT_END --
claim
are you still working on this?
Hello yes sorry for the super slow pace. I am still working on it (mostly reading the rustc dev guide so far). Is that alright or is it important to get this done quickly?
no worries, I am a beginner looking for tasks, hence the qn.


Question: <ins> error[E0308]: mismatched types --> $DIR/issue-30906.rs:15:5 | LL |     test(Compose(f, |_| {})); |     ^^^^ one type is more general than the other | = note: expected type `std::ops::FnOnce<(&'x str,)>` found type `std::ops::FnOnce<(&str,)>` error: aborting due to previous error For more information about this error, try `rustc --explain E0308`. </ins>

Reproduction branch: When applying the change from the last commit I get a panic in my code during the call to . <details<summaryBacktrace</summary</details
Cannot reproduce on my linux. Can you provide a small ? Is that possible? Maybe without all the externals :/
I can reproduce a very similar problem (appears to involve the same origin and failing assertion of ) compiling rust-lang/regex with and compiler flags: For me, setting to 2 or greater is required to present this failure. <details<summarybacktrace</summary<code<preRUSTBACKTRACE=1 cargo build Compiling regex v1.1.2 (/home/kent/rust/regex) thread 'rustc' panicked at 'assertion failed: bpos.tou32() = () + as u32', stack backtrace: 0: std::sys::unix::backtrace::tracing::imp::unwindbacktrace at 1: std::syscommon::backtrace::print at 2: std::panicking::defaulthook::{{closure}} at at 3: std::panicking::defaulthook at 4: rustc::util::common::panichook 5: std::panicking::rustpanicwithhook at 6: std::panicking::beginpanic 7: syntax::sourcemap::SourceMap::bytepostofilecharpos 8: syntax::sourcemap::SourceMap::lookupcharpos 9: <rustccodegenssa::mir::FunctionCx<'a, 'tcx, Bx::scopemetadataforloc 10: <rustccodegenssa::mir::FunctionCx<'a, 'tcx,


Question: <ins> error[E0308]: mismatched types --> $DIR/issue-30906.rs:15:5 | LL |     test(Compose(f, |_| {})); |     ^^^^ one type is more general than the other | = note: expected type `std::ops::FnOnce<(&'x str,)>` found type `std::ops::FnOnce<(&str,)>` error: aborting due to previous error For more information about this error, try `rustc --explain E0308`. </ins>

Bx::debugloc 11: rustccodegenssa::mir::codegenmir 12: rustccodegenssa::base::codegeninstance 13: rustccodegenssa::monoitem::MonoItemExt::define 14: rustccodegenllvm::base::compilecodegenunit::modulecodegen 15: rustc::depgraph::graph::DepGraph::withtask 16: rustccodegenllvm::base::compilecodegenunit 17: rustccodegenssa::base::codegencrate 18: <rustccodegenllvm::LlvmCodegenBackend as rustccodegenutils::codegenbackend::CodegenBackend::codegencrate 19: rustc::util::common::time 20: rustcdriver::driver::phase4codegen 21: rustcdriver::driver::compileinput::{{closure}} 22: <std::thread::local::LocalKey<T::with 23: rustc::ty::context::TyCtxt::createandenter 24: rustcdriver::driver::compileinput 25: rustcdriver::runcompilerwithpool 26: <scopedtls::ScopedKey<T::set 27: rustcdriver::runcompiler 28: syntax::withglobals 29: rustmaybecatchpanic at 30: <F as alloc::boxed::FnBox<A::callbox 31: std::sys::unix::thread::Thread::new::threadstart at at at 32: <unknown33: clone query stack during panic: end of query stack error: internal compiler error: unexpected panic note: the compiler unexpectedly panicked. this is a bug. note: we would appreciate a bug report: note: rustc 1.34.0-nightly ( 2019-02-26) running on x86_64-unknown-linux-gnu note: compiler flags: -Z mir-opt-level=2 -C debuginfo=2 -C incremental --crate-type lib </pre</code</details
With the help of , I've found a tiny test that reproduces this crash on Linux and Mac:
Got another one: <details</detailsHappens when compiling regex tests with and calling on every span found in the mir of the functions needing codegen.
According to glaicer, the ICE from this example has been gone.
can you confirm that your example does not crash on nightly anymore?


Question: <ins> error[E0308]: mismatched types --> $DIR/issue-30906.rs:15:5 | LL |     test(Compose(f, |_| {})); |     ^^^^ one type is more general than the other | = note: expected type `std::ops::FnOnce<(&'x str,)>` found type `std::ops::FnOnce<(&str,)>` error: aborting due to previous error For more information about this error, try `rustc --explain E0308`. </ins>

Has been fixed in
is likely the part of the rollup fixing it.
Shouldn't a testcase be instead of closing this?
A similar crash that still happens:


Question: <ins> error[E0308]: mismatched types --> $DIR/issue-30906.rs:15:5 | LL |     test(Compose(f, |_| {})); |     ^^^^ one type is more general than the other | = note: expected type `std::ops::FnOnce<(&'x str,)>` found type `std::ops::FnOnce<(&str,)>` error: aborting due to previous error For more information about this error, try `rustc --explain E0308`. </ins>

I realize it's kinda nonsensical, but here:
Why didn't WF catch this?
That's because only checks statics/constants.
Still reproducible with .
This ought to be a mostly easy fix. The problem is that the well formedness check, which ought to be rejected this code, is ignoring things in an : They fall through to this `` case: We would need to add support for the HIR item: which in turn has a number of items: which are defined here: presumably we want the to check that the types of are well-formed, roughly analogous to how we current check normal static items: (We probably want similar checks on foreign item fns, though?) One tricky part might be compatibility, we may need to turn this into a compatibility lint in case there is lots of broken code in the wild.
I am trying to fix this bug, and need help moving forward. function is modified to accept a and a , yet it doesn't report any additional errors and the ICE prevails. Test file: Commit: Should I create a pull request or is it too early?
Looks like suggestions are incomplete ( does not require ). Also, I left a comment on your commit about how you can avoid adding . I suspect the only reason regular s are required to be is they have an initializer (and that, not the type, requires ), i.e. for we have these errors:
Oddly, the PR that were previously posted to fix this (PR , following on PR ) was subsequently closed as inactive ... but the bug itself seems like it may have been resolved in the meantime?
I'm going to assume this was fixed. Tagging as E-needstest, but if someone wants to take the time, it'd be even better to bisect to where this was fixed, and see if a regression test for this was at that time.
Compiler no longer panics, tested with


Question: } types::ItemEnum::Method(_) <ins> | types::ItemEnum::Module(_) </ins> | types::ItemEnum::AssocConst { .. } | types::ItemEnum::AssocType { .. } | types::ItemEnum::PrimitiveType(_) => true, <del> types::ItemEnum::Module(_) | types::ItemEnum::ExternCrate { .. } </del> <ins> types::ItemEnum::ExternCrate { .. } </ins> | types::ItemEnum::Import(_) | types::ItemEnum::StructField(_) | types::ItemEnum::Variant(_)

Found via and seems like a different issue than with rustdoc JSON is built labels +A-rustdoc-json +T-rustdoc +I-ICE +requires-nightly +E-needs-mcve
MCVE: ` modify labels: -E-needs-mcve


Question: create_default_session_globals_then(|| { let comment = "n let a: *i32;n *a = 5;n"; let stripped = beautify_doc_string(Symbol::intern(comment), CommentKind::Block); <del> assert_eq!(stripped.as_str(), " let a: *i32;n *a = 5;"); </del> <ins> assert_eq!(stripped.as_str(), "let a: *i32;n*a = 5;"); </ins> }) }

Hi, I've just published a new version of my crate and the generated documentation is including a lot of bullet points that have never been included before. When I generate the docs locally on the 1.8.1 source code using the latest stable version of rust I see the same formatting for the 1.8.0 that generated, so I think this is a bug that's slipped into the nightly version of Stable local docs: ! ! My guess is that it's because I'm using block comments, the unwanted bullet points seem to match up with empty lines in the documentation comment which consist of just a . Thanks
Seems potentially related to , but the latest builds were from a nightly that should have that fixed in; cc you probably have some idea on where the issue is.
This is highly surprising indeed. Can you run with the last nightly locally and tell us if it reproduces the bug please? If so, I'll try to check what's wrong in rustdoc.
I have ran cargo doc on the latest nightly locally (nightly-x86_64-unknown-linux-gnu rustc 1.60.0-nightly ( 2022-01-20)) and it has reproduced the bug - I see the same generated docs as from the build.
It'll be fixed by
Thanks, is there any way I can get to rebuild the docs for the affected versions or will I have to submit a new version of my library to get a fixed build?
Sure. But that for that, please open an issue on repository directly.


Question: LL |         for _ in &self.h { |                  + <del> error: aborting due to 2 previous errors </del> <ins> error[E0507]: cannot move out of a shared reference --> $DIR/for-i-in-vec.rs:21:19 | LL |     for loader in *LOADERS { |                   ^^^^^^^^ move occurs because value has type `Vec<&u8>`, which does not implement the `Copy` trait | help: consider iterating over a slice of the `Vec<&u8>`'s content | LL |     for loader in &*LOADERS { |                   + error: aborting due to 3 previous errors </ins> For more information about this error, try `rustc --explain E0507`.

<!-- 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. --Haven't minimized the code yet, but the exact code is up here: It's a kind of search algorithm. I think the problematic code is the function in . Will report back if I figure out anything more. <!-- 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</detailsI just switched to the stable toolchain, and the compilar gave me two errors: Apparently these were not caught by the nightly compiler.
This is probably a duplicate of You're using the nightly compiler though, so working as intended
Assigning priority as discussed in the of the Prioritization Working Group. label -I-prioritize +P-medium


Question: LL |         for _ in &self.h { |                  + <del> error: aborting due to 2 previous errors </del> <ins> error[E0507]: cannot move out of a shared reference --> $DIR/for-i-in-vec.rs:21:19 | LL |     for loader in *LOADERS { |                   ^^^^^^^^ move occurs because value has type `Vec<&u8>`, which does not implement the `Copy` trait | help: consider iterating over a slice of the `Vec<&u8>`'s content | LL |     for loader in &*LOADERS { |                   + error: aborting due to 3 previous errors </ins> For more information about this error, try `rustc --explain E0507`.

<!-- 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. --Compiles with replaced for <!-- 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<!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
I got the same issue on the latest nightly and on , without using rustc-private The commented out block was used originally and triggers the ICE as well.
searched nightlies: from nightly-2021-07-29 to nightly-2021-08-02 regressed nightly: nightly-2021-07-31 searched commits: from to regressed commit: <details<summarybisected with <a href=''cargo-bisect-rustc</av0.6.0</summaryHost triple: x8664-pc-windows-msvc Reproduce with: </detailsI think this might have been introduced by , in particular this piece of code:
If that's indeed caused by then we should let its author know:
Just checked and thankfully .
claim
Assigning priority as discussed in the of the Prioritization Working Group. label -I-prioritize +P-high


Question: <del> Subproject commit 61605ebde25f920b18cc2f7e1b92838cd7b6fa67 </del> <ins> Subproject commit 05fdec916a3a9755c6ea603bab79cdb2f7c062bf </ins>

Hello, this is your friendly neighborhood mergebot. After merging PR rust-lang/rust, I observed that the tool miri no longer builds. A follow-up PR to the repository is needed to fix the fallout. cc do you think you would have time to do the follow-up work? If so, that would be great!


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. // Test that we cannot create objects from unsized types. trait Foo for Sized? {} impl Foo for str {} fn test<Sized? T: Foo>(t: &T) { let u: &Foo = t; //~^ ERROR `core::kinds::Sized` is not implemented for the type `T` let v: &Foo = t as &Foo; //~^ ERROR `core::kinds::Sized` is not implemented for the type `T` } fn main() { let _: &[&Foo] = &["hi"]; //~^ ERROR `core::kinds::Sized` is not implemented for the type `str` let _: &Foo = "hi" as &Foo; //~^ ERROR `core::kinds::Sized` is not implemented for the type `str` } </ins>

cc
cc too, presumably a consequence of the trait reform/new vtable lookup code
Hmm, yes. Probably we can fix this by just...allowing it to skolemize an open existential type. I just didn't expect this to ever happen.
actually, while debugging this I remembered that it is not possible to make an object out of an unsized type. We need to add a check for this I guess!
Explanation from PR: In the general case, at least, it is not possible to make an object out of an unsized type. This is because the object type would have to store the fat pointer information for the self value and the vtable -- meaning it'd have to be a fat pointer with three words -- but for the compiler to know that the object requires three words, it would have to know the self-type of the object (is self a thin or fat pointer?), which of course it doesn't.


Question: // was not actually bumped past it. When the `LazyAttrTokenStream` gets converted // into an `AttrTokenStream`, we will create the proper token. if self.token_cursor.break_last_token { <del> assert_eq!( trailing, TrailingToken::None, "Cannot set `break_last_token` and have trailing token" ); </del> <ins> assert!(!captured_trailing, "Cannot set break_last_token and have trailing token"); </ins> end_pos += 1; }

Found with The attribute applies to The was initially lexed as part of a token This seems to be exactly the case described by the : <details<summary<strongBacktrace</strong</summary<p</p</details<!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim
Do you have any suggestion for this case? The code path is going like this: Parser eat the first one of '' at here and set : fall pass at here: So this assertion is failed: The result is: and is true. Seems the assertion missed this scenario, do we need to add a TrailingToken::Gt ?
The assertion I wrote is overly conservative - it really just needs to check that we don't simultaneously break a token and 'really' capture a trailing token. Specifically, we only need to panic if we actually incremented in the match block. I think the simplest fix would be to add a variable, which gets set to in the parts of the block that increment . The assertion can then be changed to breaklasttoken


Question: <ins> // check-pass // compile-flags: -Zsave-analysis trait Trait { type Assoc; } trait GenericTrait<T> {} struct Wrapper<B> { b: B } fn func() { // Processing associated path in impl block definition inside a function // body does not ICE impl<B: Trait> GenericTrait<B::Assoc> for Wrapper<B> {} } fn main() {} </ins>

While compiling rayon:
cc
triage: P-high, assigning to . Removing nomination label.
The fact that this bug was unknown until now strikes me as a sign that we have never attempted to run on the rustc test suite (i.e. compiletest). is this true? Would it be worthwhile to attempt that experiment?
I'm not sure if this is the correct approach, but I just executed the with the following patch applied: and the test suite did crash/ended up all green. It might be a good idea to always run the tests along with save-analysis passed. Should that be optionally enabled? Should we run it, e.g. in the container?