Question:
These feel like an omission to me, given how is implemented for this type: And if we really want to go for feature parity, then also has impls for , but I think that's mostly for the sake of methods like , and it really doesn't make sense here. Edit: Then again, considering that RangeArgument is going to have methods that return , maybe is worth it. (secretly, I just want the standard library to implement my bounds-checking and length-computation for me in my n-dimensional array, so that I can just write and trust that it's correct. But shhhhhh, don't tell anyone)
On second thought, after seeing how meager libcore's test suite is for the existing indexing operations, I have decided that I should stop trusting the standard library and start contributing to it myself. Working on a PR. Edit: awww, looks like there's actually a good reason why there's no tests with or . (the first takes forever on debug, the second sets forth The End of All Times) Edit 2: How on earth does not appear a single time in the tests for slice or str!?!
do you still have plans to make a PR for this feature?
Nope, totally forgot about this! Feel free to take the reins. (looking back, it seems I went ahead with the test suite PR (), but that took long enough to merge that by the time it was done I must have moved on to other things.)

bad: data[4..=2]; message: "but ends at"; } <ins> in mod boundpair_neg_width { data: [0, 1, 2, 3, 4, 5]; good: data[(Bound::Included(4), Bound::Excluded(4))] == []; bad: data[(Bound::Included(4), Bound::Excluded(3))]; message: "but ends at"; } </ins> } panic_cases! {


Question:
These feel like an omission to me, given how is implemented for this type: And if we really want to go for feature parity, then also has impls for , but I think that's mostly for the sake of methods like , and it really doesn't make sense here. Edit: Then again, considering that RangeArgument is going to have methods that return , maybe is worth it. (secretly, I just want the standard library to implement my bounds-checking and length-computation for me in my n-dimensional array, so that I can just write and trust that it's correct. But shhhhhh, don't tell anyone)
On second thought, after seeing how meager libcore's test suite is for the existing indexing operations, I have decided that I should stop trusting the standard library and start contributing to it myself. Working on a PR. Edit: awww, looks like there's actually a good reason why there's no tests with or . (the first takes forever on debug, the second sets forth The End of All Times) Edit 2: How on earth does not appear a single time in the tests for slice or str!?!
do you still have plans to make a PR for this feature?
Nope, totally forgot about this! Feel free to take the reins. (looking back, it seems I went ahead with the test suite PR (), but that took long enough to merge that by the time it was done I must have moved on to other things.)

bad: data[..= usize::MAX]; message: "maximum usize"; } <ins> in mod boundpair_overflow_end { data: [0; 1]; bad: data[(Bound::Unbounded, Bound::Included(usize::MAX))]; message: "maximum usize"; } in mod boundpair_overflow_start { data: [0; 1]; bad: data[(Bound::Excluded(usize::MAX), Bound::Unbounded)]; message: "maximum usize"; } </ins> } // panic_cases! }


Question:
Context: In order to experiment with an -aware , I was preparing to modify the lang item signature, and my first step was to ensure MIR passes the right type to begin with, as noted in Legitimately, I assumed that the MIR inline code was doing the right thing, so I mimicked it in . The resulting code actually works fine, as far as completing the 3 stages of rustc bootstrapping is involved. But before going the route for the -aware , I first tried removing the special handling of 's , trying to leave it to , shortcutting the lang item. This didn't go well, and produced a stage 1 compiler that would crash on a bad in libsyntax's . From which I derived a small test case that would exhibit the problem with my code. Anyways, I was going well over my head with this approach, thus switched to the signature change. So, what's the deal with this issue, will you ask? Well, it turns out that my MIR changes, essentially copied from MIR inlining, while they worked to produce an apparently working compiler, failed to compile that reduced testcase with an LLVM ERROR. I was wondering if I did something significantly different from what the MIT inlining pass was doing, so I tried to trigger it manually (since it's not enabled by default), and after some trial and error, got it to happen on a plain nightly compiler, with the following reduced testcase: Building with yields: (Note the is only there to force MIR inlining to happen without having to go over the required threshold ; liballoc's has ; similarly, the on avoids inlining of dealloc, to limit the effects on the MIR) Interestingly enough, and fail with the same error. The former outputs a truncated MIR (truncated at the entry of the first basic block), and the latter outputs nothing.
This is what from a run with looks like: Edit: and what the llvm-ir, as disassembled from output, looks like:
The problem is that the code path bb1-bb9-bb21-bb20 in IR, corresponding to bb0-bb1-bb6-bb5 in MIR, is impossible, yet exists. And in that code path, in MIR, in IR, is never initialized, and that's what LLVM doesn't like. I guess one way to look at is it to wonder why in MIR has a switch in the first place.
And the answer to that last question is false edges, according to the following MIR from the mir_map pass:
Actually, the path bb0-bb7-bb4-bb10-bb12 has without ever being initialized, but that's pre-elaborate-drops, and I hear drop is different then, so I don't know if it bad or not.
The weird switch that eventually causes the LLVM problem is by the elaborate-drops pass. The MIR after that phase looks like the following:
I think the most relevant fact is this difference between MIR inlining being enabled or not: with MIR inlining disabled, this basic block in MIR: becomes the following IR: with MIR inlining enabled, this basic block in MIR: becomes whiich is weird... where did the extra code go?
The changes from fix this issue.

//! which do not. use rustc_data_structures::bitvec::BitVector; <ins> use rustc_data_structures::control_flow_graph::dominators::Dominators; </ins> use rustc_data_structures::indexed_vec::{Idx, IndexVec}; use rustc::mir::{self, Location, TerminatorKind}; use rustc::mir::visit::{Visitor, PlaceContext};


Question:
Context: In order to experiment with an -aware , I was preparing to modify the lang item signature, and my first step was to ensure MIR passes the right type to begin with, as noted in Legitimately, I assumed that the MIR inline code was doing the right thing, so I mimicked it in . The resulting code actually works fine, as far as completing the 3 stages of rustc bootstrapping is involved. But before going the route for the -aware , I first tried removing the special handling of 's , trying to leave it to , shortcutting the lang item. This didn't go well, and produced a stage 1 compiler that would crash on a bad in libsyntax's . From which I derived a small test case that would exhibit the problem with my code. Anyways, I was going well over my head with this approach, thus switched to the signature change. So, what's the deal with this issue, will you ask? Well, it turns out that my MIR changes, essentially copied from MIR inlining, while they worked to produce an apparently working compiler, failed to compile that reduced testcase with an LLVM ERROR. I was wondering if I did something significantly different from what the MIT inlining pass was doing, so I tried to trigger it manually (since it's not enabled by default), and after some trial and error, got it to happen on a plain nightly compiler, with the following reduced testcase: Building with yields: (Note the is only there to force MIR inlining to happen without having to go over the required threshold ; liballoc's has ; similarly, the on avoids inlining of dealloc, to limit the effects on the MIR) Interestingly enough, and fail with the same error. The former outputs a truncated MIR (truncated at the entry of the first basic block), and the latter outputs nothing.
This is what from a run with looks like: Edit: and what the llvm-ir, as disassembled from output, looks like:
The problem is that the code path bb1-bb9-bb21-bb20 in IR, corresponding to bb0-bb1-bb6-bb5 in MIR, is impossible, yet exists. And in that code path, in MIR, in IR, is never initialized, and that's what LLVM doesn't like. I guess one way to look at is it to wonder why in MIR has a switch in the first place.
And the answer to that last question is false edges, according to the following MIR from the mir_map pass:
Actually, the path bb0-bb7-bb4-bb10-bb12 has without ever being initialized, but that's pre-elaborate-drops, and I hear drop is different then, so I don't know if it bad or not.
The weird switch that eventually causes the LLVM problem is by the elaborate-drops pass. The MIR after that phase looks like the following:
I think the most relevant fact is this difference between MIR inlining being enabled or not: with MIR inlining disabled, this basic block in MIR: becomes the following IR: with MIR inlining enabled, this basic block in MIR: becomes whiich is weird... where did the extra code go?
The changes from fix this issue.

