jiebi/CodeConvo huggingface dataset:
Code change:
Normally when a static variable has a recursive the definition, the compiler issues an error. However, if the static is used (and not just defined) rustc overflows its stack. This program causes a stack overflow: Stack trace:
Constant checking -- which detects this recursion -- occurs after type checking in the phase order, but type checking needs to evaluate the constant expression in order to find the length of the array type. It looks like strategically inserting a call to in the appropriate place would fix this at the cost of potentially performing the check many times.
After some chatting on IRC, it looks like the best way to fix this is to break the item recursion check out into a separate pass that comes before type checking. This is my first time looking at this part of the compiler, but I'll give it a shot.
This approach looks promising. I need to do a full build/test run and then I can submit a PR.
Fixed.

Related discussion:
text: } visit::walk_expr(v, e); } <del> struct CheckItemRecursionVisitor<'a, 'ast: 'a> { root_it: &'a Item, sess: &'a Session, ast_map: &'a ast_map::Map<'ast>, def_map: &'a resolve::DefMap, idstack: Vec<NodeId> } // Make sure a const item doesn't recursively refer to itself // FIXME: Should use the dependency graph when it's available (#1356) pub fn check_item_recursion<'a>(sess: &'a Session, ast_map: &'a ast_map::Map, def_map: &'a resolve::DefMap, it: &'a Item) { let mut visitor = CheckItemRecursionVisitor { root_it: it, sess: sess, ast_map: ast_map, def_map: def_map, idstack: Vec::new() }; visitor.visit_item(it); } impl<'a, 'ast, 'v> Visitor<'v> for CheckItemRecursionVisitor<'a, 'ast> { fn visit_item(&mut self, it: &Item) { if self.idstack.iter().any(|x| x == &(it.id)) { self.sess.span_fatal(self.root_it.span, "recursive constant"); } self.idstack.push(it.id); visit::walk_item(self, it); self.idstack.pop(); } fn visit_expr(&mut self, e: &Expr) { match e.node { ExprPath(..) => { match self.def_map.borrow().find(&e.id) { Some(&DefStatic(def_id, _)) if ast_util::is_local(def_id) => { self.visit_item(&*self.ast_map.expect_item(def_id.node)); } _ => () } }, _ => () } visit::walk_expr(self, e); } } </del>
Code change:
Normally when a static variable has a recursive the definition, the compiler issues an error. However, if the static is used (and not just defined) rustc overflows its stack. This program causes a stack overflow: Stack trace:
Constant checking -- which detects this recursion -- occurs after type checking in the phase order, but type checking needs to evaluate the constant expression in order to find the length of the array type. It looks like strategically inserting a call to in the appropriate place would fix this at the cost of potentially performing the check many times.
After some chatting on IRC, it looks like the best way to fix this is to break the item recursion check out into a separate pass that comes before type checking. This is my first time looking at this part of the compiler, but I'll give it a shot.
This approach looks promising. I need to do a full build/test run and then I can submit a PR.
Fixed.

Related discussion:
text: <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. static FOO: uint = FOO; //~ ERROR recursive constant fn main() { let _x: [u8, ..FOO]; // caused stack overflow prior to fix let _y: uint = 1 + { static BAR: uint = BAR; //~ ERROR recursive constant let _z: [u8, ..BAR]; // caused stack overflow prior to fix 1 }; } </ins>
Code change:
Sorry for not providing smaller case but I hope this is better than nothing: Both versions works (compile and start), but runtime behavior changes. The code that follows the above part: will match no matter what really is, if the value is partially moved (so mouse events are updating my game). If I use the version with , the code works as intended and game is updated only on keyboard presses.
Minimal: This shouldn't compile at all.
Nominating.
Looks like a regression. 0.10 rejects this code.

