Question:
This is a tracking issue for the unstable methods in the standard library. cc perhaps you can fill this in some more? The specific methods in question are: -
This is basically a lame version of cursors, which is what we should use instead imo. It's not 1:1 though -- this api lets you have all the elements yielded at once. Classic iterator tradeoff.
Triage: these are still unstable.
There are some ideas for a more complete API in
seems misnamed. Doesn't it do exactly what we call elsewhere?
I'm going to echo thoughts: An iterator conceptually represents a (double-ended) range of elements. The only operation that it supports is popping an element off the end of that range. A cursor on the other hand represents a position in a collection, and can be moved backwards or forwards in the collection. The cursor can be used to insert or remove an element at any given position in the collection. I strongly oppose adding insertion/deleting methods to since they do not fit at all with existing iterator usage patterns ( loops and functional-style methods). As I mentioned in the linked thread, a design based on the types in could be used.
Since we now have cursors, I think these methods should be removed.
Reopening since we only deprecated the methods instead of removing them. I'd say give it about 2 weeks then remove them.

} #[test] <del> fn test_insert_prev() { let mut m = list_from(&[0, 2, 4, 6, 8]); let len = m.len(); { let mut it = m.iter_mut(); it.insert_next(-2); loop { match it.next() { None => break, Some(elt) => { it.insert_next(*elt + 1); match it.peek_next() { Some(x) => assert_eq!(*x, *elt + 2), None => assert_eq!(8, *elt), } } } } it.insert_next(0); it.insert_next(1); } check_links(&m); assert_eq!(m.len(), 3 + len * 2); assert_eq!(m.into_iter().collect::<Vec<_>>(), [-2, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1]); } #[test] </del> #[cfg_attr(target_os = "emscripten", ignore)] fn test_send() { let n = list_from(&[1, 2, 3]);


Question:
This is a tracking issue for the unstable methods in the standard library. cc perhaps you can fill this in some more? The specific methods in question are: -
This is basically a lame version of cursors, which is what we should use instead imo. It's not 1:1 though -- this api lets you have all the elements yielded at once. Classic iterator tradeoff.
Triage: these are still unstable.
There are some ideas for a more complete API in
seems misnamed. Doesn't it do exactly what we call elsewhere?
I'm going to echo thoughts: An iterator conceptually represents a (double-ended) range of elements. The only operation that it supports is popping an element off the end of that range. A cursor on the other hand represents a position in a collection, and can be moved backwards or forwards in the collection. The cursor can be used to insert or remove an element at any given position in the collection. I strongly oppose adding insertion/deleting methods to since they do not fit at all with existing iterator usage patterns ( loops and functional-style methods). As I mentioned in the linked thread, a design based on the types in could be used.
Since we now have cursors, I think these methods should be removed.
Reopening since we only deprecated the methods instead of removing them. I'd say give it about 2 weeks then remove them.

#[stable(feature = "fused", since = "1.26.0")] impl<T> FusedIterator for IterMut<'_, T> {} <del> impl<T> IterMut<'_, T> { /// Inserts the given element just after the element most recently returned by `.next()`. /// The inserted element does not appear in the iteration. /// /// This method will be removed soon. #[inline] #[unstable( feature = "linked_list_extras", reason = "this is probably better handled by a cursor type -- we'll see", issue = "27794" )] #[rustc_deprecated( reason = "Deprecated in favor of CursorMut methods. This method will be removed soon.", since = "1.47.0" )] pub fn insert_next(&mut self, element: T) { match self.head { // `push_back` is okay with aliasing `element` references None => self.list.push_back(element), Some(head) => unsafe { let prev = match head.as_ref().prev { // `push_front` is okay with aliasing nodes None => return self.list.push_front(element), Some(prev) => prev, }; let node = Some( Box::leak(box Node { next: Some(head), prev: Some(prev), element }).into(), ); // Not creating references to entire nodes to not invalidate the // reference to `element` we handed to the user. (*prev.as_ptr()).next = node; (*head.as_ptr()).prev = node; self.list.len += 1; }, } } /// Provides a reference to the next element, without changing the iterator. /// /// This method will be removed soon. #[inline] #[unstable( feature = "linked_list_extras", reason = "this is probably better handled by a cursor type -- we'll see", issue = "27794" )] #[rustc_deprecated( reason = "Deprecated in favor of CursorMut methods. This method will be removed soon.", since = "1.47.0" )] pub fn peek_next(&mut self) -> Option<&mut T> { if self.len == 0 { None } else { unsafe { self.head.as_mut().map(|node| &mut node.as_mut().element) } } } } </del> /// A cursor over a `LinkedList`. /// /// A `Cursor` is like an iterator, except that it can freely seek back-and-forth.


Question:
Willing to mentor this. Fix is simple, just need to check for . We should also add a run-pass test to ensure that the above code continues to compile. Feel free to ask me if you have further questions!
I've been willing for a long time to start getting involved in some contributions to Rust, so if it's ok for you I would like to give this one a go and make it my first contribution.
Go ahead!