use type_of::LayoutLlvmExt; use super::FunctionCx; <del> pub fn memory_locals<'a, 'tcx>(fx: &FunctionCx<'a, 'tcx>) -> BitVector { </del> <ins> pub fn non_ssa_locals<'a, 'tcx>(fx: &FunctionCx<'a, 'tcx>) -> BitVector { </ins> let mir = fx.mir; let mut analyzer = LocalAnalyzer::new(fx);


Question:
Context: In order to experiment with an -aware , I was preparing to modify the lang item signature, and my first step was to ensure MIR passes the right type to begin with, as noted in Legitimately, I assumed that the MIR inline code was doing the right thing, so I mimicked it in . The resulting code actually works fine, as far as completing the 3 stages of rustc bootstrapping is involved. But before going the route for the -aware , I first tried removing the special handling of 's , trying to leave it to , shortcutting the lang item. This didn't go well, and produced a stage 1 compiler that would crash on a bad in libsyntax's . From which I derived a small test case that would exhibit the problem with my code. Anyways, I was going well over my head with this approach, thus switched to the signature change. So, what's the deal with this issue, will you ask? Well, it turns out that my MIR changes, essentially copied from MIR inlining, while they worked to produce an apparently working compiler, failed to compile that reduced testcase with an LLVM ERROR. I was wondering if I did something significantly different from what the MIT inlining pass was doing, so I tried to trigger it manually (since it's not enabled by default), and after some trial and error, got it to happen on a plain nightly compiler, with the following reduced testcase: Building with yields: (Note the is only there to force MIR inlining to happen without having to go over the required threshold ; liballoc's has ; similarly, the on avoids inlining of dealloc, to limit the effects on the MIR) Interestingly enough, and fail with the same error. The former outputs a truncated MIR (truncated at the entry of the first basic block), and the latter outputs nothing.
This is what from a run with looks like: Edit: and what the llvm-ir, as disassembled from output, looks like:
The problem is that the code path bb1-bb9-bb21-bb20 in IR, corresponding to bb0-bb1-bb6-bb5 in MIR, is impossible, yet exists. And in that code path, in MIR, in IR, is never initialized, and that's what LLVM doesn't like. I guess one way to look at is it to wonder why in MIR has a switch in the first place.
And the answer to that last question is false edges, according to the following MIR from the mir_map pass:
Actually, the path bb0-bb7-bb4-bb10-bb12 has without ever being initialized, but that's pre-elaborate-drops, and I hear drop is different then, so I don't know if it bad or not.
The weird switch that eventually causes the LLVM problem is by the elaborate-drops pass. The MIR after that phase looks like the following:
I think the most relevant fact is this difference between MIR inlining being enabled or not: with MIR inlining disabled, this basic block in MIR: becomes the following IR: with MIR inlining enabled, this basic block in MIR: becomes whiich is weird... where did the extra code go?
The changes from fix this issue.

// (e.g. structs) into an alloca unconditionally, just so // that we don't have to deal with having two pathways // (gep vs extractvalue etc). <del> analyzer.mark_as_memory(mir::Local::new(index)); </del> <ins> analyzer.not_ssa(mir::Local::new(index)); </ins> } } <del> analyzer.memory_locals </del> <ins> analyzer.non_ssa_locals </ins> } struct LocalAnalyzer<'mir, 'a: 'mir, 'tcx: 'a> { fx: &'mir FunctionCx<'a, 'tcx>, <del> memory_locals: BitVector, seen_assigned: BitVector </del> <ins> dominators: Dominators<mir::BasicBlock>, non_ssa_locals: BitVector, // The location of the first visited direct assignment to each // local, or an invalid location (out of bounds `block` index). first_assignment: IndexVec<mir::Local, Location> </ins> } impl<'mir, 'a, 'tcx> LocalAnalyzer<'mir, 'a, 'tcx> { fn new(fx: &'mir FunctionCx<'a, 'tcx>) -> LocalAnalyzer<'mir, 'a, 'tcx> { <ins> let invalid_location = mir::BasicBlock::new(fx.mir.basic_blocks().len()).start_location(); </ins> let mut analyzer = LocalAnalyzer { fx, <del> memory_locals: BitVector::new(fx.mir.local_decls.len()), seen_assigned: BitVector::new(fx.mir.local_decls.len()) </del> <ins> dominators: fx.mir.dominators(), non_ssa_locals: BitVector::new(fx.mir.local_decls.len()), first_assignment: IndexVec::from_elem(invalid_location, &fx.mir.local_decls) </ins> }; // Arguments get assigned to by means of the function being called <del> for idx in 0..fx.mir.arg_count { analyzer.seen_assigned.insert(idx + 1); </del> <ins> for arg in fx.mir.args_iter() { analyzer.first_assignment[arg] = mir::START_BLOCK.start_location(); </ins> } analyzer } <del> fn mark_as_memory(&mut self, local: mir::Local) { debug!("marking {:?} as memory", local); self.memory_locals.insert(local.index()); </del> <ins> fn first_assignment(&self, local: mir::Local) -> Option<Location> { let location = self.first_assignment[local]; if location.block.index() < self.fx.mir.basic_blocks().len() { Some(location) } else { None } </ins> } <del> fn mark_assigned(&mut self, local: mir::Local) { if !self.seen_assigned.insert(local.index()) { self.mark_as_memory(local); </del> <ins> fn not_ssa(&mut self, local: mir::Local) { debug!("marking {:?} as non-SSA", local); self.non_ssa_locals.insert(local.index()); } fn assign(&mut self, local: mir::Local, location: Location) { if self.first_assignment(local).is_some() { self.not_ssa(local); } else { self.first_assignment[local] = location; </ins> } } }


Question:
Context: In order to experiment with an -aware , I was preparing to modify the lang item signature, and my first step was to ensure MIR passes the right type to begin with, as noted in Legitimately, I assumed that the MIR inline code was doing the right thing, so I mimicked it in . The resulting code actually works fine, as far as completing the 3 stages of rustc bootstrapping is involved. But before going the route for the -aware , I first tried removing the special handling of 's , trying to leave it to , shortcutting the lang item. This didn't go well, and produced a stage 1 compiler that would crash on a bad in libsyntax's . From which I derived a small test case that would exhibit the problem with my code. Anyways, I was going well over my head with this approach, thus switched to the signature change. So, what's the deal with this issue, will you ask? Well, it turns out that my MIR changes, essentially copied from MIR inlining, while they worked to produce an apparently working compiler, failed to compile that reduced testcase with an LLVM ERROR. I was wondering if I did something significantly different from what the MIT inlining pass was doing, so I tried to trigger it manually (since it's not enabled by default), and after some trial and error, got it to happen on a plain nightly compiler, with the following reduced testcase: Building with yields: (Note the is only there to force MIR inlining to happen without having to go over the required threshold ; liballoc's has ; similarly, the on avoids inlining of dealloc, to limit the effects on the MIR) Interestingly enough, and fail with the same error. The former outputs a truncated MIR (truncated at the entry of the first basic block), and the latter outputs nothing.
This is what from a run with looks like: Edit: and what the llvm-ir, as disassembled from output, looks like:
The problem is that the code path bb1-bb9-bb21-bb20 in IR, corresponding to bb0-bb1-bb6-bb5 in MIR, is impossible, yet exists. And in that code path, in MIR, in IR, is never initialized, and that's what LLVM doesn't like. I guess one way to look at is it to wonder why in MIR has a switch in the first place.
And the answer to that last question is false edges, according to the following MIR from the mir_map pass:
Actually, the path bb0-bb7-bb4-bb10-bb12 has without ever being initialized, but that's pre-elaborate-drops, and I hear drop is different then, so I don't know if it bad or not.
The weird switch that eventually causes the LLVM problem is by the elaborate-drops pass. The MIR after that phase looks like the following:
I think the most relevant fact is this difference between MIR inlining being enabled or not: with MIR inlining disabled, this basic block in MIR: becomes the following IR: with MIR inlining enabled, this basic block in MIR: becomes whiich is weird... where did the extra code go?
The changes from fix this issue.

debug!("visit_assign(block={:?}, place={:?}, rvalue={:?})", block, place, rvalue); if let mir::Place::Local(index) = *place { <del> self.mark_assigned(index); </del> <ins> self.assign(index, location); </ins> if !self.fx.rvalue_creates_operand(rvalue) { <del> self.mark_as_memory(index); </del> <ins> self.not_ssa(index); </ins> } } else { self.visit_place(place, PlaceContext::Store, location);


Question:
Context: In order to experiment with an -aware , I was preparing to modify the lang item signature, and my first step was to ensure MIR passes the right type to begin with, as noted in Legitimately, I assumed that the MIR inline code was doing the right thing, so I mimicked it in . The resulting code actually works fine, as far as completing the 3 stages of rustc bootstrapping is involved. But before going the route for the -aware , I first tried removing the special handling of 's , trying to leave it to , shortcutting the lang item. This didn't go well, and produced a stage 1 compiler that would crash on a bad in libsyntax's . From which I derived a small test case that would exhibit the problem with my code. Anyways, I was going well over my head with this approach, thus switched to the signature change. So, what's the deal with this issue, will you ask? Well, it turns out that my MIR changes, essentially copied from MIR inlining, while they worked to produce an apparently working compiler, failed to compile that reduced testcase with an LLVM ERROR. I was wondering if I did something significantly different from what the MIT inlining pass was doing, so I tried to trigger it manually (since it's not enabled by default), and after some trial and error, got it to happen on a plain nightly compiler, with the following reduced testcase: Building with yields: (Note the is only there to force MIR inlining to happen without having to go over the required threshold ; liballoc's has ; similarly, the on avoids inlining of dealloc, to limit the effects on the MIR) Interestingly enough, and fail with the same error. The former outputs a truncated MIR (truncated at the entry of the first basic block), and the latter outputs nothing.
This is what from a run with looks like: Edit: and what the llvm-ir, as disassembled from output, looks like:
The problem is that the code path bb1-bb9-bb21-bb20 in IR, corresponding to bb0-bb1-bb6-bb5 in MIR, is impossible, yet exists. And in that code path, in MIR, in IR, is never initialized, and that's what LLVM doesn't like. I guess one way to look at is it to wonder why in MIR has a switch in the first place.
And the answer to that last question is false edges, according to the following MIR from the mir_map pass:
Actually, the path bb0-bb7-bb4-bb10-bb12 has without ever being initialized, but that's pre-elaborate-drops, and I hear drop is different then, so I don't know if it bad or not.
The weird switch that eventually causes the LLVM problem is by the elaborate-drops pass. The MIR after that phase looks like the following:
I think the most relevant fact is this difference between MIR inlining being enabled or not: with MIR inlining disabled, this basic block in MIR: becomes the following IR: with MIR inlining enabled, this basic block in MIR: becomes whiich is weird... where did the extra code go?
The changes from fix this issue.

if layout.is_llvm_immediate() || layout.is_llvm_scalar_pair() { // Recurse with the same context, instead of `Projection`, // potentially stopping at non-operand projections, <del> // which would trigger `mark_as_memory` on locals. </del> <ins> // which would trigger `not_ssa` on locals. </ins> self.visit_place(&proj.base, context, location); return; }


Question:
Context: In order to experiment with an -aware , I was preparing to modify the lang item signature, and my first step was to ensure MIR passes the right type to begin with, as noted in Legitimately, I assumed that the MIR inline code was doing the right thing, so I mimicked it in . The resulting code actually works fine, as far as completing the 3 stages of rustc bootstrapping is involved. But before going the route for the -aware , I first tried removing the special handling of 's , trying to leave it to , shortcutting the lang item. This didn't go well, and produced a stage 1 compiler that would crash on a bad in libsyntax's . From which I derived a small test case that would exhibit the problem with my code. Anyways, I was going well over my head with this approach, thus switched to the signature change. So, what's the deal with this issue, will you ask? Well, it turns out that my MIR changes, essentially copied from MIR inlining, while they worked to produce an apparently working compiler, failed to compile that reduced testcase with an LLVM ERROR. I was wondering if I did something significantly different from what the MIT inlining pass was doing, so I tried to trigger it manually (since it's not enabled by default), and after some trial and error, got it to happen on a plain nightly compiler, with the following reduced testcase: Building with yields: (Note the is only there to force MIR inlining to happen without having to go over the required threshold ; liballoc's has ; similarly, the on avoids inlining of dealloc, to limit the effects on the MIR) Interestingly enough, and fail with the same error. The former outputs a truncated MIR (truncated at the entry of the first basic block), and the latter outputs nothing.
This is what from a run with looks like: Edit: and what the llvm-ir, as disassembled from output, looks like:
The problem is that the code path bb1-bb9-bb21-bb20 in IR, corresponding to bb0-bb1-bb6-bb5 in MIR, is impossible, yet exists. And in that code path, in MIR, in IR, is never initialized, and that's what LLVM doesn't like. I guess one way to look at is it to wonder why in MIR has a switch in the first place.
And the answer to that last question is false edges, according to the following MIR from the mir_map pass:
Actually, the path bb0-bb7-bb4-bb10-bb12 has without ever being initialized, but that's pre-elaborate-drops, and I hear drop is different then, so I don't know if it bad or not.
The weird switch that eventually causes the LLVM problem is by the elaborate-drops pass. The MIR after that phase looks like the following:
I think the most relevant fact is this difference between MIR inlining being enabled or not: with MIR inlining disabled, this basic block in MIR: becomes the following IR: with MIR inlining enabled, this basic block in MIR: becomes whiich is weird... where did the extra code go?
The changes from fix this issue.

} fn visit_local(&mut self, <del> &index: &mir::Local, </del> <ins> &local: &mir::Local, </ins> context: PlaceContext<'tcx>, <del> _: Location) { </del> <ins> location: Location) { </ins> match context { PlaceContext::Call => { <del> self.mark_assigned(index); </del> <ins> self.assign(local, location); </ins> } PlaceContext::StorageLive | PlaceContext::StorageDead | <del> PlaceContext::Validate | </del> <ins> PlaceContext::Validate => {} </ins> PlaceContext::Copy | <del> PlaceContext::Move => {} </del> <ins> PlaceContext::Move => { // Reads from uninitialized variables (e.g. in dead code, after // optimizations) require locals to be in (uninitialized) memory. // NB: there can be uninitialized reads of a local visited after // an assignment to that local, if they happen on disjoint paths. let ssa_read = match self.first_assignment(local) { Some(assignment_location) => { assignment_location.dominates(location, &self.dominators) } None => false }; if !ssa_read { self.not_ssa(local); } } </ins> PlaceContext::Inspect | PlaceContext::Store | PlaceContext::AsmOutput | PlaceContext::Borrow { .. } | PlaceContext::Projection(..) => { <del> self.mark_as_memory(index); </del> <ins> self.not_ssa(local); </ins> } PlaceContext::Drop => { <del> let ty = mir::Place::Local(index).ty(self.fx.mir, self.fx.cx.tcx); </del> <ins> let ty = mir::Place::Local(local).ty(self.fx.mir, self.fx.cx.tcx); </ins> let ty = self.fx.monomorphize(&ty.to_ty(self.fx.cx.tcx)); // Only need the place if we're actually dropping it. if self.fx.cx.type_needs_drop(ty) { <del> self.mark_as_memory(index); </del> <ins> self.not_ssa(local); </ins> } } }


Question:
Context: In order to experiment with an -aware , I was preparing to modify the lang item signature, and my first step was to ensure MIR passes the right type to begin with, as noted in Legitimately, I assumed that the MIR inline code was doing the right thing, so I mimicked it in . The resulting code actually works fine, as far as completing the 3 stages of rustc bootstrapping is involved. But before going the route for the -aware , I first tried removing the special handling of 's , trying to leave it to , shortcutting the lang item. This didn't go well, and produced a stage 1 compiler that would crash on a bad in libsyntax's . From which I derived a small test case that would exhibit the problem with my code. Anyways, I was going well over my head with this approach, thus switched to the signature change. So, what's the deal with this issue, will you ask? Well, it turns out that my MIR changes, essentially copied from MIR inlining, while they worked to produce an apparently working compiler, failed to compile that reduced testcase with an LLVM ERROR. I was wondering if I did something significantly different from what the MIT inlining pass was doing, so I tried to trigger it manually (since it's not enabled by default), and after some trial and error, got it to happen on a plain nightly compiler, with the following reduced testcase: Building with yields: (Note the is only there to force MIR inlining to happen without having to go over the required threshold ; liballoc's has ; similarly, the on avoids inlining of dealloc, to limit the effects on the MIR) Interestingly enough, and fail with the same error. The former outputs a truncated MIR (truncated at the entry of the first basic block), and the latter outputs nothing.
This is what from a run with looks like: Edit: and what the llvm-ir, as disassembled from output, looks like:
The problem is that the code path bb1-bb9-bb21-bb20 in IR, corresponding to bb0-bb1-bb6-bb5 in MIR, is impossible, yet exists. And in that code path, in MIR, in IR, is never initialized, and that's what LLVM doesn't like. I guess one way to look at is it to wonder why in MIR has a switch in the first place.
And the answer to that last question is false edges, according to the following MIR from the mir_map pass:
Actually, the path bb0-bb7-bb4-bb10-bb12 has without ever being initialized, but that's pre-elaborate-drops, and I hear drop is different then, so I don't know if it bad or not.
The weird switch that eventually causes the LLVM problem is by the elaborate-drops pass. The MIR after that phase looks like the following:
I think the most relevant fact is this difference between MIR inlining being enabled or not: with MIR inlining disabled, this basic block in MIR: becomes the following IR: with MIR inlining enabled, this basic block in MIR: becomes whiich is weird... where did the extra code go?
The changes from fix this issue.

}, }; <del> let memory_locals = analyze::memory_locals(&fx); </del> <ins> let memory_locals = analyze::non_ssa_locals(&fx); </ins> // Allocate variable and temp allocas fx.locals = {


