Question: } // Reverse scan: Sequence comes before `first`. <del> if subfirst.maybe_empty || seq_rep.op == quoted::KleeneOp::ZeroOrMore { </del> <ins> if subfirst.maybe_empty || seq_rep.op == quoted::KleeneOp::ZeroOrMore || seq_rep.op == quoted::KleeneOp::ZeroOrOne { </ins> // If sequence is potentially empty, then // union them (preserving first emptiness). first.add_all(&TokenSet { maybe_empty: true, ..subfirst });

The following code will cause the compiler to fail: Playground link: It should error that the inner matcher can match an empty string and reject it, just as it does if is used in place of .
The fix should be very easy, since this was already fixed for repetitions in (original bug: ): Looks like just needs to be checked against , too.
cc
Note that with on the outside, this errors properly, although with inconsistent error messages: if the inner repetition uses only, the error is "repetition matches empty token tree", but it seems that if any of the repetitions are , then the error is "multiple successful parses".
The behaviour in my previous comment is because the check for "repetition matches empty token tree" is done at definition time, but does not catch ; this is caught at expansion time however. Ideally all of this will be moved to definition time and the expansion-time check should probably be a) corrected to address the first comment and b) possibly become an ICE, since it should never be encountered since the RFC 550 rules should eliminate all ambiguity at definition time?
Hmm... I don't really remember how most of this code works... Just grepping, but it looks like there are a couple of other places we might want to look at:
I've opened


Question: /// Loads the current context and calls a function with it. /// Do not nest these, as that will ICE. pub(crate) fn with<R>(f: impl FnOnce(&mut dyn Context) -> R) -> R { <del> let ptr = TLV.replace(std::ptr::null_mut()) as *mut &mut dyn Context; assert!(!ptr.is_null()); let ret = f(unsafe { *ptr }); TLV.set(ptr as _); ret </del> <ins> assert!(TLV.is_set()); TLV.with(|tlv| { let ptr = tlv.get(); assert!(!ptr.is_null()); f(unsafe { *(ptr as *mut &mut dyn Context) }) }) </ins> }

is left set to a dangling pointer if unwinds. This is unsound because a later call to will use that dangling pointer. There is a similar issue with and unwinding. since you're on the Stable MIR cc list: cc
if you can add it as a dependency, using would probably be better than rolling your own version.
Yea, that makes sense. I think we should look into using it for the module, too, which is how we get a within the compiler itself


Question: #[stable(feature = "unicode_encode_char", since = "1.15.0")] #[inline] pub fn encode_utf8(self, dst: &mut [u8]) -> &mut str { <del> let code = self as u32; let len = self.len_utf8(); match (len, &mut dst[..]) { (1, [a, ..]) => { *a = code as u8; } (2, [a, b, ..]) => { *a = (code >> 6 & 0x1F) as u8 | TAG_TWO_B; *b = (code & 0x3F) as u8 | TAG_CONT; } (3, [a, b, c, ..]) => { *a = (code >> 12 & 0x0F) as u8 | TAG_THREE_B; *b = (code >> 6 & 0x3F) as u8 | TAG_CONT; *c = (code & 0x3F) as u8 | TAG_CONT; } (4, [a, b, c, d, ..]) => { *a = (code >> 18 & 0x07) as u8 | TAG_FOUR_B; *b = (code >> 12 & 0x3F) as u8 | TAG_CONT; *c = (code >> 6 & 0x3F) as u8 | TAG_CONT; *d = (code & 0x3F) as u8 | TAG_CONT; } _ => panic!( "encode_utf8: need {} bytes to encode U+{:X}, but the buffer has {}", len, code, dst.len(), ), }; // SAFETY: We just wrote UTF-8 content in, so converting to str is fine. unsafe { from_utf8_unchecked_mut(&mut dst[..len]) } </del> <ins> // SAFETY: `char` is not a surrogate, so this is valid UTF-8. unsafe { from_utf8_unchecked_mut(encode_utf8_raw(self as u32, dst)) } </ins> } /// Encodes this character as UTF-16 into the provided `u16` buffer,

The following program causes UB: Miri says: The problem is this code: This calls unless the new code point is in , but what about surrogates in ? This code is unchanged since its introduction in I am not sure what the intended safety contract of is. That method is not marked but clearly should be -- it calls . So my guess is the safety precondition is that must not be part of a surrogate pair, but the thing is, calls it without actually ensuring that condition. The condition it does ensure is that the codepoint is not in , but that does not help.
is excluded from Unicode scalar values a.k.a. , but it’s fine as a Unicode code point. I think this bug is not in the contract of (which is private anyway) but in its implementation, namely going through . The fix is to either duplicate the logic of into , or (to avoid duplication) move that logic to a new function in libcore that takes a parameter and that is called by both and . This function would need to be public because is in a different crate, but it should be prema-unstable and .
I would classify the priority of this bug as low. Although this call to is UB, I expect Miri checking for it explicitly is the only case where that has any consequence in today’s implementation: behaves as expected (for the purpose of WTF-8) in the surrogate range and does not exploit this UB The "layout" of in rustc excludes values beyond but not surrogates:
By the way, the docs at feel insufficient: Which values are invalid? Similarly, and say that represents Unicode Scalar values, but I couldn’t find it documented anywhere that constructing an out of range is Undefined Behavior rather than "merely" a logic bug. Is this specified elsewhere? What is the closest we have to a written down normative resource that specifies what is or isn’t UB in the the Rust language? (For APIs I assume this is the responsibility of their respective doc-comments.)
I agree the impact is low, but it's not just Miri -- this blocks , which is how I discovered the problem. That would be
But then what is "unchecked" about it? Elsewhere in that file the code is careful not to construct a from a without checking for surrogates: That made me assume the author was aware that surrogates in are UB.


Question: #[stable(feature = "unicode_encode_char", since = "1.15.0")] #[inline] pub fn encode_utf8(self, dst: &mut [u8]) -> &mut str { <del> let code = self as u32; let len = self.len_utf8(); match (len, &mut dst[..]) { (1, [a, ..]) => { *a = code as u8; } (2, [a, b, ..]) => { *a = (code >> 6 & 0x1F) as u8 | TAG_TWO_B; *b = (code & 0x3F) as u8 | TAG_CONT; } (3, [a, b, c, ..]) => { *a = (code >> 12 & 0x0F) as u8 | TAG_THREE_B; *b = (code >> 6 & 0x3F) as u8 | TAG_CONT; *c = (code & 0x3F) as u8 | TAG_CONT; } (4, [a, b, c, d, ..]) => { *a = (code >> 18 & 0x07) as u8 | TAG_FOUR_B; *b = (code >> 12 & 0x3F) as u8 | TAG_CONT; *c = (code >> 6 & 0x3F) as u8 | TAG_CONT; *d = (code & 0x3F) as u8 | TAG_CONT; } _ => panic!( "encode_utf8: need {} bytes to encode U+{:X}, but the buffer has {}", len, code, dst.len(), ), }; // SAFETY: We just wrote UTF-8 content in, so converting to str is fine. unsafe { from_utf8_unchecked_mut(&mut dst[..len]) } </del> <ins> // SAFETY: `char` is not a surrogate, so this is valid UTF-8. unsafe { from_utf8_unchecked_mut(encode_utf8_raw(self as u32, dst)) } </ins> } /// Encodes this character as UTF-16 into the provided `u16` buffer,

The type contains a (generalized-UTF-8-encoded) sequence of code point (including potentially surrogates) that doesn’t form a surrogate pair. doesn’t check for surrogate pairs. is a public method that is documented as returning a scalar value, therefore excluding all surrogates. Ok I looked into it, there are three different people involved. The original code in 2014 was YOLO Later in 2014, moved to duplicating logic instead. In 2015, PR which first imported WTF-8 support in libstd deduplicated that logic by adding a function that takes . (I knew that approach sounded familiar…) In 2016, PR changed the signature of and in passing removed . It made use + instead, presumably in the middle of updating many callers other.
Okay, so the fix would be to revert the part of that removed ?
That or copy into . I find them both not great, so meh.
Even with that done, there's still UB in another testcase: This is converting something to a before calling -- so probably the same issue as the above, just for a different encoding.


Question: /// /// [`to_ascii_uppercase`]: #method.to_ascii_uppercase #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] <del> #[rustc_const_unstable(feature = "const_make_ascii", issue = "130698")] </del> <ins> #[rustc_const_stable(feature = "const_make_ascii", since = "CURRENT_RUSTC_VERSION")] </ins> #[inline] <ins> #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] </ins> pub const fn make_ascii_uppercase(&mut self) { // FIXME(const-hack): We would like to simply iterate using `for` loops but this isn't currently allowed in constant expressions. let mut i = 0;

Feature gate: This is a tracking issue for marking the and methods in , , , and as "const." [x] Implementation for : [x] Implementation for : [x] Implementation for and : [x] Final comment period (FCP) [x] Stabilization PRNone yet.
fcp merge / have been stable in const since 1.52. / are unblocked now by the stabilization of
Team member has proposed to merge this. The next step is review by the rest of the tagged team members: [x] [x] [x] [ ] [ ] No concerns currently listed. Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See for info about what commands tagged team members can give me.
Can the methods be included in this? Similarly const stable / since 1.52.
Yes, that sounds like a good idea. I'll try adding another PR later.
:bell: This is now entering its final comment period, as per the . :bell:
stabilises this.
The final comment period, with a disposition to merge, as per the , is now complete. As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed. This will be merged soon.