for arg in &fd.inputs { match arg.pat.node { hir::PatIdent(hir::BindByValue(hir::MutImmutable), _, None) => {} <ins> hir::PatWild(_) => {} </ins> _ => { span_err!(self.tcx.sess, arg.pat.span, E0022, "arguments of constant functions can only


Question:
Willing to mentor this. Fix is simple, just need to check for . We should also add a run-pass test to ensure that the above code continues to compile. Feel free to ask me if you have further questions!
I've been willing for a long time to start getting involved in some contributions to Rust, so if it's ok for you I would like to give this one a go and make it my first contribution.
Go ahead!

<ins> // Copyright 2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. #![feature(const_fn)] fn main() {} const fn size_ofs(_: usize) {} const fn size_ofs2(_foo: usize) {} </ins>


Question: The linkable icon is difficult to . I'm playing with this currently. I'm toying with trying to change the icon from unicode into a svg because unicode has a weird box border shape that doesn't allow the icon to scale to the full box size. I'll put up a PR if I get it working. !

.rusttest { display: none; } pre.rust { position: relative; } <del> .test-arrow { </del> <ins> a.test-arrow { </ins> display: inline-block; position: absolute; <del> top: 0; right: 10px; font-size: 150%; -webkit-transform: scaleX(-1); transform: scaleX(-1); </del> <ins> background-color: #4e8bca; color: #f5f5f5; padding: 5px 10px 5px 10px; border-radius: 5px; font-size: 130%; top: 5px; right: 5px; </ins> } .methods .section-header {


Question: The linkable icon is difficult to . I'm playing with this currently. I'm toying with trying to change the icon from unicode into a svg because unicode has a weird box border shape that doesn't allow the icon to scale to the full box size. I'll put up a PR if I get it working. !

} var a = document.createElement('a'); <del> a.textContent = '⇱'; </del> a.setAttribute('class', 'test-arrow'); <ins> a.textContent = 'Run'; </ins> var code = el.previousElementSibling.textContent;


Question:
I tried this code: I expected to see this happen: "Error: invalid float literal" Instead, this happened: OK: 0 It seems the "leading +" and "leading -" is broken. Further, with i32 and i64 is emits an error but IMO an incorrect one: "cannot parse integer from empty string" I would expect: "Invalid integer literal" : rustc 1.5.0-nightly ( 2015-10-11) binary: rustc commit-hash: commit-date: 2015-10-11 host: x86_64-unknown-linux-gnu release: 1.5.0-nightly
Oh my, the float part is embarrassing. Preparing a fix right now.
Thanks for taking a look Looks like this is working as expected on stable and has leaked into beta/nightly, so tagging as such.
Yes, this is a bug (not checking for empty strings in the right places) of the dec2flt code. The bug is also in beta, so the PR (which I'll file very soon) should probably be backported to beta.

let s = s.as_bytes(); let (integral, s) = eat_digits(s); match s.first() { <del> None => Valid(Decimal::new(integral, b"", 0)), </del> <ins> None => { if integral.is_empty() { return Invalid; // No digits at all } Valid(Decimal::new(integral, b"", 0)) } </ins> Some(&b'e') | Some(&b'E') => { if integral.is_empty() { return Invalid; // No digits before 'e'


Question:
I tried this code: I expected to see this happen: "Error: invalid float literal" Instead, this happened: OK: 0 It seems the "leading +" and "leading -" is broken. Further, with i32 and i64 is emits an error but IMO an incorrect one: "cannot parse integer from empty string" I would expect: "Invalid integer literal" : rustc 1.5.0-nightly ( 2015-10-11) binary: rustc commit-hash: commit-date: 2015-10-11 host: x86_64-unknown-linux-gnu release: 1.5.0-nightly
Oh my, the float part is embarrassing. Preparing a fix right now.
Thanks for taking a look Looks like this is working as expected on stable and has leaked into beta/nightly, so tagging as such.
Yes, this is a bug (not checking for empty strings in the right places) of the dec2flt code. The bug is also in beta, so the PR (which I'll file very soon) should probably be backported to beta.

} #[test] <ins> fn lonely_sign() { assert!("+".parse::<f32>().is_err()); assert!("-".parse::<f64>().is_err()); } #[test] fn whitespace() { assert!(" 1.0".parse::<f32>().is_err()); assert!("1.0 ".parse::<f64>().is_err()); } #[test] </ins> fn nan() { assert!("NaN".parse::<f32>().unwrap().is_nan()); assert!("NaN".parse::<f64>().unwrap().is_nan());


Question:
Playpen: Code like that puts a unicode character in a byte literal gets a confusing error message: A lot of people read this as if the part after the colon is in reference to "use a xHH escape", so it should show an example of that, but it really is just displaying the char that is in error, though somewhat obfuscated by using the codepoint instead of the actual char.
I agree. As someone unfamiliar with the language the error message lead me to fix the playpen code like this: fn main() { b'u{2192}' } Which leads to: error: unicode escape sequences cannot be used as a byte or in a byte string

_ => { if ascii_only && first_source_char > 'x7F' { let last_pos = self.last_pos; <del> self.err_span_char(start, last_pos, "byte constant must be ASCII. Use a xHH escape for a  non-ASCII byte", first_source_char); </del> <ins> self.err_span_(start, last_pos, "byte constant must be ASCII. Use a xHH escape for a  non-ASCII byte"); </ins> return false; } }


Question: The message for E0139 suggests replacing with . Actually performing such a replacement will result in double drops, since the version consumes but the version does not. (It presumably needs a or something.)

``` ptr::read(&v as *const _ as *const SomeType) // `v` transmuted to `SomeType` ``` <ins> Note that this does not move `v` (unlike `transmute`), and may need a call to `mem::forget(v)` in case you want to avoid destructors being called. </ins> "##, E0152: r##"


Question:
The first example
Thanks, these are hard to keep in sync, as they don't get automated testing :/

fn expand_rn(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree]) -> Box<MacResult + 'static> { <del> static NUMERALS: &'static [(&'static str, u32)] = &[ </del> <ins> static NUMERALS: &'static [(&'static str, usize)] = &[ </ins> ("M", 1000), ("CM", 900), ("D", 500), ("CD", 400), ("C",  100), ("XC",  90), ("L",  50), ("XL",  40), ("X",   10), ("IX",   9), ("V",   5), ("IV",   4), ("I",    1)]; <del> let text = match args { [TokenTree::Token(_, token::Ident(s, _))] => s.to_string(), </del> <ins> if args.len() != 1 { cx.span_err( sp, &format!("argument should be a single identifier, but got {} arguments", args.len())); return DummyResult::any(sp); } let text = match args[0] { TokenTree::Token(_, token::Ident(s, _)) => s.to_string(), </ins> _ => { cx.span_err(sp, "argument should be a single identifier"); return DummyResult::any(sp);


Question:
The first example
Thanks, these are hard to keep in sync, as they don't get automated testing :/

} } <del> MacEager::expr(cx.expr_u32(sp, total)) </del> <ins> MacEager::expr(cx.expr_usize(sp, total)) </ins> } #[plugin_registrar]


Question:
The first example
Thanks, these are hard to keep in sync, as they don't get automated testing :/

("X",   10), ("IX",   9), ("V",   5), ("IV",   4), ("I",    1)]; <del> let text = match args { [TokenTree::Token(_, token::Ident(s, _))] => s.to_string(), </del> <ins> if args.len() != 1 { cx.span_err( sp, &format!("argument should be a single identifier, but got {} arguments", args.len())); return DummyResult::any(sp); } let text = match args[0] { TokenTree::Token(_, token::Ident(s, _)) => s.to_string(), </ins> _ => { cx.span_err(sp, "argument should be a single identifier"); return DummyResult::any(sp);


Question:
at the current version of error: internal compiler error: unexpected panic note: the compiler unexpectedly panicked. this is a bug. note: we would appreciate a bug report: note: run with for a backtrace thread 'rustc' panicked at 'internal error: entered unreachable code', playpen: application terminated with error code 101
The reason this is happening is because the code thinks is an enum variant or a tuple struct. The code around this is somewhat redundant and would probably better be solved by making enum variants const evaluable and adding a function that translates s to

let path = match def.full_def() { def::DefStruct(def_id) => def_to_path(tcx, def_id), def::DefVariant(_, variant_did, _) => def_to_path(tcx, variant_did), <ins> def::DefFn(..) => return P(hir::Pat { id: expr.id, node: hir::PatLit(P(expr.clone())), span: span, }), </ins> _ => unreachable!() }; let pats = args.iter().map(|expr| const_expr_to_pat(tcx, &**expr, span)).collect();


Question:
at the current version of error: internal compiler error: unexpected panic note: the compiler unexpectedly panicked. this is a bug. note: we would appreciate a bug report: note: run with for a backtrace thread 'rustc' panicked at 'internal error: entered unreachable code', playpen: application terminated with error code 101
The reason this is happening is because the code thinks is an enum variant or a tuple struct. The code around this is somewhat redundant and would probably better be solved by making enum variants const evaluable and adding a function that translates s to

_ => signal!(e, NonConstPath), }, Some(ast_map::NodeTraitItem(..)) => signal!(e, NonConstPath), <del> Some(_) => unimplemented!(), </del> <ins> Some(_) => signal!(e, UnimplementedConstVal("calling struct, tuple or variant")), </ins> } }


Question:
at the current version of error: internal compiler error: unexpected panic note: the compiler unexpectedly panicked. this is a bug. note: we would appreciate a bug report: note: run with for a backtrace thread 'rustc' panicked at 'internal error: entered unreachable code', playpen: application terminated with error code 101
The reason this is happening is because the code thinks is an enum variant or a tuple struct. The code around this is somewhat redundant and would probably better be solved by making enum variants const evaluable and adding a function that translates s to

<ins> // Copyright 2015 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. #![feature(const_fn)] enum Cake { BlackForest, Marmor, } use Cake::*; const BOO: (Cake, Cake) = (Marmor, BlackForest); //~^ ERROR: constant evaluation error: non-constant path in constant expression [E0471] const FOO: Cake = BOO.1; const fn foo() -> Cake { Marmor //~ ERROR: constant evaluation error: non-constant path in constant expression [E0471] //~^ ERROR: non-constant path in constant expression } const WORKS: Cake = Marmor; const GOO: Cake = foo(); fn main() { match BlackForest { FOO => println!("hi"), //~ NOTE: in pattern here GOO => println!("meh"), //~ NOTE: in pattern here WORKS => println!("möp"), _ => println!("bye"), } } </ins>


Question:
at the current version of error: internal compiler error: unexpected panic note: the compiler unexpectedly panicked. this is a bug. note: we would appreciate a bug report: note: run with for a backtrace thread 'rustc' panicked at 'internal error: entered unreachable code', playpen: application terminated with error code 101
The reason this is happening is because the code thinks is an enum variant or a tuple struct. The code around this is somewhat redundant and would probably better be solved by making enum variants const evaluable and adding a function that translates s to

<del> // Copyright 2012 The Rust Project Developers. See the COPYRIGHT </del> <ins> // Copyright 2015 The Rust Project Developers. See the COPYRIGHT </ins> // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. //


Question:
at the current version of error: internal compiler error: unexpected panic note: the compiler unexpectedly panicked. this is a bug. note: we would appreciate a bug report: note: run with for a backtrace thread 'rustc' panicked at 'internal error: entered unreachable code', playpen: application terminated with error code 101
The reason this is happening is because the code thinks is an enum variant or a tuple struct. The code around this is somewhat redundant and would probably better be solved by making enum variants const evaluable and adding a function that translates s to

// option. This file may not be copied, modified, or distributed // except according to those terms. <ins> #![feature(const_fn)] </ins> const FOO: isize = 10; const BAR: isize = 3; <ins> const fn foo() -> isize { 4 } const BOO: isize = foo(); </ins> pub fn main() { let x: isize = 3; let y = match x { FOO => 1, BAR => 2, <ins> BOO => 4, </ins> _ => 3 }; assert_eq!(y, 2);


Question:
at the current version of error: internal compiler error: unexpected panic note: the compiler unexpectedly panicked. this is a bug. note: we would appreciate a bug report: note: run with for a backtrace thread 'rustc' panicked at 'internal error: entered unreachable code', playpen: application terminated with error code 101
The reason this is happening is because the code thinks is an enum variant or a tuple struct. The code around this is somewhat redundant and would probably better be solved by making enum variants const evaluable and adding a function that translates s to

<ins> // Copyright 2015 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. #![feature(const_fn)] const fn f() -> usize { 5 } struct A { field: usize, } fn main() { let _ = [0; f()]; } </ins>


Question:
at the current version of error: internal compiler error: unexpected panic note: the compiler unexpectedly panicked. this is a bug. note: we would appreciate a bug report: note: run with for a backtrace thread 'rustc' panicked at 'internal error: entered unreachable code', playpen: application terminated with error code 101
The reason this is happening is because the code thinks is an enum variant or a tuple struct. The code around this is somewhat redundant and would probably better be solved by making enum variants const evaluable and adding a function that translates s to

<ins> // Copyright 2015 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. #![feature(const_fn)] struct A { field: usize, } const fn f() -> usize { 5 } fn main() { let _ = [0; f()]; } </ins>


Question: The macros chapter says: However the second sentence isn't true. is either nothing or a path with one and one identifier. That is, this pair of macros doesn't work, either when called from within the crate or from another one:

function name will expand to either `::increment` or `::mylib::increment`. To keep this system simple and correct, `#[macro_use] extern crate ...` may <del> only appear at the root of your crate, not inside `mod`. This ensures that `$crate` is a single identifier. </del> <ins> only appear at the root of your crate, not inside `mod`. </ins> # The deep end


Question:
broke this code:
Clone is not implemented for anymore, because it now requires (previously ), which doesn't hold for arrays bigger than 32.
I'm assuming that trying to call on an would previously ICE the compiler?
In certain contexts, such as it would / will ICE yes, issue
Ah, the bound was before.
If only we had type level integers so we could just properly implement Clone for all fixed size array sizes without massive bloat.
It doesn't even requires actual numbers, most of impls act on "size-erased" arrays. Something like would be enough.
how would that work? Don't you need to loop N times to do the actual clone?
Something like: So is not used explicitly in the implementation, although it is still needed by internally. Whether it is easier to implement than type level integers or not is a separate question.

use fmt; use hash::{Hash, self}; use iter::IntoIterator; <del> use marker::{Sized, Unsize}; </del> <ins> use marker::{Copy, Sized, Unsize}; </ins> use option::Option; use slice::{Iter, IterMut, SliceExt};


Question:
broke this code:
Clone is not implemented for anymore, because it now requires (previously ), which doesn't hold for arrays bigger than 32.
I'm assuming that trying to call on an would previously ICE the compiler?
In certain contexts, such as it would / will ICE yes, issue
Ah, the bound was before.
If only we had type level integers so we could just properly implement Clone for all fixed size array sizes without massive bloat.
It doesn't even requires actual numbers, most of impls act on "size-erased" arrays. Something like would be enough.
how would that work? Don't you need to loop N times to do the actual clone?
Something like: So is not used explicitly in the implementation, although it is still needed by internally. Whether it is easier to implement than type level integers or not is a separate question.

} #[stable(feature = "rust1", since = "1.0.0")] <ins> impl<T:Copy> Clone for [T; $N] { fn clone(&self) -> [T; $N] { *self } } #[stable(feature = "rust1", since = "1.0.0")] </ins> impl<T: Hash> Hash for [T; $N] { fn hash<H: hash::Hasher>(&self, state: &mut H) { Hash::hash(&self[..], state)


Question:
broke this code:
Clone is not implemented for anymore, because it now requires (previously ), which doesn't hold for arrays bigger than 32.
I'm assuming that trying to call on an would previously ICE the compiler?
In certain contexts, such as it would / will ICE yes, issue
Ah, the bound was before.
If only we had type level integers so we could just properly implement Clone for all fixed size array sizes without massive bloat.
It doesn't even requires actual numbers, most of impls act on "size-erased" arrays. Something like would be enough.
how would that work? Don't you need to loop N times to do the actual clone?
Something like: So is not used explicitly in the implementation, although it is still needed by internally. Whether it is easier to implement than type level integers or not is a separate question.

} array_impl_default!{32, T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T} <del> macro_rules! array_impl_clone { {$n:expr, $i:expr, $($idx:expr,)*} => { #[stable(feature = "rust1", since = "1.0.0")] impl<T: Clone> Clone for [T; $n] { fn clone(&self) -> [T; $n] { [self[$i-$i].clone(), $(self[$i-$idx].clone()),*] } } array_impl_clone!{$i, $($idx,)*} }; {$n:expr,} => { #[stable(feature = "rust1", since = "1.0.0")] impl<T: Clone> Clone for [T; 0] { fn clone(&self) -> [T; 0] { [] } } }; } array_impl_clone! { 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9,  8,  7,  6,  5,  4,  3,  2,  1,  0, } </del>


Question:
broke this code:
Clone is not implemented for anymore, because it now requires (previously ), which doesn't hold for arrays bigger than 32.
I'm assuming that trying to call on an would previously ICE the compiler?
In certain contexts, such as it would / will ICE yes, issue
Ah, the bound was before.
If only we had type level integers so we could just properly implement Clone for all fixed size array sizes without massive bloat.
It doesn't even requires actual numbers, most of impls act on "size-erased" arrays. Something like would be enough.
how would that work? Don't you need to loop N times to do the actual clone?
Something like: So is not used explicitly in the implementation, although it is still needed by internally. Whether it is easier to implement than type level integers or not is a separate question.

<ins> // Copyright 2015 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. // test for issue #30244 #[derive(Copy, Clone)] struct Array { arr: [[u8; 256]; 4] } pub fn main() {} </ins>


Question:
This code isn't valid Rust: We have an okay, but not great, diagnostic here: It might be nice to add a when the keyword found is that mentions that is not an expression, and so cannot be used in this way.
want to work on this? It's a similar task to the other doc comment one, but much simpler since it's a very specific situation.
I'd be happy to help someone :)
So, the parser already has its ways to differentiate keywords from identifiers. All we have to do is find the right place where that error is thrown, check whether it's a and add a note along with the error. The parser has all sorts of code, and adding a note's also around there somewhere :) Code:
I would like to try this. :)
Awesome! Feel free to ask waffles or me for help (you can find us both on IRC on #rust-internals), or ask questions here. (self-assigning since I can't assign to you -- just to mark it as "being taken")

use self::Destination::*; <del> use codemap::{self, COMMAND_LINE_SP, COMMAND_LINE_EXPN, Pos, Span}; </del> <ins> use codemap::{self, COMMAND_LINE_SP, COMMAND_LINE_EXPN, DUMMY_SP, Pos, Span}; </ins> use diagnostics; use errors::{Level, RenderSpan, DiagnosticBuilder};


Question:
This code isn't valid Rust: We have an okay, but not great, diagnostic here: It might be nice to add a when the keyword found is that mentions that is not an expression, and so cannot be used in this way.
want to work on this? It's a similar task to the other doc comment one, but much simpler since it's a very specific situation.
I'd be happy to help someone :)
So, the parser already has its ways to differentiate keywords from identifiers. All we have to do is find the right place where that error is thrown, check whether it's a and add a note along with the error. The parser has all sorts of code, and adding a note's also around there somewhere :) Code:
I would like to try this. :)
Awesome! Feel free to ask waffles or me for help (you can find us both on IRC on #rust-internals), or ask questions here. (self-assigning since I can't assign to you -- just to mark it as "being taken")

lvl: Level) { let error = match sp { Some(COMMAND_LINE_SP) => self.emit_(FileLine(COMMAND_LINE_SP), msg, code, lvl), <ins> Some(DUMMY_SP) | None => print_diagnostic(&mut self.dst, "", lvl, msg, code), </ins> Some(sp) => self.emit_(FullSpan(sp), msg, code, lvl), <del> None => print_diagnostic(&mut self.dst, "", lvl, msg, code), </del> }; if let Err(e) = error {


Question:
This code isn't valid Rust: We have an okay, but not great, diagnostic here: It might be nice to add a when the keyword found is that mentions that is not an expression, and so cannot be used in this way.
want to work on this? It's a similar task to the other doc comment one, but much simpler since it's a very specific situation.
I'd be happy to help someone :)
So, the parser already has its ways to differentiate keywords from identifiers. All we have to do is find the right place where that error is thrown, check whether it's a and add a note along with the error. The parser has all sorts of code, and adding a note's also around there somewhere :) Code:
I would like to try this. :)
Awesome! Feel free to ask waffles or me for help (you can find us both on IRC on #rust-internals), or ask questions here. (self-assigning since I can't assign to you -- just to mark it as "being taken")

ex = ExprBreak(None); } hi = self.last_span.hi; <ins> } else if self.token.is_keyword(keywords::Let) { // Catch this syntax error here, instead of in `check_strict_keywords`, so // that we can explicitly mention that let is not to be used as an expression let mut db = self.fatal("expected expression, found statement (`let`)"); db.note("variable declaration using `let` is a statement"); return Err(db); </ins> } else if self.check(&token::ModSep) || self.token.is_ident() && !self.check_keyword(keywords::True) &&


Question:
This code isn't valid Rust: We have an okay, but not great, diagnostic here: It might be nice to add a when the keyword found is that mentions that is not an expression, and so cannot be used in this way.
want to work on this? It's a similar task to the other doc comment one, but much simpler since it's a very specific situation.
I'd be happy to help someone :)
So, the parser already has its ways to differentiate keywords from identifiers. All we have to do is find the right place where that error is thrown, check whether it's a and add a note along with the error. The parser has all sorts of code, and adding a note's also around there somewhere :) Code:
I would like to try this. :)
Awesome! Feel free to ask waffles or me for help (you can find us both on IRC on #rust-internals), or ask questions here. (self-assigning since I can't assign to you -- just to mark it as "being taken")

// ignore-cross-compile <del> // error-pattern:expected identifier, found keyword `let` </del> <ins> // error-pattern:expected expression, found statement (`let`) </ins> #![feature(quote, rustc_private)]


Question:
All public types should implement Debug. Per conversation on #rust-internals, there might be some useful information that could be printed for these types -- but even just "Sender { .. }" etc. would be a start.
Was this
probably. It has been suggested that way more useful info could actually be printed instead of the opaque placeholders -- but that would be more of a wishlist item than a bug... The patch is sufficient to fix the actual problem I was running into: not being able to #[derive(Debug)] on any structure containing mpsc Senders/Receivers.
Ok, closing.

} } <ins> #[stable(feature = "mpsc_debug", since = "1.7.0")] impl<T> fmt::Debug for Sender<T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "Sender {{ .. }}") } } </ins> //////////////////////////////////////////////////////////////////////////////// // SyncSender ////////////////////////////////////////////////////////////////////////////////


Question:
All public types should implement Debug. Per conversation on #rust-internals, there might be some useful information that could be printed for these types -- but even just "Sender { .. }" etc. would be a start.
Was this
probably. It has been suggested that way more useful info could actually be printed instead of the opaque placeholders -- but that would be more of a wishlist item than a bug... The patch is sufficient to fix the actual problem I was running into: not being able to #[derive(Debug)] on any structure containing mpsc Senders/Receivers.
Ok, closing.

} } <ins> #[stable(feature = "mpsc_debug", since = "1.7.0")] impl<T> fmt::Debug for SyncSender<T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "SyncSender {{ .. }}") } } </ins> //////////////////////////////////////////////////////////////////////////////// // Receiver ////////////////////////////////////////////////////////////////////////////////