Question:
When I run the test suite on campus, I get a failure in : The test says "this IP is unroutable, so connections should always time out," but evidently there's something about the setup at this location that was not anticipated. The results are the same whether I am connected to WiFi or through ethernet. Both connections go through the same router (a Linksys WRT120N I have physical access to, which doesn't appear to save any sort of logs), and I don't know where it goes after that. I can work around it by disconnecting from the internet entirely, and do not have issues when running the tests at home (same laptop, different network).
is your subnet 10.255.255.0/24 or 10.255.0.0/16 or 10.0.0.0/8 or anything similar? You can check by running . Either way, the test is ill formed and should be correctled.
I'm not there right now, but just in case I forget to come back to this, I do recall that the router is accessed through an IP in the 192.168.x.x subnet. (I'm not sure if this precludes the situation you have described) (I wish GitHub notifications had a "mark unread" feature!)
It appears not to be. wifi ethernet:
I think I must have misread something when making that test - the IP is inside of an address block reserved for private networks which means it could be routable depending on how your network is set up. We could instead use an IP from one of the documentation blocks like 192.0.2.0.
The address 10.255.255.1 is routable on my vanilla Ubuntu 18.04 box: The address 192.0.2.0 is not routable: Therefore, this test always fails on this box. I will file a PR changing it to 192.0.2.0.
This is a dup of .

} #[test] <del> fn connect_timeout_unroutable() { // this IP is unroutable, so connections should always time out, // provided the network is reachable to begin with. let addr = "10.255.255.1:80".parse().unwrap(); let e = TcpStream::connect_timeout(&addr, Duration::from_millis(250)).unwrap_err(); assert!(e.kind() == io::ErrorKind::TimedOut || e.kind() == io::ErrorKind::Other, "bad error: {} {:?}", e, e.kind()); } #[test] </del> fn connect_timeout_unbound() { // bind and drop a socket to track down a "probably unassigned" port let socket = TcpListener::bind("127.0.0.1:0").unwrap();


Question:
I think this is the fourth beta I'm having to re-figure-out how all this works and figure out how to ignore their failures on beta. can we just exclude these tools from toolstate until this is figured out?
I'm slightly confused, why would these tools need to be disabled/their submodule update if they were building on master? Isn't the beta just the current master branch + some tweaks for --version output and no unstable features? The release in March actually prevented the merge of any PRs on master that would break a tool. So I thought the idea was to fix all tools in that week. Or is this about beta backports breaking tools?
I don't think we've had a beta yet whether either clippy or miri were passing tests and fails the build if any tool fails to build on beta. We also do not want to release either of these tools to stable/beta yet.
neither of these tools has a step, so there's no danger in that (the last beta) didn't have clippy issues. Since we have grace period of a week, I can easily get in a working clippy within that week (which then won't be broken until the beta). My issue is mainly that I don't really know when it begins ;) Maybe we can ping the tool authors once a day that their tool needs to be fixed for the upcoming beta?
My point with this issue is that we shouldn't automate ourselves into a hole where tools we do not want to ship block releases. That should not require authors to fix tools, we should simply ignore failures or have an easy way of disabling them. Right now producing a beta is pain as you have to resend it to bors multiple times after re-learning that these are blocking the release. We do not ship miri/clippy but a successful clippy compilation affects how rls is compiled, which should not be happening on beta/stable.
The code that influences rls is explicitly skipped on beta/stable, so the rls is completely free of clippy on beta/stable for miri I agree, but for clippy, aren't we trying to move to a model where we actually dist it on stable, so I'd call having it ready for stable some form of proof of concept for the distributing part.
Ok sure yes rls is protected but I feel like this is missing my point. Miri isn't ready. Clippy isn't ready. They're blocking beta releases. That shouldn't happen.

touch "$TOOLSTATE_FILE" <ins> # Try to test all the tools and store the build/test success in the TOOLSTATE_FILE </ins> set +e python2.7 "$X_PY" test --no-fail-fast  src/doc/book


Question:
I think this is the fourth beta I'm having to re-figure-out how all this works and figure out how to ignore their failures on beta. can we just exclude these tools from toolstate until this is figured out?
I'm slightly confused, why would these tools need to be disabled/their submodule update if they were building on master? Isn't the beta just the current master branch + some tweaks for --version output and no unstable features? The release in March actually prevented the merge of any PRs on master that would break a tool. So I thought the idea was to fix all tools in that week. Or is this about beta backports breaking tools?
I don't think we've had a beta yet whether either clippy or miri were passing tests and fails the build if any tool fails to build on beta. We also do not want to release either of these tools to stable/beta yet.
neither of these tools has a step, so there's no danger in that (the last beta) didn't have clippy issues. Since we have grace period of a week, I can easily get in a working clippy within that week (which then won't be broken until the beta). My issue is mainly that I don't really know when it begins ;) Maybe we can ping the tool authors once a day that their tool needs to be fixed for the upcoming beta?
My point with this issue is that we shouldn't automate ourselves into a hole where tools we do not want to ship block releases. That should not require authors to fix tools, we should simply ignore failures or have an easy way of disabling them. Right now producing a beta is pain as you have to resend it to bors multiple times after re-learning that these are blocking the release. We do not ship miri/clippy but a successful clippy compilation affects how rls is compiled, which should not be happening on beta/stable.
The code that influences rls is explicitly skipped on beta/stable, so the rls is completely free of clippy on beta/stable for miri I agree, but for clippy, aren't we trying to move to a model where we actually dist it on stable, so I'd call having it ready for stable some form of proof of concept for the distributing part.
Ok sure yes rls is protected but I feel like this is missing my point. Miri isn't ready. Clippy isn't ready. They're blocking beta releases. That shouldn't happen.

cat "$TOOLSTATE_FILE" echo <ins> # This function checks that if a tool's submodule changed, the tool's state must improve </ins> verify_status() { echo "Verifying status of $1..." if echo "$CHANGED_FILES" | grep -q "^M[[:blank:]]$2$"; then


