Question:
Rust version: How to reproduce: Error:
Minimized reproduction:
I'd like to work on this.

<ins> // Copyright 2018 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. pub trait ScopeHandle<'scope> {} // @has issue_54705/struct.ScopeFutureContents.html // @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//*/code' "impl<'scope, S>  // Send for ScopeFutureContents<'scope, S> where S: Sync" // // @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//*/code' "impl<'scope, S>  // Sync for ScopeFutureContents<'scope, S> where S: Sync" pub struct ScopeFutureContents<'scope, S> where S: ScopeHandle<'scope>, { dummy: &'scope S, this: Box<ScopeFuture<'scope, S>>, } struct ScopeFuture<'scope, S> where S: ScopeHandle<'scope>, { contents: ScopeFutureContents<'scope, S>, } unsafe impl<'scope, S> Send for ScopeFuture<'scope, S> where S: ScopeHandle<'scope>, {} unsafe impl<'scope, S> Sync for ScopeFuture<'scope, S> where S: ScopeHandle<'scope>, {} </ins>


Question:
That is, appears to lose incremental artifacts. cc
Yes, I believe this is because rustc/cargo will otherwise error on "found a new std" or something like that? I don't quite see how incremental is different from the normal compilation here?
incremental would still work even if dependencies changed. I think the fundamental problem here is that deletes everything, whereas (which, IIRC, does not remove incremental artifacts by default) would be appropriate.
Hm, I thought was equivalent to essentially -- could you clarify that? Would it be better to use cargo clean in rustbuild?
Regardless of what does I don't think we should execute it here. Rustbuild is overly conservative in what it deletes, and it can get away probably with just deleting the folder instead of the entire folder. That would leave around the incremental cache. I believe, however, that is like
Maybe the benchmarks I remember having for incremental had the incremental dir elsewhere than . I sure was confused by it, since I'd expect to remove all artifacts. If it does do that, then I agree should just remove a subset of the contents of target dirs.
Looking at the code, these calls appear to be relevant: The problem is that the directory refers to is non-trivially structured. Instead of removing , we need to remove all the files (or at least the ones that are artifacts) and the directory in .
I keep hitting this, specifically it keeps rebuilding and , every time I change rustc, which cause them to take much longer than any of the rustc crates, and this issue has become my main bottleneck (now that I'm building on a machine).
Nominating for discussion (specifically, allocating resources towards this) at the next relevant team meeting (tagged both and as I'm not sure which has "jurisdiction" here).
It'd be helpful to know how much rustbuild can "trust" the compiler here. Can we keep incremental artifact directories around from previous versions of the compiler?
The compiler can only work with incremental artifacts that it created itself. For any other version of the compiler it has to assume that it's incompatible. It usually just ignores such incompatible artifacts, but in the bootstrapping scenario, it might not always be smart enough to do that.
I think the question here is will rustc's incremental artifacts correctly deal with crates changing (including adding and removing crates) in the sysroot. If so, we could keep the folder around. Cargo assumes the sysroot is unchanging, which is why we remove the directory in the first place.
Incremental doesn't care about vs , so I'd expect it to be pretty resilient here.
triage: P-medium. (this inefficiency in incremental comp. would be nice to resolve, but is not P-high IMO.)

let mut cargo = Command::new(&self.initial_cargo); let out_dir = self.stage_out(compiler, mode); <del> // command specific path, we call clear_if_dirty with this let mut my_out = match cmd { "build" => self.cargo_out(compiler, mode, target), // This is the intended out directory for crate documentation. "doc" | "rustdoc" =>  self.crate_doc_out(target), _ => self.stage_out(compiler, mode), }; // This is for the original compiler, but if we're forced to use stage 1, then // std/test/rustc stamps won't exist in stage 2, so we need to get those from stage 1, since // we copy the libs forward. let cmp = self.compiler_for(compiler.stage, compiler.host, target); let libstd_stamp = match cmd { "check" | "clippy" | "fix" => check::libstd_stamp(self, cmp, target), _ => compile::libstd_stamp(self, cmp, target), }; let libtest_stamp = match cmd { "check" | "clippy" | "fix" => check::libtest_stamp(self, cmp, target), _ => compile::libtest_stamp(self, cmp, target), }; let librustc_stamp = match cmd { "check" | "clippy" | "fix" => check::librustc_stamp(self, cmp, target), _ => compile::librustc_stamp(self, cmp, target), }; </del> <ins> // Codegen backends are not yet tracked by -Zbinary-dep-depinfo, // so we need to explicitly clear out if they've been updated. for backend in self.codegen_backends(compiler) { self.clear_if_dirty(&out_dir, &backend); } </ins> if cmd == "doc" || cmd == "rustdoc" { <del> if mode == Mode::Rustc || mode == Mode::ToolRustc || mode == Mode::Codegen { </del> <ins> let my_out = match mode { </ins> // This is the intended out directory for compiler documentation. <del> my_out = self.compiler_doc_out(target); } </del> <ins> Mode::Rustc | Mode::ToolRustc | Mode::Codegen => self.compiler_doc_out(target), _ => self.crate_doc_out(target), }; </ins> let rustdoc = self.rustdoc(compiler); self.clear_if_dirty(&my_out, &rustdoc); <del> } else if cmd != "test" { match mode { Mode::Std => { self.clear_if_dirty(&my_out, &self.rustc(compiler)); for backend in self.codegen_backends(compiler) { self.clear_if_dirty(&my_out, &backend); } }, Mode::Test => { self.clear_if_dirty(&my_out, &libstd_stamp); }, Mode::Rustc => { self.clear_if_dirty(&my_out, &self.rustc(compiler)); self.clear_if_dirty(&my_out, &libstd_stamp); self.clear_if_dirty(&my_out, &libtest_stamp); }, Mode::Codegen => { self.clear_if_dirty(&my_out, &librustc_stamp); }, Mode::ToolBootstrap => { }, Mode::ToolStd => { self.clear_if_dirty(&my_out, &libstd_stamp); }, Mode::ToolTest => { self.clear_if_dirty(&my_out, &libstd_stamp); self.clear_if_dirty(&my_out, &libtest_stamp); }, Mode::ToolRustc => { self.clear_if_dirty(&my_out, &libstd_stamp); self.clear_if_dirty(&my_out, &libtest_stamp); self.clear_if_dirty(&my_out, &librustc_stamp); }, } </del> } cargo


Question:
That is, appears to lose incremental artifacts. cc
Yes, I believe this is because rustc/cargo will otherwise error on "found a new std" or something like that? I don't quite see how incremental is different from the normal compilation here?
incremental would still work even if dependencies changed. I think the fundamental problem here is that deletes everything, whereas (which, IIRC, does not remove incremental artifacts by default) would be appropriate.
Hm, I thought was equivalent to essentially -- could you clarify that? Would it be better to use cargo clean in rustbuild?
Regardless of what does I don't think we should execute it here. Rustbuild is overly conservative in what it deletes, and it can get away probably with just deleting the folder instead of the entire folder. That would leave around the incremental cache. I believe, however, that is like
Maybe the benchmarks I remember having for incremental had the incremental dir elsewhere than . I sure was confused by it, since I'd expect to remove all artifacts. If it does do that, then I agree should just remove a subset of the contents of target dirs.
Looking at the code, these calls appear to be relevant: The problem is that the directory refers to is non-trivially structured. Instead of removing , we need to remove all the files (or at least the ones that are artifacts) and the directory in .
I keep hitting this, specifically it keeps rebuilding and , every time I change rustc, which cause them to take much longer than any of the rustc crates, and this issue has become my main bottleneck (now that I'm building on a machine).
Nominating for discussion (specifically, allocating resources towards this) at the next relevant team meeting (tagged both and as I'm not sure which has "jurisdiction" here).
It'd be helpful to know how much rustbuild can "trust" the compiler here. Can we keep incremental artifact directories around from previous versions of the compiler?
The compiler can only work with incremental artifacts that it created itself. For any other version of the compiler it has to assume that it's incompatible. It usually just ignores such incompatible artifacts, but in the bootstrapping scenario, it might not always be smart enough to do that.
I think the question here is will rustc's incremental artifacts correctly deal with crates changing (including adding and removing crates) in the sysroot. If so, we could keep the folder around. Cargo assumes the sysroot is unchanging, which is why we remove the directory in the first place.
Incremental doesn't care about vs , so I'd expect it to be pretty resilient here.
triage: P-medium. (this inefficiency in incremental comp. would be nice to resolve, but is not P-high IMO.)

}, } <ins> // This tells Cargo (and in turn, rustc) to output more complete // dependency information.  Most importantly for rustbuild, this // includes sysroot artifacts, like libstd, which means that we don't // need to track those in rustbuild (an error prone process!). This // feature is currently unstable as there may be some bugs and such, but // it represents a big improvement in rustbuild's reliability on // rebuilds, so we're using it here. // // For some additional context, see #63470 (the PR originally adding // this), as well as #63012 which is the tracking issue for this // feature on the rustc side. cargo.arg("-Zbinary-dep-depinfo"); </ins> cargo.arg("-j").arg(self.jobs().to_string()); // Remove make-related flags to ensure Cargo can correctly set things up cargo.env_remove("MAKEFLAGS");


Question:
That is, appears to lose incremental artifacts. cc
Yes, I believe this is because rustc/cargo will otherwise error on "found a new std" or something like that? I don't quite see how incremental is different from the normal compilation here?
incremental would still work even if dependencies changed. I think the fundamental problem here is that deletes everything, whereas (which, IIRC, does not remove incremental artifacts by default) would be appropriate.
Hm, I thought was equivalent to essentially -- could you clarify that? Would it be better to use cargo clean in rustbuild?
Regardless of what does I don't think we should execute it here. Rustbuild is overly conservative in what it deletes, and it can get away probably with just deleting the folder instead of the entire folder. That would leave around the incremental cache. I believe, however, that is like
Maybe the benchmarks I remember having for incremental had the incremental dir elsewhere than . I sure was confused by it, since I'd expect to remove all artifacts. If it does do that, then I agree should just remove a subset of the contents of target dirs.
Looking at the code, these calls appear to be relevant: The problem is that the directory refers to is non-trivially structured. Instead of removing , we need to remove all the files (or at least the ones that are artifacts) and the directory in .
I keep hitting this, specifically it keeps rebuilding and , every time I change rustc, which cause them to take much longer than any of the rustc crates, and this issue has become my main bottleneck (now that I'm building on a machine).
Nominating for discussion (specifically, allocating resources towards this) at the next relevant team meeting (tagged both and as I'm not sure which has "jurisdiction" here).
It'd be helpful to know how much rustbuild can "trust" the compiler here. Can we keep incremental artifact directories around from previous versions of the compiler?
The compiler can only work with incremental artifacts that it created itself. For any other version of the compiler it has to assume that it's incompatible. It usually just ignores such incompatible artifacts, but in the bootstrapping scenario, it might not always be smart enough to do that.
I think the question here is will rustc's incremental artifacts correctly deal with crates changing (including adding and removing crates) in the sysroot. If so, we could keep the folder around. Cargo assumes the sysroot is unchanging, which is why we remove the directory in the first place.
Incremental doesn't care about vs , so I'd expect it to be pretty resilient here.
triage: P-medium. (this inefficiency in incremental comp. would be nice to resolve, but is not P-high IMO.)

let libdir = builder.sysroot_libdir(compiler, target); let hostdir = builder.sysroot_libdir(compiler, compiler.host); add_to_sysroot(&builder, &libdir, &hostdir, &rustdoc_stamp(builder, compiler, target)); <del> builder.cargo(compiler, Mode::ToolRustc, target, "clean"); </del> } }


Question:
That is, appears to lose incremental artifacts. cc
Yes, I believe this is because rustc/cargo will otherwise error on "found a new std" or something like that? I don't quite see how incremental is different from the normal compilation here?
incremental would still work even if dependencies changed. I think the fundamental problem here is that deletes everything, whereas (which, IIRC, does not remove incremental artifacts by default) would be appropriate.
Hm, I thought was equivalent to essentially -- could you clarify that? Would it be better to use cargo clean in rustbuild?
Regardless of what does I don't think we should execute it here. Rustbuild is overly conservative in what it deletes, and it can get away probably with just deleting the folder instead of the entire folder. That would leave around the incremental cache. I believe, however, that is like
Maybe the benchmarks I remember having for incremental had the incremental dir elsewhere than . I sure was confused by it, since I'd expect to remove all artifacts. If it does do that, then I agree should just remove a subset of the contents of target dirs.
Looking at the code, these calls appear to be relevant: The problem is that the directory refers to is non-trivially structured. Instead of removing , we need to remove all the files (or at least the ones that are artifacts) and the directory in .
I keep hitting this, specifically it keeps rebuilding and , every time I change rustc, which cause them to take much longer than any of the rustc crates, and this issue has become my main bottleneck (now that I'm building on a machine).
Nominating for discussion (specifically, allocating resources towards this) at the next relevant team meeting (tagged both and as I'm not sure which has "jurisdiction" here).
It'd be helpful to know how much rustbuild can "trust" the compiler here. Can we keep incremental artifact directories around from previous versions of the compiler?
The compiler can only work with incremental artifacts that it created itself. For any other version of the compiler it has to assume that it's incompatible. It usually just ignores such incompatible artifacts, but in the bootstrapping scenario, it might not always be smart enough to do that.
I think the question here is will rustc's incremental artifacts correctly deal with crates changing (including adding and removing crates) in the sysroot. If so, we could keep the folder around. Cargo assumes the sysroot is unchanging, which is why we remove the directory in the first place.
Incremental doesn't care about vs , so I'd expect it to be pretty resilient here.
triage: P-medium. (this inefficiency in incremental comp. would be nice to resolve, but is not P-high IMO.)

use std::process::{Command, Stdio, exit}; use std::str; <del> use build_helper::{output, mtime, t, up_to_date}; </del> <ins> use build_helper::{output, t, up_to_date}; </ins> use filetime::FileTime; use serde::Deserialize; use serde_json;


Question:
That is, appears to lose incremental artifacts. cc
Yes, I believe this is because rustc/cargo will otherwise error on "found a new std" or something like that? I don't quite see how incremental is different from the normal compilation here?
incremental would still work even if dependencies changed. I think the fundamental problem here is that deletes everything, whereas (which, IIRC, does not remove incremental artifacts by default) would be appropriate.
Hm, I thought was equivalent to essentially -- could you clarify that? Would it be better to use cargo clean in rustbuild?
Regardless of what does I don't think we should execute it here. Rustbuild is overly conservative in what it deletes, and it can get away probably with just deleting the folder instead of the entire folder. That would leave around the incremental cache. I believe, however, that is like
Maybe the benchmarks I remember having for incremental had the incremental dir elsewhere than . I sure was confused by it, since I'd expect to remove all artifacts. If it does do that, then I agree should just remove a subset of the contents of target dirs.
Looking at the code, these calls appear to be relevant: The problem is that the directory refers to is non-trivially structured. Instead of removing , we need to remove all the files (or at least the ones that are artifacts) and the directory in .
I keep hitting this, specifically it keeps rebuilding and , every time I change rustc, which cause them to take much longer than any of the rustc crates, and this issue has become my main bottleneck (now that I'm building on a machine).
Nominating for discussion (specifically, allocating resources towards this) at the next relevant team meeting (tagged both and as I'm not sure which has "jurisdiction" here).
It'd be helpful to know how much rustbuild can "trust" the compiler here. Can we keep incremental artifact directories around from previous versions of the compiler?
The compiler can only work with incremental artifacts that it created itself. For any other version of the compiler it has to assume that it's incompatible. It usually just ignores such incompatible artifacts, but in the bootstrapping scenario, it might not always be smart enough to do that.
I think the question here is will rustc's incremental artifacts correctly deal with crates changing (including adding and removing crates) in the sysroot. If so, we could keep the folder around. Cargo assumes the sysroot is unchanging, which is why we remove the directory in the first place.
Incremental doesn't care about vs , so I'd expect it to be pretty resilient here.
triage: P-medium. (this inefficiency in incremental comp. would be nice to resolve, but is not P-high IMO.)

// for reason why the sanitizers are not built in stage0. copy_apple_sanitizer_dylibs(builder, &builder.native_dir(target), "osx", &libdir); } <del> builder.cargo(target_compiler, Mode::ToolStd, target, "clean"); </del> } }


Question:
That is, appears to lose incremental artifacts. cc
Yes, I believe this is because rustc/cargo will otherwise error on "found a new std" or something like that? I don't quite see how incremental is different from the normal compilation here?
incremental would still work even if dependencies changed. I think the fundamental problem here is that deletes everything, whereas (which, IIRC, does not remove incremental artifacts by default) would be appropriate.
Hm, I thought was equivalent to essentially -- could you clarify that? Would it be better to use cargo clean in rustbuild?
Regardless of what does I don't think we should execute it here. Rustbuild is overly conservative in what it deletes, and it can get away probably with just deleting the folder instead of the entire folder. That would leave around the incremental cache. I believe, however, that is like
Maybe the benchmarks I remember having for incremental had the incremental dir elsewhere than . I sure was confused by it, since I'd expect to remove all artifacts. If it does do that, then I agree should just remove a subset of the contents of target dirs.
Looking at the code, these calls appear to be relevant: The problem is that the directory refers to is non-trivially structured. Instead of removing , we need to remove all the files (or at least the ones that are artifacts) and the directory in .
I keep hitting this, specifically it keeps rebuilding and , every time I change rustc, which cause them to take much longer than any of the rustc crates, and this issue has become my main bottleneck (now that I'm building on a machine).
Nominating for discussion (specifically, allocating resources towards this) at the next relevant team meeting (tagged both and as I'm not sure which has "jurisdiction" here).
It'd be helpful to know how much rustbuild can "trust" the compiler here. Can we keep incremental artifact directories around from previous versions of the compiler?
The compiler can only work with incremental artifacts that it created itself. For any other version of the compiler it has to assume that it's incompatible. It usually just ignores such incompatible artifacts, but in the bootstrapping scenario, it might not always be smart enough to do that.
I think the question here is will rustc's incremental artifacts correctly deal with crates changing (including adding and removing crates) in the sysroot. If so, we could keep the folder around. Cargo assumes the sysroot is unchanging, which is why we remove the directory in the first place.
Incremental doesn't care about vs , so I'd expect it to be pretty resilient here.
triage: P-medium. (this inefficiency in incremental comp. would be nice to resolve, but is not P-high IMO.)

&builder.sysroot_libdir(target_compiler, compiler.host), &libtest_stamp(builder, compiler, target) ); <del> builder.cargo(target_compiler, Mode::ToolTest, target, "clean"); </del> } }


Question:
That is, appears to lose incremental artifacts. cc
Yes, I believe this is because rustc/cargo will otherwise error on "found a new std" or something like that? I don't quite see how incremental is different from the normal compilation here?
incremental would still work even if dependencies changed. I think the fundamental problem here is that deletes everything, whereas (which, IIRC, does not remove incremental artifacts by default) would be appropriate.
Hm, I thought was equivalent to essentially -- could you clarify that? Would it be better to use cargo clean in rustbuild?
Regardless of what does I don't think we should execute it here. Rustbuild is overly conservative in what it deletes, and it can get away probably with just deleting the folder instead of the entire folder. That would leave around the incremental cache. I believe, however, that is like
Maybe the benchmarks I remember having for incremental had the incremental dir elsewhere than . I sure was confused by it, since I'd expect to remove all artifacts. If it does do that, then I agree should just remove a subset of the contents of target dirs.
Looking at the code, these calls appear to be relevant: The problem is that the directory refers to is non-trivially structured. Instead of removing , we need to remove all the files (or at least the ones that are artifacts) and the directory in .
I keep hitting this, specifically it keeps rebuilding and , every time I change rustc, which cause them to take much longer than any of the rustc crates, and this issue has become my main bottleneck (now that I'm building on a machine).
Nominating for discussion (specifically, allocating resources towards this) at the next relevant team meeting (tagged both and as I'm not sure which has "jurisdiction" here).
It'd be helpful to know how much rustbuild can "trust" the compiler here. Can we keep incremental artifact directories around from previous versions of the compiler?
The compiler can only work with incremental artifacts that it created itself. For any other version of the compiler it has to assume that it's incompatible. It usually just ignores such incompatible artifacts, but in the bootstrapping scenario, it might not always be smart enough to do that.
I think the question here is will rustc's incremental artifacts correctly deal with crates changing (including adding and removing crates) in the sysroot. If so, we could keep the folder around. Cargo assumes the sysroot is unchanging, which is why we remove the directory in the first place.
Incremental doesn't care about vs , so I'd expect it to be pretty resilient here.
triage: P-medium. (this inefficiency in incremental comp. would be nice to resolve, but is not P-high IMO.)

&builder.sysroot_libdir(target_compiler, compiler.host), &librustc_stamp(builder, compiler, target) ); <del> builder.cargo(target_compiler, Mode::ToolRustc, target, "clean"); </del> } }


Question:
That is, appears to lose incremental artifacts. cc
Yes, I believe this is because rustc/cargo will otherwise error on "found a new std" or something like that? I don't quite see how incremental is different from the normal compilation here?
incremental would still work even if dependencies changed. I think the fundamental problem here is that deletes everything, whereas (which, IIRC, does not remove incremental artifacts by default) would be appropriate.
Hm, I thought was equivalent to essentially -- could you clarify that? Would it be better to use cargo clean in rustbuild?
Regardless of what does I don't think we should execute it here. Rustbuild is overly conservative in what it deletes, and it can get away probably with just deleting the folder instead of the entire folder. That would leave around the incremental cache. I believe, however, that is like
Maybe the benchmarks I remember having for incremental had the incremental dir elsewhere than . I sure was confused by it, since I'd expect to remove all artifacts. If it does do that, then I agree should just remove a subset of the contents of target dirs.
Looking at the code, these calls appear to be relevant: The problem is that the directory refers to is non-trivially structured. Instead of removing , we need to remove all the files (or at least the ones that are artifacts) and the directory in .
I keep hitting this, specifically it keeps rebuilding and , every time I change rustc, which cause them to take much longer than any of the rustc crates, and this issue has become my main bottleneck (now that I'm building on a machine).
Nominating for discussion (specifically, allocating resources towards this) at the next relevant team meeting (tagged both and as I'm not sure which has "jurisdiction" here).
It'd be helpful to know how much rustbuild can "trust" the compiler here. Can we keep incremental artifact directories around from previous versions of the compiler?
The compiler can only work with incremental artifacts that it created itself. For any other version of the compiler it has to assume that it's incompatible. It usually just ignores such incompatible artifacts, but in the bootstrapping scenario, it might not always be smart enough to do that.
I think the question here is will rustc's incremental artifacts correctly deal with crates changing (including adding and removing crates) in the sysroot. If so, we could keep the folder around. Cargo assumes the sysroot is unchanging, which is why we remove the directory in the first place.
Incremental doesn't care about vs , so I'd expect it to be pretty resilient here.
triage: P-medium. (this inefficiency in incremental comp. would be nice to resolve, but is not P-high IMO.)

deps.push((path_to_add.into(), false)); } <del> // Now we want to update the contents of the stamp file, if necessary. First // we read off the previous contents along with its mtime. If our new // contents (the list of files to copy) is different or if any dep's mtime // is newer then we rewrite the stamp file. </del> deps.sort(); <del> let stamp_contents = fs::read(stamp); let stamp_mtime = mtime(&stamp); </del> let mut new_contents = Vec::new(); <del> let mut max = None; let mut max_path = None; </del> for (dep, proc_macro) in deps.iter() { <del> let mtime = mtime(dep); if Some(mtime) > max { max = Some(mtime); max_path = Some(dep.clone()); } </del> new_contents.extend(if *proc_macro { b"h" } else { b"t" }); new_contents.extend(dep.to_str().unwrap().as_bytes()); new_contents.extend(b"0"); } <del> let max = max.unwrap(); let max_path = max_path.unwrap(); let contents_equal = stamp_contents .map(|contents| contents == new_contents) .unwrap_or_default(); if contents_equal && max <= stamp_mtime { builder.verbose(&format!("not updating {:?}; contents equal and {:?} <= {:?}", stamp, max, stamp_mtime)); return deps.into_iter().map(|(d, _)| d).collect() } if max > stamp_mtime { builder.verbose(&format!("updating {:?} as {:?} changed", stamp, max_path)); } else { builder.verbose(&format!("updating {:?} as deps changed", stamp)); } </del> t!(fs::write(&stamp, &new_contents)); deps.into_iter().map(|(d, _)| d).collect() }


Question:
On rustc 1.31.0-nightly ( 2018-10-07) and x8664-unknown-linux-gnu, we see the following surprising behavior: In release mode it seems the write has not happened in the place that it should. Mentioning threadlocal tracking issue: .
Ah, apparently this is missing a . With the behavior is correct. We need to make sure mutating a thread_local static that does not have does not compile.
cc Did fix this by any chance?
It looks like this is fixed on nightly; I'm guessing is the reason. We probably should add some regression tests for the cases listed here.

<ins> error[E0594]: cannot assign to immutable static item `S` --> $DIR/thread-local-mutation.rs:11:5 | LL |     S = "after"; //~ ERROR cannot assign to immutable |     ^^^^^^^^^^^ cannot assign error: aborting due to previous error For more information about this error, try `rustc --explain E0594`. </ins>


Question:
On rustc 1.31.0-nightly ( 2018-10-07) and x8664-unknown-linux-gnu, we see the following surprising behavior: In release mode it seems the write has not happened in the place that it should. Mentioning threadlocal tracking issue: .
Ah, apparently this is missing a . With the behavior is correct. We need to make sure mutating a thread_local static that does not have does not compile.
cc Did fix this by any chance?
It looks like this is fixed on nightly; I'm guessing is the reason. We probably should add some regression tests for the cases listed here.

<ins> // Regression test for #54901: immutable thread locals could be mutated. See: // https://github.com/rust-lang/rust/issues/29594#issuecomment-328177697 // https://github.com/rust-lang/rust/issues/54901 #![feature(thread_local)] #[thread_local] static S: &str = "before"; fn set_s() { S = "after"; //~ ERROR cannot assign to immutable } fn main() { println!("{}", S); set_s(); println!("{}", S); } </ins>


Question:
On rustc 1.31.0-nightly ( 2018-10-07) and x8664-unknown-linux-gnu, we see the following surprising behavior: In release mode it seems the write has not happened in the place that it should. Mentioning threadlocal tracking issue: .
Ah, apparently this is missing a . With the behavior is correct. We need to make sure mutating a thread_local static that does not have does not compile.
cc Did fix this by any chance?
It looks like this is fixed on nightly; I'm guessing is the reason. We probably should add some regression tests for the cases listed here.

<ins> error[E0594]: cannot assign to immutable thread-local static item --> $DIR/thread-local-mutation.rs:11:5 | LL |     S = "after"; //~ ERROR cannot assign to immutable |     ^^^^^^^^^^^ error: aborting due to previous error For more information about this error, try `rustc --explain E0594`. </ins>


Question:
The following code gives "warning: enum is never used: ": This regressed pretty recently. cc
27.0 does not warn, 1.28.0 does.
triage: P-medium; This seems like a papercut that should be easy to work-around (at least if one isn't using ...).
switched to P-high after prompting from
whoops forgot to tag with T-compiler in time for the meeting...
assigning to
I'm grabbing this, I think I broke it and it should be easy to fix

hir::ItemKind::Fn(..) | hir::ItemKind::Ty(..) | hir::ItemKind::Static(..) <ins> | hir::ItemKind::Existential(..) </ins> | hir::ItemKind::Const(..) => { intravisit::walk_item(self, &item); }


Question:
The following code gives "warning: enum is never used: ": This regressed pretty recently. cc
27.0 does not warn, 1.28.0 does.
triage: P-medium; This seems like a papercut that should be easy to work-around (at least if one isn't using ...).
switched to P-high after prompting from
whoops forgot to tag with T-compiler in time for the meeting...
assigning to
I'm grabbing this, I think I broke it and it should be easy to fix

<ins> // compile-pass #[deny(warnings)] enum Empty { } trait Bar<T> {} impl Bar<Empty> for () {} fn boo() -> impl Bar<Empty> {} fn main() { boo(); } </ins>


Question: Regression from 1.26.0 to 1.27.0 and later. See for example See also and

fn build_external_function(cx: &DocContext, did: DefId) -> clean::Function { let sig = cx.tcx.fn_sig(did); <del> let constness = if cx.tcx.is_const_fn(did) { </del> <ins> let constness = if cx.tcx.is_min_const_fn(did) { </ins> hir::Constness::Const } else { hir::Constness::NotConst


Question: Regression from 1.26.0 to 1.27.0 and later. See for example See also and

(self.generics.clean(cx), (&self.decl, self.body).clean(cx)) }); <ins> let did = cx.tcx.hir().local_def_id(self.id); let constness = if cx.tcx.is_min_const_fn(did) { hir::Constness::Const } else { hir::Constness::NotConst }; </ins> Item { name: Some(self.name.clean(cx)), attrs: self.attrs.clean(cx),


Question: Regression from 1.26.0 to 1.27.0 and later. See for example See also and

visibility: self.vis.clean(cx), stability: self.stab.clean(cx), deprecation: self.depr.clean(cx), <del> def_id: cx.tcx.hir().local_def_id(self.id), </del> <ins> def_id: did, </ins> inner: FunctionItem(Function { decl, generics, <del> header: self.header, </del> <ins> header: hir::FnHeader { constness, ..self.header }, </ins> }), } }


Question: Regression from 1.26.0 to 1.27.0 and later. See for example See also and

ty::TraitContainer(_) => self.defaultness.has_value() }; if provided { <del> let constness = if cx.tcx.is_const_fn(self.def_id) { </del> <ins> let constness = if cx.tcx.is_min_const_fn(self.def_id) { </ins> hir::Constness::Const } else { hir::Constness::NotConst


Question: Regression from 1.26.0 to 1.27.0 and later. See for example See also and

<ins> // Copyright 2018 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. #![crate_name = "foo"] #![unstable(feature = "humans", reason = "who ever let humans program computers, we're apparently really bad at it", issue = "0")] #![feature(rustc_const_unstable, const_fn, foo, foo2)] #![feature(min_const_unsafe_fn)] #![feature(staged_api)] // @has 'foo/fn.foo.html' '//pre' 'pub unsafe fn foo() -> u32' #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature="foo")] pub const unsafe fn foo() -> u32 { 42 } // @has 'foo/fn.foo2.html' '//pre' 'pub fn foo2() -> u32' #[unstable(feature = "humans", issue="0")] pub const fn foo2() -> u32 { 42 } // @has 'foo/fn.bar2.html' '//pre' 'pub const fn bar2() -> u32' #[stable(feature = "rust1", since = "1.0.0")] pub const fn bar2() -> u32 { 42 } // @has 'foo/fn.foo2_gated.html' '//pre' 'pub unsafe fn foo2_gated() -> u32' #[unstable(feature = "foo2", issue="0")] pub const unsafe fn foo2_gated() -> u32 { 42 } // @has 'foo/fn.bar2_gated.html' '//pre' 'pub const unsafe fn bar2_gated() -> u32' #[stable(feature = "rust1", since = "1.0.0")] pub const unsafe fn bar2_gated() -> u32 { 42 } // @has 'foo/fn.bar_not_gated.html' '//pre' 'pub unsafe fn bar_not_gated() -> u32' pub const unsafe fn bar_not_gated() -> u32 { 42 } </ins>


Question:
Hi, I noticed a weird internal error using . The smallest example I could make to reproduce the bug is an basic library project () whose contains: , , and all work fine; and as mentioned in the code, the place where is declared seems to matter. Here is the output and trace of : [log was from an out of date nightly rust, see my comment below for the log for the latest nightly as of this edit] Have a nice day.
My bad, I appear to have accidentally used a version of rust that wasn't up to date. The bug still occurs in the latest nightly, here's the backtrace: Sorry again about that.
It looks like is only checking for explicit negative impls at the very beginning, and not throughout the process. I should have a fix for this later today.
Looks like this error has been there the whole time that synthetic impls have been there - that sample fails all the way back to 1.26.0.

) -> Option<(ty::ParamEnv<'c>, ty::ParamEnv<'c>)> { let tcx = infcx.tcx; <del> let mut select = SelectionContext::new(&infcx); </del> <ins> let mut select = SelectionContext::with_negative(&infcx, true); </ins> let mut already_visited = FxHashSet::default(); let mut predicates = VecDeque::new();


Question:
Hi, I noticed a weird internal error using . The smallest example I could make to reproduce the bug is an basic library project () whose contains: , , and all work fine; and as mentioned in the code, the place where is declared seems to matter. Here is the output and trace of : [log was from an out of date nightly rust, see my comment below for the log for the latest nightly as of this edit] Have a nice day.
My bad, I appear to have accidentally used a version of rust that wasn't up to date. The bug still occurs in the latest nightly, here's the backtrace: Sorry again about that.
It looks like is only checking for explicit negative impls at the very beginning, and not throughout the process. I should have a fix for this later today.
Looks like this error has been there the whole time that synthetic impls have been there - that sample fails all the way back to 1.26.0.

match &result { &Ok(Some(ref vtable)) => { <ins> // If we see an explicit negative impl (e.g. 'impl !Send for MyStruct'), // we immediately bail out, since it's impossible for us to continue. match vtable { Vtable::VtableImpl(VtableImplData { impl_def_id, .. }) => { // Blame tidy for the weird bracket placement if infcx.tcx.impl_polarity(*impl_def_id) == hir::ImplPolarity::Negative { debug!("evaluate_nested_obligations: Found explicit negative impl {:?}, bailing out", impl_def_id); return None; } }, _ => {} } </ins> let obligations = vtable.clone().nested_obligations().into_iter(); if !self.evaluate_nested_obligations(


Question:
Hi, I noticed a weird internal error using . The smallest example I could make to reproduce the bug is an basic library project () whose contains: , , and all work fine; and as mentioned in the code, the place where is declared seems to matter. Here is the output and trace of : [log was from an out of date nightly rust, see my comment below for the log for the latest nightly as of this edit] Have a nice day.
My bad, I appear to have accidentally used a version of rust that wasn't up to date. The bug still occurs in the latest nightly, here's the backtrace: Sorry again about that.
It looks like is only checking for explicit negative impls at the very beginning, and not throughout the process. I should have a fix for this later today.
Looks like this error has been there the whole time that synthetic impls have been there - that sample fails all the way back to 1.26.0.

<ins> // Copyright 2018 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. #![feature(optin_builtin_traits)] // @has issue_55321/struct.A.html // @has - '//*[@id="implementations-list"]/*[@class="impl"]//*/code' "impl !Send for A" // @has - '//*[@id="implementations-list"]/*[@class="impl"]//*/code' "impl !Sync for A" pub struct A(); impl !Send for A {} impl !Sync for A {} // @has issue_55321/struct.B.html // @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//*/code' "impl<T> !Send for  // B<T>" // @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//*/code' "impl<T> !Sync for  // B<T>" pub struct B<T: ?Sized>(A, Box<T>); </ins>


Question:
We're incorrectly suggesting wrapping with when it won't help: It should be suggesting using using instead.
Duplicate of . Let me commit to submitting a fix for this on (or, less likely, before) Sunday the twenty-eighth (hopefully preserving the -wrapping suggestion in the cases where it is correct, but if we have to scrap the whole suggestion, we will; false-positives are pretty bad)

err.span_label(arm_span, msg); } } <del> hir::MatchSource::TryDesugar => { // Issue #51632 if let Ok(try_snippet) = self.tcx.sess.source_map().span_to_snippet(arm_span) { err.span_suggestion_with_applicability( arm_span, "try wrapping with a success variant", format!("Ok({})", try_snippet), Applicability::MachineApplicable, ); } } </del> <ins> hir::MatchSource::TryDesugar => {} </ins> _ => { let msg = "match arm with an incompatible type"; if self.tcx.sess.source_map().is_multiline(arm_span) {


Question:
We're incorrectly suggesting wrapping with when it won't help: It should be suggesting using using instead.
Duplicate of . Let me commit to submitting a fix for this on (or, less likely, before) Sunday the twenty-eighth (hopefully preserving the -wrapping suggestion in the cases where it is correct, but if we have to scrap the whole suggestion, we will; false-positives are pretty bad)

<del> // Copyright 2018 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. // run-rustfix #![allow(dead_code)] fn missing_discourses() -> Result<isize, ()> { Ok(1) } fn forbidden_narratives() -> Result<isize, ()> { Ok(missing_discourses()?) //~^ ERROR try expression alternatives have incompatible types //~| HELP try wrapping with a success variant } fn main() {} </del>


Question:
We're incorrectly suggesting wrapping with when it won't help: It should be suggesting using using instead.
Duplicate of . Let me commit to submitting a fix for this on (or, less likely, before) Sunday the twenty-eighth (hopefully preserving the -wrapping suggestion in the cases where it is correct, but if we have to scrap the whole suggestion, we will; false-positives are pretty bad)

// option. This file may not be copied, modified, or distributed // except according to those terms. <del> // run-rustfix </del> #![allow(dead_code)] fn missing_discourses() -> Result<isize, ()> {


Question:
We're incorrectly suggesting wrapping with when it won't help: It should be suggesting using using instead.
Duplicate of . Let me commit to submitting a fix for this on (or, less likely, before) Sunday the twenty-eighth (hopefully preserving the -wrapping suggestion in the cases where it is correct, but if we have to scrap the whole suggestion, we will; false-positives are pretty bad)

fn forbidden_narratives() -> Result<isize, ()> { missing_discourses()? //~^ ERROR try expression alternatives have incompatible types <del> //~| HELP try wrapping with a success variant </del> } fn main() {}


Question:
We're incorrectly suggesting wrapping with when it won't help: It should be suggesting using using instead.
Duplicate of . Let me commit to submitting a fix for this on (or, less likely, before) Sunday the twenty-eighth (hopefully preserving the -wrapping suggestion in the cases where it is correct, but if we have to scrap the whole suggestion, we will; false-positives are pretty bad)

error[E0308]: try expression alternatives have incompatible types <del> --> $DIR/issue-51632-try-desugar-incompatible-types.rs:20:5 </del> <ins> --> $DIR/issue-51632-try-desugar-incompatible-types.rs:18:5 </ins> | LL |     missing_discourses()? <del> |     ^^^^^^^^^^^^^^^^^^^^^ |     | |     expected enum `std::result::Result`, found isize |     help: try wrapping with a success variant: `Ok(missing_discourses()?)` </del> <ins> |     ^^^^^^^^^^^^^^^^^^^^^ expected enum `std::result::Result`, found isize </ins> | = note: expected type `std::result::Result<isize, ()>` found type `isize`


Question:
Hi, I'm not sure if this has been reported or is known at all. If it has feel free to close it out. This example: causes an ICE on rustc 1.31.0-nightly ( 2018-10-25) This is the error I'm getting, backtrace included:
Okay, the good news here is that I only see this ICE with ; it does not arise with the NLL migration mode being deployed as part of the 2018 edition. See e.g. this .
The code in question is rejected by AST-borrowck. It looks like it is being rejected by NLL as well, and the problem is that we hit an error when trying to generated our diagnostic. Therefore, I'm going to tag this as NLL-sound (since this seems like a case where we want to reject the code in question) and NLL-diagnostics (since the ICE itself is stemming from diagnostics code). And I think I'm going to make it P-high, because 1. ICE's are super annoying and 2. I bet its not hard to fix. But I'm not going to tag it with the Release milestone, because its not something we need to worry about backporting to the beta channel (because it does not arise with NLL migration mode).
actually I'll remove NLL-sound; this isn't a case where NLL is incorrectly accepting the code. Its just incorrectly behaving while generating the diagnostics.

let mir_node_id = tcx.hir.as_local_node_id(mir_def_id).expect("non-local mir"); <del> let (return_span, mir_description) = if let hir::ExprKind::Closure(_, _, _, span, gen_move) = tcx.hir.expect_expr(mir_node_id).node { ( tcx.sess.source_map().end_point(span), if gen_move.is_some() { " of generator" } else { " of closure" }, ) } else { // unreachable? (mir.span, "") }; </del> <ins> let (return_span, mir_description) = match tcx.hir.get(mir_node_id) { hir::Node::Expr(hir::Expr { node: hir::ExprKind::Closure(_, _, _, span, gen_move), .. }) => ( tcx.sess.source_map().end_point(*span), if gen_move.is_some() { " of generator" } else { " of closure" }, ), hir::Node::ImplItem(hir::ImplItem { node: hir::ImplItemKind::Method(method_sig, _), .. }) => (method_sig.decl.output.span(), ""), _ => (mir.span, ""), }; </ins> Some(RegionName { // This counter value will already have been used, so this function will increment it


Question:
Hi, I'm not sure if this has been reported or is known at all. If it has feel free to close it out. This example: causes an ICE on rustc 1.31.0-nightly ( 2018-10-25) This is the error I'm getting, backtrace included:
Okay, the good news here is that I only see this ICE with ; it does not arise with the NLL migration mode being deployed as part of the 2018 edition. See e.g. this .
The code in question is rejected by AST-borrowck. It looks like it is being rejected by NLL as well, and the problem is that we hit an error when trying to generated our diagnostic. Therefore, I'm going to tag this as NLL-sound (since this seems like a case where we want to reject the code in question) and NLL-diagnostics (since the ICE itself is stemming from diagnostics code). And I think I'm going to make it P-high, because 1. ICE's are super annoying and 2. I bet its not hard to fix. But I'm not going to tag it with the Release milestone, because its not something we need to worry about backporting to the beta channel (because it does not arise with NLL migration mode).
actually I'll remove NLL-sound; this isn't a case where NLL is incorrectly accepting the code. Its just incorrectly behaving while generating the diagnostics.

<ins> // Copyright 2017 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. #![feature(nll)] struct Bar; struct Foo<'s> { bar: &'s mut Bar, } impl Foo<'_> { fn new(bar: &mut Bar) -> Self { Foo { bar } } } fn main() { } </ins>


Question:
Hi, I'm not sure if this has been reported or is known at all. If it has feel free to close it out. This example: causes an ICE on rustc 1.31.0-nightly ( 2018-10-25) This is the error I'm getting, backtrace included:
Okay, the good news here is that I only see this ICE with ; it does not arise with the NLL migration mode being deployed as part of the 2018 edition. See e.g. this .
The code in question is rejected by AST-borrowck. It looks like it is being rejected by NLL as well, and the problem is that we hit an error when trying to generated our diagnostic. Therefore, I'm going to tag this as NLL-sound (since this seems like a case where we want to reject the code in question) and NLL-diagnostics (since the ICE itself is stemming from diagnostics code). And I think I'm going to make it P-high, because 1. ICE's are super annoying and 2. I bet its not hard to fix. But I'm not going to tag it with the Release milestone, because its not something we need to worry about backporting to the beta channel (because it does not arise with NLL migration mode).
actually I'll remove NLL-sound; this isn't a case where NLL is incorrectly accepting the code. Its just incorrectly behaving while generating the diagnostics.

<ins> error: unsatisfied lifetime constraints --> $DIR/issue-55394.rs:21:9 | LL |     fn new(bar: &mut Bar) -> Self { |                 -            ---- return type is Foo<'2> |                 | |                 let's call the lifetime of this reference `'1` LL |         Foo { bar } |         ^^^^^^^^^^^ returning this value requires that `'1` must outlive `'2` error: aborting due to previous error </ins>


Question:
review comments:
I've looked into this some - NLL misses three errors, all of the form u.yu.x`. In each of the three cases, there is a mutable borrow of some field of the union and then a shared borrow of some other field immediately following. The issue seems to be that the mutable borrow is killed straight away as it isn't used later - therefore not causing a conflict with the shared borrow. I'm inclined to think that this is fine - and that NLL is correct in having less errors here. However, we might want to update the test to use the first mutable borrow for each case in order to make the error happen and demonstrate the diagnostic - if this is the case, I've that we can open a PR for that will update the test. cc
I'm inclined to agree that this is an instance where the test was not robust and that we need to add uses of those first mutable borrows.
I've submitted a PR () that makes the test more robust.

/// implicit closure bindings. It is needed when the closure is /// borrowing or mutating a mutable referent, e.g.: /// <del> ///    let x: &mut isize = ...; ///    let y = || *x += 5; </del> <ins> ///     let x: &mut isize = ...; ///     let y = || *x += 5; </ins> /// /// If we were to try to translate this closure into a more explicit /// form, we'd encounter an error with the code as written: /// <del> ///    struct Env { x: & &mut isize } ///    let x: &mut isize = ...; ///    let y = (&mut Env { &x }, fn_ptr);  // Closure is pair of env and fn ///    fn fn_ptr(env: &mut Env) { **env.x += 5; } </del> <ins> ///     struct Env { x: & &mut isize } ///     let x: &mut isize = ...; ///     let y = (&mut Env { &x }, fn_ptr);  // Closure is pair of env and fn ///     fn fn_ptr(env: &mut Env) { **env.x += 5; } </ins> /// /// This is then illegal because you cannot mutate an `&mut` found /// in an aliasable location. To solve, you'd have to translate with /// an `&mut` borrow: /// <del> ///    struct Env { x: & &mut isize } ///    let x: &mut isize = ...; ///    let y = (&mut Env { &mut x }, fn_ptr); // changed from &x to &mut x ///    fn fn_ptr(env: &mut Env) { **env.x += 5; } </del> <ins> ///     struct Env { x: & &mut isize } ///     let x: &mut isize = ...; ///     let y = (&mut Env { &mut x }, fn_ptr); // changed from &x to &mut x ///     fn fn_ptr(env: &mut Env) { **env.x += 5; } </ins> /// /// Now the assignment to `**env.x` is legal, but creating a /// mutable pointer to `x` is not because `x` is not mutable. We


Question:
review comments:
I've looked into this some - NLL misses three errors, all of the form u.yu.x`. In each of the three cases, there is a mutable borrow of some field of the union and then a shared borrow of some other field immediately following. The issue seems to be that the mutable borrow is killed straight away as it isn't used later - therefore not causing a conflict with the shared borrow. I'm inclined to think that this is fine - and that NLL is correct in having less errors here. However, we might want to update the test to use the first mutable borrow for each case in order to make the error happen and demonstrate the diagnostic - if this is the case, I've that we can open a PR for that will update the test. cc
I'm inclined to agree that this is an instance where the test was not robust and that we need to add uses of those first mutable borrows.
I've submitted a PR () that makes the test more robust.

<ins> error[E0502]: cannot borrow `u.y` as immutable because it is also borrowed as mutable --> $DIR/union-borrow-move-parent-sibling.rs:25:13 | LL |     let a = &mut u.x.0; |             ---------- mutable borrow occurs here LL |     let b = &u.y; //~ ERROR cannot borrow `u.y` |             ^^^^ immutable borrow occurs here LL |     use_borrow(a); |                - mutable borrow later used here </ins> error[E0382]: use of moved value: `u` <del> --> $DIR/union-borrow-move-parent-sibling.rs:29:13 </del> <ins> --> $DIR/union-borrow-move-parent-sibling.rs:32:13 </ins> | LL |     let a = u.x.0; |             ----- value moved here <del> LL |     let a = u.y; //~ ERROR use of moved value: `u.y` </del> <ins> LL |     let b = u.y; //~ ERROR use of moved value: `u.y` </ins> |             ^^^ value used here after move | = note: move occurs because `u` has type `U`, which does not implement the `Copy` trait <ins> error[E0502]: cannot borrow `u.y` as immutable because it is also borrowed as mutable --> $DIR/union-borrow-move-parent-sibling.rs:38:13 | LL |     let a = &mut (u.x.0).0; |             -------------- mutable borrow occurs here LL |     let b = &u.y; //~ ERROR cannot borrow `u.y` |             ^^^^ immutable borrow occurs here LL |     use_borrow(a); |                - mutable borrow later used here </ins> error[E0382]: use of moved value: `u` <del> --> $DIR/union-borrow-move-parent-sibling.rs:41:13 </del> <ins> --> $DIR/union-borrow-move-parent-sibling.rs:45:13 </ins> | LL |     let a = (u.x.0).0; |             --------- value moved here <del> LL |     let a = u.y; //~ ERROR use of moved value: `u.y` </del> <ins> LL |     let b = u.y; //~ ERROR use of moved value: `u.y` </ins> |             ^^^ value used here after move | = note: move occurs because `u` has type `U`, which does not implement the `Copy` trait <ins> error[E0502]: cannot borrow `u.x` as immutable because it is also borrowed as mutable --> $DIR/union-borrow-move-parent-sibling.rs:51:13 | LL |     let a = &mut *u.y; |             --------- mutable borrow occurs here LL |     let b = &u.x; //~ ERROR cannot borrow `u` (via `u.x`) |             ^^^^ immutable borrow occurs here LL |     use_borrow(a); |                - mutable borrow later used here </ins> error[E0382]: use of moved value: `u` <del> --> $DIR/union-borrow-move-parent-sibling.rs:53:13 </del> <ins> --> $DIR/union-borrow-move-parent-sibling.rs:58:13 </ins> | LL |     let a = *u.y; |             ---- value moved here <del> LL |     let a = u.x; //~ ERROR use of moved value: `u.x` </del> <ins> LL |     let b = u.x; //~ ERROR use of moved value: `u.x` </ins> |             ^^^ value used here after move | = note: move occurs because `u` has type `U`, which does not implement the `Copy` trait <del> error: aborting due to 3 previous errors </del> <ins> error: aborting due to 6 previous errors </ins> <del> For more information about this error, try `rustc --explain E0382`. </del> <ins> Some errors occurred: E0382, E0502. For more information about an error, try `rustc --explain E0382`. </ins>


Question:
review comments:
I've looked into this some - NLL misses three errors, all of the form u.yu.x`. In each of the three cases, there is a mutable borrow of some field of the union and then a shared borrow of some other field immediately following. The issue seems to be that the mutable borrow is killed straight away as it isn't used later - therefore not causing a conflict with the shared borrow. I'm inclined to think that this is fine - and that NLL is correct in having less errors here. However, we might want to update the test to use the first mutable borrow for each case in order to make the error happen and demonstrate the diagnostic - if this is the case, I've that we can open a PR for that will update the test. cc
I'm inclined to agree that this is an instance where the test was not robust and that we need to add uses of those first mutable borrows.
I've submitted a PR () that makes the test more robust.

y: Box<Vec<u8>>, } <ins> fn use_borrow<T>(_: &T) {} </ins> unsafe fn parent_sibling_borrow() { let mut u = U { x: ((Vec::new(), Vec::new()), Vec::new()) }; let a = &mut u.x.0; <del> let a = &u.y; //~ ERROR cannot borrow `u.y` </del> <ins> let b = &u.y; //~ ERROR cannot borrow `u.y` use_borrow(a); </ins> } unsafe fn parent_sibling_move() { let u = U { x: ((Vec::new(), Vec::new()), Vec::new()) }; let a = u.x.0; <del> let a = u.y; //~ ERROR use of moved value: `u.y` </del> <ins> let b = u.y; //~ ERROR use of moved value: `u.y` </ins> } unsafe fn grandparent_sibling_borrow() { let mut u = U { x: ((Vec::new(), Vec::new()), Vec::new()) }; let a = &mut (u.x.0).0; <del> let a = &u.y; //~ ERROR cannot borrow `u.y` </del> <ins> let b = &u.y; //~ ERROR cannot borrow `u.y` use_borrow(a); </ins> } unsafe fn grandparent_sibling_move() { let u = U { x: ((Vec::new(), Vec::new()), Vec::new()) }; let a = (u.x.0).0; <del> let a = u.y; //~ ERROR use of moved value: `u.y` </del> <ins> let b = u.y; //~ ERROR use of moved value: `u.y` </ins> } unsafe fn deref_sibling_borrow() { let mut u = U { y: Box::default() }; let a = &mut *u.y; <del> let a = &u.x; //~ ERROR cannot borrow `u` (via `u.x`) </del> <ins> let b = &u.x; //~ ERROR cannot borrow `u` (via `u.x`) use_borrow(a); </ins> } unsafe fn deref_sibling_move() { let u = U { x: ((Vec::new(), Vec::new()), Vec::new()) }; let a = *u.y; <del> let a = u.x; //~ ERROR use of moved value: `u.x` </del> <ins> let b = u.x; //~ ERROR use of moved value: `u.x` </ins> }


Question:
review comments:
I've looked into this some - NLL misses three errors, all of the form u.yu.x`. In each of the three cases, there is a mutable borrow of some field of the union and then a shared borrow of some other field immediately following. The issue seems to be that the mutable borrow is killed straight away as it isn't used later - therefore not causing a conflict with the shared borrow. I'm inclined to think that this is fine - and that NLL is correct in having less errors here. However, we might want to update the test to use the first mutable borrow for each case in order to make the error happen and demonstrate the diagnostic - if this is the case, I've that we can open a PR for that will update the test. cc
I'm inclined to agree that this is an instance where the test was not robust and that we need to add uses of those first mutable borrows.
I've submitted a PR () that makes the test more robust.

error[E0502]: cannot borrow `u.y` as immutable because `u.x.0` is also borrowed as mutable <del> --> $DIR/union-borrow-move-parent-sibling.rs:23:14 </del> <ins> --> $DIR/union-borrow-move-parent-sibling.rs:25:14 </ins> | LL |     let a = &mut u.x.0; |                  ----- mutable borrow occurs here <del> LL |     let a = &u.y; //~ ERROR cannot borrow `u.y` </del> <ins> LL |     let b = &u.y; //~ ERROR cannot borrow `u.y` </ins> |              ^^^ immutable borrow occurs here <ins> LL |     use_borrow(a); </ins> LL | } | - mutable borrow ends here error[E0382]: use of moved value: `u.y` <del> --> $DIR/union-borrow-move-parent-sibling.rs:29:9 </del> <ins> --> $DIR/union-borrow-move-parent-sibling.rs:32:9 </ins> | LL |     let a = u.x.0; |         - value moved here <del> LL |     let a = u.y; //~ ERROR use of moved value: `u.y` </del> <ins> LL |     let b = u.y; //~ ERROR use of moved value: `u.y` </ins> |         ^ value used here after move | = note: move occurs because `u.y` has type `[type error]`, which does not implement the `Copy` trait error[E0502]: cannot borrow `u.y` as immutable because `u.x.0.0` is also borrowed as mutable <del> --> $DIR/union-borrow-move-parent-sibling.rs:35:14 </del> <ins> --> $DIR/union-borrow-move-parent-sibling.rs:38:14 </ins> | LL |     let a = &mut (u.x.0).0; |                  --------- mutable borrow occurs here <del> LL |     let a = &u.y; //~ ERROR cannot borrow `u.y` </del> <ins> LL |     let b = &u.y; //~ ERROR cannot borrow `u.y` </ins> |              ^^^ immutable borrow occurs here <ins> LL |     use_borrow(a); </ins> LL | } | - mutable borrow ends here error[E0382]: use of moved value: `u.y` <del> --> $DIR/union-borrow-move-parent-sibling.rs:41:9 </del> <ins> --> $DIR/union-borrow-move-parent-sibling.rs:45:9 </ins> | LL |     let a = (u.x.0).0; |         - value moved here <del> LL |     let a = u.y; //~ ERROR use of moved value: `u.y` </del> <ins> LL |     let b = u.y; //~ ERROR use of moved value: `u.y` </ins> |         ^ value used here after move | = note: move occurs because `u.y` has type `[type error]`, which does not implement the `Copy` trait error[E0502]: cannot borrow `u` (via `u.x`) as immutable because `u` is also borrowed as mutable (via `*u.y`) <del> --> $DIR/union-borrow-move-parent-sibling.rs:47:14 </del> <ins> --> $DIR/union-borrow-move-parent-sibling.rs:51:14 </ins> | LL |     let a = &mut *u.y; |                  ---- mutable borrow occurs here (via `*u.y`) <del> LL |     let a = &u.x; //~ ERROR cannot borrow `u` (via `u.x`) </del> <ins> LL |     let b = &u.x; //~ ERROR cannot borrow `u` (via `u.x`) </ins> |              ^^^ immutable borrow occurs here (via `u.x`) <ins> LL |     use_borrow(a); </ins> LL | } | - mutable borrow ends here error[E0382]: use of moved value: `u.x` <del> --> $DIR/union-borrow-move-parent-sibling.rs:53:9 </del> <ins> --> $DIR/union-borrow-move-parent-sibling.rs:58:9 </ins> | LL |     let a = *u.y; |         - value moved here <del> LL |     let a = u.x; //~ ERROR use of moved value: `u.x` </del> <ins> LL |     let b = u.x; //~ ERROR use of moved value: `u.x` </ins> |         ^ value used here after move | = note: move occurs because `u.x` has type `[type error]`, which does not implement the `Copy` trait


Question:
I have two crates: Notice that the implementation of contains an . Something is not happy about that. This currently affects Serde trait impls that use a private helper type with a Serde derive, which is a common pattern. The following script reproduces the issue as of rustc 1.31.0-beta.4 ( 2018-11-01) as well as rustc 1.32.0-nightly ( 2018-11-07).
Mentioning who seems to know about extern_prelude.
The issue is caused by entering infinite recursion when trying to print the impl path. If returns and finishes , then this issue should be fixed as well.
(Also, the issue reproduces on 2015 edition as well.)
I'm hitting this on stable 1.32.0 with a , and I confirmed that replacing it with a manual impl works. Is there any other workaround?
Just ran into this on with the serde helper pattern.
Copying <kbdI-nominated</kbdfrom .
pre-triage: P-high. Leaving nominated for discussion at compiler triage meeting tomorrow.
From what I can tell, this was fixed sometime between nightly-2020-01-04 and nightly-2020-01-05. Here's what landed during that time:
I just discovered a detail about this bug that I did not previously appreciate: It needed the invocation (or some similar call to e.g. ) to replicate. The bug as described here ended up being fixed by PR . I suspect that's due to that rollup PR's inclusion of PR , but I have not yet verified this. The question I have remaining: Is the bug here really fixed, or is it merely masked by the changes from PR ? E.g. PR makes heavy revisions to the expansion of ; can one manually write code that emulates the previous expansion, and then replicate the original bug atop that? Anyway, even if the bug here is truly fixed, we should add the code from the description here as a regression test.
It's not fixed, the repro at the top still overflows rustc's stack as of 1.42.0-nightly ( 2020-01-09). We would need to minimize again to get a different minimal repro post-.
Okay I've got a new reproduction now, thanks for the pointer
removing nomination tag since I do not think this needs explicit discussion. However, it should get assignment. I'm not yet sure if I will take it on myself or try to get someone else to investigate it.
For posterity, here's the current backtrace (since the module no longer exists):
The issue is here Removing the check makes the repro case compile successfully, but it degrades some existing test output: an example of the changes: I'll see what can be done.
Just checking, did you see this? I don't remember all the details but I found that comment after looking at the context around the code you linked, which seemed vaguely familiar.
I'd seen that comment, but didn't grok the full meaning of it until I looked at this in more detail. Is there any reason not to change the to be ? is precisely as a way to avoid the problem at hand of unconditional recursion for other cases.
I found this separately in Workaround: add an (or whichever crate) at the root of your crate.
triage: nominating for discussion as part of attempt to burn down set of unassigned P-high issues at an otherwise light triage meeting.
discussed at . Assigning to
just ran into this bug in their GSoC project when adding a trybuild test (). EDIT: Rest of the comment was probably nonsense.
Just to confirm, still there in 1.46.0 (same repro with serde as posted above).
Didn't see this when it was posted, my bad, but I wanted to reply because it's not that simple because that recursion tracking is limited to , but currently, gets in between that, so that you have many independent sets, none of them containing the of the item.
I ran into this as well with while trying to delete based on the status here.

match self.tcx().extern_crate(def_id) { Some(&ExternCrate { src, dependency_of, span, .. }) => match (src, dependency_of) { (ExternCrateSource::Extern(def_id), LOCAL_CRATE) => { <del> debug!("try_print_visible_def_path: def_id={:?}", def_id); return Ok(( if !span.is_dummy() { self.print_def_path(def_id, &[])? } else { self.path_crate(cnum)? }, true, )); </del> <ins> // NOTE(eddyb) the only reason `span` might be dummy, // that we're aware of, is that it's the `std`/`core` // `extern crate` injected by default. // FIXME(eddyb) find something better to key this on, // or avoid ending up with `ExternCrateSource::Extern`, // for the injected `std`/`core`. if span.is_dummy() { return Ok((self.path_crate(cnum)?, true)); } // Disable `try_print_trimmed_def_path` behavior within // the `print_def_path` call, to avoid infinite recursion // in cases where the `extern crate foo` has non-trivial // parents, e.g. it's nested in `impl foo::Trait for Bar` // (see also issues #55779 and #87932). self = with_no_visible_paths(|| self.print_def_path(def_id, &[]))?; return Ok((self, true)); </ins> } (ExternCrateSource::Path, LOCAL_CRATE) => { <del> debug!("try_print_visible_def_path: def_id={:?}", def_id); </del> return Ok((self.path_crate(cnum)?, true)); } _ => {}


Question:
I have two crates: Notice that the implementation of contains an . Something is not happy about that. This currently affects Serde trait impls that use a private helper type with a Serde derive, which is a common pattern. The following script reproduces the issue as of rustc 1.31.0-beta.4 ( 2018-11-01) as well as rustc 1.32.0-nightly ( 2018-11-07).
Mentioning who seems to know about extern_prelude.
The issue is caused by entering infinite recursion when trying to print the impl path. If returns and finishes , then this issue should be fixed as well.
(Also, the issue reproduces on 2015 edition as well.)
I'm hitting this on stable 1.32.0 with a , and I confirmed that replacing it with a manual impl works. Is there any other workaround?
Just ran into this on with the serde helper pattern.
Copying <kbdI-nominated</kbdfrom .
pre-triage: P-high. Leaving nominated for discussion at compiler triage meeting tomorrow.
From what I can tell, this was fixed sometime between nightly-2020-01-04 and nightly-2020-01-05. Here's what landed during that time:
I just discovered a detail about this bug that I did not previously appreciate: It needed the invocation (or some similar call to e.g. ) to replicate. The bug as described here ended up being fixed by PR . I suspect that's due to that rollup PR's inclusion of PR , but I have not yet verified this. The question I have remaining: Is the bug here really fixed, or is it merely masked by the changes from PR ? E.g. PR makes heavy revisions to the expansion of ; can one manually write code that emulates the previous expansion, and then replicate the original bug atop that? Anyway, even if the bug here is truly fixed, we should add the code from the description here as a regression test.
It's not fixed, the repro at the top still overflows rustc's stack as of 1.42.0-nightly ( 2020-01-09). We would need to minimize again to get a different minimal repro post-.
Okay I've got a new reproduction now, thanks for the pointer
removing nomination tag since I do not think this needs explicit discussion. However, it should get assignment. I'm not yet sure if I will take it on myself or try to get someone else to investigate it.
For posterity, here's the current backtrace (since the module no longer exists):
The issue is here Removing the check makes the repro case compile successfully, but it degrades some existing test output: an example of the changes: I'll see what can be done.
Just checking, did you see this? I don't remember all the details but I found that comment after looking at the context around the code you linked, which seemed vaguely familiar.
I'd seen that comment, but didn't grok the full meaning of it until I looked at this in more detail. Is there any reason not to change the to be ? is precisely as a way to avoid the problem at hand of unconditional recursion for other cases.
I found this separately in Workaround: add an (or whichever crate) at the root of your crate.
triage: nominating for discussion as part of attempt to burn down set of unassigned P-high issues at an otherwise light triage meeting.
discussed at . Assigning to
just ran into this bug in their GSoC project when adding a trybuild test (). EDIT: Rest of the comment was probably nonsense.
Just to confirm, still there in 1.46.0 (same repro with serde as posted above).
Didn't see this when it was posted, my bad, but I wanted to reply because it's not that simple because that recursion tracking is limited to , but currently, gets in between that, so that you have many independent sets, none of them containing the of the item.
I ran into this as well with while trying to delete based on the status here.

<ins> pub trait Trait { fn no_op(&self); } </ins>


Question:
I have two crates: Notice that the implementation of contains an . Something is not happy about that. This currently affects Serde trait impls that use a private helper type with a Serde derive, which is a common pattern. The following script reproduces the issue as of rustc 1.31.0-beta.4 ( 2018-11-01) as well as rustc 1.32.0-nightly ( 2018-11-07).
Mentioning who seems to know about extern_prelude.
The issue is caused by entering infinite recursion when trying to print the impl path. If returns and finishes , then this issue should be fixed as well.
(Also, the issue reproduces on 2015 edition as well.)
I'm hitting this on stable 1.32.0 with a , and I confirmed that replacing it with a manual impl works. Is there any other workaround?
Just ran into this on with the serde helper pattern.
Copying <kbdI-nominated</kbdfrom .
pre-triage: P-high. Leaving nominated for discussion at compiler triage meeting tomorrow.
From what I can tell, this was fixed sometime between nightly-2020-01-04 and nightly-2020-01-05. Here's what landed during that time:
I just discovered a detail about this bug that I did not previously appreciate: It needed the invocation (or some similar call to e.g. ) to replicate. The bug as described here ended up being fixed by PR . I suspect that's due to that rollup PR's inclusion of PR , but I have not yet verified this. The question I have remaining: Is the bug here really fixed, or is it merely masked by the changes from PR ? E.g. PR makes heavy revisions to the expansion of ; can one manually write code that emulates the previous expansion, and then replicate the original bug atop that? Anyway, even if the bug here is truly fixed, we should add the code from the description here as a regression test.
It's not fixed, the repro at the top still overflows rustc's stack as of 1.42.0-nightly ( 2020-01-09). We would need to minimize again to get a different minimal repro post-.
Okay I've got a new reproduction now, thanks for the pointer
removing nomination tag since I do not think this needs explicit discussion. However, it should get assignment. I'm not yet sure if I will take it on myself or try to get someone else to investigate it.
For posterity, here's the current backtrace (since the module no longer exists):
The issue is here Removing the check makes the repro case compile successfully, but it degrades some existing test output: an example of the changes: I'll see what can be done.
Just checking, did you see this? I don't remember all the details but I found that comment after looking at the context around the code you linked, which seemed vaguely familiar.
I'd seen that comment, but didn't grok the full meaning of it until I looked at this in more detail. Is there any reason not to change the to be ? is precisely as a way to avoid the problem at hand of unconditional recursion for other cases.
I found this separately in Workaround: add an (or whichever crate) at the root of your crate.
triage: nominating for discussion as part of attempt to burn down set of unassigned P-high issues at an otherwise light triage meeting.
discussed at . Assigning to
just ran into this bug in their GSoC project when adding a trybuild test (). EDIT: Rest of the comment was probably nonsense.
Just to confirm, still there in 1.46.0 (same repro with serde as posted above).
Didn't see this when it was posted, my bad, but I wanted to reply because it's not that simple because that recursion tracking is limited to , but currently, gets in between that, so that you have many independent sets, none of them containing the of the item.
I ran into this as well with while trying to delete based on the status here.

<ins> pub trait Deserialize { fn deserialize(); } </ins>


Question:
I have two crates: Notice that the implementation of contains an . Something is not happy about that. This currently affects Serde trait impls that use a private helper type with a Serde derive, which is a common pattern. The following script reproduces the issue as of rustc 1.31.0-beta.4 ( 2018-11-01) as well as rustc 1.32.0-nightly ( 2018-11-07).
Mentioning who seems to know about extern_prelude.
The issue is caused by entering infinite recursion when trying to print the impl path. If returns and finishes , then this issue should be fixed as well.
(Also, the issue reproduces on 2015 edition as well.)
I'm hitting this on stable 1.32.0 with a , and I confirmed that replacing it with a manual impl works. Is there any other workaround?
Just ran into this on with the serde helper pattern.
Copying <kbdI-nominated</kbdfrom .
pre-triage: P-high. Leaving nominated for discussion at compiler triage meeting tomorrow.
From what I can tell, this was fixed sometime between nightly-2020-01-04 and nightly-2020-01-05. Here's what landed during that time:
I just discovered a detail about this bug that I did not previously appreciate: It needed the invocation (or some similar call to e.g. ) to replicate. The bug as described here ended up being fixed by PR . I suspect that's due to that rollup PR's inclusion of PR , but I have not yet verified this. The question I have remaining: Is the bug here really fixed, or is it merely masked by the changes from PR ? E.g. PR makes heavy revisions to the expansion of ; can one manually write code that emulates the previous expansion, and then replicate the original bug atop that? Anyway, even if the bug here is truly fixed, we should add the code from the description here as a regression test.
It's not fixed, the repro at the top still overflows rustc's stack as of 1.42.0-nightly ( 2020-01-09). We would need to minimize again to get a different minimal repro post-.
Okay I've got a new reproduction now, thanks for the pointer
removing nomination tag since I do not think this needs explicit discussion. However, it should get assignment. I'm not yet sure if I will take it on myself or try to get someone else to investigate it.
For posterity, here's the current backtrace (since the module no longer exists):
The issue is here Removing the check makes the repro case compile successfully, but it degrades some existing test output: an example of the changes: I'll see what can be done.
Just checking, did you see this? I don't remember all the details but I found that comment after looking at the context around the code you linked, which seemed vaguely familiar.
I'd seen that comment, but didn't grok the full meaning of it until I looked at this in more detail. Is there any reason not to change the to be ? is precisely as a way to avoid the problem at hand of unconditional recursion for other cases.
I found this separately in Workaround: add an (or whichever crate) at the root of your crate.
triage: nominating for discussion as part of attempt to burn down set of unassigned P-high issues at an otherwise light triage meeting.
discussed at . Assigning to
just ran into this bug in their GSoC project when adding a trybuild test (). EDIT: Rest of the comment was probably nonsense.
Just to confirm, still there in 1.46.0 (same repro with serde as posted above).
Didn't see this when it was posted, my bad, but I wanted to reply because it's not that simple because that recursion tracking is limited to , but currently, gets in between that, so that you have many independent sets, none of them containing the of the item.
I ran into this as well with while trying to delete based on the status here.

<ins> // run-pass // edition:2018 // aux-crate:issue_55779_extern_trait=issue-55779-extern-trait.rs use issue_55779_extern_trait::Trait; struct Local; struct Helper; impl Trait for Local { fn no_op(&self) { // (Unused) extern crate declaration necessary to reproduce bug extern crate issue_55779_extern_trait; // This one works // impl Trait for Helper { fn no_op(&self) { } } // This one infinite-loops const _IMPL_SERIALIZE_FOR_HELPER: () = { // (extern crate can also appear here to reproduce bug, // as in originating example from serde) impl Trait for Helper { fn no_op(&self) { } } }; } } fn main() { } </ins>


Question:
I have two crates: Notice that the implementation of contains an . Something is not happy about that. This currently affects Serde trait impls that use a private helper type with a Serde derive, which is a common pattern. The following script reproduces the issue as of rustc 1.31.0-beta.4 ( 2018-11-01) as well as rustc 1.32.0-nightly ( 2018-11-07).
Mentioning who seems to know about extern_prelude.
The issue is caused by entering infinite recursion when trying to print the impl path. If returns and finishes , then this issue should be fixed as well.
(Also, the issue reproduces on 2015 edition as well.)
I'm hitting this on stable 1.32.0 with a , and I confirmed that replacing it with a manual impl works. Is there any other workaround?
Just ran into this on with the serde helper pattern.
Copying <kbdI-nominated</kbdfrom .
pre-triage: P-high. Leaving nominated for discussion at compiler triage meeting tomorrow.
From what I can tell, this was fixed sometime between nightly-2020-01-04 and nightly-2020-01-05. Here's what landed during that time:
I just discovered a detail about this bug that I did not previously appreciate: It needed the invocation (or some similar call to e.g. ) to replicate. The bug as described here ended up being fixed by PR . I suspect that's due to that rollup PR's inclusion of PR , but I have not yet verified this. The question I have remaining: Is the bug here really fixed, or is it merely masked by the changes from PR ? E.g. PR makes heavy revisions to the expansion of ; can one manually write code that emulates the previous expansion, and then replicate the original bug atop that? Anyway, even if the bug here is truly fixed, we should add the code from the description here as a regression test.
It's not fixed, the repro at the top still overflows rustc's stack as of 1.42.0-nightly ( 2020-01-09). We would need to minimize again to get a different minimal repro post-.
Okay I've got a new reproduction now, thanks for the pointer
removing nomination tag since I do not think this needs explicit discussion. However, it should get assignment. I'm not yet sure if I will take it on myself or try to get someone else to investigate it.
For posterity, here's the current backtrace (since the module no longer exists):
The issue is here Removing the check makes the repro case compile successfully, but it degrades some existing test output: an example of the changes: I'll see what can be done.
Just checking, did you see this? I don't remember all the details but I found that comment after looking at the context around the code you linked, which seemed vaguely familiar.
I'd seen that comment, but didn't grok the full meaning of it until I looked at this in more detail. Is there any reason not to change the to be ? is precisely as a way to avoid the problem at hand of unconditional recursion for other cases.
I found this separately in Workaround: add an (or whichever crate) at the root of your crate.
triage: nominating for discussion as part of attempt to burn down set of unassigned P-high issues at an otherwise light triage meeting.
discussed at . Assigning to
just ran into this bug in their GSoC project when adding a trybuild test (). EDIT: Rest of the comment was probably nonsense.
Just to confirm, still there in 1.46.0 (same repro with serde as posted above).
Didn't see this when it was posted, my bad, but I wanted to reply because it's not that simple because that recursion tracking is limited to , but currently, gets in between that, so that you have many independent sets, none of them containing the of the item.
I ran into this as well with while trying to delete based on the status here.

<ins> // edition:2018 // aux-crate:issue_87932_a=issue-87932-a.rs pub struct A {} impl issue_87932_a::Deserialize for A { fn deserialize() { extern crate issue_87932_a as _a; } } fn main() { A::deserialize(); //~^ ERROR no function or associated item named `deserialize` found for struct `A` } </ins>


Question:
I have two crates: Notice that the implementation of contains an . Something is not happy about that. This currently affects Serde trait impls that use a private helper type with a Serde derive, which is a common pattern. The following script reproduces the issue as of rustc 1.31.0-beta.4 ( 2018-11-01) as well as rustc 1.32.0-nightly ( 2018-11-07).
Mentioning who seems to know about extern_prelude.
The issue is caused by entering infinite recursion when trying to print the impl path. If returns and finishes , then this issue should be fixed as well.
(Also, the issue reproduces on 2015 edition as well.)
I'm hitting this on stable 1.32.0 with a , and I confirmed that replacing it with a manual impl works. Is there any other workaround?
Just ran into this on with the serde helper pattern.
Copying <kbdI-nominated</kbdfrom .
pre-triage: P-high. Leaving nominated for discussion at compiler triage meeting tomorrow.
From what I can tell, this was fixed sometime between nightly-2020-01-04 and nightly-2020-01-05. Here's what landed during that time:
I just discovered a detail about this bug that I did not previously appreciate: It needed the invocation (or some similar call to e.g. ) to replicate. The bug as described here ended up being fixed by PR . I suspect that's due to that rollup PR's inclusion of PR , but I have not yet verified this. The question I have remaining: Is the bug here really fixed, or is it merely masked by the changes from PR ? E.g. PR makes heavy revisions to the expansion of ; can one manually write code that emulates the previous expansion, and then replicate the original bug atop that? Anyway, even if the bug here is truly fixed, we should add the code from the description here as a regression test.
It's not fixed, the repro at the top still overflows rustc's stack as of 1.42.0-nightly ( 2020-01-09). We would need to minimize again to get a different minimal repro post-.
Okay I've got a new reproduction now, thanks for the pointer
removing nomination tag since I do not think this needs explicit discussion. However, it should get assignment. I'm not yet sure if I will take it on myself or try to get someone else to investigate it.
For posterity, here's the current backtrace (since the module no longer exists):
The issue is here Removing the check makes the repro case compile successfully, but it degrades some existing test output: an example of the changes: I'll see what can be done.
Just checking, did you see this? I don't remember all the details but I found that comment after looking at the context around the code you linked, which seemed vaguely familiar.
I'd seen that comment, but didn't grok the full meaning of it until I looked at this in more detail. Is there any reason not to change the to be ? is precisely as a way to avoid the problem at hand of unconditional recursion for other cases.
I found this separately in Workaround: add an (or whichever crate) at the root of your crate.
triage: nominating for discussion as part of attempt to burn down set of unassigned P-high issues at an otherwise light triage meeting.
discussed at . Assigning to
just ran into this bug in their GSoC project when adding a trybuild test (). EDIT: Rest of the comment was probably nonsense.
Just to confirm, still there in 1.46.0 (same repro with serde as posted above).
Didn't see this when it was posted, my bad, but I wanted to reply because it's not that simple because that recursion tracking is limited to , but currently, gets in between that, so that you have many independent sets, none of them containing the of the item.
I ran into this as well with while trying to delete based on the status here.

<ins> error[E0599]: no function or associated item named `deserialize` found for struct `A` in the current scope --> $DIR/issue-87932.rs:13:8 | LL | pub struct A {} | ------------ function or associated item `deserialize` not found for this ... LL |     A::deserialize(); |        ^^^^^^^^^^^ function or associated item not found in `A` | = help: items from traits can only be used if the trait is in scope help: the following trait is implemented but not in scope; perhaps add a `use` for it: | LL | use <crate::A as issue_87932_a::Deserialize>::deserialize::_a::Deserialize; | error: aborting due to previous error For more information about this error, try `rustc --explain E0599`. </ins>


Question:
I may have found a bug in the compiler. The entirety of the code to reproduce this bug is this: The program should build successfully, assuming the rustc type checker does not detect any errors at the level of the Rust type system. The rustc type checker seems happy with the program. However, presumably after the LLVM IR generation phase, and during some IR verification phase, I get this type error:
Reduced:
I thought we already fixed that by adding casts. One possible fix that might be less harmful would be to give all types that are subtyping-equivalent the same LLVM type. They should be having the same layout anyway, and their fields should be subtyping-equivalent (because that's what subtyping-equivalence means). The other option would be to insert casts when subtyping is taking place.
This looks like a new instance of . cc
was just an instance of the general problem, we just started generating named types for trait objects then, which made the problem show up in more cases. I agree with first proposal, i.e. destroy the distinction ahead of time. We're only wasting time by inserting casts and LLVM wastes time ignoring those casts (insert rant about how counterproductive LLVM's types are).
Reduced to its essence:
An example that my previous approach will not make compile (but currently gives an ICE outputtypeparametermismatch):
Nah you can do it without an ICE, but you're still within deep ICE territory
This is making me suspect, that when we get higher-ranked type bounds, finding a "canonical form for subtyping" will be impossible (note: don't be so sure. You can't? (shouldn't?) have higher-ranged type bounds in trait objects, so life might be better). Might as well insert casts. Note that my old approach has problems with anonymization in invariant types:
marking this as p-medium as per the
labels +T-types This seems like a problem around higher ranked normalization etc, so we are tagging as T-types. We think it may have been fixed as a side-effect of some LLVM change or other (cc for the details).
Seems to be fixed since 1.23.
Triage: The issue hasn't been fixed actually, at least on CI (CI stderr from ):
That's interesting. It doesn't fail in a playground. Is this a debug assert now or something?
The build says so maybe this is fixed with nighty that uses llvm but llvm 13 still causes problems?
Likely, we could use if so. Is there a CI builder that uses a newer LLVM on bors?
Yeah, this is fixed by LLVM using its opaque pointers, so that's why it's possibly broken on LLVM 13?
Re-submitted a PR with :

<ins> // run-pass // ^-- The above is needed as this issue is related to LLVM/codegen. // min-llvm-version:15.0.0 // ^-- The above is needed as this issue is fixed by the opaque pointers. fn main() { type_error(|x| &x); } fn type_error<T>( _selector: for<'a> fn(&'a Vec<Box<dyn for<'b> Fn(&'b u8)>>) -> &'a Vec<Box<dyn Fn(T)>>, ) { } </ins>


Question:
The following example ICEs yields (Same is true on stable.)
That's because the ObjectCandidate code is not normalizing the upcast trait refs. Should we wait for Chalk for the fix?
Hitting this error, any updates?
Triage: no longer ICEs.
It's still an ICE, note that we should build/run the snippet to check it ().
Triage: It's no longer ICE with the latest nightly, I think it's fixed by .

<ins> // check-pass trait Mirror { type Other; } #[derive(Debug)] struct Even(usize); struct Odd; impl Mirror for Even { type Other = Odd; } impl Mirror for Odd { type Other = Even; } trait Dyn<T: Mirror>: AsRef<<T as Mirror>::Other> {} impl Dyn<Odd> for Even {} impl AsRef<Even> for Even { fn as_ref(&self) -> &Even { self } } fn code<T: Mirror>(d: &dyn Dyn<T>) -> &T::Other { d.as_ref() } fn main() { println!("{:?}", code(&Even(22))); } </ins>


Question:
The following example ICEs yields (Same is true on stable.)
That's because the ObjectCandidate code is not normalizing the upcast trait refs. Should we wait for Chalk for the fix?
Hitting this error, any updates?
Triage: no longer ICEs.
It's still an ICE, note that we should build/run the snippet to check it ().
Triage: It's no longer ICE with the latest nightly, I think it's fixed by .

<ins> fn t7p<A, B, C>(f: impl Fn(B) -> C, g: impl Fn(A) -> B) -> impl Fn(A) -> C { move |a: A| -> C { f(g(a)) } } fn t8n<A, B, C>(f: impl Fn(A) -> B, g: impl Fn(A) -> C) -> impl Fn(A) -> (B, C) where A: Copy, { move |a: A| -> (B, C) { let b = a; let fa = f(a); let ga = g(b); (fa, ga) } } fn main() { let f = |(_, _)| {}; let g = |(a, _)| a; let t7 = |env| |a| |b| t7p(f, g)(((env, a), b)); let t8 = t8n(t7, t7p(f, g)); //~^ ERROR: expected a `Fn<(_,)>` closure, found `impl Fn<(((_, _), _),)> } </ins>


Question:
The following example ICEs yields (Same is true on stable.)
That's because the ObjectCandidate code is not normalizing the upcast trait refs. Should we wait for Chalk for the fix?
Hitting this error, any updates?
Triage: no longer ICEs.
It's still an ICE, note that we should build/run the snippet to check it ().
Triage: It's no longer ICE with the latest nightly, I think it's fixed by .

<ins> error[E0277]: expected a `Fn<(_,)>` closure, found `impl Fn<(((_, _), _),)>` --> $DIR/issue-59494.rs:21:22 | LL | fn t8n<A, B, C>(f: impl Fn(A) -> B, g: impl Fn(A) -> C) -> impl Fn(A) -> (B, C) |                                             ---------- required by this bound in `t8n` ... LL |     let t8 = t8n(t7, t7p(f, g)); |                      ^^^^^^^^^ expected an `Fn<(_,)>` closure, found `impl Fn<(((_, _), _),)>` | = help: the trait `Fn<(_,)>` is not implemented for `impl Fn<(((_, _), _),)>` error: aborting due to previous error For more information about this error, try `rustc --explain E0277`. </ins>


Question:
The following example ICEs yields (Same is true on stable.)
That's because the ObjectCandidate code is not normalizing the upcast trait refs. Should we wait for Chalk for the fix?
Hitting this error, any updates?
Triage: no longer ICEs.
It's still an ICE, note that we should build/run the snippet to check it ().
Triage: It's no longer ICE with the latest nightly, I think it's fixed by .

<ins> // check-pass pub trait Trait1 { type C; } struct T1; impl Trait1 for T1 { type C = usize; } pub trait Callback<T: Trait1>: FnMut(<T as Trait1>::C) {} impl<T: Trait1, F: FnMut(<T as Trait1>::C)> Callback<T> for F {} pub struct State<T: Trait1> { callback: Option<Box<dyn Callback<T>>>, } impl<T: Trait1> State<T> { fn new() -> Self { Self { callback: None } } fn test_cb(&mut self, d: <T as Trait1>::C) { (self.callback.as_mut().unwrap())(d) } } fn main() { let mut s = State::<T1>::new(); s.test_cb(1); } </ins>


Question:
The following example ICEs yields (Same is true on stable.)
That's because the ObjectCandidate code is not normalizing the upcast trait refs. Should we wait for Chalk for the fix?
Hitting this error, any updates?
Triage: no longer ICEs.
It's still an ICE, note that we should build/run the snippet to check it ().
Triage: It's no longer ICE with the latest nightly, I think it's fixed by .

<ins> // check-pass fn any<T>() -> T { loop {} } trait Foo { type V; } trait Callback<T: Foo>: Fn(&T, &T::V) {} impl<T: Foo, F: Fn(&T, &T::V)> Callback<T> for F {} struct Bar<T: Foo> { callback: Box<dyn Callback<T>>, } impl<T: Foo> Bar<T> { fn event(&self) { (self.callback)(any(), any()); } } struct A; struct B; impl Foo for A { type V = B; } fn main() { let foo = Bar::<A> { callback: Box::new(|_: &A, _: &B| ()) }; foo.event(); } </ins>


Question:
reduced from num_cpus: built with yields cc `
What’s the target? Ah, never mind, I missed that its .
More minimal: Issue does not occur on stable (or 1.30.0 nightly), but occurs on rustc beta.
Marking T-libs as that is likely to be an issue within implementation of , but I didn’t investigate further.
Excerpt: Clearly both of those adjacent i32 aren't going to be 8-byte aligned ^^ It seems that we're storing to an key with wrong alignment for some reason.
Don't need to look particularly far, this code generates It looks like some code is assuming that both elements in a scalar pair have the same alignment as the whole pair.
Probably the easiest way to get to the root cause is to bisect.
This code is very likely the culprit: It takes the 0 and 1 GEPs, but uses the same alignment, without offset adjustment.
Ouch, that's bad. To obtain the alignment for both fields, we need to do: Note that we can't use because the components do not match fields (the latter come from the user type definitions, whereas the former are extracted as an optimization).

bx.store_with_flags(val, dest.llval, dest.align, flags); } OperandValue::Pair(a, b) => { <del> for (i, &x) in [a, b].iter().enumerate() { let llptr = bx.struct_gep(dest.llval, i as u64); let val = base::from_immediate(bx, x); bx.store_with_flags(val, llptr, dest.align, flags); } </del> <ins> let (a_scalar, b_scalar) = match dest.layout.abi { layout::Abi::ScalarPair(ref a, ref b) => (a, b), _ => bug!("store_with_flags: invalid ScalarPair layout: {:#?}", dest.layout) }; let b_offset = a_scalar.value.size(bx).align_to(b_scalar.value.align(bx).abi); let llptr = bx.struct_gep(dest.llval, 0); let val = base::from_immediate(bx, a); let align = dest.align; bx.store_with_flags(val, llptr, align, flags); let llptr = bx.struct_gep(dest.llval, 1); let val = base::from_immediate(bx, b); let align = dest.align.restrict_for_offset(b_offset); bx.store_with_flags(val, llptr, align, flags); </ins> } } }