Question:
All public types should implement Debug. Per conversation on #rust-internals, there might be some useful information that could be printed for these types -- but even just "Sender { .. }" etc. would be a start.
Was this
probably. It has been suggested that way more useful info could actually be printed instead of the opaque placeholders -- but that would be more of a wishlist item than a bug... The patch is sufficient to fix the actual problem I was running into: not being able to #[derive(Debug)] on any structure containing mpsc Senders/Receivers.
Ok, closing.

} } <ins> #[stable(feature = "mpsc_debug", since = "1.7.0")] impl<T> fmt::Debug for Receiver<T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "Receiver {{ .. }}") } } </ins> #[stable(feature = "rust1", since = "1.0.0")] impl<T> fmt::Debug for SendError<T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {


Question:
All public types should implement Debug. Per conversation on #rust-internals, there might be some useful information that could be printed for these types -- but even just "Sender { .. }" etc. would be a start.
Was this
probably. It has been suggested that way more useful info could actually be printed instead of the opaque placeholders -- but that would be more of a wishlist item than a bug... The patch is sufficient to fix the actual problem I was running into: not being able to #[derive(Debug)] on any structure containing mpsc Senders/Receivers.
Ok, closing.

repro() } } <ins> #[test] fn fmt_debug_sender() { let (tx, _) = channel::<i32>(); assert_eq!(format!("{:?}", tx), "Sender { .. }"); } #[test] fn fmt_debug_recv() { let (_, rx) = channel::<i32>(); assert_eq!(format!("{:?}", rx), "Receiver { .. }"); } #[test] fn fmt_debug_sync_sender() { let (tx, _) = sync_channel::<i32>(1); assert_eq!(format!("{:?}", tx), "SyncSender { .. }"); } </ins> }