Question:
I think this is the fourth beta I'm having to re-figure-out how all this works and figure out how to ignore their failures on beta. can we just exclude these tools from toolstate until this is figured out?
I'm slightly confused, why would these tools need to be disabled/their submodule update if they were building on master? Isn't the beta just the current master branch + some tweaks for --version output and no unstable features? The release in March actually prevented the merge of any PRs on master that would break a tool. So I thought the idea was to fix all tools in that week. Or is this about beta backports breaking tools?
I don't think we've had a beta yet whether either clippy or miri were passing tests and fails the build if any tool fails to build on beta. We also do not want to release either of these tools to stable/beta yet.
neither of these tools has a step, so there's no danger in that (the last beta) didn't have clippy issues. Since we have grace period of a week, I can easily get in a working clippy within that week (which then won't be broken until the beta). My issue is mainly that I don't really know when it begins ;) Maybe we can ping the tool authors once a day that their tool needs to be fixed for the upcoming beta?
My point with this issue is that we shouldn't automate ourselves into a hole where tools we do not want to ship block releases. That should not require authors to fix tools, we should simply ignore failures or have an easy way of disabling them. Right now producing a beta is pain as you have to resend it to bors multiple times after re-learning that these are blocking the release. We do not ship miri/clippy but a successful clippy compilation affects how rls is compiled, which should not be happening on beta/stable.
The code that influences rls is explicitly skipped on beta/stable, so the rls is completely free of clippy on beta/stable for miri I agree, but for clippy, aren't we trying to move to a model where we actually dist it on stable, so I'd call having it ready for stable some form of proof of concept for the distributing part.
Ok sure yes rls is protected but I feel like this is missing my point. Miri isn't ready. Clippy isn't ready. They're blocking beta releases. That shouldn't happen.

fi } <ins> # deduplicates the submodule check and the assertion that on beta some tools MUST be passing check_dispatch() { if [ "$1" = submodule_changed ]; then # ignore $2 (branch id) verify_status $3 $4 elif [ "$2" = beta ]; then echo "Requiring test passing for $3..." if grep -q '"'"$3"'":"(test|build)-fail"' "$TOOLSTATE_FILE"; then exit 4 fi fi } # list all tools here status_check() { check_dispatch $1 beta book src/doc/book check_dispatch $1 beta nomicon src/doc/nomicon check_dispatch $1 beta reference src/doc/reference check_dispatch $1 beta rust-by-example src/doc/rust-by-example check_dispatch $1 beta rls src/tool/rls check_dispatch $1 beta rustfmt src/tool/rustfmt # these tools are not required for beta to successfully branch check_dispatch $1 nightly clippy-driver src/tool/clippy check_dispatch $1 nightly miri src/tool/miri } </ins> # If this PR is intended to update one of these tools, do not let the build pass # when they do not test-pass. <del> verify_status book src/doc/book verify_status nomicon src/doc/nomicon verify_status reference src/doc/reference verify_status rust-by-example src/doc/rust-by-example verify_status rls src/tool/rls verify_status rustfmt src/tool/rustfmt verify_status clippy-driver src/tool/clippy verify_status miri src/tool/miri </del> <ins> status_check "submodule_changed" </ins> if [ "$RUST_RELEASE_CHANNEL" = nightly -a -n "${TOOLSTATE_REPO_ACCESS_TOKEN+is_set}" ]; then . "$(dirname $0)/repo.sh"


Question:
I think this is the fourth beta I'm having to re-figure-out how all this works and figure out how to ignore their failures on beta. can we just exclude these tools from toolstate until this is figured out?
I'm slightly confused, why would these tools need to be disabled/their submodule update if they were building on master? Isn't the beta just the current master branch + some tweaks for --version output and no unstable features? The release in March actually prevented the merge of any PRs on master that would break a tool. So I thought the idea was to fix all tools in that week. Or is this about beta backports breaking tools?
I don't think we've had a beta yet whether either clippy or miri were passing tests and fails the build if any tool fails to build on beta. We also do not want to release either of these tools to stable/beta yet.
neither of these tools has a step, so there's no danger in that (the last beta) didn't have clippy issues. Since we have grace period of a week, I can easily get in a working clippy within that week (which then won't be broken until the beta). My issue is mainly that I don't really know when it begins ;) Maybe we can ping the tool authors once a day that their tool needs to be fixed for the upcoming beta?
My point with this issue is that we shouldn't automate ourselves into a hole where tools we do not want to ship block releases. That should not require authors to fix tools, we should simply ignore failures or have an easy way of disabling them. Right now producing a beta is pain as you have to resend it to bors multiple times after re-learning that these are blocking the release. We do not ship miri/clippy but a successful clippy compilation affects how rls is compiled, which should not be happening on beta/stable.
The code that influences rls is explicitly skipped on beta/stable, so the rls is completely free of clippy on beta/stable for miri I agree, but for clippy, aren't we trying to move to a model where we actually dist it on stable, so I'd call having it ready for stable some form of proof of concept for the distributing part.
Ok sure yes rls is protected but I feel like this is missing my point. Miri isn't ready. Clippy isn't ready. They're blocking beta releases. That shouldn't happen.

exit 0 fi <del> if grep -q fail "$TOOLSTATE_FILE"; then exit 4 fi </del> <ins> # abort compilation if an important tool doesn't build # (this code is reachable if not on the nightly channel) status_check "beta_required" </ins>


Question:
When testing a local rebuild in Fedora -- using rustc 1.26.0 as stage0 to build rustc 1.26.0 again -- I ran into this ICE: The "slice index starts at 1 but ends at 0" comes from here: With GDB I found that is completely empty! Stepping through from the very beginning, does get the right argc and argv, calling appropriately. But the addresses of and are not where accesses later from , so that just sees and . It turns out that the bootstrap was causing my to load the freshly-built libraries, rather than its own in . The bootstrap wrapper does try to set a libdir at the front of that path, but it uses , here , so that doesn't help. This only hits local-rebuild, because normal prior-release stage0 builds have different library metadata.
Is this fixed? cc
Sorry, yes, fixed by .

// FIXME: Temporary fix for https://github.com/rust-lang/cargo/issues/3005 // Force cargo to output binaries with disambiguating hashes in the name <del> cargo.env("__CARGO_DEFAULT_LIB_METADATA", &self.config.channel); </del> <ins> let metadata = if compiler.stage == 0 { // Treat stage0 like special channel, whether it's a normal prior- // release rustc or a local rebuild with the same version, so we // never mix these libraries by accident. "bootstrap" } else { &self.config.channel }; cargo.env("__CARGO_DEFAULT_LIB_METADATA", &metadata); </ins> let stage; if compiler.stage == 0 && self.local_rebuild {


Question:
For type names only, submodules can't apparently see non-pub types defined in the parent module. So, this code: ... generates this error:
Now it at least tells you that is private: Though, it doesn't need to display the error twice and could do better than .
linking to for unified tracking of resolve
Closing as a dupe of , this would be allowed with the rules in that bug.

<del> Subproject commit 8b7f7e667268921c278af94ae30a61e87a22b22b </del> <ins> Subproject commit 329923edec41d0ddbea7f30ab12fca0436d459ae </ins>


Question:
This issue might be related to , which has been fixed in playground link: Backtrace:
removing the argument inside the closure gives a different ICE. Interestingly stable refuses to compile this, but beta and nightly ICE's playground: Backtrace:
UPDATE: now also ICE's in stable.
Now no longer ICE's since 1.32.
The ICE doesn't appear on the latest nightly via the above playground link, marked as E-needstest

<ins> #![feature(const_raw_ptr_to_usize_cast)] fn main() { [(); &(static |x| {}) as *const _ as usize]; //~^ ERROR: closures cannot be static //~| ERROR: type annotations needed [(); &(static || {}) as *const _ as usize]; //~^ ERROR: closures cannot be static //~| ERROR: evaluation of constant value failed } </ins>


Question:
This issue might be related to , which has been fixed in playground link: Backtrace:
removing the argument inside the closure gives a different ICE. Interestingly stable refuses to compile this, but beta and nightly ICE's playground: Backtrace:
UPDATE: now also ICE's in stable.
Now no longer ICE's since 1.32.
The ICE doesn't appear on the latest nightly via the above playground link, marked as E-needstest

<ins> error[E0697]: closures cannot be static --> $DIR/issue-52432.rs:4:12 | LL |     [(); &(static |x| {}) as *const _ as usize]; |            ^^^^^^^^^^ error[E0697]: closures cannot be static --> $DIR/issue-52432.rs:7:12 | LL |     [(); &(static || {}) as *const _ as usize]; |            ^^^^^^^^^ error[E0282]: type annotations needed --> $DIR/issue-52432.rs:4:20 | LL |     [(); &(static |x| {}) as *const _ as usize]; |                    ^ consider giving this closure parameter a type error[E0080]: evaluation of constant value failed --> $DIR/issue-52432.rs:7:10 | LL |     [(); &(static || {}) as *const _ as usize]; |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ "pointer-to-integer cast" needs an rfc before being allowed inside constants error: aborting due to 4 previous errors Some errors have detailed explanations: E0080, E0282, E0697. For more information about an error, try `rustc --explain E0080`. </ins>


Question:
This issue might be related to , which has been fixed in playground link: Backtrace:
removing the argument inside the closure gives a different ICE. Interestingly stable refuses to compile this, but beta and nightly ICE's playground: Backtrace:
UPDATE: now also ICE's in stable.
Now no longer ICE's since 1.32.
The ICE doesn't appear on the latest nightly via the above playground link, marked as E-needstest

<ins> // check-pass #![allow(dead_code)] trait Structure<E>: Sized where E: Encoding { type RefTarget: ?Sized; type FfiPtr; unsafe fn borrow_from_ffi_ptr<'a>(ptr: Self::FfiPtr) -> Option<&'a Self::RefTarget>; } enum Slice {} impl<E> Structure<E> for Slice where E: Encoding { type RefTarget = [E::Unit]; type FfiPtr = (*const E::FfiUnit, usize); unsafe fn borrow_from_ffi_ptr<'a>(_ptr: Self::FfiPtr) -> Option<&'a Self::RefTarget> { panic!() } } trait Encoding { type Unit: Unit; type FfiUnit; } trait Unit {} enum Utf16 {} impl Encoding for Utf16 { type Unit = Utf16Unit; type FfiUnit = u16; } struct Utf16Unit(pub u16); impl Unit for Utf16Unit {} type SUtf16Str = SeStr<Slice, Utf16>; struct SeStr<S, E> where S: Structure<E>, E: Encoding { _data: S::RefTarget, } impl<S, E> SeStr<S, E> where S: Structure<E>, E: Encoding { pub unsafe fn from_ptr<'a>(_ptr: S::FfiPtr) -> Option<&'a Self> { panic!() } } fn main() { const TEXT_U16: &'static [u16] = &[]; let _ = unsafe { SUtf16Str::from_ptr((TEXT_U16.as_ptr(), TEXT_U16.len())).unwrap() }; } </ins>