Related discussion:
text: euv::AutoRef(..) | euv::ClosureInvocation(..) | euv::ForLoop(..) | <del> euv::RefBinding(..) => { </del> <ins> euv::RefBinding(..) | euv::MatchDiscriminant(..) => { </ins> format!("previous borrow of `{}` occurs here", self.bccx.loan_path_to_string(&*old_loan.loan_path)) }
Code change:
Sorry for not providing smaller case but I hope this is better than nothing: Both versions works (compile and start), but runtime behavior changes. The code that follows the above part: will match no matter what really is, if the value is partially moved (so mouse events are updating my game). If I use the version with , the code works as intended and game is updated only on keyboard presses.
Minimal: This shouldn't compile at all.
Nominating.
Looks like a regression. 0.10 rejects this code.

Related discussion:
text: euv::AddrOf | euv::RefBinding | euv::AutoRef | <del> euv::ForLoop => { </del> <ins> euv::ForLoop | euv::MatchDiscriminant => { </ins> format!("cannot borrow {} as mutable", descr) } euv::ClosureInvocation => {
Code change:
Sorry for not providing smaller case but I hope this is better than nothing: Both versions works (compile and start), but runtime behavior changes. The code that follows the above part: will match no matter what really is, if the value is partially moved (so mouse events are updating my game). If I use the version with , the code works as intended and game is updated only on keyboard presses.
Minimal: This shouldn't compile at all.
Nominating.
Looks like a regression. 0.10 rejects this code.

Related discussion:
text: BorrowViolation(euv::OverloadedOperator) | BorrowViolation(euv::AddrOf) | BorrowViolation(euv::AutoRef) | <del> BorrowViolation(euv::RefBinding) => { </del> <ins> BorrowViolation(euv::RefBinding) | BorrowViolation(euv::MatchDiscriminant) => { </ins> "cannot borrow data mutably" }
Code change:
Sorry for not providing smaller case but I hope this is better than nothing: Both versions works (compile and start), but runtime behavior changes. The code that follows the above part: will match no matter what really is, if the value is partially moved (so mouse events are updating my game). If I use the version with , the code works as intended and game is updated only on keyboard presses.
Minimal: This shouldn't compile at all.
Nominating.
Looks like a regression. 0.10 rejects this code.

Related discussion:
text: OverloadedOperator, ClosureInvocation, ForLoop, <ins> MatchDiscriminant </ins> } #[deriving(PartialEq,Show)]
Code change:
Sorry for not providing smaller case but I hope this is better than nothing: Both versions works (compile and start), but runtime behavior changes. The code that follows the above part: will match no matter what really is, if the value is partially moved (so mouse events are updating my game). If I use the version with , the code works as intended and game is updated only on keyboard presses.
Minimal: This shouldn't compile at all.
Nominating.
Looks like a regression. 0.10 rejects this code.

Related discussion:
text: } ast::ExprMatch(ref discr, ref arms) => { <del> // treatment of the discriminant is handled while // walking the arms: self.walk_expr(&**discr); </del> let discr_cmt = return_if_err!(self.mc.cat_expr(&**discr)); <ins> self.borrow_expr(&**discr, ty::ReEmpty, ty::ImmBorrow, MatchDiscriminant); // treatment of the discriminant is handled while walking the arms. </ins> for arm in arms.iter() { self.walk_arm(discr_cmt.clone(), arm); }
Code change:
Sorry for not providing smaller case but I hope this is better than nothing: Both versions works (compile and start), but runtime behavior changes. The code that follows the above part: will match no matter what really is, if the value is partially moved (so mouse events are updating my game). If I use the version with , the code works as intended and game is updated only on keyboard presses.
Minimal: This shouldn't compile at all.
Nominating.
Looks like a regression. 0.10 rejects this code.

Related discussion:
text: ref s => { tcx.sess.span_bug( span, <del> format!("ty_region() invoked on in appropriate ty: {:?}", </del> <ins> format!("ty_region() invoked on an inappropriate ty: {:?}", </ins> s).as_slice()); } }
Code change:
Sorry for not providing smaller case but I hope this is better than nothing: Both versions works (compile and start), but runtime behavior changes. The code that follows the above part: will match no matter what really is, if the value is partially moved (so mouse events are updating my game). If I use the version with , the code works as intended and game is updated only on keyboard presses.
Minimal: This shouldn't compile at all.
Nominating.
Looks like a regression. 0.10 rejects this code.

Related discussion:
text: <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. fn foo(_s: i16) { } fn bar(_s: u32) { } fn main() { foo(1*(1 as int)); //~^ ERROR: mismatched types: expected `i16`, found `int` (expected `i16`, found `int`) bar(1*(1 as uint)); //~^ ERROR: mismatched types: expected `u32`, found `uint` (expected `u32`, found `uint`) } </ins>
Code change:
Sorry for not providing smaller case but I hope this is better than nothing: Both versions works (compile and start), but runtime behavior changes. The code that follows the above part: will match no matter what really is, if the value is partially moved (so mouse events are updating my game). If I use the version with , the code works as intended and game is updated only on keyboard presses.
Minimal: This shouldn't compile at all.
Nominating.
Looks like a regression. 0.10 rejects this code.

Related discussion:
text: <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. struct X(int); enum Enum { Variant1, Variant2 } impl Drop for X { fn drop(&mut self) {} } impl Drop for Enum { fn drop(&mut self) {} } fn main() { let foo = X(1i); drop(foo); match foo { //~ ERROR use of moved value X(1i) => (), _ => unreachable!() } let e = Variant2; drop(e); match e { //~ ERROR use of moved value Variant1 => unreachable!(), Variant2 => () } } </ins>
Code change:
Sorry for not providing smaller case but I hope this is better than nothing: Both versions works (compile and start), but runtime behavior changes. The code that follows the above part: will match no matter what really is, if the value is partially moved (so mouse events are updating my game). If I use the version with , the code works as intended and game is updated only on keyboard presses.
Minimal: This shouldn't compile at all.
Nominating.
Looks like a regression. 0.10 rejects this code.

Related discussion:
text: <del> // 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. fn foo(_s: i16) { } fn bar(_s: u32) { } fn main() { foo(1*(1 as int)); //~^ ERROR: mismatched types: expected `i16`, found `int` (expected `i16`, found `int`) bar(1*(1 as uint)); //~^ ERROR: mismatched types: expected `u32`, found `uint` (expected `u32`, found `uint`) } </del>
Code change:
Couldn't find another issue for this. The error message for this is poor and should suggest qualifying the type, or at least clearly saying that a value from cannot be used as a type, and the span should then help the user understand (it is currently fine): Error message comes from astconv, so we could probably catch this in resolve?
(I'll update the example so that the bug is still demonstrable.)

Related discussion:
text: { let parent = self.get_parent(id); let parent = match self.find_entry(id) { <del> Some(EntryForeignItem(..)) | Some(EntryVariant(..)) => { // Anonymous extern items, enum variants and struct ctors // go in the parent scope. </del> <ins> Some(EntryForeignItem(..)) => { // Anonymous extern items go in the parent scope. </ins> self.get_parent(parent) } // But tuple struct ctors don't have names, so use the path of its
Code change:
Couldn't find another issue for this. The error message for this is poor and should suggest qualifying the type, or at least clearly saying that a value from cannot be used as a type, and the span should then help the user understand (it is currently fine): Error message comes from astconv, so we could probably catch this in resolve?
(I'll update the example so that the bug is still demonstrable.)

Related discussion:
text: prim_ty_to_ty(tcx, base_segments, prim_ty) } _ => { <ins> let node = def.def_id().node; </ins> span_err!(tcx.sess, span, E0248, <del> "found value name used as a type: {:?}", *def); </del> <ins> "found value `{}` used as a type", tcx.map.path_to_string(node)); </ins> return this.tcx().types.err; } }
Code change:
Couldn't find another issue for this. The error message for this is poor and should suggest qualifying the type, or at least clearly saying that a value from cannot be used as a type, and the span should then help the user understand (it is currently fine): Error message comes from astconv, so we could probably catch this in resolve?
(I'll update the example so that the bug is still demonstrable.)

Related discussion:
text: Bar } <del> fn foo(x: Foo::Bar) {} //~ERROR found value name used as a type </del> <ins> fn foo(x: Foo::Bar) {} //~ERROR found value `Foo::Bar` used as a type </ins> fn main() {}
Code change:
Couldn't find another issue for this. The error message for this is poor and should suggest qualifying the type, or at least clearly saying that a value from cannot be used as a type, and the span should then help the user understand (it is currently fine): Error message comes from astconv, so we could probably catch this in resolve?
(I'll update the example so that the bug is still demonstrable.)

Related discussion:
text: <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. use foo::MyEnum::Result; use foo::NoResult; // Through a re-export mod foo { pub use self::MyEnum::NoResult; enum MyEnum { Result, NoResult } fn new() -> NoResult<MyEnum, String> { //~^ ERROR: found value `foo::MyEnum::NoResult` used as a type unimplemented!() } } mod bar { use foo::MyEnum::Result; use foo; fn new() -> Result<foo::MyEnum, String> { //~^ ERROR: found value `foo::MyEnum::Result` used as a type unimplemented!() } } fn new() -> Result<foo::MyEnum, String> { //~^ ERROR: found value `foo::MyEnum::Result` used as a type unimplemented!() } fn newer() -> NoResult<foo::MyEnum, String> { //~^ ERROR: found value `foo::MyEnum::NoResult` used as a type unimplemented!() } fn main() { let _ = new(); } </ins>
Code change:
Couldn't find another issue for this. The error message for this is poor and should suggest qualifying the type, or at least clearly saying that a value from cannot be used as a type, and the span should then help the user understand (it is currently fine): Error message comes from astconv, so we could probably catch this in resolve?
(I'll update the example so that the bug is still demonstrable.)

Related discussion:
text: #[rustc_move_fragments] pub fn test_match_partial(p: Lonely<D, D>) { //~^ ERROR                 parent_of_fragments: `$(local p)` <del> //~| ERROR                  assigned_leaf_path: `($(local p) as Zero)` </del> <ins> //~| ERROR                  assigned_leaf_path: `($(local p) as Lonely::Zero)` </ins> match p { Zero(..) => {} _ => {}
Code change:
Couldn't find another issue for this. The error message for this is poor and should suggest qualifying the type, or at least clearly saying that a value from cannot be used as a type, and the span should then help the user understand (it is currently fine): Error message comes from astconv, so we could probably catch this in resolve?
(I'll update the example so that the bug is still demonstrable.)

Related discussion:
text: #[rustc_move_fragments] pub fn test_match_full(p: Lonely<D, D>) { //~^ ERROR                 parent_of_fragments: `$(local p)` <del> //~| ERROR                  assigned_leaf_path: `($(local p) as Zero)` //~| ERROR                  assigned_leaf_path: `($(local p) as One)` //~| ERROR                  assigned_leaf_path: `($(local p) as Two)` </del> <ins> //~| ERROR                  assigned_leaf_path: `($(local p) as Lonely::Zero)` //~| ERROR                  assigned_leaf_path: `($(local p) as Lonely::One)` //~| ERROR                  assigned_leaf_path: `($(local p) as Lonely::Two)` </ins> match p { Zero(..) => {} One(..) => {}
Code change:
Couldn't find another issue for this. The error message for this is poor and should suggest qualifying the type, or at least clearly saying that a value from cannot be used as a type, and the span should then help the user understand (it is currently fine): Error message comes from astconv, so we could probably catch this in resolve?
(I'll update the example so that the bug is still demonstrable.)

Related discussion:
text: #[rustc_move_fragments] pub fn test_match_bind_one(p: Lonely<D, D>) { //~^ ERROR                 parent_of_fragments: `$(local p)` <del> //~| ERROR                  assigned_leaf_path: `($(local p) as Zero)` //~| ERROR                 parent_of_fragments: `($(local p) as One)` //~| ERROR                     moved_leaf_path: `($(local p) as One).#0` //~| ERROR                  assigned_leaf_path: `($(local p) as Two)` </del> <ins> //~| ERROR                  assigned_leaf_path: `($(local p) as Lonely::Zero)` //~| ERROR                 parent_of_fragments: `($(local p) as Lonely::One)` //~| ERROR                     moved_leaf_path: `($(local p) as Lonely::One).#0` //~| ERROR                  assigned_leaf_path: `($(local p) as Lonely::Two)` </ins> //~| ERROR                  assigned_leaf_path: `$(local data)` match p { Zero(..) => {}
Code change:
Couldn't find another issue for this. The error message for this is poor and should suggest qualifying the type, or at least clearly saying that a value from cannot be used as a type, and the span should then help the user understand (it is currently fine): Error message comes from astconv, so we could probably catch this in resolve?
(I'll update the example so that the bug is still demonstrable.)

Related discussion:
text: #[rustc_move_fragments] pub fn test_match_bind_many(p: Lonely<D, D>) { //~^ ERROR                 parent_of_fragments: `$(local p)` <del> //~| ERROR                  assigned_leaf_path: `($(local p) as Zero)` //~| ERROR                 parent_of_fragments: `($(local p) as One)` //~| ERROR                     moved_leaf_path: `($(local p) as One).#0` </del> <ins> //~| ERROR                  assigned_leaf_path: `($(local p) as Lonely::Zero)` //~| ERROR                 parent_of_fragments: `($(local p) as Lonely::One)` //~| ERROR                     moved_leaf_path: `($(local p) as Lonely::One).#0` </ins> //~| ERROR                  assigned_leaf_path: `$(local data)` <del> //~| ERROR                 parent_of_fragments: `($(local p) as Two)` //~| ERROR                     moved_leaf_path: `($(local p) as Two).#0` //~| ERROR                     moved_leaf_path: `($(local p) as Two).#1` </del> <ins> //~| ERROR                 parent_of_fragments: `($(local p) as Lonely::Two)` //~| ERROR                     moved_leaf_path: `($(local p) as Lonely::Two).#0` //~| ERROR                     moved_leaf_path: `($(local p) as Lonely::Two).#1` </ins> //~| ERROR                  assigned_leaf_path: `$(local left)` //~| ERROR                  assigned_leaf_path: `$(local right)` match p {
Code change:
Couldn't find another issue for this. The error message for this is poor and should suggest qualifying the type, or at least clearly saying that a value from cannot be used as a type, and the span should then help the user understand (it is currently fine): Error message comes from astconv, so we could probably catch this in resolve?
(I'll update the example so that the bug is still demonstrable.)

Related discussion:
text: <del> // Copyright 2014 The Rust Project Developers. See the COPYRIGHT </del> <ins> // Copyright 2014-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. //
Code change:
Couldn't find another issue for this. The error message for this is poor and should suggest qualifying the type, or at least clearly saying that a value from cannot be used as a type, and the span should then help the user understand (it is currently fine): Error message comes from astconv, so we could probably catch this in resolve?
(I'll update the example so that the bug is still demonstrable.)

Related discussion:
text: #[rustc_move_fragments] pub fn test_match_bind_and_underscore(p: Lonely<D, D>) { //~^ ERROR                 parent_of_fragments: `$(local p)` <del> //~| ERROR                  assigned_leaf_path: `($(local p) as Zero)` //~| ERROR                  assigned_leaf_path: `($(local p) as One)` //~| ERROR                 parent_of_fragments: `($(local p) as Two)` //~| ERROR                     moved_leaf_path: `($(local p) as Two).#0` //~| ERROR                    unmoved_fragment: `($(local p) as Two).#1` </del> <ins> //~| ERROR                  assigned_leaf_path: `($(local p) as Lonely::Zero)` //~| ERROR                  assigned_leaf_path: `($(local p) as Lonely::One)` //~| ERROR                 parent_of_fragments: `($(local p) as Lonely::Two)` //~| ERROR                     moved_leaf_path: `($(local p) as Lonely::Two).#0` //~| ERROR                    unmoved_fragment: `($(local p) as Lonely::Two).#1` </ins> //~| ERROR                  assigned_leaf_path: `$(local left)` match p {