Question:
All public types should implement Debug. Per conversation on #rust-internals, there might be some useful information that could be printed for these types -- but even just "Sender { .. }" etc. would be a start.
Was this
probably. It has been suggested that way more useful info could actually be printed instead of the opaque placeholders -- but that would be more of a wishlist item than a bug... The patch is sufficient to fix the actual problem I was running into: not being able to #[derive(Debug)] on any structure containing mpsc Senders/Receivers.
Ok, closing.

issue = "27800")] <ins> use fmt; </ins> use core::cell::{Cell, UnsafeCell}; use core::marker; use core::ptr;


Question:
All public types should implement Debug. Per conversation on #rust-internals, there might be some useful information that could be printed for these types -- but even just "Sender { .. }" etc. would be a start.
Was this
probably. It has been suggested that way more useful info could actually be printed instead of the opaque placeholders -- but that would be more of a wishlist item than a bug... The patch is sufficient to fix the actual problem I was running into: not being able to #[derive(Debug)] on any structure containing mpsc Senders/Receivers.
Ok, closing.

} } <ins> #[stable(feature = "mpsc_debug", since = "1.7.0")] impl fmt::Debug for Select { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "Select {{ .. }}") } } #[stable(feature = "mpsc_debug", since = "1.7.0")] impl<'rx, T:Send+'rx> fmt::Debug for Handle<'rx, T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "Handle {{ .. }}") } } </ins> #[cfg(test)] #[allow(unused_imports)] mod tests {


Question:
All public types should implement Debug. Per conversation on #rust-internals, there might be some useful information that could be printed for these types -- but even just "Sender { .. }" etc. would be a start.
Was this
probably. It has been suggested that way more useful info could actually be printed instead of the opaque placeholders -- but that would be more of a wishlist item than a bug... The patch is sufficient to fix the actual problem I was running into: not being able to #[derive(Debug)] on any structure containing mpsc Senders/Receivers.
Ok, closing.

} } } <ins> #[test] fn fmt_debug_select() { let sel = Select::new(); assert_eq!(format!("{:?}", sel), "Select { .. }"); } #[test] fn fmt_debug_handle() { let (_, rx) = channel::<i32>(); let sel = Select::new(); let mut handle = sel.handle(&rx); assert_eq!(format!("{:?}", handle), "Handle { .. }"); } </ins> }


Question: Code like the following one generates some unnecessary LLVM IR. Namely: We should skip zero-sized fields in .

operand: OperandRef<'tcx>) { debug!("store_operand: operand={}", operand.repr(bcx)); <ins> // Avoid generating stores of zero-sized values, because the only way to have a zero-sized // value is through `undef`, and store itself is useless. if common::type_is_zero_size(bcx.ccx(), operand.ty) { return; } </ins> match operand.val { OperandValue::Ref(r) => base::memcpy_ty(bcx, lldest, r, operand.ty), OperandValue::Immediate(s) => base::store_ty(bcx, s, lldest, operand.ty),