Question:
This issue might be related to , which has been fixed in playground link: Backtrace:
removing the argument inside the closure gives a different ICE. Interestingly stable refuses to compile this, but beta and nightly ICE's playground: Backtrace:
UPDATE: now also ICE's in stable.
Now no longer ICE's since 1.32.
The ICE doesn't appear on the latest nightly via the above playground link, marked as E-needstest

<ins> // check-pass #![allow(dead_code)] trait Structure<E>: Sized where E: Encoding { type RefTarget: ?Sized; type FfiPtr; unsafe fn borrow_from_ffi_ptr<'a>(ptr: Self::FfiPtr) -> Option<&'a Self::RefTarget>; } enum Slice {} impl<E> Structure<E> for Slice where E: Encoding { type RefTarget = [E::Unit]; type FfiPtr = (*const E::FfiUnit, usize); unsafe fn borrow_from_ffi_ptr<'a>(_ptr: Self::FfiPtr) -> Option<&'a Self::RefTarget> { panic!() } } trait Encoding { type Unit: Unit; type FfiUnit; } trait Unit {} enum Utf16 {} impl Encoding for Utf16 { type Unit = Utf16Unit; type FfiUnit = u16; } struct Utf16Unit(pub u16); impl Unit for Utf16Unit {} struct SUtf16Str { _data: <Slice as Structure<Utf16>>::RefTarget, } impl SUtf16Str { pub unsafe fn from_ptr<'a>(ptr: <Slice as Structure<Utf16>>::FfiPtr) -> Option<&'a Self> { std::mem::transmute::<Option<&[<Utf16 as Encoding>::Unit]>, _>( <Slice as Structure<Utf16>>::borrow_from_ffi_ptr(ptr)) } } fn main() { const TEXT_U16: &'static [u16] = &[]; let _ = unsafe { SUtf16Str::from_ptr((TEXT_U16.as_ptr(), TEXT_U16.len())).unwrap() }; } </ins>


Question:
This issue might be related to , which has been fixed in playground link: Backtrace:
removing the argument inside the closure gives a different ICE. Interestingly stable refuses to compile this, but beta and nightly ICE's playground: Backtrace:
UPDATE: now also ICE's in stable.
Now no longer ICE's since 1.32.
The ICE doesn't appear on the latest nightly via the above playground link, marked as E-needstest

<ins> #![feature(type_alias_impl_trait)] type Closure = impl FnOnce(); //~ ERROR: type mismatch resolving fn c() -> Closure { || -> Closure { || () } } fn main() {} </ins>


Question:
This issue might be related to , which has been fixed in playground link: Backtrace:
removing the argument inside the closure gives a different ICE. Interestingly stable refuses to compile this, but beta and nightly ICE's playground: Backtrace:
UPDATE: now also ICE's in stable.
Now no longer ICE's since 1.32.
The ICE doesn't appear on the latest nightly via the above playground link, marked as E-needstest