Question: <ins> struct NotCopyable; fn func<F: FnMut() -> H, H: FnMut()>(_: F) {} fn parse() { let mut var = None; func(|| { // Shouldn't suggest `move ||.as_ref()` here move || { //~^ ERROR: cannot move out of `var` var = Some(NotCopyable); } }); } fn main() {} </ins>

gives the error: Error0507 gives a wrong suggestion here:
Error: Label D-invalid-suggestion can only be set by Rust team members Please let know if you're having trouble with this bot.
modify labels: A-suggestion-diagnostics C-bug T-compiler


Question: <ins> // ignore-32bit // This test gives a different error on 32-bit architectures. union Transmute<T: Copy, U: Copy> { t: T, u: U, } trait Bar { fn bar(&self) -> u32; } struct Foo { foo: u32, bar: bool, } impl Bar for Foo { fn bar(&self) -> u32 { self.foo } } #[derive(Copy, Clone)] struct Fat<'a>(&'a Foo, &'static VTable); struct VTable { size: Foo, } const FOO: &dyn Bar = &Foo { foo: 128, bar: false, }; const G: Fat = unsafe { Transmute { t: FOO }.u }; //~^ ERROR it is undefined behavior to use this value fn main() {} </ins>

<!-- Thank you for finding an Internal Compiler Error! If possible, try to provide a minimal verifiable example. You can read "Rust Bug Minimization Patterns" for how to create smaller examples. --<!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</details
glacier ""
Error: Parsing glacier command in failed: ...'cier https' ''... Please let know if you're having trouble with this bot.
Compiler error on but ICE on label +regression-from-stable-to-stable
cc
A previous (now-fixed) ICE with the same error message is
Thanks for the report! Would be good to get a better backtrace; this one seems to be missing many frames and there are no line numbers.
, I updated the backtrace in my first post. I used rustup to get the latest trunk version, and the one I have been using does not have line numbers. If there is a flag or configuration for rustup to get rustc binaries with line numbers, I would be happy to change the settings on my testing machine.
I think getting line numbers requires a debug build of the compiler, so it's not quite as easy as installing something via rustup.
Labeling .
Here's a backtrace with debug info: <details</details
Unfortunately, this bottoms out ; more digging will be needed to determine the true underlying cause of the error.
Here is the actual backtrace of the underlying CTFE/Miri error: <details</detailsIt points to this line: can handle pointer values just fine, so I think what is happening is that we are reading parts of a pointer value here, which indeed is not supported in CTFE.
So... I guess the fix is to make this kind of error also be permitted during validation and turn it into a proper validation error?
Permitting it at the top-level is no good, since then we don't know "where in the value" it arose. We need a version of that catches this error and turns it into a validation error with the current "path".
Oh... right, we should fix this in general, and not just wrap in .


Question: <ins> // ignore-32bit // This test gives a different error on 32-bit architectures. union Transmute<T: Copy, U: Copy> { t: T, u: U, } trait Bar { fn bar(&self) -> u32; } struct Foo { foo: u32, bar: bool, } impl Bar for Foo { fn bar(&self) -> u32 { self.foo } } #[derive(Copy, Clone)] struct Fat<'a>(&'a Foo, &'static VTable); struct VTable { size: Foo, } const FOO: &dyn Bar = &Foo { foo: 128, bar: false, }; const G: Fat = unsafe { Transmute { t: FOO }.u }; //~^ ERROR it is undefined behavior to use this value fn main() {} </ins>

Maybe we should not have any automatic way to bubble up errors and require all sites to use ?
I think we should wrap it but put the wrapped thing into a helper function sow e can also use it for the other places. So basically, you want to use a different error type for validation, one that excludes all the other errors? I am open to refactorings here.
Let's start out with wrapping, and then I can experiment with the refactoring so we can have a look at the usability effect of it Instructions: wrap the call at in a macro invocation and capture the error. Emit a validation message about the fact that reading parts of a pointer is not possible during CTFE. Don't forget to add a test (the failing example from this issue works great as a test) and run the test with
There are quite a few calls in that will all have this problem, so ideally they should all be treated this way. To avoid code duplication, it will probably make sense to move this into a helper function.
Reopening this to track that is still called unguarded a few times in , so e.g. the issue can still arise with .


Question: offsets[usize::try_from(field).unwrap()], layout::FieldPlacement::Array { stride, .. } => { let len = base.len(self)?; <del> assert!(field < len, "Tried to access element {} of array/slice with length {}", field, len); </del> <ins> if field >= len { // This can be violated because this runs during promotion on code where the // type system has not yet ensured that such things don't happen. debug!("Tried to access element {} of array/slice with length {}", field, len); return err!(BoundsCheck { len, index: field }); } </ins> stride * field } layout::FieldPlacement::Union(count) => {

Originally stumbled upon through the eval IRC bot: Here's the smallest reproduction I could get, Removing either the block or the borrow displays only a normal compiler error (not an ICE) trace
triage: P-high, assigned to ; removing I-nominated label


Question: LL | m!(); | ----- in this macro invocation <del> warning: `$crate` may not be imported </del> <ins> error: `$crate` may not be imported </ins> --> $DIR/dollar-crate-is-keyword.rs:9:9 | <del> LL |         use $crate; // OK </del> <ins> LL |         use $crate; </ins> |         ^^^^^^^^^^^ ... LL | m!(); | ----- in this macro invocation <del> | = note: `use $crate;` was erroneously allowed and will become a hard error in a future release warning: `$crate` may not be imported --> $DIR/dollar-crate-is-keyword.rs:11:9 </del> <ins> error: `$crate` may not be imported --> $DIR/dollar-crate-is-keyword.rs:10:9 </ins> | LL |         use $crate as $crate; |         ^^^^^^^^^^^^^^^^^^^^^ ... LL | m!(); | ----- in this macro invocation <del> | = note: `use $crate;` was erroneously allowed and will become a hard error in a future release error: aborting due to 2 previous errors </del> <ins> error: aborting due to 4 previous errors </ins>

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


Question: /// ``` #[macro_export] macro_rules! write { <del> ($dst:expr, $($arg:tt)*) => ((&mut *$dst).write_fmt(format_args!($($arg)*))) </del> <ins> ($dst:expr, $($arg:tt)*) => ($dst.write_fmt(format_args!($($arg)*))) </ins> } /// Equivalent to the `write!` macro, except that a newline is appended after

For clarity, the second call to ends up using the impl on . cc I had concerns about this kind of thing when these impls were being introduced but I thought I convinced myself that this kind of thing couldn't happen. Did something change in the way we designed these impls since then?
Possible solutions are to either remove the impl for or update to prevent it from invoking . Seems to me like the second is the better approach.
I believe the reason for the was because it was considered a good thing to require callers to explicitly pass references. I think we've actually gone back and forth on that a few times. Are we committed now to allowing callers to just say ?


Question: use libc::{mmap, munmap}; use libc::{sigaction, sighandler_t, SA_ONSTACK, SA_SIGINFO, SIGBUS, SIG_DFL}; use libc::{sigaltstack, SIGSTKSZ, SS_DISABLE}; <del> use libc::{MAP_ANON, MAP_PRIVATE, PROT_READ, PROT_WRITE, SIGSEGV}; </del> <ins> use libc::{MAP_ANON, MAP_PRIVATE, PROT_NONE, PROT_READ, PROT_WRITE, SIGSEGV}; use crate::sys::unix::os::page_size; </ins> use crate::sys_common::thread_info; #[cfg(any(target_os = "linux", target_os = "android"))]

Rust's runtime installs a signal handler to distinguish stack overflows from other faults. This requires using an alternate signal stack (), which we create with the default size . That's usually quite small, 8KB or so depending on the target, but it's still plenty for what the handler is doing. There's currently no guard page like we have on normal stacks. That alternate stack is shared by all signals for a thread, so if a user installs any other signal handler, and they opt in with the flag , they'll be limited to the same tiny stack. If their handler happens to be more involved and overflows that stack, it may silently clobber other memory. If we had a guard page on the signal stack, that would cause a process abort instead. This was reported to the Security Response WG with a reproducer in . However, after discussion we decided to treat this as a normal issue for a few reasons: Setting a custom signal handler requires code. Signal handlers already run in a quite constrained environment, e.g. . It's unusual to use for signals other than , and if you choose so, you also bear responsibility to make sure that stack suffices. Nevertheless, as a defensive measure, it's still a reasonable idea to map a guard page when Rust is creating its signal stack, so an unexpected overflow will abort rather than silently corrupting memory. For full protection, that would also depend on the guard page not being skipped, but not all targets have stack probes yet (). Thanks to for reporting this in accordance with our , even though we have decided not to treat this as a security issue at this time. cc
cc This is another reason we perhaps shouldn't be registering the signal handler... cc


Question: let source = pprust::token_to_string(self); parse_stream_from_source_str(FileName::MacroExpansion, source, sess, Some(span)) }); <ins> // During early phases of the compiler the AST could get modified // directly (e.g. attributes added or removed) and the internal cache // of tokens my not be invalidated or updated. Consequently if the // "lossless" token stream disagrees with our actual stringification // (which has historically been much more battle-tested) then we go // with the lossy stream anyway (losing span information). // // Note that the comparison isn't `==` here to avoid comparing spans, // but it *also* is a "probable" equality which is a pretty weird // definition. We mostly want to catch actual changes to the AST // like a `#[cfg]` being processed or some weird `macro_rules!` // expansion. // // What we *don't* want to catch is the fact that a user-defined // literal like `0xf` is stringified as `15`, causing the cached token // stream to not be literal `==` token-wise (ignoring spans) to the // token stream we got from stringification. // // Instead the "probably equal" check here is "does each token // recursively have the same discriminant?" We basically don't look at // the token values here and assume that such fine grained modifications // of token streams doesn't happen. </ins> if let Some(tokens) = tokens { <del> if tokens.eq_unspanned(&tokens_for_real) { </del> <ins> if tokens.probably_equal_for_proc_macro(&tokens_for_real) { </ins> return tokens } } return tokens_for_real } <ins> // See comments in `interpolated_to_tokenstream` for why we care about // *probably* equal here rather than actual equality pub fn probably_equal_for_proc_macro(&self, other: &Token) -> bool { if mem::discriminant(self) != mem::discriminant(other) { return false } match (self, other) { (&Eq, &Eq) | (&Lt, &Lt) | (&Le, &Le) | (&EqEq, &EqEq) | (&Ne, &Ne) | (&Ge, &Ge) | (&Gt, &Gt) | (&AndAnd, &AndAnd) | (&OrOr, &OrOr) | (&Not, &Not) | (&Tilde, &Tilde) | (&At, &At) | (&Dot, &Dot) | (&DotDot, &DotDot) | (&DotDotDot, &DotDotDot) | (&DotDotEq, &DotDotEq) | (&DotEq, &DotEq) | (&Comma, &Comma) | (&Semi, &Semi) | (&Colon, &Colon) | (&ModSep, &ModSep) | (&RArrow, &RArrow) | (&LArrow, &LArrow) | (&FatArrow, &FatArrow) | (&Pound, &Pound) | (&Dollar, &Dollar) | (&Question, &Question) | (&Whitespace, &Whitespace) | (&Comment, &Comment) | (&Eof, &Eof) => true, (&BinOp(a), &BinOp(b)) | (&BinOpEq(a), &BinOpEq(b)) => a == b, (&OpenDelim(a), &OpenDelim(b)) | (&CloseDelim(a), &CloseDelim(b)) => a == b, (&DocComment(a), &DocComment(b)) | (&Shebang(a), &Shebang(b)) => a == b, (&Lifetime(a), &Lifetime(b)) => a.name == b.name, (&Ident(a, b), &Ident(c, d)) => a.name == c.name && b == d, (&Literal(ref a, b), &Literal(ref c, d)) => { b == d && a.probably_equal_for_proc_macro(c) } (&Interpolated(_), &Interpolated(_)) => false, _ => panic!("forgot to add a token?"), } } </ins> } #[derive(Clone, RustcEncodable, RustcDecodable, Eq, Hash)]

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


Question: let source = pprust::token_to_string(self); parse_stream_from_source_str(FileName::MacroExpansion, source, sess, Some(span)) }); <ins> // During early phases of the compiler the AST could get modified // directly (e.g. attributes added or removed) and the internal cache // of tokens my not be invalidated or updated. Consequently if the // "lossless" token stream disagrees with our actual stringification // (which has historically been much more battle-tested) then we go // with the lossy stream anyway (losing span information). // // Note that the comparison isn't `==` here to avoid comparing spans, // but it *also* is a "probable" equality which is a pretty weird // definition. We mostly want to catch actual changes to the AST // like a `#[cfg]` being processed or some weird `macro_rules!` // expansion. // // What we *don't* want to catch is the fact that a user-defined // literal like `0xf` is stringified as `15`, causing the cached token // stream to not be literal `==` token-wise (ignoring spans) to the // token stream we got from stringification. // // Instead the "probably equal" check here is "does each token // recursively have the same discriminant?" We basically don't look at // the token values here and assume that such fine grained modifications // of token streams doesn't happen. </ins> if let Some(tokens) = tokens { <del> if tokens.eq_unspanned(&tokens_for_real) { </del> <ins> if tokens.probably_equal_for_proc_macro(&tokens_for_real) { </ins> return tokens } } return tokens_for_real } <ins> // See comments in `interpolated_to_tokenstream` for why we care about // *probably* equal here rather than actual equality pub fn probably_equal_for_proc_macro(&self, other: &Token) -> bool { if mem::discriminant(self) != mem::discriminant(other) { return false } match (self, other) { (&Eq, &Eq) | (&Lt, &Lt) | (&Le, &Le) | (&EqEq, &EqEq) | (&Ne, &Ne) | (&Ge, &Ge) | (&Gt, &Gt) | (&AndAnd, &AndAnd) | (&OrOr, &OrOr) | (&Not, &Not) | (&Tilde, &Tilde) | (&At, &At) | (&Dot, &Dot) | (&DotDot, &DotDot) | (&DotDotDot, &DotDotDot) | (&DotDotEq, &DotDotEq) | (&DotEq, &DotEq) | (&Comma, &Comma) | (&Semi, &Semi) | (&Colon, &Colon) | (&ModSep, &ModSep) | (&RArrow, &RArrow) | (&LArrow, &LArrow) | (&FatArrow, &FatArrow) | (&Pound, &Pound) | (&Dollar, &Dollar) | (&Question, &Question) | (&Whitespace, &Whitespace) | (&Comment, &Comment) | (&Eof, &Eof) => true, (&BinOp(a), &BinOp(b)) | (&BinOpEq(a), &BinOpEq(b)) => a == b, (&OpenDelim(a), &OpenDelim(b)) | (&CloseDelim(a), &CloseDelim(b)) => a == b, (&DocComment(a), &DocComment(b)) | (&Shebang(a), &Shebang(b)) => a == b, (&Lifetime(a), &Lifetime(b)) => a.name == b.name, (&Ident(a, b), &Ident(c, d)) => a.name == c.name && b == d, (&Literal(ref a, b), &Literal(ref c, d)) => { b == d && a.probably_equal_for_proc_macro(c) } (&Interpolated(_), &Interpolated(_)) => false, _ => panic!("forgot to add a token?"), } } </ins> } #[derive(Clone, RustcEncodable, RustcDecodable, Eq, Hash)]

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


Question: // no-pretty-expanded FIXME #15189 // ignore-android FIXME #17520 <del> // ignore-msvc FIXME #28133 </del> <ins> // compile-flags:-g </ins> use std::env; use std::process::{Command, Stdio}; use std::str; <del> use std::ops::{Drop, FnMut, FnOnce}; </del> #[inline(never)] fn foo() {

Symbol names are not properly supported yet on msvc, so backtraces are generally unhelpful. As a result, is currently disabled. This issue can be closed when it's been reenabled.


Question: types that do not implement `Drop` can still have drop glue, consider instead using `{$needs_drop}` to detect whether a type is trivially dropped lint_range_endpoint_out_of_range = range endpoint is out of range for `{$ty}` <del> .suggestion = use an inclusive range instead </del> <ins> lint_range_use_inclusive_range = use an inclusive range instead </ins> lint_overflowing_bin_hex = literal out of range for `{$ty}` .negative_note = the literal `{$lit}` (decimal `{$dec}`) does not fit into the type `{$ty}`

<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. --I tried this code: I expected to see this happen: printing all numbers from 0 to 255 (inclusive) Instead, this happened: : <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
The error is correct, 256 is indeed out of range for u8. You need to use .
You can run that code if you want, by allowing the lint: if you do you'll see that it will print nothing because the overflows and becomes , so it's which is empty. Examples like this where allowing the literal overflow would do something you don't want are exactly why this lint is deny-by-default
I've renamed this issue because the lint is correct. If there's anything to be done here, it would be to add a range-specific suggestion for this situation to help guide towards the correct code.
claim


Question: <ins> PRINT-ATTR INPUT (DISPLAY): fn main() { match() { | () => () } } PRINT-ATTR INPUT (DEBUG): TokenStream [ Ident { ident: "fn", span: $DIR/issue-76182-leading-vert-pat.rs:14:1: 14:3 (#0), }, Ident { ident: "main", span: $DIR/issue-76182-leading-vert-pat.rs:14:4: 14:8 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [], span: $DIR/issue-76182-leading-vert-pat.rs:14:8: 14:10 (#0), }, Group { delimiter: Brace, stream: TokenStream [ Ident { ident: "match", span: $DIR/issue-76182-leading-vert-pat.rs:15:5: 15:10 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [], span: $DIR/issue-76182-leading-vert-pat.rs:15:11: 15:13 (#0), }, Group { delimiter: Brace, stream: TokenStream [ Punct { ch: '|', spacing: Alone, span: $DIR/issue-76182-leading-vert-pat.rs:15:16: 15:17 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [], span: $DIR/issue-76182-leading-vert-pat.rs:15:18: 15:20 (#0), }, Punct { ch: '=', spacing: Joint, span: $DIR/issue-76182-leading-vert-pat.rs:15:21: 15:23 (#0), }, Punct { ch: '>', spacing: Alone, span: $DIR/issue-76182-leading-vert-pat.rs:15:21: 15:23 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [], span: $DIR/issue-76182-leading-vert-pat.rs:15:24: 15:26 (#0), }, ], span: $DIR/issue-76182-leading-vert-pat.rs:15:14: 15:28 (#0), }, ], span: $DIR/issue-76182-leading-vert-pat.rs:14:11: 16:2 (#0), }, ] </ins>

The following code: is currently pretty-printed as: If this occurs in a macro invocation, it leads to an instance of
Extra info (but it boils down to what said): Using I get the following log: Rendered diff:
This applies to all trailing separators in theory (except that the separator is leading rather than trailing in this case), but in other cases the difference is fixed up by fuzzy comparison in .


Question: let mut cmd = Command::new(SHELL); cmd.current_dir(&empty_dir) .arg(sanitize_sh(&tarball.decompressed_output().join("install.sh"))) <del> .arg(format!("--prefix={}", prepare_dir(prefix))) .arg(format!("--sysconfdir={}", prepare_dir(sysconfdir))) .arg(format!("--datadir={}", prepare_dir(datadir))) .arg(format!("--docdir={}", prepare_dir(docdir))) .arg(format!("--bindir={}", prepare_dir(bindir))) .arg(format!("--libdir={}", prepare_dir(libdir))) .arg(format!("--mandir={}", prepare_dir(mandir))) </del> <ins> .arg(format!("--prefix={}", prepare_dir(&destdir_env, prefix))) .arg(format!("--sysconfdir={}", prepare_dir(&destdir_env, sysconfdir))) .arg(format!("--datadir={}", prepare_dir(&destdir_env, datadir))) .arg(format!("--docdir={}", prepare_dir(&destdir_env, docdir))) .arg(format!("--bindir={}", prepare_dir(&destdir_env, bindir))) .arg(format!("--libdir={}", prepare_dir(&destdir_env, libdir))) .arg(format!("--mandir={}", prepare_dir(&destdir_env, mandir))) </ins> .arg("--disable-ldconfig"); builder.run(&mut cmd); t!(fs::remove_dir_all(&empty_dir));

hey everyone, I get this message from when is executed: It seems there are some backports still missing for beta, since I can fix this by reverting locally, and there are some subsequent fixes in nightly who seemed to have fixed the issue for good. So, is there somewhere a list of the nightly backports needed to fix this problem? Thanks.
can I ping you on this? Beta is not compiling on gentoo, I assume at least one patch from nightly still needs to be backported to beta.
There is that should have fixed that and it's .
Hi, I'm on latest beta from last week. If I apply locally and compile, I get access denied error:
Logs says you don't have permission to put files into path from your build configuration. Without you would still get permission error.
I believe this is a sandbox error, so x.py install tries to write to / instead of it's prefix, and this is caused either by or it was already introduced by the older If I revert them both locally, I get a working x.py install
Interesting :thinking: Can you share your build configuration?
it basically does this: which translates to: and the patch seems to make x.py ignore the DESTDIR="" command In the rust context, the build config you asked me to share is the Have it attached for you, please feel free to ask for any additional information. also I can provide you with the full build log:
Did you wait for whole process(x.py install) to be finished? I don't understand how mkdir gets you into access denied error for path while you can actually create dirs/files in it..
Maybe there is some confusion about relative and absolute path? The access denied error is valid, as x.py never should mess with /usr/lib/ in install, but use /var/tmp/portage/dev-lang/rust-1.74.0_beta/image/ as it's prefix, if you want to name it like that.
True, there is a confusion between prefix and DESTDIR right now. I will fix it today.
Thank you, I'm happy to test any patch before you commit it to master.
You can test
yes this works for me, please also beta nominate
has this been beta-nominated? I'm new to this process, it's just I can't see a rollup pullrequest anywhere and the release of 1.74.0 is coming closer every day.


Question: let mut cmd = Command::new(SHELL); cmd.current_dir(&empty_dir) .arg(sanitize_sh(&tarball.decompressed_output().join("install.sh"))) <del> .arg(format!("--prefix={}", prepare_dir(prefix))) .arg(format!("--sysconfdir={}", prepare_dir(sysconfdir))) .arg(format!("--datadir={}", prepare_dir(datadir))) .arg(format!("--docdir={}", prepare_dir(docdir))) .arg(format!("--bindir={}", prepare_dir(bindir))) .arg(format!("--libdir={}", prepare_dir(libdir))) .arg(format!("--mandir={}", prepare_dir(mandir))) </del> <ins> .arg(format!("--prefix={}", prepare_dir(&destdir_env, prefix))) .arg(format!("--sysconfdir={}", prepare_dir(&destdir_env, sysconfdir))) .arg(format!("--datadir={}", prepare_dir(&destdir_env, datadir))) .arg(format!("--docdir={}", prepare_dir(&destdir_env, docdir))) .arg(format!("--bindir={}", prepare_dir(&destdir_env, bindir))) .arg(format!("--libdir={}", prepare_dir(&destdir_env, libdir))) .arg(format!("--mandir={}", prepare_dir(&destdir_env, mandir))) </ins> .arg("--disable-ldconfig"); builder.run(&mut cmd); t!(fs::remove_dir_all(&empty_dir));

It is cc
for backport, the PR's responsible team (T-bootstrap) also needs to label it beta-accepted. Once it has both labels, the release team will handle the actual backport.


Question: #[note] pub struct BuiltinInternalFeatures { pub name: Symbol, <del> #[subdiagnostic] pub note: Option<BuiltinFeatureIssueNote>, </del> } #[derive(Subdiagnostic)]

<!-- 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: note the duplicate <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
feature, not a bug: we want people to be very strongly discouraged, so we say it twice.
the more repetions, the more discouraged. lang_items should go up to 10.
Maybe we should print it in an infinite loop, just to be on the save side?
This is happening on as well.
claim The source of the problem is the decorator for which is adding two to the Diagnostic instead of one. I'm trying to dig further and decipher the marco-generated decorator code here: I also noticed that the behaviour seems to differ across gates. E.g. building this: emits one note for and two notes for : Not sure what's different about these gates. I'm new to this area, so if you can provide any pointers based on the above, please do.
This program tests all the internal gates: It produces the following output: Of the 21 internal gates, only the last 6 result in duplicate notes.
These should be more, there's a file somewhere that defines all the features but I can't check it right now on mobile
I think that should be all of them. This is super weird indeed, no idea
Thanks & I found what's different about gates with duplicate notes: they all have an associated issue. Here's the full list grepped from : Notice that the second last field in the last 6 lines is unlike the rest where it is . Apparently having an associated issue causes this problem.
The root cause is the being passed on this line: Its value is for gates that have an associated issue and for others. Since already has a attribute: this results in duplicates. The solution is to always pass for internal gates.


Question: show_type_layout, generate_link_to_definition, call_locations, <ins> no_emit_shared, </ins> .. } = options;

<!-- 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 rendering docs for a crate with: That puts this in the sidebar: ! In this case, and are dependencies (which I don't want to document). And is the name of one of the examples, this is a dead link.
cc - running on dependencies seems like a cargo bug, but showing them in the sidebar seems like it's an issue in rustdoc.
Thanks for the report I will take a look this week.
Ok, I have fixed the issue where examples show up in the crates list. However, I wasn't able to reproduce the issue with non-examples appearing in the crates list. Specifically, my setup was: I could not get to appear in the sidebar when using .
Thanks I tried some more things, and I think what happened is that I used it without at first, and then without clearing the folder, did it with , which apparently doesn't remove the dependencies from the sidebar. So I guess that part of the issue is about not working quite right when these artefacts already exist, and unrelated to .


Question: Exercise: use macros to reduce duplication in the above definition of the `bct!` macro. <ins> # Common macros Here are some common macros you’ll see in Rust code. ## panic! This macro causes the current thread to panic. You can give it a message to panic with: ```rust,no_run panic!("oh no!"); ``` ## vec! The `vec!` macro is used throughout the book, so you’ve probably seen it already. It creates `Vec<T>`s with ease: ```rust let v = vec![1, 2, 3, 4, 5]; ``` It also lets you make vectors with repeating values. For example, a hundred zeroes: ```rust let v = vec![0; 100]; ``` ## assert! and assert_eq! These two macros are used in tests. `assert!` takes a boolean, and `assert_eq!` takes two values and compares them. Truth passes, success `panic!`s. Like this: ```rust,no_run // A-ok! assert!(true); assert_eq!(5, 3 + 2); // nope :( assert!(5 < 3); assert_eq!(5, 3); ``` ## try! `try!` is used for error handling. It takes something that can return a `Result<T, E>`, and gives `T` if it’s a `Ok<T>`, and `return`s with the `Err(E)` if it’s that. Like this: ```rust,no_run use std::fs::File; fn foo() -> std::io::Result<()> { let f = try!(File::create("foo.txt")); Ok(()) } ``` This is cleaner than doing this: ```rust,no_run use std::fs::File; fn foo() -> std::io::Result<()> { let f = File::create("foo.txt"); let f = match f { Ok(t) => t, Err(e) => return Err(e), }; Ok(()) } ``` ## unreachable! This macro is used when you think some code should never execute: ```rust if false { unreachable!(); } ``` Sometimes, the compiler may make you have a different branch that you know will never, ever run. In these cases, use this macro, so that if you end up wrong, you’ll get a `panic!` about it. ```rust let x: Option<i32> = None; match x { Some(_) => unreachable!(), None => println!("I know x is None!"), } ``` ## unimplemented! The `unimplemented!` macro can be used when you’re trying to get your functions to typecheck, and don’t want to worry about writing out the body of the function. One example of this situation is implementing a trait with multiple required methods, where you want to tackle one at a time. Define the others as `unimplemented!` until you’re ready to write them. </ins> # Procedural macros If Rust's macro system can't do what you need, you may want to write a

is useless () so skip it.
Neither of the macro chapters have sections for "common macros". Should we add one? Presumably there would be quite a few of them.
There is for the macros in std, plus some of the built-in syntax extensions. It's not that easy to find; there used to be a module in the rustdoc output but no longer :( I'm not sure exactly what should be documented where. The built-in syntax extensions like might deserve special mention, as they give you capabilities within that you otherwise would not have. cc
I think , , and also deserve mentions.
I would like to take on the task of documenting all the common macros. I've started them and appreciate some input on how big the final list should be, and if every macro needs an example (or three). What about the most common one, prinln! ? Should that be in there too?
It's not clear to me what doing this issue actually means. Moving some docs between some places?
The original issue was to add several common macro definitions with examples in TRPL, which I agreed with. I'm not sure what's up with the edits.


Question: /// Strip items marked `#[doc(hidden)]` pub fn strip_hidden(krate: clean::Crate) -> plugins::PluginResult { <del> struct Stripper; impl fold::DocFolder for Stripper { fn fold_item(&mut self, i: Item) -> Option<Item> { for attr in i.attrs.iter() { match attr { &clean::List(~"doc", ref l) => { for innerattr in l.iter() { match innerattr { &clean::Word(ref s) if "hidden" == *s => { debug!("found one in strip_hidden; removing"); return None; }, _ => (), </del> <ins> let mut stripped = HashSet::new(); // strip all #[doc(hidden)] items let krate = { struct Stripper<'a> { stripped: &'a mut HashSet<ast::NodeId> }; impl<'a> fold::DocFolder for Stripper<'a> { fn fold_item(&mut self, i: Item) -> Option<Item> { for attr in i.attrs.iter() { match attr { &clean::List(~"doc", ref l) => { for innerattr in l.iter() { match innerattr { &clean::Word(ref s) if "hidden" == *s => { debug!("found one in strip_hidden; removing"); self.stripped.insert(i.id); return None; }, _ => (), } </ins> } <ins> }, _ => () } } self.fold_item_recur(i) } } let mut stripper = Stripper{ stripped: &mut stripped }; stripper.fold_crate(krate) }; // strip any traits implemented on stripped items let krate = { struct ImplStripper<'a> { stripped: &'a mut HashSet<ast::NodeId> }; impl<'a> fold::DocFolder for ImplStripper<'a> { fn fold_item(&mut self, i: Item) -> Option<Item> { match i.inner { clean::ImplItem(clean::Impl{ for_: clean::ResolvedPath{ id: for_id, .. }, .. }) => { if self.stripped.contains(&for_id) { return None; </ins> } <del> }, _ => () </del> <ins> } _ => {} </ins> } <ins> self.fold_item_recur(i) </ins> } <del> self.fold_item_recur(i) </del> } <del> } let mut stripper = Stripper; let krate = stripper.fold_crate(krate); </del> <ins> let mut stripper = ImplStripper{ stripped: &mut stripped }; stripper.fold_crate(krate) }; </ins> (krate, None) }

Trying to search for anything on results in a Javascript error: on line 313 of I'm on Chrome 30.0.1599.101 if that matters.
Weirdly, search results still appear if I search for most things, but not for anything starting with "sle" like "sleep".
This appears to be dying because of the method defined in . This shouldn't be showing up in the search because the entire module should be pruned as a result of it being private. This warrants more investigation...
Update: seems like it's not for "any" keyword as the OP states; for example or don't trigger any error for me. does for instance.
doesn't work either.
Happens to me too.
, , , , , , , and (and all shortened forms e.g. , ) don't work for me, but does work (i.e. shows results). The error I'm getting (on Firefox Nightly 29.0a1) is .
The error happens when a trait is implemented on a type that is pruned by one of the passes ( or ). The type was pruned but the implementation was not, so the search index included a method that referenced a missing type. fixes this.


Question: self_expr: &'tcx hir::Expr<'tcx>, call_expr: &'tcx hir::Expr<'tcx>, ) -> ConfirmContext<'a, 'tcx> { <del> ConfirmContext { fcx, span, self_expr, call_expr } </del> <ins> ConfirmContext { fcx, span, self_expr, call_expr, skip_record_for_diagnostics: false } </ins> } fn confirm(

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


Question: // can just use the tcx as the typer. // // FIXME(stage0): the :'t here is probably only important for stage0 <del> pub struct ExprUseVisitor<'d, 't, 'a: 't, 'tcx:'a+'d+'t> { </del> <ins> pub struct ExprUseVisitor<'d, 't, 'a: 't, 'tcx:'a+'d> { </ins> typer: &'t infer::InferCtxt<'a, 'tcx>, mc: mc::MemCategorizationContext<'t, 'a, 'tcx>, delegate: &'d mut Delegate<'tcx>,

When trying to update uutils/coreutils to HEAD, I got this ICE: Version: code:
apparently, this happens as a side effect of the build process. i had built with stable, then tried to build with nightly, giving incorrect metadata


Question: #[rustc_on_unimplemented = "the type {Self} contains interior mutability  and a reference may not be safely transferrable  across a recover boundary"] <del> pub trait NoUnsafeCell {} </del> <ins> pub trait RefRecoverSafe {} </ins> /// A simple wrapper around a type to assert that it is panic safe. ///

Test Case 1: Test Case 2: Both produce errors like this: CC
Hm, so the first case here should work (e.g. should subvert basically everything), although the second case is correct in yielding an error (albeit not a very good one)
Is the second case not allowed then? 's documentation suggests that manually implementing it is okay to do: I figured only existed to wrap types which you couldn't yourself, but for which you can ensure their invariants are upheld across the boundary. And what about moving values into the closure? can't be unwrapped, at least not currently.
Oh wait sorry I misread your second example, I failed to notice the manual ! This is basically a case where closure captures are coming into play. The closures aren't annotated with , so outer variables are captured by-reference which means that the actual types being tested against the trait here are and . In the first case that should be handled by , but the second is legitimately indicating that it's not a recover-safe type (b/c the reference is different than the by-value). You should be able to get around this via either plus or via . Certainly an interesting interaction going on here though. One would likely expect that if isn't recover safe that would fix the problem but it's likely what you really need to do is due to the way closures largely work.
There's , why not ? Coherence?
Nah unfortunately that'd defeat the purpose of the distinction. The type is itself recover safe, it's just that's not (so the distinction need to be there)
It's unfortunate that fails due to coherence or something like that:
Hm interesting, I guess yeah you'll be forced to move the reference inside the wrapper rather than having a reference to the wrapper
Is it possible to implement then? My use case can contain and friends but I'm guaranteeing that they're unobservable in user code after recovery because I immediately re-panic after escaping the FFI stack.
I guess I can just use once it's fixed :stuckouttongue:. I see your PR has been accepted so I'll look forward to trying it on tonight's nightly. When do the buildbots fire?
Yeah currently you can implement (being renamed to ) I believe (although I can't say I've tried). For now though yeah I'd recommend just using plus closures.


Question: #[rustc_on_unimplemented = "the type {Self} contains interior mutability  and a reference may not be safely transferrable  across a recover boundary"] <del> pub trait NoUnsafeCell {} </del> <ins> pub trait RefRecoverSafe {} </ins> /// A simple wrapper around a type to assert that it is panic safe. ///

The PR is in but'll take a few hours at least to land.
the problem with moving at this point in time is that I call in different branches of a but I pass the same closed-over value to it; I can't do the branch in the closure because I need to do some FFI cleanup afterwards regardless of whether a panic happened or not (which also requires the closed-over value). It would help if derived and/or so I could reuse it without constructing a new value for each arm, but that would probably require some discussion because I don't know if it's safe or not. I'll probably just implement and fix the name after your PR drops. A quick check confirms that it works just fine. Thanks anyways!
Oh yeah we could totally add more traits like and to , there shouldn't be any safety concerns there.
Updating code to modern functions and traits in makes this compile, so I'm going to close.


Question: impl FromStr for Ipv4Addr { type Err = AddrParseError; fn from_str(s: &str) -> Result<Ipv4Addr, AddrParseError> { <del> Parser::new(s).parse_with(|p| p.read_ipv4_addr()) </del> <ins> // don't try to parse if too long if s.len() > 15 { Err(AddrParseError(())) } else { Parser::new(s).parse_with(|p| p.read_ipv4_addr()) } </ins> } }

According to the , "The four octets are in decimal notation, divided by . (this is called 'dot-decimal notation'). Notably, octal numbers and hexadecimal numbers are not allowed per IETF RFC 6943"; however the parsing of the violates the "strict" form mentioned in —this form is what prohibits octal and hexadecimal numbers—meanwhile the conforms to it. IETF RFC 6943 Section 3.1.1. states: If the af argument of inetpton() is AFINET, the src string shall be in the standard IPv4 dotted-decimal form: where "ddd" is a one to three digit decimal number between 0 and The inetpton() function does not accept other formats (such as the octal numbers, hexadecimal numbers, and fewer than four numbers that inetaddr() accepts). As shown above, inetpton() uses what we will refer to as the "strict" form of an IPv4 address literal. Some platforms also use the strict form with getaddrinfo() when the AINUMERICHOST flag is passed to it. I tried this code: I expected to see this happen: both s not causing a panic since the first has an octet represented by more than three base-10 numbers despite the requirement per RFC 6943 stating each octet be a "one to three digit decimal number". The second is valid per RFC 6943 since it is a string of exactly 4 octets separated by where each octet is a "one to three digit decimal number". Instead, this happened: Both lines cause a panic. : : <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summaryBacktrace</summary<p</p</details
I believe that the second input () is not valid, since the spec explicitly says that octal numbers are disallowed, and is an octal number in the loose form. The example in the RFC for an octal number is , which parses to if you use octal, but if you use decimal. If you instead have it parse it always as , that means that bad things can happen, such as different tools interpreting as different things.


Question: impl FromStr for Ipv4Addr { type Err = AddrParseError; fn from_str(s: &str) -> Result<Ipv4Addr, AddrParseError> { <del> Parser::new(s).parse_with(|p| p.read_ipv4_addr()) </del> <ins> // don't try to parse if too long if s.len() > 15 { Err(AddrParseError(())) } else { Parser::new(s).parse_with(|p| p.read_ipv4_addr()) } </ins> } }

If you read the source code where the ipv4 address is parsed, it specifically disallows that: Regarding , the documentation only says that the disallowing of hexadecimal and octal numbers are according to IETF RFC 6943, and does not say anything about only allowing three digits. Also, four or more zeroes are an edge case, and thus the only numbers that can be parsed there with more than three digits, due to the disallowing of octal numbers apart from .
From the :
I'm confused by these comments. Padded zeros is not unique to the base-8 numeral system. Base-2, Base-3, etc. all have the property of having an infinite number of padded zeros with the convention being to truncate them all. After all is also valid in base-8, base-9, etc. The documentation is quite clear that the octets are to be interpreted in base-10 though, so this problem of how to interpret the octets is solved. Consequently the last octet in is interpreted as 1 in base-10 for the same reason the first octet in is interpreted as 127 in base-10 and not some other value (e.g., 87 in base-10) namely because the documentation says so. After all objecting to on the grounds that the last octet could be in base-8—again, all of the octets there could be in base-8—doesn't apply to the fact that is also rejected by the parsing algorithm since clearly each of those octets are not in base-8 since is not a symbol in the base-8 numeral system. This is of course nothing more than a consequence of incorrectly assuming padded 0s means base-8. The inconsistent treatment of 0 (in base-10) is also a consequence of this incorrect assumption. Why is 0 (in base-10) allowed to be represented by one or more s, but 1 (in base-10) cannot have padded s? There is nothing special about the syntactic representation of 0 (in base-10) that warrants this inconsistent treatment. To me the solution is clear: more strictly follow IETF RFC 6943 and enforce that each octet be one-to-three digits in length.


Question: impl FromStr for Ipv4Addr { type Err = AddrParseError; fn from_str(s: &str) -> Result<Ipv4Addr, AddrParseError> { <del> Parser::new(s).parse_with(|p| p.read_ipv4_addr()) </del> <ins> // don't try to parse if too long if s.len() > 15 { Err(AddrParseError(())) } else { Parser::new(s).parse_with(|p| p.read_ipv4_addr()) } </ins> } }

One could even follow a stricter format and require that there be no padded s at all—since the RFC doesn't actually specify that. This would then lead to consistent behavior (that's also more easily predictable since it follows a well-established convention) in that both and will either be accepted (since they both follow RFC 6943) or rejected (if a stricter form is required that requires the minimal number of digits necessary to represent each octet).
This is not an incorrect assumption, as octal numbers in the loose format are specified by the number having a leading zero. (See for the PR that banned octal numbers) This is an implementation detail in the way that it checks for leading zeroes: it checks if the number starts with a zero and rejects it if the resultant parsed number is not zero.
So we are re-defining how mathematics defines numeral systems? Saying that is in base-8 (i.e., octal) because of the leading makes no sense since none of those symbols except exist in that system. Rust certainly doesn't treat the in base-8 here: . Also the documentation clearly states that each octet is in "decimal notation". Suddenly treating the octet as base-8 is a clear contradiction to the documentation.
Using leading zeros to designate octal literals is a fairly common convention. In other languages like JS and C, . Rust doesn't have that as an octal prefix because it is confusing. When using leading zeros to indicate octal numbers, isn't a valid number at all (in the same way that isn't a valid base-10 number).
So it sounds like the documentation needs to be modified. It is confusing (because it is contradictory to reality) to say that each octet is in decimal notation when the actual implementation requires each octet to be either base-10 or base-8 where the latter is assumed when there are leading s and the value is not 0—at which point any positive-integer amount of s are allowed—and furthermore error when any octet is interpreted as base-8. Seems much easier to both document and comprehend to simply require at most 3 decimal digits for each octet and either forbid leading s (including for the integer 0) or allow leading s (including ).
"The actual implementation" is relevant only insofar as its behavior is externally observable.


Question: impl FromStr for Ipv4Addr { type Err = AddrParseError; fn from_str(s: &str) -> Result<Ipv4Addr, AddrParseError> { <del> Parser::new(s).parse_with(|p| p.read_ipv4_addr()) </del> <ins> // don't try to parse if too long if s.len() > 15 { Err(AddrParseError(())) } else { Parser::new(s).parse_with(|p| p.read_ipv4_addr()) } </ins> } }

And -- correct me if I'm wrong -- in every case where the function succeeds, it (behaves as if it) interprets all digits in decimal, right? So I'd say it is correct to say that everything is "in decimal notation". The only weird bit is that is accepted, but is not. This is strange, but not in contradiction with saying things are "in decimal notation".
When the documentation says the "four octets are in decimal notation", that is effectively a definition which in turn can be phrased as a logical biconditional. In this case, the logical biconditional I formed in my head was something like: "a will be parsed into an iff it is a sequence of exactly 4 base-10 numbers delimited by a ". Only one of those directions is true: if an is produced from parsing a , then the was a sequence of exactly 4 base-10 numbers delimited by a . The other direction, which is observable via a parsing failure, is not true as can be seen with something like . That is a sequence of exactly 4 base-10 numbers delimited by a , but it leads to a parsing failure. As was discovered in the discussion , it sounds like "decimal notation" as used in the documentation is not what it has meant my entire life nor what it means in a lot of areas in Rust. Specifically, any number that has leading s is not a base-10 number but in fact a base-8 number. With this modified definition of "decimal"; then my counterexample, , is in fact not a counterexample since each of those octets are not in "decimal" notation but in fact base-8. Even more perplexing as stated by is that "a lone 0 is technically octal as well in C, not that it matters" which means the definition of "decimal" used in the documentation is neither the mathematical definition nor the C definition—since something like is successfully parsed despite each of those octets being in base-8 per the C definition.
That's true in C. (Specifically, it is how C converts series of digits to numbers. "Numbers" don't have leading 0s, numbers are elements of the set of integers. The representation of a number as a string of digits can have leading 0s.


Question: impl FromStr for Ipv4Addr { type Err = AddrParseError; fn from_str(s: &str) -> Result<Ipv4Addr, AddrParseError> { <del> Parser::new(s).parse_with(|p| p.read_ipv4_addr()) </del> <ins> // don't try to parse if too long if s.len() > 15 { Err(AddrParseError(())) } else { Parser::new(s).parse_with(|p| p.read_ipv4_addr()) } </ins> } }

At least that's how I think the term is usually used when one needs to be precise about series of digits vs. the thing they represent.) However, it's not true for this function. Any number that has leading 0s is rejected by this function. This fact about C was brought up only to explain why leading 0s are rejected. No base-8 occurs anywhere in the behavior of this function. If you disagree, please show an input-output pair for this function which demonstrates that base 8 is used. (The code inside the function doesn't matter, of course. Only its observable behavior does.) I really don't understand why you keep insisting that this function has anything to do with base 8. I think it might be because of some quirk in how it is implemented, but unobservable implementation details are irrelevant. As a mathematician you should be even more used to this than most programmers, since the usual way of defining mathematical functions consists entirely of input-output pairs, there is not even such a thing as an "implementation"... but I am digressing. ;) Even mathematically speaking, the sequence of digits "0" represents the same number in any base system. So, in a very precise formal sense, "not that it matters" is accurate. A base is just a way to convert a series of digits into a number, and for series of digits consisting only of 0s, the result is always the same. The definition of "decimal" used in the documentation exactly matches the mathematical definition. The documentation just fails to mention that there is an additional restriction, namely that no leading 0s are accepted (except if all digits of an octet are 0). However, it remains the case that if an input is accepted by this function, then all octets are interpreted as decimal -- and moreover, all decimal representations without leading 0s are accepted by this function.
Saying a definition matches exactly with another definition before subsequently changing the definition by adding other restrictions does not make sense to me. Does the definition of an even integer "match exactly" with the definition of an integer? No. Adding or removing restrictions to a definition changes the definition. So the fact that leading s is not allowed means we are not talking about mathematical base-10.


Question: impl FromStr for Ipv4Addr { type Err = AddrParseError; fn from_str(s: &str) -> Result<Ipv4Addr, AddrParseError> { <del> Parser::new(s).parse_with(|p| p.read_ipv4_addr()) </del> <ins> // don't try to parse if too long if s.len() > 15 { Err(AddrParseError(())) } else { Parser::new(s).parse_with(|p| p.read_ipv4_addr()) } </ins> } }

If I define a function that takes an integer and it errors any time the integer is not even; however the documentation of that function makes no mention of that seems very problematic. I would not defend such documentation by saying "my definition of integer matches exactly with the definition of the mathematical definition of an integer except I also require the integer to be divisible by 2". My documentation should very clearly define what I mean by "integer", or better, simply state "even integer".
Okay, I guess I should have said that it is strictly a restriction of the mathematical definition (a subset, if you take the graph view of a function). But it doesn't disagree on any inputs where it is defined. Your talking about base 8 makes it sound like sometimes it is not matching the base 10 function even when it does produce a result (but matches the base 8 function instead), and it took a quite a lot of time to realize that is not what happens. Moreover, the subset still contains the full graph of the inverse of the full "base 10" function where you always pick the shortest representation (i.e., the most common "serialization" function of numbers into base 10 representation). So unlike your "even" example it is a pretty reasonable parsing function still. There are only some "non-canonical" representations being rejected.
Well, I think we are talking in circles at this point honestly, lol. While I would agree my example is a more extreme example of documentation failure since conflating the definition of "even integer" with "integer" is more absurd than conflating the definition of "base-10 in the shortest representation (with the exception of 0 which is allowed any non-negative integer amount of leading 0s)" with "base-10", both examples suffer from the fact that additional failures occur than otherwise would occur based on the exact definition of the term that is used (in my example "integer" and in this example "decimal"). For me, as I mentioned in the other discussion, this really is not me being "pedantic". I wrote code based on the documentation that ended being invalid since I (mis-)interpreted "decimal" to be more general than what it actually means in this context.


Question: impl FromStr for Ipv4Addr { type Err = AddrParseError; fn from_str(s: &str) -> Result<Ipv4Addr, AddrParseError> { <del> Parser::new(s).parse_with(|p| p.read_ipv4_addr()) </del> <ins> // don't try to parse if too long if s.len() > 15 { Err(AddrParseError(())) } else { Parser::new(s).parse_with(|p| p.read_ipv4_addr()) } </ins> } }

Ideally, in my opinion at least, that should not happen especially since it is not that much additional effort to more properly document what certain terms mean even if that means just adding one or two more examples highlighting parsing failures (or successes) that one (like myself) would not expect.
We already agree that the docs need to be improved. :) The rest of this discussion is then mostly philosophical and not going to lead to a productive outcome, so maybe we better stop it. ;)


Question: _ => {} } } <del> if arg.layout.is_aggregate() && (int_regs < needed_int || sse_regs < needed_sse) { cls_or_mem = Err(Memory); </del> <ins> match (int_regs.checked_sub(needed_int), sse_regs.checked_sub(needed_sse)) { (Some(left_int), Some(left_sse)) => { int_regs = left_int; sse_regs = left_sse; } _ => { // Not enough registers for this argument, so it will be // passed on the stack, but we only mark aggregates // explicitly as indirect `byval` arguments, as LLVM will // automatically put immediates on the stack itself. if arg.layout.is_aggregate() { cls_or_mem = Err(Memory); } } </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: _ => {} } } <del> if arg.layout.is_aggregate() && (int_regs < needed_int || sse_regs < needed_sse) { cls_or_mem = Err(Memory); </del> <ins> match (int_regs.checked_sub(needed_int), sse_regs.checked_sub(needed_sse)) { (Some(left_int), Some(left_sse)) => { int_regs = left_int; sse_regs = left_sse; } _ => { // Not enough registers for this argument, so it will be // passed on the stack, but we only mark aggregates // explicitly as indirect `byval` arguments, as LLVM will // automatically put immediates on the stack itself. if arg.layout.is_aggregate() { cls_or_mem = Err(Memory); } } </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> fn foo() { match 0 { _ => {} } if foo } } //~ ERROR unexpected closing delimiter: `}` fn main() {} </ins>

See: This code: produces on latest stable (1.61.0).
Maybe we could form a heuristic around tokens that we know should eventually be followed by -- , , , etc. If we see one of those, (then some random other tokens), then we see , then that would be a suspicious rbrace which we could point out later.. e.g. if we see that triggers the heuristic, but not
The problem is that the error happens in the lexer, not the parser. Ideally we'd rework the lexer to have a token stream mode of operation instead of a token tree mode of operation, only for code that is being passed to the parser (i.e., not coming from a macro).
This is particularly confusing when the points to a macro: gives on 1.65.0-nightly (2022-08-31 )
the output now changed to: Do you think the should be removed?
This is changed to: it seems more helpful now.
Let's close this ticket after adding these two cases to the test suite then. I'm sure there are outstanding issues in this area, but we can hope that we'll get tickets for those more specific cases, while the tests keep us from regressing silently (hopefully, lets make sure the tests are fully annotated so its harder to do that by accident).


Question: /// use std::sync::Arc; /// use std::task::{Context, Poll, Wake}; /// use std::thread::{self, Thread}; <ins> /// use core::pin::pin; </ins> /// /// /// A waker that wakes up the current thread when called. /// struct ThreadWaker(Thread);

The example currently uses , but now that the macro has been stabilized in , it should probably use that instead. This should be an easy contribution for someone who wants to land a first contribution. <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim
hey can u help me from where i can fix this
Can u tell me how u solve this?
I have already solved this one and it is in the process of being reviewed for merging. If you wish to solve an issue, you need to pick one that has not been assigned yet. Try looking at this:
hey im new to open source, i want to grow in this field . Can i contact with u ?
I am pretty new to this project myself, but please reach out if you have any starter-questions and then I might be able to help you out. There is a chat on https://rust- - I am just "Mads Ravn" in there.
Thanks


Question: <ins> // check-pass // revisions: legacy v0 //[legacy]compile-flags: -Z symbol-mangling-version=legacy --crate-type=lib //[v0]compile-flags: -Z symbol-mangling-version=v0 --crate-type=lib #![feature(min_const_generics)] pub struct Bar<const F: bool>; impl Bar<true> { pub fn foo() {} } impl<const F: bool> Bar<F> { pub fn bar() {} } fn main() {} </ins>

Command was with the following <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</details
And yes, was enough to get the build to finish, in case there were any questions as to whether that was the difference.
This is the first PR that fails with the error described in I do not know if the fault is here or in the symbol mangling but it as I understand it that function that is called is only used for the the size of an array and it feels strange that it shall be a bool -- it seems pretty clear the bug is in the symbol mangling rather than with , because it's not adding anything out of the "ordinary" Rust code. That said, it's likely that the const generic could be replaced to avoid the error perhaps.
Yeah, isn't this "just" an instance of new symbol mangling not being compatible with const generics?
was to tired that night when I hade bisected the rust build and this hade nothing to do with arrays that I was writing. was possible to avoid the bisect all together if I only hade looked trough all of the log. it is saying that it is eg. that fails so it is the bool in the path that is triggering the fault in symbol mangling. according to only unsigned integers is handled and the rest is left for "future const-generics work" shall this be marked with some const-generic label? right now it is only bool that also needs to be handled for rustc to compile but do not know how to go forward
seems like there is a issue for adding mangling support here so this will probably be fixed when that issue is fixed.


Question: } #[cfg(any( <del> all(not(target_arch = "aarch64"), not(target_arch = "powerpc"), not(target_arch = "x86_64")), </del> <ins> all( not(target_arch = "aarch64"), not(target_arch = "powerpc"), not(target_arch = "s390x"), not(target_arch = "x86_64") ), </ins> all(target_arch = "aarch64", any(target_os = "macos", target_os = "ios")), target_family = "wasm", target_arch = "asmjs",

fails this test on native : (This is not a new failure, but I am cleaning up issues from downstream Red Hat bugzilla.)
We started discussing this in , and looking at the clang implementation here: I tried that minimal step with , but it still gives the same "Cannot select" error. I don't see any lowering of in like other targets, only stuff implementing the calling convention. So I guess we do need custom support, or perhaps the clang bits could be moved down into the LLVM lowering?
Hi , I ran into the same problem and noticed you had already opened an issue. I've now submitted a PR to implement valist and vaarg for s390x to fix this.


Question: <ins> use std::marker::PhantomData; struct Foo<'a, 'b, T>(PhantomData<(&'a (), &'b (), T)>) where Foo<'short, 'out, T>: Convert<'a, 'b>; //~^ ERROR mismatched types //~^^ ERROR mismatched types //~^^^ ERROR use of undeclared lifetime name //~| ERROR use of undeclared lifetime name `'out` trait Convert<'a, 'b>: Sized { fn cast(&'a self) -> &'b Self; } impl<'long: 'short, 'short, T> Convert<'long, 'b> for Foo<'short, 'out, T> { //~^ ERROR use of undeclared lifetime name //~^^ ERROR use of undeclared lifetime name `'out` //~| ERROR cannot infer an appropriate lifetime for lifetime parameter fn cast(&'long self) -> &'short Foo<'short, 'out, T> { //~^ ERROR use of undeclared lifetime name //~| ERROR cannot infer an appropriate lifetime for lifetime parameter self } } fn badboi<'in_, 'out, T>(x: Foo<'in_, 'out, T>, sadness: &'in_ Foo<'short, 'out, T>) -> &'out T { //~^ ERROR use of undeclared lifetime name //~^^ ERROR incompatible lifetime on type //~| ERROR `x` has lifetime `'in_` but it needs to satisfy a `'static` lifetime requirement sadness.cast() } fn main() {} </ins>

[ ] 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: /// assert!(weak.upgrade().is_none()); /// ``` /// <del> /// Unaligned values cannot be dropped in place, they must be copied to an aligned /// location first: /// ``` /// use std::ptr; /// use std::mem::{self, MaybeUninit}; /// /// unsafe fn drop_after_copy<T>(to_drop: *mut T) { ///     let mut copy: MaybeUninit<T> = MaybeUninit::uninit(); ///     ptr::copy(to_drop, copy.as_mut_ptr(), 1); ///     drop(copy.assume_init()); /// } /// /// #[repr(packed, C)] /// struct Packed { ///     _padding: u8, ///     unaligned: Vec<i32>, /// } /// /// let mut p = Packed { _padding: 0, unaligned: vec![42] }; /// unsafe { ///     drop_after_copy(&mut p.unaligned as *mut _); ///     mem::forget(p); /// } /// ``` /// </del> /// Notice that the compiler performs this copy automatically when dropping packed structs, /// i.e., you do not usually have to worry about such issues unless you call `drop_in_place` /// manually.

The docs for  state: And include an example which uses to copy the value from an unaligned pointer into an aligned one. However, the docs for  state: Either the docs for are wrong, and does not need to be aligned, or the example for invokes UB and should be updated to use
cc (It's also notable that the example in is wrong when it uses as is seen if you move the statement out of the block; we should fix that ASAP)
Good catch! What we'd really want is , I think... we don't want an intermediate value on the stack. Feel free to suggest code that we can use instead. We have several doctests that need They have been there since 1.0 and longer, probably. But nobody listens to me when I say that there is existing code that we need to support ASAP.
The example given is just using to put it on the stack anyway. If you're having to copy the value at all, there's really no reason to use at that point, since the only reason to use it instead of is to avoid the copy (which is optimized out in release mode anyway). I think we can probably just remove the unaligned example entirely and change the documentation to read: I think we should probably mention the caveat WRT the optimizer eliminating the copy (or can it even do that in this case? The docs mention that the drop glue generated for packed structs does this copy automatically, I'm curious if it's doing so in a way that is UB or if the copy is just the price you have to pay here. It's also worth noting that there's no way to an unsized value through an unaligned pointer, but I'm not sure that's worth bringing up at all in the docs, since there's no reasonable way to actually get that pointer in the first place.
Oh, good point. Yeah then you can basically just make it , right? I wonder why / ever got used here? Well but wouldn't it make sense for that text to come with an example? It cannot, because then it would be introducing alignment errors. Uh... yeah. With it could work. Doesn't seem like a reasonable thing to have either way?
Presumably because they wanted the example to continue to use Sure, we could -- it just wouldn't ever call the function being documented.


Question: /// assert!(weak.upgrade().is_none()); /// ``` /// <del> /// Unaligned values cannot be dropped in place, they must be copied to an aligned /// location first: /// ``` /// use std::ptr; /// use std::mem::{self, MaybeUninit}; /// /// unsafe fn drop_after_copy<T>(to_drop: *mut T) { ///     let mut copy: MaybeUninit<T> = MaybeUninit::uninit(); ///     ptr::copy(to_drop, copy.as_mut_ptr(), 1); ///     drop(copy.assume_init()); /// } /// /// #[repr(packed, C)] /// struct Packed { ///     _padding: u8, ///     unaligned: Vec<i32>, /// } /// /// let mut p = Packed { _padding: 0, unaligned: vec![42] }; /// unsafe { ///     drop_after_copy(&mut p.unaligned as *mut _); ///     mem::forget(p); /// } /// ``` /// </del> /// Notice that the compiler performs this copy automatically when dropping packed structs, /// i.e., you do not usually have to worry about such issues unless you call `drop_in_place` /// manually.

Yes, it's just unrelated to dropping unaligned pointers since the only place you can reasonably copy them to is the stack. Unless you happen to already have an valid pointer of the proper size and alignment sitting around
I'm not actually sure unalgined DSTs are so unreasonable. For example, is only stopped by this rule: Which could be solved if we had e.g. a way to express "does not have drop glue" as a bound ( doesn't work for obvious reasons). In any case, I think "copy unaligned" functions make sense but we might want to consider multiple variants for src only / dest only / both unaligned. This can be expressed in LLVM IR though in a brief test I couldn't demonstrate that it currently makes a codegen difference (but I could only try on x86_64, where alignment rarely matters for codegen).
:rofl: fair. I guess all of this is basically saying an in-place drop of unaligned data is just not possible. Do an "out-of-place" drop instead.
Actually looks like the use of an unaligned pointer in the doctest just caused to fail to land. ;)
Proposed fix at


Question: } } <del> /// If a tool does not pass its tests, don't ship it. /// Right now, we do this only for Miri. fn check_toolstate(&mut self) { // Get the toolstate for this rust revision. let rev = self.rust_git_commit_hash.as_ref().expect("failed to determine rust git hash"); let toolstates = reqwest::get(TOOLSTATE).expect("failed to get toolstates"); let toolstates = BufReader::new(toolstates); let toolstate = toolstates.lines() .find_map(|line| { let line = line.expect("failed to read toolstate lines"); let mut pieces = line.splitn(2, 't'); let commit = pieces.next().expect("malformed toolstate line"); if commit != rev { // Not the right commit. return None; } // Return the 2nd piece, the JSON. Some(pieces.next().expect("malformed toolstate line").to_owned()) }) .expect("failed to find toolstate for rust commit"); let toolstate: HashMap<String, String> = serde_json::from_str(&toolstate).expect("toolstate is malformed JSON"); // Mark some tools as missing based on toolstate. if toolstate.get("miri").map(|s| &*s as &str) != Some("test-pass") { println!("Miri tests are not passing, removing component"); self.miri_version = None; self.miri_git_commit_hash = None; } } /// Hash all files, compute their signatures, and collect the hashes in `self.digests`. </del> fn digest_and_sign(&mut self) { for file in t!(self.input.read_dir()).map(|e| t!(e).path()) { let filename = file.file_name().unwrap().to_str().unwrap();

Seems like no nightly was released today. That might be related to Unfortunately I don't think I have access to the logs. Cc
Logs are missing on the server, let me start a manual release...
Well that is odd. You wouldn't know what commit is is using? ( file in the tarball, if I recall correctly.)
Is there a way for me to download the "dist" artifacts for better testing? Right now I am manually grabbing a bunch of files from https://s3-us-west- (and we only get dir listing for alt builds there it seems so I am using those). That's not very convenient at all.
Apparently not all commits are pushed to toolstate ( vs ), for example the latest one () is missing in toolstate .
Reverting the cause in the meantime --
Alternatively we could land which will just skip of the toolstate is not found. That installs a toolchain based on these artifacts, but I don't think it gives me access to the tarballs. FTR, for now I did So we are only committing when the toolstate changed? Ouch. That kills my entire approach :(
It should print the URLs it's downloading though, and you can use to avoid it actually downloading stuff.


Question: } } <ins> impl Allocation<()> { /// Add Tag and Extra fields pub fn retag<T, E>( self, mut tagger: impl FnMut(AllocId) -> T, extra: E, ) -> Allocation<T, E> { Allocation { bytes: self.bytes, size: self.size, relocations: Relocations::from_presorted( self.relocations.iter() // The allocations in the relocations (pointers stored *inside* this allocation) // all get the base pointer tag. .map(|&(offset, ((), alloc))| { let tag = tagger(alloc); (offset, (tag, alloc)) }) .collect() ), undef_mask: self.undef_mask, align: self.align, mutability: self.mutability, extra, } } } </ins> /// Raw accessors. Provide access to otherwise private bytes. impl<Tag, Extra> Allocation<Tag, Extra> { pub fn len(&self) -> usize {

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! cc the PR reviewer, and -- nominating for prioritization.
I need to port parts of from miri to rustc and only keep the actual miri-parts in miri. I'll try to get it done by tomorrow night.
check-in from compiler triage: Go go!


Question: <ins> #![feature(const_fn_trait_bound)] // Regression test for issue 88434 const _CONST: &[u8] = &f(&[], |_| {}); const fn f<F>(_: &[u8], _: F) -> &[u8] where F: FnMut(&u8), { panic!() //~ ERROR evaluation of constant value failed } fn main() { } </ins>

<!-- Thank you for finding an Internal Compiler Error! If possible, try to provide a minimal verifiable example. You can read "Rust Bug Minimization Patterns" for how to create smaller examples. --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: use crate::ffi::CStr; use crate::mem; <del> use crate::os::raw::{c_char, c_int, c_long, c_longlong, c_uint, c_ulong, c_ushort}; </del> <ins> use crate::os::raw::{c_char, c_long, c_longlong, c_uint, c_ulong, c_ushort}; </ins> use crate::os::windows::io::{BorrowedHandle, HandleOrInvalid, HandleOrNull}; use crate::ptr; use core::ffi::NonZero_c_ulong; use libc::{c_void, size_t, wchar_t}; <ins> pub use crate::os::raw::c_int; </ins> #[path = "c/errors.rs"] // c.rs is included from two places so we need to specify this mod errors; pub use errors::*;

(and similarly, should call ) Windows provides these nice functions which performantly implement utf-8 <-utf-16 conversions. We should probably call them in the standard library when possible.
Do we get measurable performance wins that make calling more unsafe C APIs worth it? Especially with the inlining barrier across languages. And I would assume console printing is bottlenecked on the console rendering part anyway, not on string conversions.
Do we have any good benchmarks for console I/O perf?
A simple main writing 100MB worth of lines to stdout and measuring the time it takes should do?
For sure. I was just wondering if we had something already. I mean, we'd probably want to be testing a few different languages as well to make sure we're not just optimizing for ASCII only.
I don't think we do because most benchmarks suppress console output.
I did do a benchmark, and interestingly, ASCII text was about twice as fast with as with rust-native code; however, Chinese text was slightly slower. Given that most of the actual cost of printing to the screen is in the actual printing, I no longer think it's a good idea to do this. See benchmarks at [strega-nil/rust-bench-cvt-utf8-utf16][]. [strega-nil/rust-bench-cvt-utf8-utf16]: Run on M1 chip: someone may want to check on an x64 chip, since that might be faster.
Just to check my understanding: The utf16 conversion only happens when one writes to an actually rendered console. There isn't some stuff like virtual consoles that act more like NUL where speeding up the conversion could help because the data will be discarded by the OS. And output to files is binary anyway.
There are now (since Windows 10, 1809) which are consoles without the rendering part. Though the intent would be for the rendering to be implemented by another program, it would also be possible to skip or delay (e.g. by writing a log) rendering.
In that case a speedup may be useful, but is the optimization potential of the built-in conversion already squeezed dry?
yeah, I think it's unlikely that the complexity is worth it given what the benchmarks show; I would really appreciate if someone ran the benchmark on x64, since it may be that Windows implements faster algorithms on that platform.


Question: use crate::ffi::CStr; use crate::mem; <del> use crate::os::raw::{c_char, c_int, c_long, c_longlong, c_uint, c_ulong, c_ushort}; </del> <ins> use crate::os::raw::{c_char, c_long, c_longlong, c_uint, c_ulong, c_ushort}; </ins> use crate::os::windows::io::{BorrowedHandle, HandleOrInvalid, HandleOrNull}; use crate::ptr; use core::ffi::NonZero_c_ulong; use libc::{c_void, size_t, wchar_t}; <ins> pub use crate::os::raw::c_int; </ins> #[path = "c/errors.rs"] // c.rs is included from two places so we need to specify this mod errors; pub use errors::*;

I don't think anyone has worked on optimizing this so I'm sure there's plenty of optimization potential. The results from I got from an AMD Ryzen 5 3600 machine are:
Mmh, thanks I'll also push some benchmarks for testing other cases later, since there are plenty of other cases than just "bulk-converting a bunch of text". Thanks! Nicole


Question: let md_content = fs::read_to_string(entry.path()).unwrap(); fs::write(&out_dir.join(entry.file_name()), &md_content).unwrap(); } <del> let mut all = String::new(); all.push_str( r###" fn register_all() -> Vec<(&'static str, Option<&'static str>)> { let mut long_codes: Vec<(&'static str, Option<&'static str>)> = Vec::new(); macro_rules! register_diagnostics { ($($ecode:ident: $message:expr,)*) => ( register_diagnostics!{$($ecode:$message,)* ;} ); ($($ecode:ident: $message:expr,)* ; $($code:ident,)*) => ( $( {long_codes.extend([ (stringify!($ecode), Some($message)), ].iter());} )* $( {long_codes.extend([ stringify!($code), ].iter().cloned().map(|s| (s, None)).collect::<Vec<_>>());} )* ) } "###, ); all.push_str(r#"include!(concat!(env!("OUT_DIR"), "/all_error_codes.rs"));"#); all.push_str("nlong_codesn"); all.push_str("}n"); fs::write(&dest, all).unwrap(); </del> }

Steps: Checkout commit Have in . In particular, this implies Run Output (on the second run):
cc
For what it’s worth is just what I happened to get after running today. I mentioned it in case something changes later, it’s a coincidence that that commit happens to be related to downloading LLVM from Rust CI.
I think this is a duplicate of
That issue is closed, and its final comment points to this issue.
I just hit this on the following sequence. Do a fresh clone of Run Select option (b) "compiler: Contribute to the compiler itself" Run The build finished like so:
IMO the proper fix for this is to remove error-index's dependency on rustdoc, either by moving the relevant code out into a library that doesn't use rustc_private, or by duplicating the code altogether. There are other ways to solve this but they'll be more complicated and take longer to compile for no real benefit.
by making it invoke rustdoc-the-binary (through ), rather than using rustdoc-the-library.
you should be able to work around this by adding --stage 2 I think.
Thanks, that worked
I think you're right that the binary will be easier - parsing the markdown requires parsing doctests so that it can generate the "Run" button, and parsing doctests requires all of .


Question: } } <ins> fn visit_generic_args(&mut self, args: &'a ast::GenericArgs) { // This check needs to happen here because the never type can be returned from a function, // but cannot be used in any other context. If this check was in `visit_fn_ret_ty`, it // include both functions and generics like `impl Fn() -> !`. if let ast::GenericArgs::Parenthesized(generic_args) = args && let ast::FnRetTy::Ty(ref ty) = generic_args.output && matches!(ty.kind, ast::TyKind::Never) { gate!(&self, never_type, ty.span, "the `!` type is experimental"); } visit::walk_generic_args(self, args); } </ins> fn visit_expr(&mut self, e: &'a ast::Expr) { match e.kind { ast::ExprKind::TryBlock(_) => {

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.