Question: Code like the following one generates some unnecessary LLVM IR. Namely: We should skip zero-sized fields in .

}, _ => { for (i, operand) in operands.iter().enumerate() { <del> // Note: perhaps this should be StructGep, but // note that in some cases the values here will // not be structs but arrays. let lldest_i = build::GEPi(bcx, dest.llval, &[0, i]); self.trans_operand_into(bcx, lldest_i, operand); </del> <ins> let op = self.trans_operand(bcx, operand); // Do not generate stores and GEPis for zero-sized fields. if !common::type_is_zero_size(bcx.ccx(), op.ty) { // Note: perhaps this should be StructGep, but // note that in some cases the values here will // not be structs but arrays. let dest = build::GEPi(bcx, dest.llval, &[0, i]); self.store_operand(bcx, dest, op); } </ins> } } }


Question: Code like the following one generates some unnecessary LLVM IR. Namely: We should skip zero-sized fields in .

<ins> // Copyright 2016 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. // compile-flags: -C no-prepopulate-passes #![feature(rustc_attrs)] #![crate_type = "lib"] use std::marker::PhantomData; struct Zst { phantom: PhantomData<Zst> } // CHECK-LABEL: @mir #[no_mangle] #[rustc_mir] fn mir(){ // CHECK-NOT: getelementptr // CHECK-NOT: store{{.*}}undef let x = Zst { phantom: PhantomData }; } </ins>


Question:
As , if one of the stdio handles for a Windows process is unset (e.g. isn't present) then you won't actually be able to spawn a process by default. All handles are set, by default, to "inherit", but duplicate the existing handle, which in turn means that if the stdio handle isn't present this operation will fail. Rust currently by always opening up handles even if is specified (just pointing them to a blank stream), but Rust should also defend against this situation when it was spawned from elsewhere.
cc

impl<R: io::Read> io::Read for Maybe<R> { fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { match *self { <del> Maybe::Real(ref mut r) => handle_ebadf(r.read(buf), buf.len()), </del> <ins> Maybe::Real(ref mut r) => handle_ebadf(r.read(buf), 0), </ins> Maybe::Fake => Ok(0) } }


Question:
As , if one of the stdio handles for a Windows process is unset (e.g. isn't present) then you won't actually be able to spawn a process by default. All handles are set, by default, to "inherit", but duplicate the existing handle, which in turn means that if the stdio handle isn't present this operation will fail. Rust currently by always opening up handles even if is specified (just pointing them to a blank stream), but Rust should also defend against this situation when it was spawned from elsewhere.
cc

impl Stdio { fn to_handle(&self, stdio_id: c::DWORD) -> io::Result<Handle> { match *self { <ins> // If no stdio handle is available, then inherit means that it // should still be unavailable so propagate the // INVALID_HANDLE_VALUE. </ins> Stdio::Inherit => { <del> stdio::get(stdio_id).and_then(|io| { io.handle().duplicate(0, true, c::DUPLICATE_SAME_ACCESS) }) </del> <ins> match stdio::get(stdio_id) { Ok(io) => io.handle().duplicate(0, true, c::DUPLICATE_SAME_ACCESS), Err(..) => Ok(Handle::new(c::INVALID_HANDLE_VALUE)), } </ins> } Stdio::Raw(handle) => { RawHandle::new(handle).duplicate(0, true, c::DUPLICATE_SAME_ACCESS)


Question:
As , if one of the stdio handles for a Windows process is unset (e.g. isn't present) then you won't actually be able to spawn a process by default. All handles are set, by default, to "inherit", but duplicate the existing handle, which in turn means that if the stdio handle isn't present this operation will fail. Rust currently by always opening up handles even if is specified (just pointing them to a blank stream), but Rust should also defend against this situation when it was spawned from elsewhere.
cc

<ins> // Copyright 2016 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. #![feature(libc)] extern crate libc; use std::process::{Command, Stdio}; use std::env; use std::io::{self, Read, Write}; #[cfg(unix)] unsafe fn without_stdio<R, F: FnOnce() -> R>(f: F) -> R { let doit = |a| { let r = libc::dup(a); assert!(r >= 0); return r }; let a = doit(0); let b = doit(1); let c = doit(2); assert!(libc::close(0) >= 0); assert!(libc::close(1) >= 0); assert!(libc::close(2) >= 0); let r = f(); assert!(libc::dup2(a, 0) >= 0); assert!(libc::dup2(b, 1) >= 0); assert!(libc::dup2(c, 2) >= 0); return r } #[cfg(windows)] unsafe fn without_stdio<R, F: FnOnce() -> R>(f: F) -> R { type DWORD = u32; type HANDLE = *mut u8; type BOOL = i32; const STD_INPUT_HANDLE: DWORD = -10i32 as DWORD; const STD_OUTPUT_HANDLE: DWORD = -11i32 as DWORD; const STD_ERROR_HANDLE: DWORD = -12i32 as DWORD; const INVALID_HANDLE_VALUE: HANDLE = !0 as HANDLE; extern "system" { fn GetStdHandle(which: DWORD) -> HANDLE; fn SetStdHandle(which: DWORD, handle: HANDLE) -> BOOL; } let doit = |id| { let handle = GetStdHandle(id); assert!(handle != INVALID_HANDLE_VALUE); assert!(SetStdHandle(id, INVALID_HANDLE_VALUE) != 0); return handle }; let a = doit(STD_INPUT_HANDLE); let b = doit(STD_OUTPUT_HANDLE); let c = doit(STD_ERROR_HANDLE); let r = f(); let doit = |id, handle| { assert!(SetStdHandle(id, handle) != 0); }; doit(STD_INPUT_HANDLE, a); doit(STD_OUTPUT_HANDLE, b); doit(STD_ERROR_HANDLE, c); return r } fn main() { if env::args().len() > 1 { println!("test"); assert!(io::stdout().write(b"testn").is_ok()); assert!(io::stderr().write(b"testn").is_ok()); assert_eq!(io::stdin().read(&mut [0; 10]).unwrap(), 0); return } // First, make sure reads/writes without stdio work if stdio itself is // missing. let (a, b, c) = unsafe { without_stdio(|| { let a = io::stdout().write(b"testn"); let b = io::stderr().write(b"testn"); let c = io::stdin().read(&mut [0; 10]); (a, b, c) }) }; assert_eq!(a.unwrap(), 5); assert_eq!(b.unwrap(), 5); assert_eq!(c.unwrap(), 0); // Second, spawn a child and do some work with "null" descriptors to make // sure it's ok let me = env::current_exe().unwrap(); let status = Command::new(&me) .arg("next") .stdin(Stdio::null()) .stdout(Stdio::null()) .stderr(Stdio::null()) .status().unwrap(); assert!(status.success(), "{:?} isn't a success", status); // Finally, close everything then spawn a child to make sure everything is // *still* ok. let status = unsafe { without_stdio(|| Command::new(&me).arg("next").status()) }.unwrap(); assert!(status.success(), "{:?} isn't a success", status); } </ins>


Question: I am following the Book in the Getting Started chapter, try my first rustc and get the error: The manual should at least mention the need for a C compiler (or at least a linker) as a dependency if you are using to install the binaries.

repair, or remove installation" page and ensure "Add to PATH" is installed on the local hard drive. <ins> Rust does not do its own linking, and so you’ll need to have a linker installed. Doing so will depend on your specific system, consult its documentation for more details. </ins> If not, there are a number of places where we can get help. The easiest is [the #rust IRC channel on irc.mozilla.org][irc], which we can access through [Mibbit][mibbit]. Click that link, and we'll be chatting with other Rustaceans


Question:
Brand new to Rust so I apologize if this is not the right place for something like this. I just finished "The Guessing Game" and noticed a small typo: We can do that with three more lines. Here’s our new program: The new three lines: It appears the book was updated at some point to only contain two lines. Similarly. in the following section. this could be a typo or possibly just confusing: If we leave off calling these two methods, our program will compile, but we’ll get a warning: The two methods could refer to .expect and panic!.
Nope, this is a typo. There used to be calls to in there, and they were removed, but the English wasn't.

[expect]: ../std/option/enum.Option.html#method.expect [panic]: error-handling.html <del> If we leave off calling these two methods, our program will compile, but </del> <ins> If we leave off calling this method, our program will compile, but </ins> we’ll get a warning: ```bash


Question:
Brand new to Rust so I apologize if this is not the right place for something like this. I just finished "The Guessing Game" and noticed a small typo: We can do that with three more lines. Here’s our new program: The new three lines: It appears the book was updated at some point to only contain two lines. Similarly. in the following section. this could be a typo or possibly just confusing: If we leave off calling these two methods, our program will compile, but we’ll get a warning: The two methods could refer to .expect and panic!.
Nope, this is a typo. There used to be calls to in there, and they were removed, but the English wasn't.

} ``` <del> The new three lines: </del> <ins> The new two lines: </ins> ```rust,ignore let guess: u32 = guess.trim().parse()


Question:
The method on iterators consumes the first falsy value, instead of leaving it in the iterator. This behavior seems unintuitive to me; and I could not find any documentation of this functionality. Due to this (I think) being a breaking change, it's probably not worth changing the functionality, but documenting this is probably a good idea. I tried code: I expected to see this output: Instead, this I saw this output: : I believe this also occurs on stable (tested in ).
Not only would it be a breaking change, but it is impossible for a general iterator: the only way to tell if needs to stop or not is to get the element out of the iterator with , and there's no way to uncall /push an element back on to the end. (E.g. consider something like : once the message has been received and yielded, it is gone.)
For people reaching here and seeking a way to do this currently, provides a that will leave the last element in the iterator, but at the cost of cloning the entire iterator every iteration.
Well, maybe we can put the first falsy value to inside and add an accessor to it...
The cost of cloning an iterator is totally depedent on which iterator it is. A slice iterator is implemented using two pointers, so the cloning amounts to storing two pointers during the iteration. When the whole iteration is inlined, and llvm breaking the structs down to their members, it should be able to remove the store of the pointer that doesn't change (the end), so the overhead is down to storing and restoring one pointer.
is a nice hack, but it should be complemented by either adaptors on Peekable and/or itertools' PutBack.

/// // got a false, take_while() isn't used any more /// assert_eq!(iter.next(), None); /// ``` <ins> /// /// Because `take_while()` needs to look at the value in order to see if it /// should be included or not, consuming iterators will see that it is /// removed: /// /// ``` /// let a = [1, 2, 3, 4]; /// let mut iter = a.into_iter(); /// /// let result: Vec<i32> = iter.by_ref() ///                            .take_while(|n| **n != 3) ///                            .cloned() ///                            .collect(); /// /// assert_eq!(result, &[1, 2]); /// /// let result: Vec<i32> = iter.cloned().collect(); /// /// assert_eq!(result, &[4]); /// ``` /// /// The `3` is no longer there, because it was consumed in order to see if /// the iteration should stop, but wasn't placed back into the iterator or /// some similar thing. </ins> #[inline] #[stable(feature = "rust1", since = "1.0.0")] fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P> where


Question:
For clippy's lint, I made use of a so I could stop clippy from linting the same macro multiple times while being reasonably fast. However, this unfortunately means the lint ignores .. attributes below the crate level. To solve this and other related problems, I propose any of allow a lint to check anything from anywhere in the analysis by moving up the parent chain to check the level allow a lint to opt out of calls for the duration of a specific node including its child nodes add methods to the {Early, Late}LintPass trait, so lints can decide themselves The third option is probably the easiest to implement, yet the most flexible. This would bring the trait closer to other stream parser implementations like SAX.
Seeing that we already have a few, _post methods, I think adding some more will be an acceptable solution here. I'll have a PR shortly.

run_lints!(cx, check_item, late_passes, it); cx.visit_ids(|v| v.visit_item(it)); hir_visit::walk_item(cx, it); <ins> run_lints!(cx, check_item_post, late_passes, it); </ins> }) }


Question:
For clippy's lint, I made use of a so I could stop clippy from linting the same macro multiple times while being reasonably fast. However, this unfortunately means the lint ignores .. attributes below the crate level. To solve this and other related problems, I propose any of allow a lint to check anything from anywhere in the analysis by moving up the parent chain to check the level allow a lint to opt out of calls for the duration of a specific node including its child nodes add methods to the {Early, Late}LintPass trait, so lints can decide themselves The third option is probably the easiest to implement, yet the most flexible. This would bring the trait closer to other stream parser implementations like SAX.
Seeing that we already have a few, _post methods, I think adding some more will be an acceptable solution here. I'll have a PR shortly.

fn visit_block(&mut self, b: &hir::Block) { run_lints!(self, check_block, late_passes, b); hir_visit::walk_block(self, b); <ins> run_lints!(self, check_block_post, late_passes, b); </ins> } fn visit_arm(&mut self, a: &hir::Arm) {


Question:
For clippy's lint, I made use of a so I could stop clippy from linting the same macro multiple times while being reasonably fast. However, this unfortunately means the lint ignores .. attributes below the crate level. To solve this and other related problems, I propose any of allow a lint to check anything from anywhere in the analysis by moving up the parent chain to check the level allow a lint to opt out of calls for the duration of a specific node including its child nodes add methods to the {Early, Late}LintPass trait, so lints can decide themselves The third option is probably the easiest to implement, yet the most flexible. This would bring the trait closer to other stream parser implementations like SAX.
Seeing that we already have a few, _post methods, I think adding some more will be an acceptable solution here. I'll have a PR shortly.

run_lints!(cx, check_item, early_passes, it); cx.visit_ids(|v| v.visit_item(it)); ast_visit::walk_item(cx, it); <ins> run_lints!(cx, check_item_post, early_passes, it); </ins> }) }


Question:
For clippy's lint, I made use of a so I could stop clippy from linting the same macro multiple times while being reasonably fast. However, this unfortunately means the lint ignores .. attributes below the crate level. To solve this and other related problems, I propose any of allow a lint to check anything from anywhere in the analysis by moving up the parent chain to check the level allow a lint to opt out of calls for the duration of a specific node including its child nodes add methods to the {Early, Late}LintPass trait, so lints can decide themselves The third option is probably the easiest to implement, yet the most flexible. This would bring the trait closer to other stream parser implementations like SAX.
Seeing that we already have a few, _post methods, I think adding some more will be an acceptable solution here. I'll have a PR shortly.

fn visit_block(&mut self, b: &ast::Block) { run_lints!(self, check_block, early_passes, b); ast_visit::walk_block(self, b); <ins> run_lints!(self, check_block_post, early_passes, b); </ins> } fn visit_arm(&mut self, a: &ast::Arm) {


Question:
For clippy's lint, I made use of a so I could stop clippy from linting the same macro multiple times while being reasonably fast. However, this unfortunately means the lint ignores .. attributes below the crate level. To solve this and other related problems, I propose any of allow a lint to check anything from anywhere in the analysis by moving up the parent chain to check the level allow a lint to opt out of calls for the duration of a specific node including its child nodes add methods to the {Early, Late}LintPass trait, so lints can decide themselves The third option is probably the easiest to implement, yet the most flexible. This would bring the trait closer to other stream parser implementations like SAX.
Seeing that we already have a few, _post methods, I think adding some more will be an acceptable solution here. I'll have a PR shortly.

run_lints!(cx, check_crate, late_passes, krate); hir_visit::walk_crate(cx, krate); <ins> run_lints!(cx, check_crate_post, late_passes, krate); </ins> }); // If we missed any lints added to the session, then there's a bug somewhere


Question:
For clippy's lint, I made use of a so I could stop clippy from linting the same macro multiple times while being reasonably fast. However, this unfortunately means the lint ignores .. attributes below the crate level. To solve this and other related problems, I propose any of allow a lint to check anything from anywhere in the analysis by moving up the parent chain to check the level allow a lint to opt out of calls for the duration of a specific node including its child nodes add methods to the {Early, Late}LintPass trait, so lints can decide themselves The third option is probably the easiest to implement, yet the most flexible. This would bring the trait closer to other stream parser implementations like SAX.
Seeing that we already have a few, _post methods, I think adding some more will be an acceptable solution here. I'll have a PR shortly.

run_lints!(cx, check_crate, early_passes, krate); ast_visit::walk_crate(cx, krate); <ins> run_lints!(cx, check_crate_post, early_passes, krate); </ins> }); // Put the lint store back in the session.