<ins> error[E0271]: type mismatch resolving `<[closure@$DIR/issue-63279.rs:6:5: 6:28] as std::ops::FnOnce<()>>::Output == ()` --> $DIR/issue-63279.rs:3:1 | LL | type Closure = impl FnOnce(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected opaque type, found () | = note: expected type `Closure` found type `()` = note: the return type of a function must have a statically known size error: aborting due to previous error For more information about this error, try `rustc --explain E0271`. </ins>


Question:
This issue might be related to , which has been fixed in playground link: Backtrace:
removing the argument inside the closure gives a different ICE. Interestingly stable refuses to compile this, but beta and nightly ICE's playground: Backtrace:
UPDATE: now also ICE's in stable.
Now no longer ICE's since 1.32.
The ICE doesn't appear on the latest nightly via the above playground link, marked as E-needstest

<ins> #![feature(fn_traits, unboxed_closures)] fn test<F: for<'x> FnOnce<(&'x str,)>>(_: F) {} struct Compose<F,G>(F,G); impl<T,F,G> FnOnce<(T,)> for Compose<F,G> where F: FnOnce<(T,)>, G: FnOnce<(F::Output,)> { type Output = G::Output; extern "rust-call" fn call_once(self, (x,): (T,)) -> G::Output { (self.1)((self.0)(x)) } } struct Str<'a>(&'a str); fn mk_str<'a>(s: &'a str) -> Str<'a> { Str(s) } fn main() { let _: for<'a> fn(&'a str) -> Str<'a> = mk_str; // expected concrete lifetime, found bound lifetime parameter 'a let _: for<'a> fn(&'a str) -> Str<'a> = Str; //~^ ERROR: mismatched types test(|_: &str| {}); test(mk_str); // expected concrete lifetime, found bound lifetime parameter 'x test(Str); //~ ERROR: type mismatch in function arguments test(Compose(|_: &str| {}, |_| {})); test(Compose(mk_str, |_| {})); // internal compiler error: cannot relate bound region: //   ReLateBound(DebruijnIndex { depth: 2 }, //     BrNamed(DefId { krate: 0, node: DefIndex(6) => test::'x }, 'x(65))) //<= ReSkolemized(0, //     BrNamed(DefId { krate: 0, node: DefIndex(6) => test::'x }, 'x(65))) test(Compose(Str, |_| {})); } </ins>


Question:
This issue might be related to , which has been fixed in playground link: Backtrace:
removing the argument inside the closure gives a different ICE. Interestingly stable refuses to compile this, but beta and nightly ICE's playground: Backtrace:
UPDATE: now also ICE's in stable.
Now no longer ICE's since 1.32.
The ICE doesn't appear on the latest nightly via the above playground link, marked as E-needstest

<ins> error[E0308]: mismatched types --> $DIR/issue-30904.rs:20:45 | LL |     let _: for<'a> fn(&'a str) -> Str<'a> = Str; |                                             ^^^ expected concrete lifetime, found bound lifetime parameter 'a | = note: expected type `for<'a> fn(&'a str) -> Str<'a>` found type `fn(&str) -> Str<'_> {Str::<'_>}` error[E0631]: type mismatch in function arguments --> $DIR/issue-30904.rs:26:10 | LL | fn test<F: for<'x> FnOnce<(&'x str,)>>(_: F) {} |    ----    -------------------------- required by this bound in `test` ... LL | struct Str<'a>(&'a str); | ------------------------ found signature of `fn(&str) -> _` ... LL |     test(Str); |          ^^^ expected signature of `for<'x> fn(&'x str) -> _` error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0308`. </ins>


Question:
I've some code reading a stream from stdin. Wanted to wrap it in a Cursor to have it keep track of the number of bytes read already instead of having to do it manually, but started getting odd compiler errors. Since works just fine with (and ) shouldn't it work just the same with ? () Errors:
A Cursor is meant as a wrapper to Vec<u8or &mut [u8] to be able to write to them. The compiler error says that StdinLock cant be converted to a slice.
That's not how I understood it from the documentation. to me that suggests the main purpose is to provide Seek implementation. If it's only meant to wrap Vec or [u8] I think it would avoid misunderstandings to say so out right. Again suggesting Cursor is fairly generic about underlying I/O object. (FWIW if asked to name some I/O objects, I'd be pressed to consider Vec and [u8] as such.) ... The compiler error is confusing as at no point is there any (obvious) attempt to convert StdinLock into a slice. It's only ever used through the Read trait. Though looking more closely I now see the fine print later on () so I guess one could argue this is just a minor documentation issue (+ user error.) I'd still argue the behavior is surprising. StdinLock implements Read, so does Cursor, there's no obvious reason why Cursor<StdinLockwouldn't. I can sort of understand why it's currently that way, and can imagine some problems there may be generalizing it, but can't quite see any fundamental reasons for Cursor to be restricted to only Vec and [u8] and the documentation is vague enough to make that seem like a bug / unintended omission rather than intentional design / limitation.
It is a docs bug. The entire purpose of Cursor is to take a buffer of bytes and turn that into a reader by adding a cursor indicating the current position in the buffer.
Made a PR to suggest some documentation changes to better describe the intention. I do wonder though if the guard should also be included for , it could capture the problem more accurately where it's happening?
There probably should have been an bound on , but we can't add it now.

use cmp; use io::{self, Initializer, SeekFrom, Error, ErrorKind}; <del> /// A `Cursor` wraps another type and provides it with a </del> <ins> /// A `Cursor` wraps an in-memory buffer and provides it with a </ins> /// [`Seek`] implementation. /// <del> /// `Cursor`s are typically used with in-memory buffers to allow them to /// implement [`Read`] and/or [`Write`], allowing these buffers to be used /// anywhere you might use a reader or writer that does actual I/O. </del> <ins> /// `Cursor`s are used with in-memory buffers, anything implementing /// `AsRef<[u8]>`, to allow them to implement [`Read`] and/or [`Write`], /// allowing these buffers to be used anywhere you might use a reader or writer /// that does actual I/O. </ins> /// /// The standard library implements some I/O traits on various types which /// are commonly used as a buffer, like `Cursor<`[`Vec`]`<u8>>` and


Question:
I've some code reading a stream from stdin. Wanted to wrap it in a Cursor to have it keep track of the number of bytes read already instead of having to do it manually, but started getting odd compiler errors. Since works just fine with (and ) shouldn't it work just the same with ? () Errors:
A Cursor is meant as a wrapper to Vec<u8or &mut [u8] to be able to write to them. The compiler error says that StdinLock cant be converted to a slice.
That's not how I understood it from the documentation. to me that suggests the main purpose is to provide Seek implementation. If it's only meant to wrap Vec or [u8] I think it would avoid misunderstandings to say so out right. Again suggesting Cursor is fairly generic about underlying I/O object. (FWIW if asked to name some I/O objects, I'd be pressed to consider Vec and [u8] as such.) ... The compiler error is confusing as at no point is there any (obvious) attempt to convert StdinLock into a slice. It's only ever used through the Read trait. Though looking more closely I now see the fine print later on () so I guess one could argue this is just a minor documentation issue (+ user error.) I'd still argue the behavior is surprising. StdinLock implements Read, so does Cursor, there's no obvious reason why Cursor<StdinLockwouldn't. I can sort of understand why it's currently that way, and can imagine some problems there may be generalizing it, but can't quite see any fundamental reasons for Cursor to be restricted to only Vec and [u8] and the documentation is vague enough to make that seem like a bug / unintended omission rather than intentional design / limitation.
It is a docs bug. The entire purpose of Cursor is to take a buffer of bytes and turn that into a reader by adding a cursor indicating the current position in the buffer.
Made a PR to suggest some documentation changes to better describe the intention. I do wonder though if the guard should also be included for , it could capture the problem more accurately where it's happening?
There probably should have been an bound on , but we can't add it now.

} impl<T> Cursor<T> { <del> /// Creates a new cursor wrapping the provided underlying I/O object. </del> <ins> /// Creates a new cursor wrapping the provided underlying in-memory buffer. </ins> /// <del> /// Cursor initial position is `0` even if underlying object (e. /// g. `Vec`) is not empty. So writing to cursor starts with /// overwriting `Vec` content, not with appending to it. </del> <ins> /// Cursor initial position is `0` even if underlying buffer (e.g. `Vec`) /// is not empty. So writing to cursor starts with overwriting `Vec` /// content, not with appending to it. </ins> /// /// # Examples ///


Question:
Reproduced on versions: - Isolated example to reproduce: Actual error: Mentioned suggestion about "wrap into " is incorrect at all. There we should deref the value from the . - - Expected error: (something like this)
Here's where the suggestion gets issued: The motivation was to solve (where a -expression appears in tail position, which seemed likely to be a common mistake), but it turns out that there are other situations where we run into a type mismatch between match arms of a desugared expression. We regret the error.
Here's another case of this:
I see what's happening, we're only checking wether the error came from a desugaring, disregarding the types involved. It should be possible to check that information as well, even if the suggestion is only provided when it's a where everything but the error type matches. (I think it's ok if the supplied error cannot be converted to the expected error, as this suggestion exposes newcomers to a non-obvious construct at least.)
Clippy to detect this that we might want to uplift ...
(But for now I'm just going to remove the suggestion.)

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:
Reproduced on versions: - Isolated example to reproduce: Actual error: Mentioned suggestion about "wrap into " is incorrect at all. There we should deref the value from the . - - Expected error: (something like this)
Here's where the suggestion gets issued: The motivation was to solve (where a -expression appears in tail position, which seemed likely to be a common mistake), but it turns out that there are other situations where we run into a type mismatch between match arms of a desugared expression. We regret the error.
Here's another case of this:
I see what's happening, we're only checking wether the error came from a desugaring, disregarding the types involved. It should be possible to check that information as well, even if the suggestion is only provided when it's a where everything but the error type matches. (I think it's ok if the supplied error cannot be converted to the expected error, as this suggestion exposes newcomers to a non-obvious construct at least.)
Clippy to detect this that we might want to uplift ...
(But for now I'm just going to remove the suggestion.)

<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:
Reproduced on versions: - Isolated example to reproduce: Actual error: Mentioned suggestion about "wrap into " is incorrect at all. There we should deref the value from the . - - Expected error: (something like this)
Here's where the suggestion gets issued: The motivation was to solve (where a -expression appears in tail position, which seemed likely to be a common mistake), but it turns out that there are other situations where we run into a type mismatch between match arms of a desugared expression. We regret the error.
Here's another case of this:
I see what's happening, we're only checking wether the error came from a desugaring, disregarding the types involved. It should be possible to check that information as well, even if the suggestion is only provided when it's a where everything but the error type matches. (I think it's ok if the supplied error cannot be converted to the expected error, as this suggestion exposes newcomers to a non-obvious construct at least.)
Clippy to detect this that we might want to uplift ...
(But for now I'm just going to remove the suggestion.)

// 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:
Reproduced on versions: - Isolated example to reproduce: Actual error: Mentioned suggestion about "wrap into " is incorrect at all. There we should deref the value from the . - - Expected error: (something like this)
Here's where the suggestion gets issued: The motivation was to solve (where a -expression appears in tail position, which seemed likely to be a common mistake), but it turns out that there are other situations where we run into a type mismatch between match arms of a desugared expression. We regret the error.
Here's another case of this:
I see what's happening, we're only checking wether the error came from a desugaring, disregarding the types involved. It should be possible to check that information as well, even if the suggestion is only provided when it's a where everything but the error type matches. (I think it's ok if the supplied error cannot be converted to the expected error, as this suggestion exposes newcomers to a non-obvious construct at least.)
Clippy to detect this that we might want to uplift ...
(But for now I'm just going to remove the suggestion.)

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:
Reproduced on versions: - Isolated example to reproduce: Actual error: Mentioned suggestion about "wrap into " is incorrect at all. There we should deref the value from the . - - Expected error: (something like this)
Here's where the suggestion gets issued: The motivation was to solve (where a -expression appears in tail position, which seemed likely to be a common mistake), but it turns out that there are other situations where we run into a type mismatch between match arms of a desugared expression. We regret the error.
Here's another case of this:
I see what's happening, we're only checking wether the error came from a desugaring, disregarding the types involved. It should be possible to check that information as well, even if the suggestion is only provided when it's a where everything but the error type matches. (I think it's ok if the supplied error cannot be converted to the expected error, as this suggestion exposes newcomers to a non-obvious construct at least.)
Clippy to detect this that we might want to uplift ...
(But for now I'm just going to remove the suggestion.)

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:
What I actually wanted was . <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
The problem is by the time this error is emittedwe don't have the information about the root cause anymore. In this case that would be the type of being checked for and figuring out the the rhs needs to be of the same type. Clippy has a lint that will tell you to clean it up afterwards, but we should probably issue a better diagnostic to begin with.
can you please create a ?
Please excuse my naïvety, but why is this (according to csmoes MCVE) a problem? You can actually write if i < &0 {} and everything works just fine. Can you please explain this part (to me)?
The comparison operator already takes references to both sides. so it seems simpler to dereference the lhs and save the monomorphizer and the optimizer some effort
Resurrecting this. what're the benefits of dereferencing the lhs instead of referencing the rhs? Also, if I were to go about fixing this, where would I start?
The benefit is that expands to , so if you start out with you get , seems better to just do instead (since is a no-op that gets easily removed). I'm not sure how to solve this or whether we should try at all.
claim
I want to get started with this, but would appreciate some mentoring from someone before I do, to point me in the right direction please
There's a reason I marked this as . I have no idea how to do this reasonably. I'm sorry, but I have no hints for you, and I don't even know if it's possible to do in a reasonable way.
cue terminator background music Leaving this here for future generations to see. I'm gonna try attempting to solve this and see if I can do something about it. I don't know if I can, or if I'll even survive this, but there's only one way to find out. Lol in all seriousness, if someone wants to claim this up, feel free to. Until then, I'll try and fix this.
Hi, are you still working on this issue
Hey I've been meaning to fix this up. I've reached a point where I know exactly how to fix this as well. I just haven't found the time to fix this. Feel free to take it up, considering I wouldn't be having the time to work on this in the forseeable future.
release-assignment If do you find the time in the future, please claim this issue again. Until then I'll free it up in case anybody else wants it
Is anyone currently working on this? If not, I'd be happy to give it a go. claim

)); } <del> let needs_parens = match expr.kind { // parenthesize if needed (Issue #46756) hir::ExprKind::Cast(_, _) | hir::ExprKind::Binary(_, _, _) => true, // parenthesize borrows of range literals (Issue #54505) _ if is_range_literal(expr) => true, _ => false, }; </del> if let Some((sugg, msg)) = self.can_use_as_ref(expr) { return Some(( sugg,


Question:
What I actually wanted was . <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
The problem is by the time this error is emittedwe don't have the information about the root cause anymore. In this case that would be the type of being checked for and figuring out the the rhs needs to be of the same type. Clippy has a lint that will tell you to clean it up afterwards, but we should probably issue a better diagnostic to begin with.
can you please create a ?
Please excuse my naïvety, but why is this (according to csmoes MCVE) a problem? You can actually write if i < &0 {} and everything works just fine. Can you please explain this part (to me)?
The comparison operator already takes references to both sides. so it seems simpler to dereference the lhs and save the monomorphizer and the optimizer some effort
Resurrecting this. what're the benefits of dereferencing the lhs instead of referencing the rhs? Also, if I were to go about fixing this, where would I start?
The benefit is that expands to , so if you start out with you get , seems better to just do instead (since is a no-op that gets easily removed). I'm not sure how to solve this or whether we should try at all.
claim
I want to get started with this, but would appreciate some mentoring from someone before I do, to point me in the right direction please
There's a reason I marked this as . I have no idea how to do this reasonably. I'm sorry, but I have no hints for you, and I don't even know if it's possible to do in a reasonable way.
cue terminator background music Leaving this here for future generations to see. I'm gonna try attempting to solve this and see if I can do something about it. I don't know if I can, or if I'll even survive this, but there's only one way to find out. Lol in all seriousness, if someone wants to claim this up, feel free to. Until then, I'll try and fix this.
Hi, are you still working on this issue
Hey I've been meaning to fix this up. I've reached a point where I know exactly how to fix this as well. I just haven't found the time to fix this. Feel free to take it up, considering I wouldn't be having the time to work on this in the forseeable future.
release-assignment If do you find the time in the future, please claim this issue again. Until then I'll free it up in case anybody else wants it
Is anyone currently working on this? If not, I'd be happy to give it a go. claim

} } <del> let sugg = mutability.ref_prefix_str(); let (sugg, verbose) = if needs_parens { ( vec![ (sp.shrink_to_lo(), format!("{prefix}{sugg}(")), (sp.shrink_to_hi(), ")".to_string()), ], false, ) } else { (vec![(sp.shrink_to_lo(), format!("{prefix}{sugg}"))], true) </del> <ins> let make_sugg = |expr: &Expr<'_>, span: Span, sugg: &str| { let needs_parens = match expr.kind { // parenthesize if needed (Issue #46756) hir::ExprKind::Cast(_, _) | hir::ExprKind::Binary(_, _, _) => true, // parenthesize borrows of range literals (Issue #54505) _ if is_range_literal(expr) => true, _ => false, }; if needs_parens { ( vec![ (span.shrink_to_lo(), format!("{prefix}{sugg}(")), (span.shrink_to_hi(), ")".to_string()), ], false, ) } else { (vec![(span.shrink_to_lo(), format!("{prefix}{sugg}"))], true) } </ins> }; <ins> // Suggest dereferencing the lhs for expressions such as `&T == T` if let Some(hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Binary(_, lhs, ..), .. })) = self.tcx.hir().find_parent(expr.hir_id) && let &ty::Ref(..) = self.check_expr(lhs).kind() { let (sugg, verbose) = make_sugg(lhs, lhs.span, "*"); return Some(( sugg, "consider dereferencing the borrow".to_string(), Applicability::MachineApplicable, verbose, false, )); } let sugg = mutability.ref_prefix_str(); let (sugg, verbose) = make_sugg(expr, sp, sugg); </ins> return Some(( sugg, format!("consider {}borrowing here", mutability.mutably_str()),


Question:
What I actually wanted was . <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
The problem is by the time this error is emittedwe don't have the information about the root cause anymore. In this case that would be the type of being checked for and figuring out the the rhs needs to be of the same type. Clippy has a lint that will tell you to clean it up afterwards, but we should probably issue a better diagnostic to begin with.
can you please create a ?
Please excuse my naïvety, but why is this (according to csmoes MCVE) a problem? You can actually write if i < &0 {} and everything works just fine. Can you please explain this part (to me)?
The comparison operator already takes references to both sides. so it seems simpler to dereference the lhs and save the monomorphizer and the optimizer some effort
Resurrecting this. what're the benefits of dereferencing the lhs instead of referencing the rhs? Also, if I were to go about fixing this, where would I start?
The benefit is that expands to , so if you start out with you get , seems better to just do instead (since is a no-op that gets easily removed). I'm not sure how to solve this or whether we should try at all.
claim
I want to get started with this, but would appreciate some mentoring from someone before I do, to point me in the right direction please
There's a reason I marked this as . I have no idea how to do this reasonably. I'm sorry, but I have no hints for you, and I don't even know if it's possible to do in a reasonable way.
cue terminator background music Leaving this here for future generations to see. I'm gonna try attempting to solve this and see if I can do something about it. I don't know if I can, or if I'll even survive this, but there's only one way to find out. Lol in all seriousness, if someone wants to claim this up, feel free to. Until then, I'll try and fix this.
Hi, are you still working on this issue
Hey I've been meaning to fix this up. I've reached a point where I know exactly how to fix this as well. I just haven't found the time to fix this. Feel free to take it up, considering I wouldn't be having the time to work on this in the forseeable future.
release-assignment If do you find the time in the future, please claim this issue again. Until then I'll free it up in case anybody else wants it
Is anyone currently working on this? If not, I'd be happy to give it a go. claim

<ins> // Issue #52544 // run-rustfix fn main() { let i: &i64 = &1; if *i < 0 {} //~^ ERROR mismatched types [E0308] } </ins>


Question:
What I actually wanted was . <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
The problem is by the time this error is emittedwe don't have the information about the root cause anymore. In this case that would be the type of being checked for and figuring out the the rhs needs to be of the same type. Clippy has a lint that will tell you to clean it up afterwards, but we should probably issue a better diagnostic to begin with.
can you please create a ?
Please excuse my naïvety, but why is this (according to csmoes MCVE) a problem? You can actually write if i < &0 {} and everything works just fine. Can you please explain this part (to me)?
The comparison operator already takes references to both sides. so it seems simpler to dereference the lhs and save the monomorphizer and the optimizer some effort
Resurrecting this. what're the benefits of dereferencing the lhs instead of referencing the rhs? Also, if I were to go about fixing this, where would I start?
The benefit is that expands to , so if you start out with you get , seems better to just do instead (since is a no-op that gets easily removed). I'm not sure how to solve this or whether we should try at all.
claim
I want to get started with this, but would appreciate some mentoring from someone before I do, to point me in the right direction please
There's a reason I marked this as . I have no idea how to do this reasonably. I'm sorry, but I have no hints for you, and I don't even know if it's possible to do in a reasonable way.
cue terminator background music Leaving this here for future generations to see. I'm gonna try attempting to solve this and see if I can do something about it. I don't know if I can, or if I'll even survive this, but there's only one way to find out. Lol in all seriousness, if someone wants to claim this up, feel free to. Until then, I'll try and fix this.
Hi, are you still working on this issue
Hey I've been meaning to fix this up. I've reached a point where I know exactly how to fix this as well. I just haven't found the time to fix this. Feel free to take it up, considering I wouldn't be having the time to work on this in the forseeable future.
release-assignment If do you find the time in the future, please claim this issue again. Until then I'll free it up in case anybody else wants it
Is anyone currently working on this? If not, I'd be happy to give it a go. claim

<ins> // Issue #52544 // run-rustfix fn main() { let i: &i64 = &1; if i < 0 {} //~^ ERROR mismatched types [E0308] } </ins>


Question:
What I actually wanted was . <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
The problem is by the time this error is emittedwe don't have the information about the root cause anymore. In this case that would be the type of being checked for and figuring out the the rhs needs to be of the same type. Clippy has a lint that will tell you to clean it up afterwards, but we should probably issue a better diagnostic to begin with.
can you please create a ?
Please excuse my naïvety, but why is this (according to csmoes MCVE) a problem? You can actually write if i < &0 {} and everything works just fine. Can you please explain this part (to me)?
The comparison operator already takes references to both sides. so it seems simpler to dereference the lhs and save the monomorphizer and the optimizer some effort
Resurrecting this. what're the benefits of dereferencing the lhs instead of referencing the rhs? Also, if I were to go about fixing this, where would I start?
The benefit is that expands to , so if you start out with you get , seems better to just do instead (since is a no-op that gets easily removed). I'm not sure how to solve this or whether we should try at all.
claim
I want to get started with this, but would appreciate some mentoring from someone before I do, to point me in the right direction please
There's a reason I marked this as . I have no idea how to do this reasonably. I'm sorry, but I have no hints for you, and I don't even know if it's possible to do in a reasonable way.
cue terminator background music Leaving this here for future generations to see. I'm gonna try attempting to solve this and see if I can do something about it. I don't know if I can, or if I'll even survive this, but there's only one way to find out. Lol in all seriousness, if someone wants to claim this up, feel free to. Until then, I'll try and fix this.
Hi, are you still working on this issue
Hey I've been meaning to fix this up. I've reached a point where I know exactly how to fix this as well. I just haven't found the time to fix this. Feel free to take it up, considering I wouldn't be having the time to work on this in the forseeable future.
release-assignment If do you find the time in the future, please claim this issue again. Until then I'll free it up in case anybody else wants it
Is anyone currently working on this? If not, I'd be happy to give it a go. claim

<ins> error[E0308]: mismatched types --> $DIR/binary-op-suggest-deref.rs:6:12 | LL |     if i < 0 {} |            ^ expected `&i64`, found integer | help: consider dereferencing the borrow | LL |     if *i < 0 {} |        + error: aborting due to previous error For more information about this error, try `rustc --explain E0308`. </ins>


Question:
LLVM 7.0 has been branched as of 2018-08-01, with the final tag probably a couple weeks away. The first release candidate will be tagged in a couple of days. is the llvm-dev announcement, and is a view of the commits on the branch. Once the final release has been tagged, Rust should be updated to LLVM 7.0.
Great! I've started our branches: I'm hoping that this'll be pretty smooth since we upgraded most of the way through the cycle! I'm testing locally now and will send a PR once green.

<del> Subproject commit 52a6a4d7087d14a35d44a11c39c77fa79d71378d </del> <ins> Subproject commit d549d85b1735dc5066b2973f8549557a813bb9c8 </ins>


Question:
LLVM 7.0 has been branched as of 2018-08-01, with the final tag probably a couple weeks away. The first release candidate will be tagged in a couple of days. is the llvm-dev announcement, and is a view of the commits on the branch. Once the final release has been tagged, Rust should be updated to LLVM 7.0.
Great! I've started our branches: I'm hoping that this'll be pretty smooth since we upgraded most of the way through the cycle! I'm testing locally now and will send a PR once green.

<del> Subproject commit 03684905101f0b7e49dfe530e54dc1aeac6ef0fb </del> <ins> Subproject commit e19f07f5a6e5546ab4f6ea951e3c6b8627edeaa7 </ins>


Question:
LLVM 7.0 has been branched as of 2018-08-01, with the final tag probably a couple weeks away. The first release candidate will be tagged in a couple of days. is the llvm-dev announcement, and is a view of the commits on the branch. Once the final release has been tagged, Rust should be updated to LLVM 7.0.
Great! I've started our branches: I'm hoping that this'll be pretty smooth since we upgraded most of the way through the cycle! I'm testing locally now and will send a PR once green.

# If this file is modified, then llvm will be (optionally) cleaned and then rebuilt. # The actual contents of this file do not matter, but to trigger a change on the # build bots then the contents should be changed so git updates the mtime. <del> 2018-07-12 </del>  No newline at end of file <ins> 2018-08-02 </ins>


Question:
LLVM 7.0 has been branched as of 2018-08-01, with the final tag probably a couple weeks away. The first release candidate will be tagged in a couple of days. is the llvm-dev announcement, and is a view of the commits on the branch. Once the final release has been tagged, Rust should be updated to LLVM 7.0.
Great! I've started our branches: I'm hoping that this'll be pretty smooth since we upgraded most of the way through the cycle! I'm testing locally now and will send a PR once green.

<del> Subproject commit 8214ccf861d538671b0a1436dbf4538dc4a64d09 </del> <ins> Subproject commit f76ea3ca16ed22dde8ef929db74a4b4df6f2f899 </ins>


Question:
a programming language that I am working on, and the VM is written in Rust. Up until Rust nightly 2018-08-17, everything works fine. Starting with the nightly from the 17th, I'm observing various crashes and different program behaviour. For example: On Windows it will either fail with a , or (more on this in a moment). On Linux . Note that the funny segfault output is because the command is started with Ruby, and Ruby installs its own segmentation fault handler. Locally it will usually fail with the same runtime error as observed in Windows above, but sometimes it will segfault. Sometimes it will panic because certain operations are performed using NULL pointers where this is not expected. The last nightly that did not suffer from these problems was Rust 2018-08-16. Stable Rust also works fine. When the segmentation faults happen, they are usually in different places. For example, for one segmentation fault the backtrace is as follows: 0x00007ffff7e12763 in intmalloc () from 0x00007ffff7e13ada in malloc () from 0x0000555555568e6b in alloc::alloc::alloc (layout=...) at <libinko::chunk::Chunk<T::new (capacity=3) at libinko::register::Register::new (amount=3) at libinko::executioncontext::ExecutionContext::fromblock (block=0x7fffdc0971e0, returnregister=Some = {...}) at libinko::vm::machine::Machine::run (self=<optimized out, process=<optimized out) at 0x0000555555568b7f in libinko::vm::machine::Machine::runwitherrorhandling (self=0x55555567d8c0, process=0x7ffff75fcbd0) at 0x00005555555c88a4 in libinko::vm::machine::Machine::startprimarythreads::{{closure}} (process=...) at <libinko::pool::PoolInner<T::process (self=<optimized out, index=0, closure=0x7ffff75fcc60) at 0x00005555555b739d in <libinko::pool::Pool<T::run::{{closure}} () at std::syscommon::backtrace::rustbeginshortbacktrace (f=...) at 0x00005555555cb0dc in std::thread::Builder::spawn::{{closure}}::{{closure}} () at <std::panic::AssertUnwindSafe<Fas core::ops::function::FnOnce<()::callonce (self=..., args=<optimized out) at std::panicking::try::docall (data=<optimized out) at 0x0000555555618a3a in rustmaybecatchpanic () at 0x00005555555ba39b in std::panicking::try (f=...) at std::panic::catchunwind (f=...) at std::thread::Builder::spawn::{{closure}} () at <F as alloc::boxed::FnBox<A::callbox (self=0x55555567db50, args=<optimized out) at 0x00005555556090db in LTdynLTCOutputRu20u20aGTasLTGT::callonce::h904fcd0dbdc71d4f () at std::syscommon::thread::startthread () at 0x00005555555f83b6 in std::sys::unix::thread::Thread::new::threadstart () at 0x00007ffff7f73a9d in startthread () from 0x00007ffff7e89a43 in clone () from While for another segfault the backtrace is instead: libinko::runtimepanic::displaypanic (process=0x7f, message="ObjectValue::asblock() called on a non block object") at 0x0000555555568baa in libinko::vm::machine::Machine::panic (self=0x55555567d8c0, process=0x7ffff71f8bd0, message="") at libinko::vm::machine::Machine::runwitherrorhandling (self=0x55555567d8c0, process=0x7ffff71f8bd0) at 0x00005555555c88a4 in libinko::vm::machine::Machine::startprimarythreads::{{closure}} (process=...) at <libinko::pool::PoolInner<T::process (self=<optimized out, index=4, closure=0x7ffff71f8c60) at 0x00005555555b739d in <libinko::pool::Pool<T::run::{{closure}} () at std::syscommon::backtrace::rustbeginshortbacktrace (f=...) at 0x00005555555cb0dc in std::thread::Builder::spawn::{{closure}}::{{closure}} () at <std::panic::AssertUnwindSafe<Fas core::ops::function::FnOnce<()::callonce (self=..., args=<optimized out) at std::panicking::try::docall (data=<optimized out) at 0x0000555555618a3a in rustmaybecatchpanic () at 0x00005555555ba39b in std::panicking::try (f=...) at std::panic::catchunwind (f=...) at std::thread::Builder::spawn::{{closure}} () at <F as alloc::boxed::FnBox<A::callbox (self=0x55555567e5d0, args=<optimized out) at 0x00005555556090db in LTdynLTCOutputRu20u20aGTasLTGT::callonce::h904fcd0dbdc71d4f () at std::syscommon::thread::startthread () at 0x00005555555f83b6 in std::sys::unix::thread::Thread::new::threadstart () at 0x00007ffff7f73a9d in startthread () from 0x00007ffff7e89a43 in clone () from And a third segfault: 0x0000555555568d84 in libinko::vm::machine::Machine::run (self=<optimized out, process=<optimized out) at 0x0000555555568b7f in libinko::vm::machine::Machine::runwitherrorhandling (self=0x55555567d8c0, process=0x7ffff6cf3bd0) at 0x00005555555c88a4 in libinko::vm::machine::Machine::startprimarythreads::{{closure}} (process=...) at <libinko::pool::PoolInner<T::process (self=<optimized out, index=10, closure=0x7ffff6cf3c60) at 0x00005555555b739d in <libinko::pool::Pool<T::run::{{closure}} () at std::syscommon::backtrace::rustbeginshortbacktrace (f=...) at 0x00005555555cb0dc in std::thread::Builder::spawn::{{closure}}::{{closure}} () at <std::panic::AssertUnwindSafe<Fas core::ops::function::FnOnce<()::callonce (self=..., args=<optimized out) at std::panicking::try::docall (data=<optimized out) at 0x0000555555618a3a in rustmaybecatchpanic () at 0x00005555555ba39b in std::panicking::try (f=...) at std::panic::catchunwind (f=...) at std::thread::Builder::spawn::{{closure}} () at <F as alloc::boxed::FnBox<A::callbox (self=0x55555567f590, args=<optimized out) at 0x00005555556090db in LTdynLTCOutputRu20u20aGTasLTGT::callonce::h904fcd0dbdc71d4f () at std::syscommon::thread::startthread () at 0x00005555555f83b6 in std::sys::unix::thread::Thread::new::threadstart () at 0x00007ffff7f73a9d in startthread () from 0x00007ffff7e89a43 in clone () from In case of the last segfault, it seems certain local variables that are used are NULL pointers, when this should be impossible. Debugging this in GDB proves to be quite difficult, as a variety of variables are reported as <optimized outeven when debugging symbols are included. For example, for the last backtrace the output of "info locals" is: The VM test suite passes, even when running . I'm wondering if perhaps code is optimised in the wrong way, and this is somehow not triggered in the test suite (certainly possible, code coverage is not 100%). Reproducing this is a bit weird. If we leave the code as-is, the segmentation faults rarely occur, instead the VM panics with the following: Stack trace (the most recent call comes last): 0: "", line 324, in "<block" 1: "", line 281, in "<lambda" 2: "", line 220, in "run" Process 1 panicked: ObjectValue::as_block() called on a non block object However, if we apply the following patch things will start to segfault really quick: Note that the last command requires Ruby 2.3 or newer. This will run the test suite of the standard library, which is where all the crashes happen rather frequently (probably because they run much more than the VM's own test suite).
There's a lot of questionable unsafe code in that project. For example, should really be marked as (same goes for . It's very likely that the cause of the issue is preexisting UB due to misuse of .
Simply marking functions as to my knowledge doesn't influence the compiler's code generation. Many of the unsafe operations are safe in practise, as they will only fail if (for example) the input bytecode is invalid. Tagging them as does nothing but make the code significantly more verbose. The various operations in the bytecode parser are there to convert sequences of bytes into particular types. To the best of my knowledge there is no stable way of converting a into say a , requiring you to use instead. The closest is but this: nightly the platform's endianness, instead of allowing you to specify which to use.
Yes, but marking a function as requires all call sites to opt into that unsafety, and the functions I mentioned all assume that their arguments are valid (and cause UB if not). This additional constraint on the arguments is expressed by marking the function and documenting the safety constraints. Check out the crate.
This wouldn't achieve much, as a lot would have to be marked unsafe as VMs and GCs inherently perform many operations Rust may consider unsafe. There are a few cases where I want to get rid of more risky code (e.g. the borrowing of you highlighted), but all of this feels rather offtopic since it's very project specific. I avoided it in the past because it also just used , so it didn't feel like much of an improvement. It appears this is no longer the case, so I'll take another look.
To better understand what is going on I dumped the MIR output using and (2018-08-18). After replacing a bunch of SHA hashes with placeholders (to reduce diff noise), I ended up with the exact same MIR before and after. Next I'll try LLVM IR.
It appears the LLVM IR uses a different order for things when using the different nightly versions. This generates a lot of diff noise, so I'm not sure how useful this information will be. I tried to clean it up a bit by replacing various SHA hashes with placeholders, but even then there is a lot of noise.
The ASM output was a bit easier to clean up, but there are still lots of differences. To be exact, reports: Again this is probably because of ordering. The new version has 99 lines more, but I'm really not sure if that's expected or not.
Using I found that nightly-2018-08-19 is the first version that introduces the regression, while nightly-2018-08-18 works fine. The commits included into the 18th nightly can be found at (if I got things right at least).
This hints at , which can change the behaviour of any latent UB, or , since your project uses in a few places.
I don't fully understand the first mentioned PR. What would I need to do to verify if that has any impact? For the second one, I'll see if I can somehow get my code to use a version of from before that PR, to see if it affects anything.
A custom version of probably isn't going to work. For example, I'm using Rayon which only implements its traits for the default :<
I ended up replacing all my uses of with to test if the VecDeque changes are to blame. I used LinkedList because its API is closest to VecDeque, making it easier to test things. When using LinkedList, my code runs fine. This suggests that the changes in may have somehow broken things. cc
The first PR changes details about the generated code that is passed to LLVM. In fact, it just removes unneeded information. The easiest way to check if it's at fault is to manually build the compiler from with the PR reverted. If the problem stops happening, it's at fault (or more likely, UB in your code is). It would also be helpful if you could reduce the code as much as possible so that we can get a few hundred line example that shows the issue.
Specifically, the patch I applied is:
I narrowed this down to the following file being broken by the changes: If I switch back to for this file, my code breaks. There are two possibilities here: was a bug before in my code that only somehow didn't get triggered before VecDeque changes themselves break things The Mailbox data structure has multiple threads accessing it concurrently. This is synchronised using a mutex of type (provided by parking_lot). The structure is broken up into essentially two parts: a synchronised external part, and an unsynchronised internal part. The internal part is only used by a single thread, while multiple threads can compete for the external part. For this reason the mutex is separate, so we don't need to synchronise both. Edit: I forgot, this is synchronised earlier on, preventing concurrent writes. I'll see if I can refactor this code a bit so it's safer, that way we can at least rule out my own code being the problem (or not).
Upon closer inspection, the VecDeque changes specifically affect , and I happen to use that in my Mailbox structure. Specifically, I have the following: I don't remember why this is using since is also a , probably I wrote this when not paying attention. Regardless, changing this to doesn't make any difference regarding the errors. Next I changed this code to the following: This is based on the old implementation of , which was: This then produces output like: This is a bit odd considering the implementation is the same as before, but at least now part of the program is running.
There was another place where I relied on . After also replacing that with the pattern my code now runs fine again, both on nightly and stable Rust. This suggests the failure is definitely due to the changes made to . Now to see if I can get this in a standalone example.
Good news: Thanks to the great investigation of and I think I found the reason for the segfault: the new calls which unsoundly creates mutable slices to uninitialized memory. I will try to send a fixing PR tomorrow.
Aha, thanks! I was looking at the code to see how I might be able to trigger this problem, but I hadn't made my way to just yet. Looking at the code, I'm not sure exactly how to trigger this reliably.
That could be it, nice find!
The problem AFAIK is that this function is triggering Undefined Behavior, and so can cause the program to segfault randomly, and so it may be difficult to reproduce it reliably.
I can verify that this is because of my PR. Minimal example that segfaults for me: And the reason for the segfault is apparent when run with simpler types This will print and continue in such a loop forever, printing the buffer over and over again. This happens because of line hitting an edge case when that causes head to be placed outside of the buffer. This can be fixed by changing that line to I think that is the only thing that is causing these segfaults.

len); } <del> /// Returns a pair of slices which contain the contents of the buffer not used by the VecDeque. #[inline] unsafe fn unused_as_mut_slices<'a>(&'a mut self) -> (&'a mut [T], &'a mut [T]) { let head = self.head; let tail = self.tail; let buf = self.buffer_as_mut_slice(); if head != tail { // In buf, head..tail contains the VecDeque and tail..head is unused. // So calling `ring_slices` with tail and head swapped returns unused slices. RingSlices::ring_slices(buf, tail, head) } else { // Swapping doesn't help when head == tail. let (before, after) = buf.split_at_mut(head); (after, before) } } </del> /// Copies a potentially wrapping block of memory len long from src to dest. /// (abs(dst - src) + len) must be no larger than cap() (There must be at /// most one continuous overlapping region between src and dest).