Question:
For clippy's lint, I made use of a so I could stop clippy from linting the same macro multiple times while being reasonably fast. However, this unfortunately means the lint ignores .. attributes below the crate level. To solve this and other related problems, I propose any of allow a lint to check anything from anywhere in the analysis by moving up the parent chain to check the level allow a lint to opt out of calls for the duration of a specific node including its child nodes add methods to the {Early, Late}LintPass trait, so lints can decide themselves The third option is probably the easiest to implement, yet the most flexible. This would bring the trait closer to other stream parser implementations like SAX.
Seeing that we already have a few, _post methods, I think adding some more will be an acceptable solution here. I'll have a PR shortly.

pub trait LateLintPass: LintPass { fn check_name(&mut self, _: &LateContext, _: Span, _: ast::Name) { } fn check_crate(&mut self, _: &LateContext, _: &hir::Crate) { } <ins> fn check_crate_post(&mut self, _: &LateContext, _: &hir::Crate) { } </ins> fn check_mod(&mut self, _: &LateContext, _: &hir::Mod, _: Span, _: ast::NodeId) { } fn check_foreign_item(&mut self, _: &LateContext, _: &hir::ForeignItem) { } fn check_item(&mut self, _: &LateContext, _: &hir::Item) { } <ins> fn check_item_post(&mut self, _: &LateContext, _: &hir::Item) { } </ins> fn check_local(&mut self, _: &LateContext, _: &hir::Local) { } fn check_block(&mut self, _: &LateContext, _: &hir::Block) { } <ins> fn check_block_post(&mut self, _: &LateContext, _: &hir::Block) { } </ins> fn check_stmt(&mut self, _: &LateContext, _: &hir::Stmt) { } fn check_arm(&mut self, _: &LateContext, _: &hir::Arm) { } fn check_pat(&mut self, _: &LateContext, _: &hir::Pat) { }


Question:
For clippy's lint, I made use of a so I could stop clippy from linting the same macro multiple times while being reasonably fast. However, this unfortunately means the lint ignores .. attributes below the crate level. To solve this and other related problems, I propose any of allow a lint to check anything from anywhere in the analysis by moving up the parent chain to check the level allow a lint to opt out of calls for the duration of a specific node including its child nodes add methods to the {Early, Late}LintPass trait, so lints can decide themselves The third option is probably the easiest to implement, yet the most flexible. This would bring the trait closer to other stream parser implementations like SAX.
Seeing that we already have a few, _post methods, I think adding some more will be an acceptable solution here. I'll have a PR shortly.

pub trait EarlyLintPass: LintPass { fn check_ident(&mut self, _: &EarlyContext, _: Span, _: ast::Ident) { } fn check_crate(&mut self, _: &EarlyContext, _: &ast::Crate) { } <ins> fn check_crate_post(&mut self, _: &EarlyContext, _: &ast::Crate) { } </ins> fn check_mod(&mut self, _: &EarlyContext, _: &ast::Mod, _: Span, _: ast::NodeId) { } fn check_foreign_item(&mut self, _: &EarlyContext, _: &ast::ForeignItem) { } fn check_item(&mut self, _: &EarlyContext, _: &ast::Item) { } <ins> fn check_item_post(&mut self, _: &EarlyContext, _: &ast::Item) { } </ins> fn check_local(&mut self, _: &EarlyContext, _: &ast::Local) { } fn check_block(&mut self, _: &EarlyContext, _: &ast::Block) { } <ins> fn check_block_post(&mut self, _: &EarlyContext, _: &ast::Block) { } </ins> fn check_stmt(&mut self, _: &EarlyContext, _: &ast::Stmt) { } fn check_arm(&mut self, _: &EarlyContext, _: &ast::Arm) { } fn check_pat(&mut self, _: &EarlyContext, _: &ast::Pat) { }


Question:
The documentation of the unstable function makes a reference to , but this function does not exist (anymore?). Expressing the semantics of in terms of something that does not exist is unhelpful. The problem seems to be located . I imagine the fix would involve traveling back in time until before was removed and copying its documentation, after correcting for the differences between it and the function.
Filling drop is a temporary "feature" of rust, and in the long run this function will not be needed once the in-struct drop flags are gone. In anticipation of this improvement, it would be best to not write any code that relies on readanddrop. Edit: Well maybe that's exactly what to have in the docs..
I'm not using that function, I was merely browsing the docs and noticed the documentation was wrong. I would expect the documentation of functions to be correct even if they are unstable and scheduled for removal, unless the removal is scheduled for the immediate future.

tmp } <del> /// Variant of read_and_zero that writes the specific drop-flag byte /// (which may be more appropriate than zero). </del> <ins> #[allow(missing_docs)] </ins> #[inline(always)] #[unstable(feature = "filling_drop", reason = "may play a larger role in std::ptr future extensions",


Question:
In a few places in there are casts from to or for Windows APIs which causes breakage on 64-bit. Some examples I have found so far: () () (rust-lang-nursery/rand, ) There may be more.
Well I didn't find any more so I'll close this.

use prelude::v1::*; <ins> use cmp; </ins> use ffi::{CStr, CString}; use fmt; use io::{self, Error, ErrorKind};


Question:
In a few places in there are casts from to or for Windows APIs which causes breakage on 64-bit. Some examples I have found so far: () () (rust-lang-nursery/rand, ) There may be more.
Well I didn't find any more so I'll close this.

} pub fn write(&self, buf: &[u8]) -> io::Result<usize> { <ins> let len = cmp::min(buf.len(), <wrlen_t>::max_value() as usize) as wrlen_t; </ins> let ret = try!(cvt(unsafe { c::send(*self.inner.as_inner(), buf.as_ptr() as *const c_void, <del> buf.len() as wrlen_t, </del> <ins> len, </ins> 0) })); Ok(ret as usize)


Question:
In a few places in there are casts from to or for Windows APIs which causes breakage on 64-bit. Some examples I have found so far: () () (rust-lang-nursery/rand, ) There may be more.
Well I didn't find any more so I'll close this.

pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> { let mut storage: c::sockaddr_storage = unsafe { mem::zeroed() }; let mut addrlen = mem::size_of_val(&storage) as c::socklen_t; <ins> let len = cmp::min(buf.len(), <wrlen_t>::max_value() as usize) as wrlen_t; </ins> let n = try!(cvt(unsafe { c::recvfrom(*self.inner.as_inner(), buf.as_mut_ptr() as *mut c_void, <del> buf.len() as wrlen_t, 0, </del> <ins> len, 0, </ins> &mut storage as *mut _ as *mut _, &mut addrlen) })); Ok((n as usize, try!(sockaddr_to_addr(&storage, addrlen as usize)))) } pub fn send_to(&self, buf: &[u8], dst: &SocketAddr) -> io::Result<usize> { <ins> let len = cmp::min(buf.len(), <wrlen_t>::max_value() as usize) as wrlen_t; </ins> let (dstp, dstlen) = dst.into_inner(); let ret = try!(cvt(unsafe { c::sendto(*self.inner.as_inner(), <del> buf.as_ptr() as *const c_void, buf.len() as wrlen_t, </del> <ins> buf.as_ptr() as *const c_void, len, </ins> 0, dstp, dstlen) })); Ok(ret as usize)


Question:
In a few places in there are casts from to or for Windows APIs which causes breakage on 64-bit. Some examples I have found so far: () () (rust-lang-nursery/rand, ) There may be more.
Well I didn't find any more so I'll close this.

// option. This file may not be copied, modified, or distributed // except according to those terms. <ins> use cmp; </ins> use io; use libc::{c_int, c_void}; use mem;


Question:
In a few places in there are casts from to or for Windows APIs which causes breakage on 64-bit. Some examples I have found so far: () () (rust-lang-nursery/rand, ) There may be more.
Well I didn't find any more so I'll close this.

pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> { // On unix when a socket is shut down all further reads return 0, so we // do the same on windows to map a shut down socket to returning EOF. <ins> let len = cmp::min(buf.len(), i32::max_value() as usize) as i32; </ins> unsafe { <del> match c::recv(self.0, buf.as_mut_ptr() as *mut c_void, buf.len() as i32, 0) { </del> <ins> match c::recv(self.0, buf.as_mut_ptr() as *mut c_void, len, 0) { </ins> -1 if c::WSAGetLastError() == c::WSAESHUTDOWN => Ok(0), -1 => Err(last_error()), n => Ok(n as usize)


Question:
Travis-CI build failed, my local builds with a slightly older rustc nightly works just fine. This is the repository in question and the Travis-CI build log: Repo: Travis-CI Log: rustc only seems to fail when compiling my crate: Could be related to , a way older and closed issue. (rustc 0.13.0-dev) Backtrace:
cc
Related: arcnmx/cargo-clippy/issues/19

// Define the name or return the existing binding if there is a collision. pub fn try_define_child(&self, name: Name, ns: Namespace, binding: NameBinding<'a>) -> Result<(), &'a NameBinding<'a>> { <del> if self.resolutions.borrow_state() != ::std::cell::BorrowState::Unused { return Ok(()); } </del> self.update_resolution(name, ns, |resolution| { resolution.try_define(self.arenas.alloc_name_binding(binding)) })


Question:
Travis-CI build failed, my local builds with a slightly older rustc nightly works just fine. This is the repository in question and the Travis-CI build log: Repo: Travis-CI Log: rustc only seems to fail when compiling my crate: Could be related to , a way older and closed issue. (rustc 0.13.0-dev) Backtrace:
cc
Related: arcnmx/cargo-clippy/issues/19

fn update_resolution<T, F>(&self, name: Name, ns: Namespace, update: F) -> T where F: FnOnce(&mut NameResolution<'a>) -> T { <del> let mut resolution = &mut *self.resolution(name, ns).borrow_mut(); let was_known = resolution.binding().is_some(); let t = update(resolution); if !was_known { if let Some(binding) = resolution.binding() { self.define_in_glob_importers(name, ns, binding); </del> <ins> // Ensure that `resolution` isn't borrowed during `define_in_glob_importers`, // where it might end up getting re-defined via a glob cycle. let (new_binding, t) = { let mut resolution = &mut *self.resolution(name, ns).borrow_mut(); let was_known = resolution.binding().is_some(); let t = update(resolution); if was_known { return t; } match resolution.binding() { Some(binding) => (binding, t), None => return t, </ins> } <del> } </del> <ins> }; self.define_in_glob_importers(name, ns, new_binding); </ins> t }


Question:
Travis-CI build failed, my local builds with a slightly older rustc nightly works just fine. This is the repository in question and the Travis-CI build log: Repo: Travis-CI Log: rustc only seems to fail when compiling my crate: Could be related to , a way older and closed issue. (rustc 0.13.0-dev) Backtrace:
cc
Related: arcnmx/cargo-clippy/issues/19

// Add to target_module's glob_importers target_module.glob_importers.borrow_mut().push((module_, directive)); <del> for (&(name, ns), resolution) in target_module.resolutions.borrow().iter() { if let Some(binding) = resolution.borrow().binding() { if binding.defined_with(DefModifiers::IMPORTABLE | DefModifiers::PUBLIC) { let _ = module_.try_define_child(name, ns, directive.import(binding, None)); } </del> <ins> // Ensure that `resolutions` isn't borrowed during `try_define_child`, // since it might get updated via a glob cycle. let bindings = target_module.resolutions.borrow().iter().filter_map(|(name, resolution)| { resolution.borrow().binding().map(|binding| (*name, binding)) }).collect::<Vec<_>>(); for ((name, ns), binding) in bindings { if binding.defined_with(DefModifiers::IMPORTABLE | DefModifiers::PUBLIC) { let _ = module_.try_define_child(name, ns, directive.import(binding, None)); </ins> } }


Question:
Travis-CI build failed, my local builds with a slightly older rustc nightly works just fine. This is the repository in question and the Travis-CI build log: Repo: Travis-CI Log: rustc only seems to fail when compiling my crate: Could be related to , a way older and closed issue. (rustc 0.13.0-dev) Backtrace:
cc
Related: arcnmx/cargo-clippy/issues/19

<ins> // Copyright 2016 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. mod foo { pub use bar::*; pub use main as f; //~ ERROR has already been imported } mod bar { pub use foo::*; } pub use foo::*; pub use baz::*; //~ ERROR has already been imported mod baz { pub use super::*; } pub fn main() {} </ins>


Question:
Travis-CI build failed, my local builds with a slightly older rustc nightly works just fine. This is the repository in question and the Travis-CI build log: Repo: Travis-CI Log: rustc only seems to fail when compiling my crate: Could be related to , a way older and closed issue. (rustc 0.13.0-dev) Backtrace:
cc
Related: arcnmx/cargo-clippy/issues/19

<ins> // Copyright 2016 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. pub use bar::*; mod bar { pub use super::*; } pub use baz::*; //~ ERROR already been imported mod baz { pub use main as f; } pub fn main() {} </ins>


Question:
:
Triage: still an issue.
I just hit this, though the error is a bit different now: "resolving bounds after type-checking" rather than "fulfilling during trans". error: internal compiler error: Encountered errors resolving bounds after type-checking note: the compiler unexpectedly panicked. this is a bug. note: we would appreciate a bug report: note: run with for a backtrace thread 'rustc' panicked at 'Box<Any', stack backtrace: 1: 0x7f91a71b237a - std::sys::imp::backtrace::tracing::imp::write::h944c02ac40aee2d7 at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 2: 0x7f91a71c122f - std::panicking::defaulthook::{{closure}}::h6875a2976258b020 at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 3: 0x7f91a71c0dcd - std::panicking::defaulthook::h88ffbc5922643264 at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 4: 0x7f91a71c16d7 - std::panicking::rustpanicwithhook::ha5aed1dfc0e220e3 at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 5: 0x7f91a67fae4b - std::panicking::beginpanic::h264cdc75d51b518b at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 6: 0x7f91a6817d93 - rustc::session::optspanbugfmt::{{closure}}::h4a9b70c3df8b4b3a at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/<panic macros:3 at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 7: 0x7f91a6817bb6 - rustc::session::spanbugfmt::h0c5d2225aa96fe42 at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 8: 0x7f91a688fc77 - rustctrans::common::fulfillobligation::{{closure}}::{{closure}}::hf13a4d09f7cbb18e at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 9: 0x7f91a688c0dc - rustctrans::common::fulfillobligation::h6bfd7b7f15728b60 at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 10: 0x7f91a6887278 - rustctrans::collector::dostaticdispatch::h9456c98c4201c352 at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 11: 0x7f91a68868aa - <rustctrans::collector::MirNeighborCollector<'a, 'tcxas rustc::mir::visit::Visitor<'tcx::visitoperand::h7428e8287ff72240 at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 12: 0x7f91a6886fe6 - <rustctrans::collector::MirNeighborCollector<'a, 'tcxas rustc::mir::visit::Visitor<'tcx::visitterminatorkind::h8233aed64e4688ea at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 13: 0x7f91a6813387 - rustc::mir::visit::Visitor::visitmir::hc23b408d887d8c09 at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 14: 0x7f91a688524c - rustctrans::collector::collectitemsrec::h9535e33b3068eb29 at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 15: 0x7f91a68858ff - rustctrans::collector::collectitemsrec::h9535e33b3068eb29 at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 16: 0x7f91a686f200 - rustctrans::base::collectandpartitiontranslationitems::{{closure}}::h9f2b052ae16b5f0b at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 17: 0x7f91a686b59f - rustctrans::base::collectandpartitiontranslationitems::h6a325f48a6efa8c7 at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 18: 0x7f91a685ddca - rustctrans::base::transcrate::h6e0b0bf1b66798ce at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 19: 0x7f91a7571401 - rustcdriver::driver::phase4translatetollvm::h48ed91c172294403 at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 20: 0x7f91a7541c36 - rustcdriver::driver::compileinput::{{closure}}::hf13172fc4e5a2f4d at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 21: 0x7f91a755f503 - rustcdriver::driver::phase3runanalysispasses::{{closure}}::h97a3a12d948df547 at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 22: 0x7f91a7558833 - rustcdriver::driver::phase3runanalysispasses::hb0ad9de18d423e67 at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 23: 0x7f91a753fb77 - rustcdriver::driver::compileinput::h8e119234b60571d5 at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 24: 0x7f91a7585cd8 - rustcdriver::runcompiler::hbdfc4f84e2e0f4b9 at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 25: 0x7f91a74a1158 - std::panicking::try::docall::hf679f17bf3b43b0b at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 26: 0x7f91a71cbc1a - _rustmaybecatchpanic at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 27: 0x7f91a74c31b8 - <F as alloc::boxed::FnBox<A::callbox::h506fb5d7b8891cd4 at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 28: 0x7f91a71c0094 - std::sys::imp::thread::Thread::new::threadstart::h8084b1107992ae5b at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 29: 0x7f919f3f5709 - start_thread 30: 0x7f91a6e7a82c - clone 31: 0x0 - <unknown
ping how is this unsound?
Given that has seen fit to tag this as a soundness bug I'm nominating it so that it can receive a priority assessment, though I'll second ubsan in asking for a demonstration of the unsoundness here.
In general, having trait bounds that are not checked can lead to unsoundness, since some part of the code will assume that they hold when in fact they do not (consider, e.g., what might happen if the bound were ).
I'm going to mark this as P-medium and tag it from the specialization issue (it is specific to specialization, right?)
triage: P-medium
The code in the OP compiles for me with the latest nightly Rust (1.29.0-nightly ( 2018-08-01)). However, the following still fails (and I assume it's the same issue; if not I can file a new issue): Backtrace:
So I think this is "fixed-by-chalk", but this is fixed-by-chalk in a way that breaks specialization (cc Let's have a more easy-to-understand version of the problem: The problem is the following: our impl needs to prove the where-clause, which in the environment is . holds by (by the impl we are checking), so we can prove that obligation by (which will be a ) that depends on the . Therefore, wfchecking is OK. Therefore, fun. why isn't this a problem every time we have a projection? Normally, rustc normalizes to the real associated type, and then it can't find the , so no problem. With specialization, rustc can't normalize the associated type, so it sees the bug. I can't have a proof for this working, but this seems reasonably likely to work. way that might solve this in the rustc model would be to basically say that for any given trait ref, only the most specialized impl is supposed to be checking the wf requirement (for every trait-ref, there is always a most-specialized impl, so this is OK), and when checking wf, add the associated types for our own impl explicitly to our parameter environment (e.g., add - note no quantification over - to the param env in our example). That will make things normalize and work, and I'm not even sure is particularly ugly. I don't think it is less sound than , but then I don't quite know when is sound. what's going on with Chalk? Last time I saw it, the way we made implied bounds work was to move to the environment - in rustc terms, basically only allow it if we have proven the impl using . This solves the problem, because our impl was proven in a well-formed way, so a will ensure we make progress and there will be no cycles. The reason this does not work in specialization, is that we do want users to be able to prove things like , even while they might not know what is. For that, they need to have a keyed off a . I have no idea how to do this in the Chalk model. Was Chalk changed to do something else by now? Does this have a different interaction with specialization?
A PoC to show the unsoundness of this. It's a use-after free by 'copying' a String: Link to the playground:
This is fixed now: and needs a test

<ins> // Test to ensure that trait bounds are propertly // checked on specializable associated types #![allow(incomplete_features)] #![feature(specialization)] trait UncheckedCopy: Sized { type Output: From<Self> + Copy + Into<Self>; } impl<T> UncheckedCopy for T { default type Output = Self; //~^ ERROR: the trait bound `T: Copy` is not satisfied } fn unchecked_copy<T: UncheckedCopy>(other: &T::Output) -> T { (*other).into() } fn bug(origin: String) { // Turn the String into it's Output type... // Which we can just do by `.into()`, the assoc type states `From<Self>`. let origin_output = origin.into(); // Make a copy of String::Output, which is a String... let mut copy: String = unchecked_copy::<String>(&origin_output); // Turn the Output type into a String again, // Which we can just do by `.into()`, the assoc type states `Into<Self>`. let mut origin: String = origin_output.into(); // assert both Strings use the same buffer. assert_eq!(copy.as_ptr(), origin.as_ptr()); // Any use of the copy we made becomes invalid, drop(origin); // OH NO! UB UB UB UB! copy.push_str(" world!"); println!("{}", copy); } fn main() { bug(String::from("hello")); } </ins>


Question:
:
Triage: still an issue.
I just hit this, though the error is a bit different now: "resolving bounds after type-checking" rather than "fulfilling during trans". error: internal compiler error: Encountered errors resolving bounds after type-checking note: the compiler unexpectedly panicked. this is a bug. note: we would appreciate a bug report: note: run with for a backtrace thread 'rustc' panicked at 'Box<Any', stack backtrace: 1: 0x7f91a71b237a - std::sys::imp::backtrace::tracing::imp::write::h944c02ac40aee2d7 at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 2: 0x7f91a71c122f - std::panicking::defaulthook::{{closure}}::h6875a2976258b020 at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 3: 0x7f91a71c0dcd - std::panicking::defaulthook::h88ffbc5922643264 at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 4: 0x7f91a71c16d7 - std::panicking::rustpanicwithhook::ha5aed1dfc0e220e3 at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 5: 0x7f91a67fae4b - std::panicking::beginpanic::h264cdc75d51b518b at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 6: 0x7f91a6817d93 - rustc::session::optspanbugfmt::{{closure}}::h4a9b70c3df8b4b3a at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/<panic macros:3 at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 7: 0x7f91a6817bb6 - rustc::session::spanbugfmt::h0c5d2225aa96fe42 at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 8: 0x7f91a688fc77 - rustctrans::common::fulfillobligation::{{closure}}::{{closure}}::hf13a4d09f7cbb18e at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 9: 0x7f91a688c0dc - rustctrans::common::fulfillobligation::h6bfd7b7f15728b60 at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 10: 0x7f91a6887278 - rustctrans::collector::dostaticdispatch::h9456c98c4201c352 at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 11: 0x7f91a68868aa - <rustctrans::collector::MirNeighborCollector<'a, 'tcxas rustc::mir::visit::Visitor<'tcx::visitoperand::h7428e8287ff72240 at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 12: 0x7f91a6886fe6 - <rustctrans::collector::MirNeighborCollector<'a, 'tcxas rustc::mir::visit::Visitor<'tcx::visitterminatorkind::h8233aed64e4688ea at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 13: 0x7f91a6813387 - rustc::mir::visit::Visitor::visitmir::hc23b408d887d8c09 at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 14: 0x7f91a688524c - rustctrans::collector::collectitemsrec::h9535e33b3068eb29 at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 15: 0x7f91a68858ff - rustctrans::collector::collectitemsrec::h9535e33b3068eb29 at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 16: 0x7f91a686f200 - rustctrans::base::collectandpartitiontranslationitems::{{closure}}::h9f2b052ae16b5f0b at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 17: 0x7f91a686b59f - rustctrans::base::collectandpartitiontranslationitems::h6a325f48a6efa8c7 at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 18: 0x7f91a685ddca - rustctrans::base::transcrate::h6e0b0bf1b66798ce at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 19: 0x7f91a7571401 - rustcdriver::driver::phase4translatetollvm::h48ed91c172294403 at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 20: 0x7f91a7541c36 - rustcdriver::driver::compileinput::{{closure}}::hf13172fc4e5a2f4d at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 21: 0x7f91a755f503 - rustcdriver::driver::phase3runanalysispasses::{{closure}}::h97a3a12d948df547 at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 22: 0x7f91a7558833 - rustcdriver::driver::phase3runanalysispasses::hb0ad9de18d423e67 at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 23: 0x7f91a753fb77 - rustcdriver::driver::compileinput::h8e119234b60571d5 at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 24: 0x7f91a7585cd8 - rustcdriver::runcompiler::hbdfc4f84e2e0f4b9 at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 25: 0x7f91a74a1158 - std::panicking::try::docall::hf679f17bf3b43b0b at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 26: 0x7f91a71cbc1a - _rustmaybecatchpanic at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 27: 0x7f91a74c31b8 - <F as alloc::boxed::FnBox<A::callbox::h506fb5d7b8891cd4 at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 28: 0x7f91a71c0094 - std::sys::imp::thread::Thread::new::threadstart::h8084b1107992ae5b at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 29: 0x7f919f3f5709 - start_thread 30: 0x7f91a6e7a82c - clone 31: 0x0 - <unknown
ping how is this unsound?
Given that has seen fit to tag this as a soundness bug I'm nominating it so that it can receive a priority assessment, though I'll second ubsan in asking for a demonstration of the unsoundness here.
In general, having trait bounds that are not checked can lead to unsoundness, since some part of the code will assume that they hold when in fact they do not (consider, e.g., what might happen if the bound were ).
I'm going to mark this as P-medium and tag it from the specialization issue (it is specific to specialization, right?)
triage: P-medium
The code in the OP compiles for me with the latest nightly Rust (1.29.0-nightly ( 2018-08-01)). However, the following still fails (and I assume it's the same issue; if not I can file a new issue): Backtrace:
So I think this is "fixed-by-chalk", but this is fixed-by-chalk in a way that breaks specialization (cc Let's have a more easy-to-understand version of the problem: The problem is the following: our impl needs to prove the where-clause, which in the environment is . holds by (by the impl we are checking), so we can prove that obligation by (which will be a ) that depends on the . Therefore, wfchecking is OK. Therefore, fun. why isn't this a problem every time we have a projection? Normally, rustc normalizes to the real associated type, and then it can't find the , so no problem. With specialization, rustc can't normalize the associated type, so it sees the bug. I can't have a proof for this working, but this seems reasonably likely to work. way that might solve this in the rustc model would be to basically say that for any given trait ref, only the most specialized impl is supposed to be checking the wf requirement (for every trait-ref, there is always a most-specialized impl, so this is OK), and when checking wf, add the associated types for our own impl explicitly to our parameter environment (e.g., add - note no quantification over - to the param env in our example). That will make things normalize and work, and I'm not even sure is particularly ugly. I don't think it is less sound than , but then I don't quite know when is sound. what's going on with Chalk? Last time I saw it, the way we made implied bounds work was to move to the environment - in rustc terms, basically only allow it if we have proven the impl using . This solves the problem, because our impl was proven in a well-formed way, so a will ensure we make progress and there will be no cycles. The reason this does not work in specialization, is that we do want users to be able to prove things like , even while they might not know what is. For that, they need to have a keyed off a . I have no idea how to do this in the Chalk model. Was Chalk changed to do something else by now? Does this have a different interaction with specialization?
A PoC to show the unsoundness of this. It's a use-after free by 'copying' a String: Link to the playground:
This is fixed now: and needs a test

<ins> error[E0277]: the trait bound `T: Copy` is not satisfied --> $DIR/issue-33017.rs:12:5 | LL |     type Output: From<Self> + Copy + Into<Self>; |                               ---- required by this bound in `UncheckedCopy::Output` ... LL |     default type Output = Self; |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `T` | help: consider restricting type parameter `T` | LL | impl<T: std::marker::Copy> UncheckedCopy for T { |       ^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error For more information about this error, try `rustc --explain E0277`. </ins>