diff --git a/src/libextra/crypto/cryptoutil.rs b/src/libextra/crypto/cryptoutil.rs index d4d43558110b1..9516517d9f7be 100644 --- a/src/libextra/crypto/cryptoutil.rs +++ b/src/libextra/crypto/cryptoutil.rs @@ -420,6 +420,7 @@ mod test { #[test] #[should_fail] fn test_add_bytes_to_bits_tuple_overflow2() { - add_bytes_to_bits_tuple::((Bounded::max_value::() - 1, 0), 0x8000000000000000); + let value: u64 = Bounded::max_value(); + add_bytes_to_bits_tuple::((value - 1, 0), 0x8000000000000000); } } diff --git a/src/libextra/dlist.rs b/src/libextra/dlist.rs index 076e86dd5b040..8e64107363785 100644 --- a/src/libextra/dlist.rs +++ b/src/libextra/dlist.rs @@ -661,7 +661,7 @@ mod tests { #[test] fn test_basic() { - let mut m = DList::new::<~int>(); + let mut m: DList<~int> = DList::new(); assert_eq!(m.pop_front(), None); assert_eq!(m.pop_back(), None); assert_eq!(m.pop_front(), None); @@ -768,7 +768,7 @@ mod tests { #[test] fn test_rotate() { - let mut n = DList::new::(); + let mut n: DList = DList::new(); n.rotate_backward(); check_links(&n); assert_eq!(n.len(), 0); n.rotate_forward(); check_links(&n); @@ -1033,7 +1033,7 @@ mod tests { #[cfg(test)] fn fuzz_test(sz: int) { - let mut m = DList::new::(); + let mut m: DList = DList::new(); let mut v = ~[]; for i in range(0, sz) { check_links(&m); @@ -1078,7 +1078,7 @@ mod tests { #[bench] fn bench_push_front(b: &mut test::BenchHarness) { - let mut m = DList::new::(); + let mut m: DList = DList::new(); do b.iter { m.push_front(0); } @@ -1086,7 +1086,7 @@ mod tests { #[bench] fn bench_push_back(b: &mut test::BenchHarness) { - let mut m = DList::new::(); + let mut m: DList = DList::new(); do b.iter { m.push_back(0); } @@ -1094,7 +1094,7 @@ mod tests { #[bench] fn bench_push_back_pop_back(b: &mut test::BenchHarness) { - let mut m = DList::new::(); + let mut m: DList = DList::new(); do b.iter { m.push_back(0); m.pop_back(); @@ -1103,7 +1103,7 @@ mod tests { #[bench] fn bench_push_front_pop_front(b: &mut test::BenchHarness) { - let mut m = DList::new::(); + let mut m: DList = DList::new(); do b.iter { m.push_front(0); m.pop_front(); @@ -1112,7 +1112,7 @@ mod tests { #[bench] fn bench_rotate_forward(b: &mut test::BenchHarness) { - let mut m = DList::new::(); + let mut m: DList = DList::new(); m.push_front(0); m.push_front(1); do b.iter { @@ -1122,7 +1122,7 @@ mod tests { #[bench] fn bench_rotate_backward(b: &mut test::BenchHarness) { - let mut m = DList::new::(); + let mut m: DList = DList::new(); m.push_front(0); m.push_front(1); do b.iter { diff --git a/src/libextra/flate.rs b/src/libextra/flate.rs index 530885001292c..65d4f79c64024 100644 --- a/src/libextra/flate.rs +++ b/src/libextra/flate.rs @@ -25,13 +25,13 @@ pub mod rustrt { #[link_name = "rustrt"] extern { - pub fn tdefl_compress_mem_to_heap(psrc_buf: *const c_void, + pub fn tdefl_compress_mem_to_heap(psrc_buf: *c_void, src_buf_len: size_t, pout_len: *mut size_t, flags: c_int) -> *c_void; - pub fn tinfl_decompress_mem_to_heap(psrc_buf: *const c_void, + pub fn tinfl_decompress_mem_to_heap(psrc_buf: *c_void, src_buf_len: size_t, pout_len: *mut size_t, flags: c_int) diff --git a/src/libextra/num/bigint.rs b/src/libextra/num/bigint.rs index 354696ef42060..7e74fff82f7a3 100644 --- a/src/libextra/num/bigint.rs +++ b/src/libextra/num/bigint.rs @@ -380,7 +380,7 @@ impl Integer for BigUint { fn div_mod_floor_inner(a: BigUint, b: BigUint) -> (BigUint, BigUint) { let mut m = a; - let mut d = Zero::zero::(); + let mut d: BigUint = Zero::zero(); let mut n = 1; while m >= b { let (d0, d_unit, b_unit) = div_estimate(&m, &b, n); @@ -432,8 +432,9 @@ impl Integer for BigUint { if shift == 0 { return (BigUint::new(d), One::one(), (*b).clone()); } + let one: BigUint = One::one(); return (BigUint::from_slice(d).shl_unit(shift), - One::one::().shl_unit(shift), + one.shl_unit(shift), b.shl_unit(shift)); } } @@ -1510,11 +1511,18 @@ mod biguint_tests { #[test] fn test_is_even() { - assert!(FromStr::from_str::("1").unwrap().is_odd()); - assert!(FromStr::from_str::("2").unwrap().is_even()); - assert!(FromStr::from_str::("1000").unwrap().is_even()); - assert!(FromStr::from_str::("1000000000000000000000").unwrap().is_even()); - assert!(FromStr::from_str::("1000000000000000000001").unwrap().is_odd()); + let one: Option = FromStr::from_str("1"); + let two: Option = FromStr::from_str("2"); + let thousand: Option = FromStr::from_str("1000"); + let big: Option = + FromStr::from_str("1000000000000000000000"); + let bigger: Option = + FromStr::from_str("1000000000000000000001"); + assert!(one.unwrap().is_odd()); + assert!(two.unwrap().is_even()); + assert!(thousand.unwrap().is_even()); + assert!(big.unwrap().is_even()); + assert!(bigger.unwrap().is_odd()); assert!((BigUint::from_uint(1) << 64).is_even()); assert!(((BigUint::from_uint(1) << 64) + BigUint::from_uint(1)).is_odd()); } @@ -1599,15 +1607,19 @@ mod biguint_tests { } } - assert_eq!(FromStrRadix::from_str_radix::("Z", 10), None); - assert_eq!(FromStrRadix::from_str_radix::("_", 2), None); - assert_eq!(FromStrRadix::from_str_radix::("-1", 10), None); + let zed: Option = FromStrRadix::from_str_radix("Z", 10); + assert_eq!(zed, None); + let blank: Option = FromStrRadix::from_str_radix("_", 2); + assert_eq!(blank, None); + let minus_one: Option = FromStrRadix::from_str_radix("-1", + 10); + assert_eq!(minus_one, None); } #[test] fn test_factor() { fn factor(n: uint) -> BigUint { - let mut f= One::one::(); + let mut f: BigUint = One::one(); for i in range(2, n + 1) { // FIXME(#6102): Assignment operator for BigInt causes ICE // f *= BigUint::from_uint(i); @@ -2005,17 +2017,24 @@ mod bigint_tests { #[test] fn test_abs_sub() { - assert_eq!((-One::one::()).abs_sub(&One::one()), Zero::zero()); - assert_eq!(One::one::().abs_sub(&One::one()), Zero::zero()); - assert_eq!(One::one::().abs_sub(&Zero::zero()), One::one()); - assert_eq!(One::one::().abs_sub(&-One::one::()), - IntConvertible::from_int(2)); + let zero: BigInt = Zero::zero(); + let one: BigInt = One::one(); + assert_eq!((-one).abs_sub(&one), zero); + let one: BigInt = One::one(); + let zero: BigInt = Zero::zero(); + assert_eq!(one.abs_sub(&one), zero); + let one: BigInt = One::one(); + let zero: BigInt = Zero::zero(); + assert_eq!(one.abs_sub(&zero), one); + let one: BigInt = One::one(); + assert_eq!(one.abs_sub(&-one), IntConvertible::from_int(2)); } #[test] fn test_to_str_radix() { fn check(n: int, ans: &str) { - assert!(ans == IntConvertible::from_int::(n).to_str_radix(10)); + let n: BigInt = IntConvertible::from_int(n); + assert!(ans == n.to_str_radix(10)); } check(10, "10"); check(1, "1"); @@ -2028,7 +2047,10 @@ mod bigint_tests { #[test] fn test_from_str_radix() { fn check(s: &str, ans: Option) { - let ans = ans.map_move(|n| IntConvertible::from_int::(n)); + let ans = ans.map_move(|n| { + let x: BigInt = IntConvertible::from_int(n); + x + }); assert_eq!(FromStrRadix::from_str_radix(s, 10), ans); } check("10", Some(10)); @@ -2046,6 +2068,7 @@ mod bigint_tests { BigInt::new(Minus, ~[1, 1, 1])); assert!(-BigInt::new(Minus, ~[1, 1, 1]) == BigInt::new(Plus, ~[1, 1, 1])); - assert_eq!(-Zero::zero::(), Zero::zero::()); + let zero: BigInt = Zero::zero(); + assert_eq!(-zero, zero); } } diff --git a/src/libextra/num/rational.rs b/src/libextra/num/rational.rs index 60dd36a3b886e..41e9a488bf8ae 100644 --- a/src/libextra/num/rational.rs +++ b/src/libextra/num/rational.rs @@ -269,9 +269,13 @@ impl /// Parses `numer/denom`. fn from_str(s: &str) -> Option> { let split: ~[&str] = s.splitn_iter('/', 1).collect(); - if split.len() < 2 { return None; } - do FromStr::from_str::(split[0]).chain |a| { - do FromStr::from_str::(split[1]).chain |b| { + if split.len() < 2 { + return None + } + let a_option: Option = FromStr::from_str(split[0]); + do a_option.chain |a| { + let b_option: Option = FromStr::from_str(split[1]); + do b_option.chain |b| { Some(Ratio::new(a.clone(), b.clone())) } } @@ -282,10 +286,15 @@ impl /// Parses `numer/denom` where the numbers are in base `radix`. fn from_str_radix(s: &str, radix: uint) -> Option> { let split: ~[&str] = s.splitn_iter('/', 1).collect(); - if split.len() < 2 { None } - else { - do FromStrRadix::from_str_radix::(split[0], radix).chain |a| { - do FromStrRadix::from_str_radix::(split[1], radix).chain |b| { + if split.len() < 2 { + None + } else { + let a_option: Option = FromStrRadix::from_str_radix(split[0], + radix); + do a_option.chain |a| { + let b_option: Option = + FromStrRadix::from_str_radix(split[1], radix); + do b_option.chain |b| { Some(Ratio::new(a.clone(), b.clone())) } } @@ -496,7 +505,8 @@ mod test { #[test] fn test_from_str_fail() { fn test(s: &str) { - assert_eq!(FromStr::from_str::(s), None); + let rational: Option = FromStr::from_str(s); + assert_eq!(rational, None); } let xs = ["0 /1", "abc", "", "1/", "--1/2","3/2/1"]; @@ -536,7 +546,8 @@ mod test { #[test] fn test_from_str_radix_fail() { fn test(s: &str) { - assert_eq!(FromStrRadix::from_str_radix::(s, 3), None); + let radix: Option = FromStrRadix::from_str_radix(s, 3); + assert_eq!(radix, None); } let xs = ["0 /1", "abc", "", "1/", "--1/2","3/2/1", "3/2"]; diff --git a/src/libextra/priority_queue.rs b/src/libextra/priority_queue.rs index 4f0fed5fccf47..09b351433a26d 100644 --- a/src/libextra/priority_queue.rs +++ b/src/libextra/priority_queue.rs @@ -339,29 +339,38 @@ mod tests { #[test] #[should_fail] #[ignore(cfg(windows))] - fn test_empty_pop() { let mut heap = PriorityQueue::new::(); heap.pop(); } + fn test_empty_pop() { + let mut heap: PriorityQueue = PriorityQueue::new(); + heap.pop(); + } #[test] fn test_empty_maybe_pop() { - let mut heap = PriorityQueue::new::(); + let mut heap: PriorityQueue = PriorityQueue::new(); assert!(heap.maybe_pop().is_none()); } #[test] #[should_fail] #[ignore(cfg(windows))] - fn test_empty_top() { let empty = PriorityQueue::new::(); empty.top(); } + fn test_empty_top() { + let empty: PriorityQueue = PriorityQueue::new(); + empty.top(); + } #[test] fn test_empty_maybe_top() { - let empty = PriorityQueue::new::(); + let empty: PriorityQueue = PriorityQueue::new(); assert!(empty.maybe_top().is_none()); } #[test] #[should_fail] #[ignore(cfg(windows))] - fn test_empty_replace() { let mut heap = PriorityQueue::new(); heap.replace(5); } + fn test_empty_replace() { + let mut heap: PriorityQueue = PriorityQueue::new(); + heap.replace(5); + } #[test] fn test_from_iter() { diff --git a/src/libextra/ringbuf.rs b/src/libextra/ringbuf.rs index a38cb580c5057..4f2755374af02 100644 --- a/src/libextra/ringbuf.rs +++ b/src/libextra/ringbuf.rs @@ -483,7 +483,7 @@ mod tests { #[bench] fn bench_new(b: &mut test::BenchHarness) { do b.iter { - let _ = RingBuf::new::(); + let _: RingBuf = RingBuf::new(); } } diff --git a/src/libextra/treemap.rs b/src/libextra/treemap.rs index 118754ec02830..307de43a067f0 100644 --- a/src/libextra/treemap.rs +++ b/src/libextra/treemap.rs @@ -879,7 +879,8 @@ mod test_treemap { #[test] fn find_empty() { - let m = TreeMap::new::(); assert!(m.find(&5) == None); + let m: TreeMap = TreeMap::new(); + assert!(m.find(&5) == None); } #[test] @@ -1006,7 +1007,7 @@ mod test_treemap { #[test] fn test_rand_int() { - let mut map = TreeMap::new::(); + let mut map: TreeMap = TreeMap::new(); let mut ctrl = ~[]; check_equal(ctrl, &map); diff --git a/src/librustc/front/std_inject.rs b/src/librustc/front/std_inject.rs index 2a61ea28e0c6b..429a1c35b3421 100644 --- a/src/librustc/front/std_inject.rs +++ b/src/librustc/front/std_inject.rs @@ -17,6 +17,7 @@ use syntax::attr; use syntax::codemap::dummy_sp; use syntax::codemap; use syntax::fold; +use syntax::opt_vec; static STD_VERSION: &'static str = "0.8-pre"; @@ -90,12 +91,18 @@ fn inject_libstd_ref(sess: Session, crate: &ast::Crate) -> @ast::Crate { let prelude_path = ast::Path { span: dummy_sp(), global: false, - idents: ~[ - sess.ident_of("std"), - sess.ident_of("prelude") + segments: ~[ + ast::PathSegment { + identifier: sess.ident_of("std"), + lifetime: None, + types: opt_vec::Empty, + }, + ast::PathSegment { + identifier: sess.ident_of("prelude"), + lifetime: None, + types: opt_vec::Empty, + }, ], - rp: None, - types: ~[] }; let vp = @spanned(ast::view_path_glob(prelude_path, n2)); diff --git a/src/librustc/front/test.rs b/src/librustc/front/test.rs index 0aacd4c5063db..a341db75393d3 100644 --- a/src/librustc/front/test.rs +++ b/src/librustc/front/test.rs @@ -16,14 +16,15 @@ use front::config; use std::vec; use syntax::ast_util::*; +use syntax::attr::AttrMetaMethods; use syntax::attr; use syntax::codemap::{dummy_sp, span, ExpnInfo, NameAndSpan}; use syntax::codemap; use syntax::ext::base::ExtCtxt; use syntax::fold; +use syntax::opt_vec; use syntax::print::pprust; use syntax::{ast, ast_util}; -use syntax::attr::AttrMetaMethods; type node_id_gen = @fn() -> ast::NodeId; @@ -383,19 +384,27 @@ fn nospan(t: T) -> codemap::spanned { } fn path_node(ids: ~[ast::ident]) -> ast::Path { - ast::Path { span: dummy_sp(), - global: false, - idents: ids, - rp: None, - types: ~[] } + ast::Path { + span: dummy_sp(), + global: false, + segments: ids.move_iter().map(|identifier| ast::PathSegment { + identifier: identifier, + lifetime: None, + types: opt_vec::Empty, + }).collect() + } } fn path_node_global(ids: ~[ast::ident]) -> ast::Path { - ast::Path { span: dummy_sp(), - global: true, - idents: ids, - rp: None, - types: ~[] } + ast::Path { + span: dummy_sp(), + global: true, + segments: ids.move_iter().map(|identifier| ast::PathSegment { + identifier: identifier, + lifetime: None, + types: opt_vec::Empty, + }).collect() + } } #[cfg(stage0)] diff --git a/src/librustc/metadata/creader.rs b/src/librustc/metadata/creader.rs index c8c4a396c87af..f74fecb522390 100644 --- a/src/librustc/metadata/creader.rs +++ b/src/librustc/metadata/creader.rs @@ -25,7 +25,8 @@ use syntax::codemap::{span, dummy_sp}; use syntax::diagnostic::span_handler; use syntax::parse::token; use syntax::parse::token::ident_interner; -use syntax::oldvisit; +use syntax::visit::SimpleVisitor; +use syntax::visit; // Traverses an AST, reading all the information about use'd crates and extern // libraries necessary for later resolving, typechecking, linking, etc. @@ -46,13 +47,11 @@ pub fn read_crates(diag: @mut span_handler, next_crate_num: 1, intr: intr }; - let v = - oldvisit::mk_simple_visitor(@oldvisit::SimpleVisitor { - visit_view_item: |a| visit_view_item(e, a), - visit_item: |a| visit_item(e, a), - .. *oldvisit::default_simple_visitor()}); - visit_crate(e, crate); - oldvisit::visit_crate(crate, ((), v)); + e.visit_crate(crate); + let mut visitor = visit::SimpleVisitorVisitor { + simple_visitor: e as @mut SimpleVisitor, + }; + visit::walk_crate(&mut visitor, crate, ()); dump_crates(*e.crate_cache); warn_if_multiple_versions(e, diag, *e.crate_cache); } @@ -115,103 +114,113 @@ struct Env { intr: @ident_interner } -fn visit_crate(e: &Env, c: &ast::Crate) { - let cstore = e.cstore; +impl Env { + fn visit_crate(&self, c: &ast::Crate) { + let cstore = self.cstore; - for a in c.attrs.iter().filter(|m| "link_args" == m.name()) { - match a.value_str() { - Some(ref linkarg) => { - cstore::add_used_link_args(cstore, *linkarg); - } - None => {/* fallthrough */ } + for a in c.attrs.iter().filter(|m| "link_args" == m.name()) { + match a.value_str() { + Some(ref linkarg) => { + cstore::add_used_link_args(cstore, *linkarg); + } + None => {/* fallthrough */ } + } } } } -fn visit_view_item(e: @mut Env, i: &ast::view_item) { - match i.node { - ast::view_item_extern_mod(ident, path_opt, ref meta_items, id) => { - let ident = token::ident_to_str(&ident); - let meta_items = match path_opt { - None => meta_items.clone(), - Some(p) => { - let p_path = Path(p); - match p_path.filestem() { - Some(s) => - vec::append( - ~[attr::mk_name_value_item_str(@"package_id", p), - attr::mk_name_value_item_str(@"name", s.to_managed())], - *meta_items), - None => e.diag.span_bug(i.span, "Bad package path in `extern mod` item") - } - } - }; - debug!("resolving extern mod stmt. ident: %?, meta: %?", - ident, meta_items); - let cnum = resolve_crate(e, - ident, - meta_items, - @"", - i.span); - cstore::add_extern_mod_stmt_cnum(e.cstore, id, cnum); + +impl SimpleVisitor for Env { + fn visit_view_item(&mut self, i: &ast::view_item) { + match i.node { + ast::view_item_extern_mod(ident, path_opt, ref meta_items, id) => { + let ident = token::ident_to_str(&ident); + let meta_items = match path_opt { + None => meta_items.clone(), + Some(p) => { + let p_path = Path(p); + match p_path.filestem() { + Some(s) => + vec::append( + ~[attr::mk_name_value_item_str(@"package_id", p), + attr::mk_name_value_item_str(@"name", s.to_managed())], + *meta_items), + None => { + self.diag.span_bug(i.span, + "bad package path in `extern mod` item") + } + } + } + }; + debug!("resolving extern mod stmt. ident: %?, meta: %?", + ident, meta_items); + let cnum = resolve_crate(self, + ident, + meta_items, + @"", + i.span); + cstore::add_extern_mod_stmt_cnum(self.cstore, id, cnum); + } + _ => () } - _ => () - } -} + } -fn visit_item(e: &Env, i: @ast::item) { - match i.node { - ast::item_foreign_mod(ref fm) => { - if fm.abis.is_rust() || fm.abis.is_intrinsic() { - return; - } + fn visit_item(&mut self, i: @ast::item) { + match i.node { + ast::item_foreign_mod(ref fm) => { + if fm.abis.is_rust() || fm.abis.is_intrinsic() { + return; + } - let cstore = e.cstore; - let mut already_added = false; - let link_args = i.attrs.iter() - .filter_map(|at| if "link_args" == at.name() {Some(at)} else {None}) - .collect::<~[&ast::Attribute]>(); - - match fm.sort { - ast::named => { - let link_name = i.attrs.iter() - .find(|at| "link_name" == at.name()) - .chain(|at| at.value_str()); - - let foreign_name = match link_name { - Some(nn) => { - if nn.is_empty() { - e.diag.span_fatal( - i.span, - "empty #[link_name] not allowed; use \ - #[nolink]."); + let cstore = self.cstore; + let mut already_added = false; + let link_args = i.attrs.iter() + .filter_map(|at| if "link_args" == at.name() {Some(at)} else {None}) + .collect::<~[&ast::Attribute]>(); + + match fm.sort { + ast::named => { + let link_name = i.attrs.iter() + .find(|at| "link_name" == at.name()) + .chain(|at| at.value_str()); + + let foreign_name = match link_name { + Some(nn) => { + if nn.is_empty() { + self.diag.span_fatal( + i.span, + "empty #[link_name] not allowed; use \ + #[nolink]."); + } + nn } - nn - } - None => token::ident_to_str(&i.ident) - }; - if !attr::contains_name(i.attrs, "nolink") { - already_added = - !cstore::add_used_library(cstore, foreign_name); - } - if !link_args.is_empty() && already_added { - e.diag.span_fatal(i.span, ~"library '" + foreign_name + - "' already added: can't specify link_args."); + None => token::ident_to_str(&i.ident) + }; + if !attr::contains_name(i.attrs, "nolink") { + already_added = + !cstore::add_used_library(cstore, foreign_name); + } + if !link_args.is_empty() && already_added { + self.diag.span_fatal(i.span, ~"library '" + + foreign_name + + "' already added: can't specify \ + link_args."); + } } + ast::anonymous => { /* do nothing */ } } - ast::anonymous => { /* do nothing */ } - } - for m in link_args.iter() { - match m.value_str() { - Some(linkarg) => { - cstore::add_used_link_args(cstore, linkarg); + for m in link_args.iter() { + match m.value_str() { + Some(linkarg) => { + cstore::add_used_link_args(cstore, linkarg); + } + None => { /* fallthrough */ } } - None => { /* fallthrough */ } } + } + _ => { } } - } - _ => { } } } @@ -240,7 +249,7 @@ fn existing_match(e: &Env, metas: &[@ast::MetaItem], hash: &str) return None; } -fn resolve_crate(e: @mut Env, +fn resolve_crate(e: &mut Env, ident: @str, metas: ~[@ast::MetaItem], hash: @str, @@ -308,7 +317,7 @@ fn resolve_crate(e: @mut Env, } // Go through the crate metadata and load any crates that it references -fn resolve_crate_deps(e: @mut Env, cdata: @~[u8]) -> cstore::cnum_map { +fn resolve_crate_deps(e: &mut Env, cdata: @~[u8]) -> cstore::cnum_map { debug!("resolving deps of external crate"); // The map from crate numbers in the crate we're resolving to local crate // numbers diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index 81a2e863bde00..34c100a95f2f3 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -335,15 +335,19 @@ fn item_to_def_like(item: ebml::Doc, did: ast::def_id, cnum: ast::CrateNum) let purity = if fam == UnsafeStaticMethod { ast::unsafe_fn } else { ast::impure_fn }; // def_static_method carries an optional field of its enclosing - // *trait*, but not an inclosing Impl (if this is an inherent - // static method). So we need to detect whether this is in - // a trait or not, which we do through the mildly hacky - // way of checking whether there is a trait_method_sort. - let trait_did_opt = if reader::maybe_get_doc( + // trait or enclosing impl (if this is an inherent static method). + // So we need to detect whether this is in a trait or not, which + // we do through the mildly hacky way of checking whether there is + // a trait_method_sort. + let provenance = if reader::maybe_get_doc( item, tag_item_trait_method_sort).is_some() { - Some(item_reqd_and_translated_parent_item(cnum, item)) - } else { None }; - dl_def(ast::def_static_method(did, trait_did_opt, purity)) + ast::FromTrait(item_reqd_and_translated_parent_item(cnum, + item)) + } else { + ast::FromImpl(item_reqd_and_translated_parent_item(cnum, + item)) + }; + dl_def(ast::def_static_method(did, provenance, purity)) } Type | ForeignType => dl_def(ast::def_ty(did)), Mod => dl_def(ast::def_mod(did)), @@ -792,12 +796,9 @@ pub fn get_enum_variants(intr: @ident_interner, cdata: cmd, id: ast::NodeId, fn get_explicit_self(item: ebml::Doc) -> ast::explicit_self_ { fn get_mutability(ch: u8) -> ast::mutability { match ch as char { - 'i' => { ast::m_imm } - 'm' => { ast::m_mutbl } - 'c' => { ast::m_const } - _ => { - fail!("unknown mutability character: `%c`", ch as char) - } + 'i' => ast::m_imm, + 'm' => ast::m_mutbl, + _ => fail!("unknown mutability character: `%c`", ch as char), } } diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 4a3704dc3aa4e..915eaad87f593 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -645,15 +645,8 @@ fn encode_explicit_self(ebml_w: &mut writer::Encoder, explicit_self: ast::explic fn encode_mutability(ebml_w: &writer::Encoder, m: ast::mutability) { match m { - m_imm => { - ebml_w.writer.write(&[ 'i' as u8 ]); - } - m_mutbl => { - ebml_w.writer.write(&[ 'm' as u8 ]); - } - m_const => { - ebml_w.writer.write(&[ 'c' as u8 ]); - } + m_imm => ebml_w.writer.write(&[ 'i' as u8 ]), + m_mutbl => ebml_w.writer.write(&[ 'm' as u8 ]), } } } @@ -1005,7 +998,8 @@ fn encode_info_for_item(ecx: &EncodeContext, encode_name(ecx, ebml_w, item.ident); encode_attributes(ebml_w, item.attrs); match ty.node { - ast::ty_path(ref path, ref bounds, _) if path.idents.len() == 1 => { + ast::ty_path(ref path, ref bounds, _) if path.segments + .len() == 1 => { assert!(bounds.is_none()); encode_impl_type_basename(ecx, ebml_w, ast_util::path_to_ident(path)); diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs index 89b30e46ac06d..f5bad88b1ca66 100644 --- a/src/librustc/metadata/tydecode.rs +++ b/src/librustc/metadata/tydecode.rs @@ -138,12 +138,20 @@ fn parse_path(st: &mut PState) -> @ast::Path { ':' => { next(st); next(st); } c => { if c == '(' { - return @ast::Path { span: dummy_sp(), - global: false, - idents: idents, - rp: None, - types: ~[] }; - } else { idents.push(parse_ident_(st, is_last)); } + return @ast::Path { + span: dummy_sp(), + global: false, + segments: idents.move_iter().map(|identifier| { + ast::PathSegment { + identifier: identifier, + lifetime: None, + types: opt_vec::Empty, + } + }).collect() + }; + } else { + idents.push(parse_ident_(st, is_last)); + } } } }; @@ -417,7 +425,6 @@ fn parse_ty(st: &mut PState, conv: conv_did) -> ty::t { fn parse_mutability(st: &mut PState) -> ast::mutability { match peek(st) { 'm' => { next(st); ast::m_mutbl } - '?' => { next(st); ast::m_const } _ => { ast::m_imm } } } diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs index 915729d254f94..82b79f864848d 100644 --- a/src/librustc/metadata/tyencode.rs +++ b/src/librustc/metadata/tyencode.rs @@ -100,7 +100,6 @@ fn enc_mutability(w: @io::Writer, mt: ast::mutability) { match mt { m_imm => (), m_mutbl => w.write_char('m'), - m_const => w.write_char('?') } } diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index bca1a811a1372..58c70c69e0555 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -374,9 +374,16 @@ impl tr for ast::def { fn tr(&self, xcx: @ExtendedDecodeContext) -> ast::def { match *self { ast::def_fn(did, p) => ast::def_fn(did.tr(xcx), p), - ast::def_static_method(did, did2_opt, p) => { + ast::def_static_method(did, wrapped_did2, p) => { ast::def_static_method(did.tr(xcx), - did2_opt.map(|did2| did2.tr(xcx)), + match wrapped_did2 { + ast::FromTrait(did2) => { + ast::FromTrait(did2.tr(xcx)) + } + ast::FromImpl(did2) => { + ast::FromImpl(did2.tr(xcx)) + } + }, p) } ast::def_method(did0, did1) => { diff --git a/src/librustc/middle/borrowck/check_loans.rs b/src/librustc/middle/borrowck/check_loans.rs index 0fa7750afa7aa..a2178658d3592 100644 --- a/src/librustc/middle/borrowck/check_loans.rs +++ b/src/librustc/middle/borrowck/check_loans.rs @@ -23,12 +23,12 @@ use mc = middle::mem_categorization; use middle::borrowck::*; use middle::moves; use middle::ty; -use syntax::ast::{m_mutbl, m_imm, m_const}; +use syntax::ast::m_mutbl; use syntax::ast; use syntax::ast_util; use syntax::codemap::span; -use syntax::visit; use syntax::visit::Visitor; +use syntax::visit; use util::ppaux::Repr; #[deriving(Clone)] @@ -86,6 +86,44 @@ enum MoveError { } impl<'self> CheckLoanCtxt<'self> { + fn check_by_move_capture(&self, + closure_id: ast::NodeId, + cap_var: &moves::CaptureVar, + move_path: @LoanPath) { + let move_err = self.analyze_move_out_from(closure_id, move_path); + match move_err { + MoveOk => {} + MoveWhileBorrowed(loan_path, loan_span) => { + self.bccx.span_err( + cap_var.span, + fmt!("cannot move `%s` into closure \ + because it is borrowed", + self.bccx.loan_path_to_str(move_path))); + self.bccx.span_note( + loan_span, + fmt!("borrow of `%s` occurs here", + self.bccx.loan_path_to_str(loan_path))); + } + } + } + + fn check_captured_variables(&self, closure_id: ast::NodeId, span: span) { + let cap_vars = self.bccx.capture_map.get(&closure_id); + for cap_var in cap_vars.iter() { + let var_id = ast_util::def_id_of_def(cap_var.def).node; + let var_path = @LpVar(var_id); + self.check_if_path_is_moved(closure_id, span, + MovedInCapture, var_path); + match cap_var.mode { + moves::CapRef | moves::CapCopy => {} + moves::CapMove => { + self.check_by_move_capture(closure_id, cap_var, var_path); + } + } + } + return; + } + pub fn tcx(&self) -> ty::ctxt { self.bccx.tcx } pub fn each_issued_loan(&self, @@ -220,9 +258,9 @@ impl<'self> CheckLoanCtxt<'self> { // Restrictions that would cause the new loan to be illegal: let illegal_if = match loan2.mutbl { - m_mutbl => RESTR_ALIAS | RESTR_FREEZE | RESTR_CLAIM, - m_imm => RESTR_ALIAS | RESTR_FREEZE, - m_const => RESTR_ALIAS, + MutableMutability => RESTR_ALIAS | RESTR_FREEZE | RESTR_CLAIM, + ImmutableMutability => RESTR_ALIAS | RESTR_FREEZE, + ConstMutability => RESTR_ALIAS, }; debug!("illegal_if=%?", illegal_if); @@ -231,7 +269,7 @@ impl<'self> CheckLoanCtxt<'self> { if restr.loan_path != loan2.loan_path { loop; } match (new_loan.mutbl, old_loan.mutbl) { - (m_mutbl, m_mutbl) => { + (MutableMutability, MutableMutability) => { self.bccx.span_err( new_loan.span, fmt!("cannot borrow `%s` as mutable \ @@ -537,7 +575,6 @@ impl<'self> CheckLoanCtxt<'self> { // Otherwise stop iterating LpExtend(_, mc::McDeclared, _) | LpExtend(_, mc::McImmutable, _) | - LpExtend(_, mc::McReadOnly, _) | LpVar(_) => { return true; } @@ -545,8 +582,11 @@ impl<'self> CheckLoanCtxt<'self> { // Check for a non-const loan of `loan_path` let cont = do this.each_in_scope_loan(expr.id) |loan| { - if loan.loan_path == loan_path && loan.mutbl != m_const { - this.report_illegal_mutation(expr, full_loan_path, loan); + if loan.loan_path == loan_path && + loan.mutbl != ConstMutability { + this.report_illegal_mutation(expr, + full_loan_path, + loan); false } else { true @@ -780,3 +820,4 @@ fn check_loans_in_block<'a>(vt: &mut CheckLoanVisitor, visit::walk_block(vt, blk, this); this.check_for_conflicting_loans(blk.id); } + diff --git a/src/librustc/middle/borrowck/gather_loans/lifetime.rs b/src/librustc/middle/borrowck/gather_loans/lifetime.rs index b315a7a2e7290..5bb7e63485e63 100644 --- a/src/librustc/middle/borrowck/gather_loans/lifetime.rs +++ b/src/librustc/middle/borrowck/gather_loans/lifetime.rs @@ -15,7 +15,7 @@ use middle::borrowck::*; use mc = middle::mem_categorization; use middle::ty; -use syntax::ast::{m_const, m_imm, m_mutbl}; +use syntax::ast::{m_imm, m_mutbl}; use syntax::ast; use syntax::codemap::span; use util::ppaux::{note_and_explain_region}; @@ -26,7 +26,7 @@ pub fn guarantee_lifetime(bccx: @BorrowckCtxt, span: span, cmt: mc::cmt, loan_region: ty::Region, - loan_mutbl: ast::mutability) { + loan_mutbl: LoanMutability) { debug!("guarantee_lifetime(cmt=%s, loan_region=%s)", cmt.repr(bccx.tcx), loan_region.repr(bccx.tcx)); let ctxt = GuaranteeLifetimeContext {bccx: bccx, @@ -54,7 +54,7 @@ struct GuaranteeLifetimeContext { span: span, loan_region: ty::Region, - loan_mutbl: ast::mutability, + loan_mutbl: LoanMutability, cmt_original: mc::cmt } @@ -236,11 +236,11 @@ impl GuaranteeLifetimeContext { // we need to dynamically mark it to prevent incompatible // borrows from happening later. let opt_dyna = match ptr_mutbl { - m_imm | m_const => None, + m_imm => None, m_mutbl => { match self.loan_mutbl { - m_mutbl => Some(DynaMut), - m_imm | m_const => Some(DynaImm) + MutableMutability => Some(DynaMut), + ImmutableMutability | ConstMutability => Some(DynaImm) } } }; diff --git a/src/librustc/middle/borrowck/gather_loans/mod.rs b/src/librustc/middle/borrowck/gather_loans/mod.rs index 6d2a4fcc9f31a..dbe5214e0eb50 100644 --- a/src/librustc/middle/borrowck/gather_loans/mod.rs +++ b/src/librustc/middle/borrowck/gather_loans/mod.rs @@ -26,7 +26,6 @@ use middle::ty; use util::common::indenter; use util::ppaux::{Repr}; -use syntax::ast::{m_const, m_imm, m_mutbl}; use syntax::ast; use syntax::ast_util::id_range; use syntax::codemap::span; @@ -237,7 +236,11 @@ fn gather_loans_in_expr(v: &mut GatherLoanVisitor, // make sure that the thing we are pointing out stays valid // for the lifetime `scope_r` of the resulting ptr: let scope_r = ty_region(tcx, ex.span, ty::expr_ty(tcx, ex)); - this.guarantee_valid(ex.id, ex.span, base_cmt, mutbl, scope_r); + this.guarantee_valid(ex.id, + ex.span, + base_cmt, + LoanMutability::from_ast_mutability(mutbl), + scope_r); visit::walk_expr(v, ex, this); } @@ -278,7 +281,11 @@ fn gather_loans_in_expr(v: &mut GatherLoanVisitor, // adjustments). let scope_r = ty::re_scope(ex.id); let arg_cmt = this.bccx.cat_expr(arg); - this.guarantee_valid(arg.id, arg.span, arg_cmt, m_imm, scope_r); + this.guarantee_valid(arg.id, + arg.span, + arg_cmt, + ImmutableMutability, + scope_r); visit::walk_expr(v, ex, this); } @@ -357,18 +364,22 @@ impl GatherLoanCtxt { match *autoref { ty::AutoPtr(r, m) => { + let loan_mutability = + LoanMutability::from_ast_mutability(m); self.guarantee_valid(expr.id, expr.span, cmt, - m, + loan_mutability, r) } ty::AutoBorrowVec(r, m) | ty::AutoBorrowVecRef(r, m) => { let cmt_index = mcx.cat_index(expr, cmt, autoderefs+1); + let loan_mutability = + LoanMutability::from_ast_mutability(m); self.guarantee_valid(expr.id, expr.span, cmt_index, - m, + loan_mutability, r) } ty::AutoBorrowFn(r) => { @@ -376,15 +387,17 @@ impl GatherLoanCtxt { self.guarantee_valid(expr.id, expr.span, cmt_deref, - m_imm, + ImmutableMutability, r) } ty::AutoBorrowObj(r, m) => { let cmt_deref = mcx.cat_deref_fn_or_obj(expr, cmt, 0); + let loan_mutability = + LoanMutability::from_ast_mutability(m); self.guarantee_valid(expr.id, expr.span, cmt_deref, - m, + loan_mutability, r) } ty::AutoUnsafe(_) => {} @@ -402,7 +415,7 @@ impl GatherLoanCtxt { borrow_id: ast::NodeId, borrow_span: span, cmt: mc::cmt, - req_mutbl: ast::mutability, + req_mutbl: LoanMutability, loan_region: ty::Region) { debug!("guarantee_valid(borrow_id=%?, cmt=%s, \ req_mutbl=%?, loan_region=%?)", @@ -473,7 +486,7 @@ impl GatherLoanCtxt { let kill_scope = self.compute_kill_scope(loan_scope, loan_path); debug!("kill_scope = %?", kill_scope); - if req_mutbl == m_mutbl { + if req_mutbl == MutableMutability { self.mark_loan_path_as_mutated(loan_path); } @@ -516,7 +529,7 @@ impl GatherLoanCtxt { // index: all_loans.len(), // loan_path: loan_path, // cmt: cmt, - // mutbl: m_const, + // mutbl: ConstMutability, // gen_scope: borrow_id, // kill_scope: kill_scope, // span: borrow_span, @@ -527,29 +540,20 @@ impl GatherLoanCtxt { fn check_mutability(bccx: @BorrowckCtxt, borrow_span: span, cmt: mc::cmt, - req_mutbl: ast::mutability) { + req_mutbl: LoanMutability) { //! Implements the M-* rules in doc.rs. match req_mutbl { - m_const => { + ConstMutability => { // Data of any mutability can be lent as const. } - m_imm => { - match cmt.mutbl { - mc::McImmutable | mc::McDeclared | mc::McInherited => { - // both imm and mut data can be lent as imm; - // for mutable data, this is a freeze - } - mc::McReadOnly => { - bccx.report(BckError {span: borrow_span, - cmt: cmt, - code: err_mutbl(req_mutbl)}); - } - } + ImmutableMutability => { + // both imm and mut data can be lent as imm; + // for mutable data, this is a freeze } - m_mutbl => { + MutableMutability => { // Only mutable data can be lent as mutable. if !cmt.mutbl.is_mutable() { bccx.report(BckError {span: borrow_span, @@ -561,12 +565,14 @@ impl GatherLoanCtxt { } } - pub fn restriction_set(&self, req_mutbl: ast::mutability) + pub fn restriction_set(&self, req_mutbl: LoanMutability) -> RestrictionSet { match req_mutbl { - m_const => RESTR_EMPTY, - m_imm => RESTR_EMPTY | RESTR_MUTATE | RESTR_CLAIM, - m_mutbl => RESTR_EMPTY | RESTR_MUTATE | RESTR_CLAIM | RESTR_FREEZE + ConstMutability => RESTR_EMPTY, + ImmutableMutability => RESTR_EMPTY | RESTR_MUTATE | RESTR_CLAIM, + MutableMutability => { + RESTR_EMPTY | RESTR_MUTATE | RESTR_CLAIM | RESTR_FREEZE + } } } @@ -582,8 +588,8 @@ impl GatherLoanCtxt { self.mark_loan_path_as_mutated(base); } LpExtend(_, mc::McDeclared, _) | - LpExtend(_, mc::McImmutable, _) | - LpExtend(_, mc::McReadOnly, _) => { + LpExtend(_, mc::McImmutable, _) => { + // Nothing to do. } } } @@ -701,8 +707,13 @@ impl GatherLoanCtxt { } } }; - self.guarantee_valid(pat.id, pat.span, - cmt_discr, mutbl, scope_r); + let loan_mutability = + LoanMutability::from_ast_mutability(mutbl); + self.guarantee_valid(pat.id, + pat.span, + cmt_discr, + loan_mutability, + scope_r); } ast::bind_infer => { // No borrows here, but there may be moves @@ -725,6 +736,8 @@ impl GatherLoanCtxt { self.vec_slice_info(slice_pat, slice_ty); let mcx = self.bccx.mc_ctxt(); let cmt_index = mcx.cat_index(slice_pat, cmt, 0); + let slice_loan_mutability = + LoanMutability::from_ast_mutability(slice_mutbl); // Note: We declare here that the borrow occurs upon // entering the `[...]` pattern. This implies that @@ -743,8 +756,11 @@ impl GatherLoanCtxt { // trans do the right thing, and it would only work // for `~` vectors. It seems simpler to just require // that people call `vec.pop()` or `vec.unshift()`. - self.guarantee_valid(pat.id, pat.span, - cmt_index, slice_mutbl, slice_r); + self.guarantee_valid(pat.id, + pat.span, + cmt_index, + slice_loan_mutability, + slice_r); } _ => {} diff --git a/src/librustc/middle/borrowck/gather_loans/restrictions.rs b/src/librustc/middle/borrowck/gather_loans/restrictions.rs index 46bb23e400ee5..cdd6ed71114a3 100644 --- a/src/librustc/middle/borrowck/gather_loans/restrictions.rs +++ b/src/librustc/middle/borrowck/gather_loans/restrictions.rs @@ -15,7 +15,7 @@ use std::vec; use middle::borrowck::*; use mc = middle::mem_categorization; use middle::ty; -use syntax::ast::{m_const, m_imm, m_mutbl}; +use syntax::ast::{m_imm, m_mutbl}; use syntax::codemap::span; pub enum RestrictionResult { @@ -122,13 +122,6 @@ impl RestrictionsContext { Safe } - mc::cat_deref(_, _, mc::region_ptr(m_const, _)) | - mc::cat_deref(_, _, mc::gc_ptr(m_const)) => { - // R-Deref-Freeze-Borrowed - self.check_no_mutability_control(cmt, restrictions); - Safe - } - mc::cat_deref(cmt_base, _, mc::gc_ptr(m_mutbl)) => { // R-Deref-Managed-Borrowed // diff --git a/src/librustc/middle/borrowck/mod.rs b/src/librustc/middle/borrowck/mod.rs index 95eae32922b7f..7414cefe8bd13 100644 --- a/src/librustc/middle/borrowck/mod.rs +++ b/src/librustc/middle/borrowck/mod.rs @@ -241,12 +241,39 @@ pub enum PartialTotal { /////////////////////////////////////////////////////////////////////////// // Loans and loan paths +#[deriving(Clone, Eq)] +pub enum LoanMutability { + ImmutableMutability, + ConstMutability, + MutableMutability, +} + +impl LoanMutability { + pub fn from_ast_mutability(ast_mutability: ast::mutability) + -> LoanMutability { + match ast_mutability { + ast::m_imm => ImmutableMutability, + ast::m_mutbl => MutableMutability, + } + } +} + +impl ToStr for LoanMutability { + fn to_str(&self) -> ~str { + match *self { + ImmutableMutability => ~"immutable", + ConstMutability => ~"read-only", + MutableMutability => ~"mutable", + } + } +} + /// Record of a loan that was issued. pub struct Loan { index: uint, loan_path: @LoanPath, cmt: mc::cmt, - mutbl: ast::mutability, + mutbl: LoanMutability, restrictions: ~[Restriction], gen_scope: ast::NodeId, kill_scope: ast::NodeId, @@ -418,7 +445,7 @@ impl ToStr for DynaFreezeKind { // Errors that can occur #[deriving(Eq)] pub enum bckerr_code { - err_mutbl(ast::mutability), + err_mutbl(LoanMutability), err_out_of_root_scope(ty::Region, ty::Region), // superscope, subscope err_out_of_scope(ty::Region, ty::Region), // superscope, subscope err_freeze_aliasable_const @@ -795,17 +822,14 @@ impl BorrowckCtxt { mc.cmt_to_str(cmt) } - pub fn mut_to_str(&self, mutbl: ast::mutability) -> ~str { - let mc = &mc::mem_categorization_ctxt {tcx: self.tcx, - method_map: self.method_map}; - mc.mut_to_str(mutbl) + pub fn mut_to_str(&self, mutbl: LoanMutability) -> ~str { + mutbl.to_str() } pub fn mut_to_keyword(&self, mutbl: ast::mutability) -> &'static str { match mutbl { ast::m_imm => "", - ast::m_const => "const", - ast::m_mutbl => "mut" + ast::m_mutbl => "mut", } } } diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs index 0530ffd30b4f0..fc779f73060a0 100644 --- a/src/librustc/middle/check_const.rs +++ b/src/librustc/middle/check_const.rs @@ -141,7 +141,7 @@ pub fn check_expr(v: &mut CheckCrateVisitor, // to handle on-demand instantiation of functions via // foo:: in a const. Currently that is only done on // a path in trans::callee that only works in block contexts. - if pth.types.len() != 0 { + if !pth.segments.iter().all(|segment| segment.types.is_empty()) { sess.span_err( e.span, "paths in constants may only refer to \ items without type parameters"); diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 283724447f831..8bf3f4900b5d9 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -52,7 +52,7 @@ use middle::typeck; use util::ppaux::{ty_to_str, region_ptr_to_str, Repr}; use util::common::indenter; -use syntax::ast::{m_imm, m_const, m_mutbl}; +use syntax::ast::{m_imm, m_mutbl}; use syntax::ast; use syntax::codemap::span; use syntax::print::pprust; @@ -114,7 +114,6 @@ pub enum ElementKind { #[deriving(Eq, IterBytes)] pub enum MutabilityCategory { McImmutable, // Immutable. - McReadOnly, // Read-only (`const`) McDeclared, // Directly declared as mutable. McInherited // Inherited from the fact that owner is mutable. } @@ -298,7 +297,6 @@ impl MutabilityCategory { pub fn from_mutbl(m: ast::mutability) -> MutabilityCategory { match m { m_imm => McImmutable, - m_const => McReadOnly, m_mutbl => McDeclared } } @@ -306,7 +304,6 @@ impl MutabilityCategory { pub fn inherit(&self) -> MutabilityCategory { match *self { McImmutable => McImmutable, - McReadOnly => McReadOnly, McDeclared => McInherited, McInherited => McInherited } @@ -314,7 +311,7 @@ impl MutabilityCategory { pub fn is_mutable(&self) -> bool { match *self { - McImmutable | McReadOnly => false, + McImmutable => false, McDeclared | McInherited => true } } @@ -322,7 +319,7 @@ impl MutabilityCategory { pub fn is_immutable(&self) -> bool { match *self { McImmutable => true, - McReadOnly | McDeclared | McInherited => false + McDeclared | McInherited => false } } @@ -330,7 +327,6 @@ impl MutabilityCategory { match *self { McDeclared | McInherited => "mutable", McImmutable => "immutable", - McReadOnly => "const" } } } @@ -617,7 +613,6 @@ impl mem_categorization_ctxt { -> MutabilityCategory { match interior_m { m_imm => base_m.inherit(), - m_const => McReadOnly, m_mutbl => McDeclared } } @@ -1006,7 +1001,6 @@ impl mem_categorization_ctxt { pub fn mut_to_str(&self, mutbl: ast::mutability) -> ~str { match mutbl { m_mutbl => ~"mutable", - m_const => ~"const", m_imm => ~"immutable" } } @@ -1175,7 +1169,6 @@ impl cmt_ { Some(AliasableManaged(m)) } - cat_deref(_, _, region_ptr(m @ m_const, _)) | cat_deref(_, _, region_ptr(m @ m_imm, _)) => { Some(AliasableBorrowed(m)) } diff --git a/src/librustc/middle/privacy.rs b/src/librustc/middle/privacy.rs index 6a566f10f1e60..ad4a07b82362c 100644 --- a/src/librustc/middle/privacy.rs +++ b/src/librustc/middle/privacy.rs @@ -8,9 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// A pass that checks to make sure private fields and methods aren't used -// outside their scopes. - +//! A pass that checks to make sure private fields and methods aren't used +//! outside their scopes. use metadata::csearch; use middle::ty::{ty_struct, ty_enum}; @@ -251,7 +250,9 @@ impl PrivacyVisitor { match def { def_static_method(method_id, _, _) => { debug!("found static method def, checking it"); - self.check_method_common(span, method_id, path.idents.last()) + self.check_method_common(span, + method_id, + &path.segments.last().identifier) } def_fn(def_id, _) => { if def_id.crate == LOCAL_CRATE { @@ -259,13 +260,19 @@ impl PrivacyVisitor { !self.privileged_items.iter().any(|x| x == &def_id.node) { self.tcx.sess.span_err(span, fmt!("function `%s` is private", - token::ident_to_str(path.idents.last()))); + token::ident_to_str( + &path.segments + .last() + .identifier))); } } else if csearch::get_item_visibility(self.tcx.sess.cstore, def_id) != public { self.tcx.sess.span_err(span, fmt!("function `%s` is private", - token::ident_to_str(path.idents.last()))); + token::ident_to_str( + &path.segments + .last() + .identifier))); } } _ => {} diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index ddd22a0add4c6..d6b6a948a5715 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -827,7 +827,7 @@ fn determine_rp_in_ty(visitor: &mut DetermineRpVisitor, Some(&ast::def_trait(did)) | Some(&ast::def_struct(did)) => { if did.crate == ast::LOCAL_CRATE { - if cx.region_is_relevant(&path.rp) { + if cx.region_is_relevant(&path.segments.last().lifetime) { cx.add_dep(did.node); } } else { @@ -837,7 +837,7 @@ fn determine_rp_in_ty(visitor: &mut DetermineRpVisitor, Some(variance) => { debug!("reference to external, rp'd type %s", pprust::ty_to_str(ty, sess.intr())); - if cx.region_is_relevant(&path.rp) { + if cx.region_is_relevant(&path.segments.last().lifetime) { let rv = cx.add_variance(variance); cx.add_rp(cx.item_id, rv) } @@ -860,7 +860,7 @@ fn determine_rp_in_ty(visitor: &mut DetermineRpVisitor, ast::ty_path(ref path, _, _) => { // type parameters are---for now, anyway---always invariant do cx.with_ambient_variance(rv_invariant) { - for tp in path.types.iter() { + for tp in path.segments.iter().flat_map(|s| s.types.iter()) { visitor.visit_ty(tp, cx); } } diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index 9654bf3fc01fb..720d5d955b265 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -55,6 +55,12 @@ pub type BindingMap = HashMap; // Trait method resolution pub type TraitMap = HashMap; +// A summary of the generics on a trait. +struct TraitGenerics { + has_lifetime: bool, + type_parameter_count: uint, +} + // This is the replacement export map. It maps a module to all of the exports // within. pub type ExportMap2 = @mut HashMap; @@ -1271,7 +1277,7 @@ impl Resolver { &Ty { node: ty_path(ref path, _, _), _ - } if path.idents.len() == 1 => { + } if path.segments.len() == 1 => { let name = path_to_ident(path); let new_parent = match parent.children.find(&name) { @@ -1315,9 +1321,12 @@ impl Resolver { method.span); let def = match method.explicit_self.node { sty_static => { - // Static methods become `def_fn`s. - def_fn(local_def(method.id), - method.purity) + // Static methods become + // `def_static_method`s. + def_static_method(local_def(method.id), + FromImpl(local_def( + item.id)), + method.purity) } _ => { // Non-static methods become @@ -1367,7 +1376,7 @@ impl Resolver { sty_static => { // Static methods become `def_static_method`s. def_static_method(local_def(ty_m.id), - Some(local_def(item.id)), + FromTrait(local_def(item.id)), ty_m.purity) } _ => { @@ -1470,20 +1479,22 @@ impl Resolver { let mut module_path = ~[]; match view_path.node { view_path_simple(_, ref full_path, _) => { - let path_len = full_path.idents.len(); + let path_len = full_path.segments.len(); assert!(path_len != 0); - for (i, ident) in full_path.idents.iter().enumerate() { + for (i, segment) in full_path.segments + .iter() + .enumerate() { if i != path_len - 1 { - module_path.push(*ident); + module_path.push(segment.identifier) } } } view_path_glob(ref module_ident_path, _) | view_path_list(ref module_ident_path, _, _) => { - for ident in module_ident_path.idents.iter() { - module_path.push(*ident); + for segment in module_ident_path.segments.iter() { + module_path.push(segment.identifier) } } } @@ -1492,7 +1503,8 @@ impl Resolver { let module_ = self.get_module_from_parent(parent); match view_path.node { view_path_simple(binding, ref full_path, id) => { - let source_ident = *full_path.idents.last(); + let source_ident = + full_path.segments.last().identifier; let subclass = @SingleImport(binding, source_ident); self.build_import_directive(privacy, @@ -2103,6 +2115,14 @@ impl Resolver { return result; } + fn path_idents_to_str(@mut self, path: &Path) -> ~str { + let identifiers: ~[ast::ident] = path.segments + .iter() + .map(|seg| seg.identifier) + .collect(); + self.idents_to_str(identifiers) + } + pub fn import_directive_subclass_to_str(@mut self, subclass: ImportDirectiveSubclass) -> @str { @@ -3840,8 +3860,7 @@ impl Resolver { reference_type: TraitReferenceType) { match self.resolve_path(id, &trait_reference.path, TypeNS, true, visitor) { None => { - let path_str = self.idents_to_str(trait_reference.path.idents); - + let path_str = self.path_idents_to_str(&trait_reference.path); let usage_str = match reference_type { TraitBoundingTypeParameter => "bound type parameter with", TraitImplementation => "implement", @@ -4140,8 +4159,8 @@ impl Resolver { let mut result_def = None; // First, check to see whether the name is a primitive type. - if path.idents.len() == 1 { - let name = *path.idents.last(); + if path.segments.len() == 1 { + let name = path.segments.last().identifier; match self.primitive_type_table .primitive_types @@ -4150,6 +4169,22 @@ impl Resolver { Some(&primitive_type) => { result_def = Some(def_prim_ty(primitive_type)); + + if path.segments + .iter() + .any(|s| s.lifetime.is_some()) { + self.session.span_err(path.span, + "lifetime parameters \ + are not allowed on \ + this type") + } else if path.segments + .iter() + .any(|s| s.types.len() > 0) { + self.session.span_err(path.span, + "type parameters are \ + not allowed on this \ + type") + } } None => { // Continue. @@ -4159,12 +4194,17 @@ impl Resolver { match result_def { None => { - match self.resolve_path(ty.id, path, TypeNS, true, visitor) { + match self.resolve_path(ty.id, + path, + TypeNS, + true, + visitor) { Some(def) => { debug!("(resolving type) resolved `%s` to \ type %?", - self.session.str_of( - *path.idents.last()), + self.session.str_of(path.segments + .last() + .identifier), def); result_def = Some(def); } @@ -4173,9 +4213,7 @@ impl Resolver { } } } - Some(_) => { - // Continue. - } + Some(_) => {} // Continue. } match result_def { @@ -4183,14 +4221,15 @@ impl Resolver { // Write the result into the def map. debug!("(resolving type) writing resolution for `%s` \ (id %d)", - self.idents_to_str(path.idents), + self.path_idents_to_str(path), path_id); self.record_def(path_id, def); } None => { self.session.span_err - (ty.span, fmt!("use of undeclared type name `%s`", - self.idents_to_str(path.idents))); + (ty.span, + fmt!("use of undeclared type name `%s`", + self.path_idents_to_str(path))) } } @@ -4229,7 +4268,7 @@ impl Resolver { do walk_pat(pattern) |pattern| { match pattern.node { pat_ident(binding_mode, ref path, _) - if !path.global && path.idents.len() == 1 => { + if !path.global && path.segments.len() == 1 => { // The meaning of pat_ident with no type parameters // depends on whether an enum variant or unit-like struct @@ -4240,7 +4279,7 @@ impl Resolver { // such a value is simply disallowed (since it's rarely // what you want). - let ident = path.idents[0]; + let ident = path.segments[0].identifier; match self.resolve_bare_identifier_pattern(ident) { FoundStructOrEnumVariant(def) @@ -4350,7 +4389,9 @@ impl Resolver { } // Check the types in the path pattern. - for ty in path.types.iter() { + for ty in path.segments + .iter() + .flat_map(|seg| seg.types.iter()) { self.resolve_type(ty, visitor); } } @@ -4374,7 +4415,7 @@ impl Resolver { path.span, fmt!("`%s` is not an enum variant or constant", self.session.str_of( - *path.idents.last()))); + path.segments.last().identifier))) } None => { self.session.span_err(path.span, @@ -4383,7 +4424,9 @@ impl Resolver { } // Check the types in the path pattern. - for ty in path.types.iter() { + for ty in path.segments + .iter() + .flat_map(|s| s.types.iter()) { self.resolve_type(ty, visitor); } } @@ -4401,8 +4444,10 @@ impl Resolver { self.session.span_err( path.span, fmt!("`%s` is not an enum variant, struct or const", - self.session.str_of( - *path.idents.last()))); + self.session + .str_of(path.segments + .last() + .identifier))); } None => { self.session.span_err(path.span, @@ -4412,7 +4457,9 @@ impl Resolver { } // Check the types in the path pattern. - for ty in path.types.iter() { + for ty in path.segments + .iter() + .flat_map(|s| s.types.iter()) { self.resolve_type(ty, visitor); } } @@ -4447,7 +4494,7 @@ impl Resolver { self.session.span_err( path.span, fmt!("`%s` does not name a structure", - self.idents_to_str(path.idents))); + self.path_idents_to_str(path))); } } } @@ -4509,7 +4556,7 @@ impl Resolver { visitor: &mut ResolveVisitor) -> Option { // First, resolve the types. - for ty in path.types.iter() { + for ty in path.segments.iter().flat_map(|s| s.types.iter()) { self.resolve_type(ty, visitor); } @@ -4519,20 +4566,27 @@ impl Resolver { namespace); } - let unqualified_def = self.resolve_identifier( - *path.idents.last(), namespace, check_ribs, path.span); + let unqualified_def = self.resolve_identifier(path.segments + .last() + .identifier, + namespace, + check_ribs, + path.span); - if path.idents.len() > 1 { - let def = self.resolve_module_relative_path( - path, self.xray_context, namespace); + if path.segments.len() > 1 { + let def = self.resolve_module_relative_path(path, + self.xray_context, + namespace); match (def, unqualified_def) { (Some(d), Some(ud)) if d == ud => { self.session.add_lint(unnecessary_qualification, - id, path.span, + id, + path.span, ~"unnecessary qualification"); } _ => () } + return def; } @@ -4639,12 +4693,12 @@ impl Resolver { pub fn intern_module_part_of_path(@mut self, path: &Path) -> ~[ident] { let mut module_path_idents = ~[]; - for (index, ident) in path.idents.iter().enumerate() { - if index == path.idents.len() - 1 { + for (index, segment) in path.segments.iter().enumerate() { + if index == path.segments.len() - 1 { break; } - module_path_idents.push(*ident); + module_path_idents.push(segment.identifier); } return module_path_idents; @@ -4680,7 +4734,7 @@ impl Resolver { } } - let name = *path.idents.last(); + let name = path.segments.last().identifier; let def = match self.resolve_definition_of_name_in_module(containing_module, name, namespace, @@ -4748,7 +4802,7 @@ impl Resolver { } } - let name = *path.idents.last(); + let name = path.segments.last().identifier; match self.resolve_definition_of_name_in_module(containing_module, name, namespace, @@ -4951,7 +5005,7 @@ impl Resolver { Some(def) => { // Write the result into the def map. debug!("(resolving expr) resolved `%s`", - self.idents_to_str(path.idents)); + self.path_idents_to_str(path)); // First-class methods are not supported yet; error // out here. @@ -4971,8 +5025,7 @@ impl Resolver { self.record_def(expr.id, def); } None => { - let wrong_name = self.idents_to_str( - path.idents); + let wrong_name = self.path_idents_to_str(path); if self.name_exists_in_scope_struct(wrong_name) { self.session.span_err(expr.span, fmt!("unresolved name `%s`. \ @@ -5030,7 +5083,7 @@ impl Resolver { self.session.span_err( path.span, fmt!("`%s` does not name a structure", - self.idents_to_str(path.idents))); + self.path_idents_to_str(path))); } } diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs index ab5f3289cc722..64fb7b78e2936 100644 --- a/src/librustc/middle/trans/callee.rs +++ b/src/librustc/middle/trans/callee.rs @@ -117,10 +117,13 @@ pub fn trans(bcx: @mut Block, expr: @ast::expr) -> Callee { fn trans_def(bcx: @mut Block, def: ast::def, ref_expr: @ast::expr) -> Callee { match def { - ast::def_fn(did, _) | ast::def_static_method(did, None, _) => { + ast::def_fn(did, _) | + ast::def_static_method(did, ast::FromImpl(_), _) => { fn_callee(bcx, trans_fn_ref(bcx, did, ref_expr.id)) } - ast::def_static_method(impl_did, Some(trait_did), _) => { + ast::def_static_method(impl_did, + ast::FromTrait(trait_did), + _) => { fn_callee(bcx, meth::trans_static_method_callee(bcx, impl_did, trait_did, ref_expr.id)) diff --git a/src/librustc/middle/trans/consts.rs b/src/librustc/middle/trans/consts.rs index 87d26fa5ba07c..771decb4e6c1b 100644 --- a/src/librustc/middle/trans/consts.rs +++ b/src/librustc/middle/trans/consts.rs @@ -559,7 +559,9 @@ fn const_expr_unadjusted(cx: @mut CrateContext, e: &ast::expr) -> ValueRef { v } ast::expr_path(ref pth) => { - assert_eq!(pth.types.len(), 0); + // Assert that there are no type parameters in this path. + assert!(pth.segments.iter().all(|seg| seg.types.is_empty())); + let tcx = cx.tcx; match tcx.def_map.find(&e.id) { Some(&ast::def_fn(def_id, _purity)) => { diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index 2ce8756848fa8..dc2b764c978e1 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -821,12 +821,14 @@ fn trans_def_datum_unadjusted(bcx: @mut Block, let _icx = push_ctxt("trans_def_datum_unadjusted"); match def { - ast::def_fn(did, _) | ast::def_static_method(did, None, _) => { + ast::def_fn(did, _) | + ast::def_static_method(did, ast::FromImpl(_), _) => { let fn_data = callee::trans_fn_ref(bcx, did, ref_expr.id); return fn_data_to_datum(bcx, ref_expr, did, fn_data); } - ast::def_static_method(impl_did, Some(trait_did), _) => { - let fn_data = meth::trans_static_method_callee(bcx, impl_did, + ast::def_static_method(impl_did, ast::FromTrait(trait_did), _) => { + let fn_data = meth::trans_static_method_callee(bcx, + impl_did, trait_did, ref_expr.id); return fn_data_to_datum(bcx, ref_expr, impl_did, fn_data); diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs index c666e98c9c15f..735e9a8a37f4d 100644 --- a/src/librustc/middle/typeck/astconv.rs +++ b/src/librustc/middle/typeck/astconv.rs @@ -63,7 +63,6 @@ use middle::typeck::rscope::RegionParamNames; use middle::typeck::lookup_def_tcx; use std::result; -use std::vec; use syntax::abi::AbiSet; use syntax::{ast, ast_util}; use syntax::codemap::span; @@ -150,7 +149,8 @@ fn ast_path_substs( // If the type is parameterized by the this region, then replace this // region with the current anon region binding (in other words, // whatever & would get replaced with). - let regions = match (&decl_generics.region_param, &path.rp) { + let regions = match (&decl_generics.region_param, + &path.segments.last().lifetime) { (&None, &None) => { opt_vec::Empty } @@ -169,20 +169,34 @@ fn ast_path_substs( } (&Some(_), &Some(_)) => { opt_vec::with( - ast_region_to_region(this, rscope, path.span, &path.rp)) + ast_region_to_region(this, + rscope, + path.span, + &path.segments.last().lifetime)) } }; // Convert the type parameters supplied by the user. - if !vec::same_length(*decl_generics.type_param_defs, path.types) { + let supplied_type_parameter_count = + path.segments.iter().flat_map(|s| s.types.iter()).len(); + if decl_generics.type_param_defs.len() != supplied_type_parameter_count { this.tcx().sess.span_fatal( path.span, fmt!("wrong number of type arguments: expected %u but found %u", - decl_generics.type_param_defs.len(), path.types.len())); + decl_generics.type_param_defs.len(), + supplied_type_parameter_count)); + } + let tps = path.segments + .iter() + .flat_map(|s| s.types.iter()) + .map(|a_t| ast_ty_to_ty(this, rscope, a_t)) + .collect(); + + substs { + regions: ty::NonerasedRegions(regions), + self_ty: self_ty, + tps: tps } - let tps = path.types.map(|a_t| ast_ty_to_ty(this, rscope, a_t)); - - substs {regions:ty::NonerasedRegions(regions), self_ty:self_ty, tps:tps} } pub fn ast_path_to_substs_and_ty( match a_seq_ty.ty.node { ast::ty_vec(ref mt) => { let mut mt = ast_mt_to_mt(this, rscope, mt); - if a_seq_ty.mutbl == ast::m_mutbl || - a_seq_ty.mutbl == ast::m_const { + if a_seq_ty.mutbl == ast::m_mutbl { mt = ty::mt { ty: mt.ty, mutbl: a_seq_ty.mutbl }; } return ty::mk_evec(tcx, mt, vst); @@ -326,7 +339,7 @@ pub fn ast_ty_to_ty( path: &ast::Path, flags: uint) { if (flags & NO_TPS) != 0u { - if path.types.len() > 0u { + if !path.segments.iter().all(|s| s.types.is_empty()) { tcx.sess.span_err( path.span, "type parameters are not allowed on this type"); @@ -334,7 +347,7 @@ pub fn ast_ty_to_ty( } if (flags & NO_REGIONS) != 0u { - if path.rp.is_some() { + if path.segments.last().lifetime.is_some() { tcx.sess.span_err( path.span, "region parameters are not allowed on this type"); diff --git a/src/librustc/middle/typeck/check/_match.rs b/src/librustc/middle/typeck/check/_match.rs index b7114e602830f..628ceccd61e7e 100644 --- a/src/librustc/middle/typeck/check/_match.rs +++ b/src/librustc/middle/typeck/check/_match.rs @@ -128,7 +128,12 @@ pub fn check_pat_variant(pcx: &pat_ctxt, pat: @ast::pat, path: &ast::Path, Some((enm, var)) => { // Assign the pattern the type of the *enum*, not the variant. let enum_tpt = ty::lookup_item_type(tcx, enm); - instantiate_path(pcx.fcx, path, enum_tpt, pat.span, pat.id); + instantiate_path(pcx.fcx, + path, + enum_tpt, + v_def, + pat.span, + pat.id); // check that the type of the value being matched is a subtype // of the type of the pattern: @@ -185,7 +190,12 @@ pub fn check_pat_variant(pcx: &pat_ctxt, pat: @ast::pat, path: &ast::Path, } else { ctor_tpt }; - instantiate_path(pcx.fcx, path, struct_tpt, pat.span, pat.id); + instantiate_path(pcx.fcx, + path, + struct_tpt, + s_def, + pat.span, + pat.id); // Check that the type of the value being matched is a subtype of // the type of the pattern. diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs index 352836d81e459..84f238496c2ff 100644 --- a/src/librustc/middle/typeck/check/method.rs +++ b/src/librustc/middle/typeck/check/method.rs @@ -102,7 +102,7 @@ use std::vec; use extra::list::Nil; use syntax::ast::{def_id, sty_value, sty_region, sty_box}; use syntax::ast::{sty_uniq, sty_static, NodeId}; -use syntax::ast::{m_const, m_mutbl, m_imm}; +use syntax::ast::{m_mutbl, m_imm}; use syntax::ast; use syntax::ast_map; @@ -653,7 +653,7 @@ impl<'self> LookupContext<'self> { ty_evec(mt, vstore_fixed(_)) => { // First try to borrow to a slice let entry = self.search_for_some_kind_of_autorefd_method( - AutoBorrowVec, autoderefs, [m_const, m_imm, m_mutbl], + AutoBorrowVec, autoderefs, [m_imm, m_mutbl], |m,r| ty::mk_evec(tcx, ty::mt {ty:mt.ty, mutbl:m}, vstore_slice(r))); @@ -662,7 +662,7 @@ impl<'self> LookupContext<'self> { // Then try to borrow to a slice *and* borrow a pointer. self.search_for_some_kind_of_autorefd_method( - AutoBorrowVecRef, autoderefs, [m_const, m_imm, m_mutbl], + AutoBorrowVecRef, autoderefs, [m_imm, m_mutbl], |m,r| { let slice_ty = ty::mk_evec(tcx, ty::mt {ty:mt.ty, mutbl:m}, @@ -697,7 +697,7 @@ impl<'self> LookupContext<'self> { // Coerce ~/@/&Trait instances to &Trait. self.search_for_some_kind_of_autorefd_method( - AutoBorrowObj, autoderefs, [m_const, m_imm, m_mutbl], + AutoBorrowObj, autoderefs, [m_imm, m_mutbl], |trt_mut, reg| { ty::mk_trait(tcx, trt_did, trt_substs.clone(), RegionTraitStore(reg), trt_mut, b) @@ -732,7 +732,7 @@ impl<'self> LookupContext<'self> { ty_float(*) | ty_enum(*) | ty_ptr(*) | ty_struct(*) | ty_tup(*) | ty_estr(*) | ty_evec(*) | ty_trait(*) | ty_closure(*) => { self.search_for_some_kind_of_autorefd_method( - AutoPtr, autoderefs, [m_const, m_imm, m_mutbl], + AutoPtr, autoderefs, [m_imm, m_mutbl], |m,r| ty::mk_rptr(tcx, r, ty::mt {ty:self_ty, mutbl:m})) } @@ -1220,18 +1220,10 @@ impl<'self> LookupContext<'self> { } fn mutability_matches(self_mutbl: ast::mutability, - candidate_mutbl: ast::mutability) -> bool { + candidate_mutbl: ast::mutability) + -> bool { //! True if `self_mutbl <: candidate_mutbl` - - match (self_mutbl, candidate_mutbl) { - (_, m_const) => true, - (m_mutbl, m_mutbl) => true, - (m_imm, m_imm) => true, - (m_mutbl, m_imm) => false, - (m_imm, m_mutbl) => false, - (m_const, m_imm) => false, - (m_const, m_mutbl) => false, - } + self_mutbl == candidate_mutbl } } diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index ad6bf69d55ad6..7d992365d3b44 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -377,7 +377,7 @@ impl Visitor<()> for GatherLocalsVisitor { if pat_util::pat_is_binding(self.fcx.ccx.tcx.def_map, p) => { self.assign(p.id, None); debug!("Pattern binding %s is assigned to %s", - self.tcx.sess.str_of(path.idents[0]), + self.tcx.sess.str_of(path.segments[0].identifier), self.fcx.infcx().ty_to_str( self.fcx.inh.locals.get_copy(&p.id))); } @@ -1132,8 +1132,160 @@ pub enum DerefArgs { DoDerefArgs } -pub fn break_here() { - debug!("break here!"); +// Given the provenance of a static method, returns the generics of the static +// method's container. +fn generics_of_static_method_container(type_context: ty::ctxt, + provenance: ast::MethodProvenance) + -> ty::Generics { + match provenance { + ast::FromTrait(trait_def_id) => { + ty::lookup_trait_def(type_context, trait_def_id).generics + } + ast::FromImpl(impl_def_id) => { + ty::lookup_item_type(type_context, impl_def_id).generics + } + } +} + +// Verifies that type parameters supplied in paths are in the right +// locations. +fn check_type_parameter_positions_in_path(function_context: @mut FnCtxt, + path: &ast::Path, + def: ast::def) { + // We only care about checking the case in which the path has two or + // more segments. + if path.segments.len() < 2 { + return + } + + // Verify that no lifetimes or type parameters are present anywhere + // except the final two elements of the path. + for i in range(0, path.segments.len() - 2) { + match path.segments[i].lifetime { + None => {} + Some(lifetime) => { + function_context.tcx() + .sess + .span_err(lifetime.span, + "lifetime parameters may not \ + appear here") + } + } + + for typ in path.segments[i].types.iter() { + function_context.tcx() + .sess + .span_err(typ.span, + "type parameters may not appear here") + } + } + + // If there are no parameters at all, there is nothing more to do; the + // rest of typechecking will (attempt to) infer everything. + if path.segments + .iter() + .all(|s| s.lifetime.is_none() && s.types.is_empty()) { + return + } + + match def { + // If this is a static method of a trait or implementation, then + // ensure that the segment of the path which names the trait or + // implementation (the penultimate segment) is annotated with the + // right number of type parameters. + ast::def_static_method(_, provenance, _) => { + let generics = + generics_of_static_method_container(function_context.ccx.tcx, + provenance); + let name = match provenance { + ast::FromTrait(_) => "trait", + ast::FromImpl(_) => "impl", + }; + + let trait_segment = &path.segments[path.segments.len() - 2]; + + // Make sure lifetime parameterization agrees with the trait or + // implementation type. + match (generics.region_param, trait_segment.lifetime) { + (Some(_), None) => { + function_context.tcx() + .sess + .span_err(path.span, + fmt!("this %s has a lifetime \ + parameter but no \ + lifetime was specified", + name)) + } + (None, Some(_)) => { + function_context.tcx() + .sess + .span_err(path.span, + fmt!("this %s has no lifetime \ + parameter but a lifetime \ + was specified", + name)) + } + (Some(_), Some(_)) | (None, None) => {} + } + + // Make sure the number of type parameters supplied on the trait + // or implementation segment equals the number of type parameters + // on the trait or implementation definition. + let trait_type_parameter_count = generics.type_param_defs.len(); + let supplied_type_parameter_count = trait_segment.types.len(); + if trait_type_parameter_count != supplied_type_parameter_count { + let trait_count_suffix = if trait_type_parameter_count == 1 { + "" + } else { + "s" + }; + let supplied_count_suffix = + if supplied_type_parameter_count == 1 { + "" + } else { + "s" + }; + function_context.tcx() + .sess + .span_err(path.span, + fmt!("the %s referenced by this \ + path has %u type \ + parameter%s, but %u type \ + parameter%s were supplied", + name, + trait_type_parameter_count, + trait_count_suffix, + supplied_type_parameter_count, + supplied_count_suffix)) + } + } + _ => { + // Verify that no lifetimes or type parameters are present on + // the penultimate segment of the path. + let segment = &path.segments[path.segments.len() - 2]; + match segment.lifetime { + None => {} + Some(lifetime) => { + function_context.tcx() + .sess + .span_err(lifetime.span, + "lifetime parameters may not + appear here") + } + } + for typ in segment.types.iter() { + function_context.tcx() + .sess + .span_err(typ.span, + "type parameters may not appear \ + here"); + function_context.tcx() + .sess + .span_note(typ.span, + fmt!("this is a %?", def)); + } + } + } } /// Invariant: @@ -2333,8 +2485,9 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, ast::expr_path(ref pth) => { let defn = lookup_def(fcx, pth.span, id); + check_type_parameter_positions_in_path(fcx, pth, defn); let tpt = ty_param_bounds_and_ty_for_def(fcx, expr.span, defn); - instantiate_path(fcx, pth, tpt, expr.span, expr.id); + instantiate_path(fcx, pth, tpt, defn, expr.span, expr.id); } ast::expr_self => { let definition = lookup_def(fcx, expr.span, id); @@ -3158,12 +3311,16 @@ pub fn ty_param_bounds_and_ty_for_def(fcx: @mut FnCtxt, pub fn instantiate_path(fcx: @mut FnCtxt, pth: &ast::Path, tpt: ty_param_bounds_and_ty, + def: ast::def, span: span, node_id: ast::NodeId) { debug!(">>> instantiate_path"); let ty_param_count = tpt.generics.type_param_defs.len(); - let ty_substs_len = pth.types.len(); + let mut ty_substs_len = 0; + for segment in pth.segments.iter() { + ty_substs_len += segment.types.len() + } debug!("ty_param_count=%? ty_substs_len=%?", ty_param_count, @@ -3171,7 +3328,7 @@ pub fn instantiate_path(fcx: @mut FnCtxt, // determine the region bound, using the value given by the user // (if any) and otherwise using a fresh region variable - let regions = match pth.rp { + let regions = match pth.segments.last().lifetime { Some(_) => { // user supplied a lifetime parameter... match tpt.generics.region_param { None => { // ...but the type is not lifetime parameterized! @@ -3181,7 +3338,10 @@ pub fn instantiate_path(fcx: @mut FnCtxt, } Some(_) => { // ...and the type is lifetime parameterized, ok. opt_vec::with( - ast_region_to_region(fcx, fcx, span, &pth.rp)) + ast_region_to_region(fcx, + fcx, + span, + &pth.segments.last().lifetime)) } } } @@ -3190,6 +3350,21 @@ pub fn instantiate_path(fcx: @mut FnCtxt, } }; + // Special case: If there is a self parameter, omit it from the list of + // type parameters. + // + // Here we calculate the "user type parameter count", which is the number + // of type parameters actually manifest in the AST. This will differ from + // the internal type parameter count when there are self types involved. + let (user_type_parameter_count, self_parameter_index) = match def { + ast::def_static_method(_, provenance @ ast::FromTrait(_), _) => { + let generics = generics_of_static_method_container(fcx.ccx.tcx, + provenance); + (ty_param_count - 1, Some(generics.type_param_defs.len())) + } + _ => (ty_param_count, None), + }; + // determine values for type parameters, using the values given by // the user (if any) and otherwise using fresh type variables let tps = if ty_substs_len == 0 { @@ -3198,34 +3373,51 @@ pub fn instantiate_path(fcx: @mut FnCtxt, fcx.ccx.tcx.sess.span_err (span, "this item does not take type parameters"); fcx.infcx().next_ty_vars(ty_param_count) - } else if ty_substs_len > ty_param_count { + } else if ty_substs_len > user_type_parameter_count { fcx.ccx.tcx.sess.span_err (span, fmt!("too many type parameters provided: expected %u, found %u", - ty_param_count, ty_substs_len)); + user_type_parameter_count, ty_substs_len)); fcx.infcx().next_ty_vars(ty_param_count) - } else if ty_substs_len < ty_param_count { - let is_static_method = match fcx.ccx.tcx.def_map.find(&node_id) { - Some(&ast::def_static_method(*)) => true, - _ => false - }; + } else if ty_substs_len < user_type_parameter_count { fcx.ccx.tcx.sess.span_err (span, fmt!("not enough type parameters provided: expected %u, found %u", - ty_param_count, ty_substs_len)); - if is_static_method { - fcx.ccx.tcx.sess.span_note - (span, "Static methods have an extra implicit type parameter -- \ - did you omit the type parameter for the `Self` type?"); - } + user_type_parameter_count, ty_substs_len)); fcx.infcx().next_ty_vars(ty_param_count) } else { - pth.types.map(|aty| fcx.to_ty(aty)) + // Build up the list of type parameters, inserting the self parameter + // at the appropriate position. + let mut result = ~[]; + let mut pushed = false; + for (i, ast_type) in pth.segments + .iter() + .flat_map(|segment| segment.types.iter()) + .enumerate() { + match self_parameter_index { + Some(index) if index == i => { + result.push(fcx.infcx().next_ty_vars(1)[0]); + pushed = true; + } + _ => {} + } + result.push(fcx.to_ty(ast_type)) + } + + // If the self parameter goes at the end, insert it there. + if !pushed && self_parameter_index.is_some() { + result.push(fcx.infcx().next_ty_vars(1)[0]) + } + + assert_eq!(result.len(), ty_param_count) + result }; - let substs = substs {regions: ty::NonerasedRegions(regions), - self_ty: None, - tps: tps }; + let substs = substs { + regions: ty::NonerasedRegions(regions), + self_ty: None, + tps: tps + }; fcx.write_ty_substs(node_id, tpt.ty, substs); debug!("<<<"); diff --git a/src/librustc/middle/typeck/infer/glb.rs b/src/librustc/middle/typeck/infer/glb.rs index f05388344bc71..4b951d00677d6 100644 --- a/src/librustc/middle/typeck/infer/glb.rs +++ b/src/librustc/middle/typeck/infer/glb.rs @@ -22,7 +22,7 @@ use middle::typeck::infer::{TypeTrace, Subtype}; use middle::typeck::infer::fold_regions_in_sig; use middle::typeck::isr_alist; use syntax::ast; -use syntax::ast::{Many, Once, extern_fn, impure_fn, m_const, m_imm, m_mutbl}; +use syntax::ast::{Many, Once, extern_fn, impure_fn, m_imm, m_mutbl}; use syntax::ast::{unsafe_fn}; use syntax::ast::{Onceness, purity}; use syntax::abi::AbiSet; @@ -54,16 +54,6 @@ impl Combine for Glb { match (a.mutbl, b.mutbl) { // If one side or both is mut, then the GLB must use // the precise type from the mut side. - (m_mutbl, m_const) => { - Sub(**self).tys(a.ty, b.ty).chain(|_t| { - Ok(ty::mt {ty: a.ty, mutbl: m_mutbl}) - }) - } - (m_const, m_mutbl) => { - Sub(**self).tys(b.ty, a.ty).chain(|_t| { - Ok(ty::mt {ty: b.ty, mutbl: m_mutbl}) - }) - } (m_mutbl, m_mutbl) => { eq_tys(self, a.ty, b.ty).then(|| { Ok(ty::mt {ty: a.ty, mutbl: m_mutbl}) @@ -72,22 +62,12 @@ impl Combine for Glb { // If one side or both is immutable, we can use the GLB of // both sides but mutbl must be `m_imm`. - (m_imm, m_const) | - (m_const, m_imm) | (m_imm, m_imm) => { self.tys(a.ty, b.ty).chain(|t| { Ok(ty::mt {ty: t, mutbl: m_imm}) }) } - // If both sides are const, then we can use GLB of both - // sides and mutbl of only `m_const`. - (m_const, m_const) => { - self.tys(a.ty, b.ty).chain(|t| { - Ok(ty::mt {ty: t, mutbl: m_const}) - }) - } - // There is no mutual subtype of these combinations. (m_mutbl, m_imm) | (m_imm, m_mutbl) => { diff --git a/src/librustc/middle/typeck/infer/lub.rs b/src/librustc/middle/typeck/infer/lub.rs index 8afb5a18d4f6f..c97b99aaf0c08 100644 --- a/src/librustc/middle/typeck/infer/lub.rs +++ b/src/librustc/middle/typeck/infer/lub.rs @@ -26,7 +26,7 @@ use util::ppaux::mt_to_str; use extra::list; use syntax::abi::AbiSet; use syntax::ast; -use syntax::ast::{Many, Once, extern_fn, m_const, impure_fn}; +use syntax::ast::{Many, Once, extern_fn, impure_fn}; use syntax::ast::{unsafe_fn}; use syntax::ast::{Onceness, purity}; @@ -57,14 +57,13 @@ impl Combine for Lub { mt_to_str(tcx, a), mt_to_str(tcx, b)); - let m = if a.mutbl == b.mutbl { - a.mutbl - } else { - m_const - }; + if a.mutbl != b.mutbl { + return Err(ty::terr_mutability) + } + let m = a.mutbl; match m { - m_imm | m_const => { + m_imm => { self.tys(a.ty, b.ty).chain(|t| Ok(ty::mt {ty: t, mutbl: m}) ) } @@ -73,11 +72,7 @@ impl Combine for Lub { eq_tys(self, a.ty, b.ty).then(|| { Ok(ty::mt {ty: a.ty, mutbl: m}) }) - }).chain_err(|_e| { - self.tys(a.ty, b.ty).chain(|t| { - Ok(ty::mt {ty: t, mutbl: m_const}) - }) - }) + }).chain_err(|e| Err(e)) } } } diff --git a/src/librustc/middle/typeck/infer/sub.rs b/src/librustc/middle/typeck/infer/sub.rs index 441e71d4722b8..3a4d7df6a5b93 100644 --- a/src/librustc/middle/typeck/infer/sub.rs +++ b/src/librustc/middle/typeck/infer/sub.rs @@ -28,7 +28,7 @@ use extra::list::Nil; use extra::list; use syntax::abi::AbiSet; use syntax::ast; -use syntax::ast::{Onceness, m_const, purity}; +use syntax::ast::{Onceness, purity}; pub struct Sub(CombineFields); // "subtype", "subregion" etc @@ -69,7 +69,7 @@ impl Combine for Sub { fn mts(&self, a: &ty::mt, b: &ty::mt) -> cres { debug!("mts(%s <: %s)", a.inf_str(self.infcx), b.inf_str(self.infcx)); - if a.mutbl != b.mutbl && b.mutbl != m_const { + if a.mutbl != b.mutbl { return Err(ty::terr_mutability); } @@ -79,7 +79,7 @@ impl Combine for Sub { // (i.e., invariant if mut): eq_tys(self, a.ty, b.ty).then(|| Ok(*a)) } - m_imm | m_const => { + m_imm => { // Otherwise we can be covariant: self.tys(a.ty, b.ty).chain(|_t| Ok(*a) ) } diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 5ba52326579e1..ba803521eda9d 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -239,7 +239,6 @@ fn mutability_to_str(m: ast::mutability) -> ~str { match m { ast::m_mutbl => ~"mut ", ast::m_imm => ~"", - ast::m_const => ~"const " } } diff --git a/src/libstd/at_vec.rs b/src/libstd/at_vec.rs index 120946ad161e3..c031a4d28051e 100644 --- a/src/libstd/at_vec.rs +++ b/src/libstd/at_vec.rs @@ -278,7 +278,7 @@ pub mod raw { use rt::local::Local; use rt::task::Task; - do Local::borrow:: |task| { + do Local::borrow |task: &mut Task| { task.heap.realloc(ptr as *libc::c_void, size) as *() } } diff --git a/src/libstd/cast.rs b/src/libstd/cast.rs index 9d1d6e65901ae..7512dd3457a3a 100644 --- a/src/libstd/cast.rs +++ b/src/libstd/cast.rs @@ -10,6 +10,7 @@ //! Unsafe casting functions +use ptr::RawPtr; use sys; use unstable::intrinsics; @@ -91,13 +92,13 @@ pub unsafe fn transmute_region<'a,'b,T>(ptr: &'a T) -> &'b T { /// Coerce an immutable reference to be mutable. #[inline] -pub unsafe fn transmute_mut_unsafe(ptr: *const T) -> *mut T { +pub unsafe fn transmute_mut_unsafe>(ptr: P) -> *mut T { transmute(ptr) } /// Coerce an immutable reference to be mutable. #[inline] -pub unsafe fn transmute_immut_unsafe(ptr: *const T) -> *T { +pub unsafe fn transmute_immut_unsafe>(ptr: P) -> *T { transmute(ptr) } diff --git a/src/libstd/cell.rs b/src/libstd/cell.rs index 372effad61d3c..918731073ba8c 100644 --- a/src/libstd/cell.rs +++ b/src/libstd/cell.rs @@ -95,7 +95,7 @@ fn test_basic() { #[should_fail] #[ignore(cfg(windows))] fn test_take_empty() { - let value_cell = Cell::new_empty::<~int>(); + let value_cell: Cell<~int> = Cell::new_empty(); value_cell.take(); } diff --git a/src/libstd/cleanup.rs b/src/libstd/cleanup.rs index 6a6ba12bae301..6b982ec75da12 100644 --- a/src/libstd/cleanup.rs +++ b/src/libstd/cleanup.rs @@ -11,7 +11,7 @@ #[doc(hidden)]; use libc::c_void; -use ptr::{mut_null}; +use ptr::null; use unstable::intrinsics::TyDesc; use unstable::raw; @@ -37,7 +37,7 @@ unsafe fn each_live_alloc(read_next_before: bool, use rt::local_heap; let mut box = local_heap::live_allocs(); - while box != mut_null() { + while box != null() { let next_before = (*box).next; let uniq = (*box).ref_count == managed::RC_MANAGED_UNIQUE; diff --git a/src/libstd/fmt/mod.rs b/src/libstd/fmt/mod.rs index db8a17c0bd070..2aba1c3e1366d 100644 --- a/src/libstd/fmt/mod.rs +++ b/src/libstd/fmt/mod.rs @@ -862,10 +862,17 @@ impl Poly for T { } } -// n.b. use 'const' to get an implementation for both '*mut' and '*' at the same -// time. -impl Pointer for *const T { - fn fmt(t: &*const T, f: &mut Formatter) { +impl Pointer for *T { + fn fmt(t: &*T, f: &mut Formatter) { + f.flags |= 1 << (parse::FlagAlternate as uint); + do ::uint::to_str_bytes(*t as uint, 16) |buf| { + f.pad_integral(buf, "0x", true); + } + } +} + +impl Pointer for *mut T { + fn fmt(t: &*mut T, f: &mut Formatter) { f.flags |= 1 << (parse::FlagAlternate as uint); do ::uint::to_str_bytes(*t as uint, 16) |buf| { f.pad_integral(buf, "0x", true); @@ -901,8 +908,12 @@ delegate!(float to Float) delegate!(f32 to Float) delegate!(f64 to Float) -impl Default for *const T { - fn fmt(me: &*const T, f: &mut Formatter) { Pointer::fmt(me, f) } +impl Default for *T { + fn fmt(me: &*T, f: &mut Formatter) { Pointer::fmt(me, f) } +} + +impl Default for *mut T { + fn fmt(me: &*mut T, f: &mut Formatter) { Pointer::fmt(me, f) } } // If you expected tests to be here, look instead at the run-pass/ifmt.rs test, diff --git a/src/libstd/hashmap.rs b/src/libstd/hashmap.rs index 50e59cf438d0c..bcd658ece6653 100644 --- a/src/libstd/hashmap.rs +++ b/src/libstd/hashmap.rs @@ -869,21 +869,21 @@ mod test_map { #[test] fn test_find_or_insert() { - let mut m = HashMap::new::(); + let mut m: HashMap = HashMap::new(); assert_eq!(*m.find_or_insert(1, 2), 2); assert_eq!(*m.find_or_insert(1, 3), 2); } #[test] fn test_find_or_insert_with() { - let mut m = HashMap::new::(); + let mut m: HashMap = HashMap::new(); assert_eq!(*m.find_or_insert_with(1, |_| 2), 2); assert_eq!(*m.find_or_insert_with(1, |_| 3), 2); } #[test] fn test_insert_or_update_with() { - let mut m = HashMap::new::(); + let mut m: HashMap = HashMap::new(); assert_eq!(*m.insert_or_update_with(1, 2, |_,x| *x+=1), 2); assert_eq!(*m.insert_or_update_with(1, 2, |_,x| *x+=1), 3); } diff --git a/src/libstd/iterator.rs b/src/libstd/iterator.rs index 1d32c5df14ed9..e12e0581e044e 100644 --- a/src/libstd/iterator.rs +++ b/src/libstd/iterator.rs @@ -639,7 +639,10 @@ pub trait AdditiveIterator { impl + Zero, T: Iterator> AdditiveIterator for T { #[inline] - fn sum(&mut self) -> A { self.fold(Zero::zero::(), |s, x| s + x) } + fn sum(&mut self) -> A { + let zero: A = Zero::zero(); + self.fold(zero, |s, x| s + x) + } } /// A trait for iterators over elements whose elements can be multiplied @@ -664,7 +667,10 @@ pub trait MultiplicativeIterator { impl + One, T: Iterator> MultiplicativeIterator for T { #[inline] - fn product(&mut self) -> A { self.fold(One::one::(), |p, x| p * x) } + fn product(&mut self) -> A { + let one: A = One::one(); + self.fold(one, |p, x| p * x) + } } /// A trait for iterators over elements which can be compared to one another. diff --git a/src/libstd/logging.rs b/src/libstd/logging.rs index 7de55f48317a5..215067ea72919 100644 --- a/src/libstd/logging.rs +++ b/src/libstd/logging.rs @@ -59,7 +59,8 @@ fn newsched_log_str(msg: ~str) { use rt::local::Local; unsafe { - match Local::try_unsafe_borrow::() { + let optional_task: Option<*mut Task> = Local::try_unsafe_borrow(); + match optional_task { Some(local) => { // Use the available logger (*local).logger.log(Left(msg)); diff --git a/src/libstd/num/f32.rs b/src/libstd/num/f32.rs index 17175de9b929d..6333b25a160bc 100644 --- a/src/libstd/num/f32.rs +++ b/src/libstd/num/f32.rs @@ -182,7 +182,7 @@ impl ApproxEq for f32 { #[inline] fn approx_eq(&self, other: &f32) -> bool { - self.approx_eq_eps(other, &ApproxEq::approx_epsilon::()) + self.approx_eq_eps(other, &1.0e-6) } #[inline] @@ -561,11 +561,14 @@ impl Real for f32 { /// Converts to degrees, assuming the number is in radians #[inline] - fn to_degrees(&self) -> f32 { *self * (180.0 / Real::pi::()) } + fn to_degrees(&self) -> f32 { *self * (180.0f32 / Real::pi()) } /// Converts to radians, assuming the number is in degrees #[inline] - fn to_radians(&self) -> f32 { *self * (Real::pi::() / 180.0) } + fn to_radians(&self) -> f32 { + let value: f32 = Real::pi(); + *self * (value / 180.0f32) + } } impl Bounded for f32 { @@ -578,10 +581,10 @@ impl Bounded for f32 { impl Primitive for f32 { #[inline] - fn bits() -> uint { 32 } + fn bits(_: Option) -> uint { 32 } #[inline] - fn bytes() -> uint { Primitive::bits::() / 8 } + fn bytes(_: Option) -> uint { Primitive::bits(Some(0f32)) / 8 } } impl Float for f32 { @@ -638,25 +641,25 @@ impl Float for f32 { } #[inline] - fn mantissa_digits() -> uint { 24 } + fn mantissa_digits(_: Option) -> uint { 24 } #[inline] - fn digits() -> uint { 6 } + fn digits(_: Option) -> uint { 6 } #[inline] fn epsilon() -> f32 { 1.19209290e-07 } #[inline] - fn min_exp() -> int { -125 } + fn min_exp(_: Option) -> int { -125 } #[inline] - fn max_exp() -> int { 128 } + fn max_exp(_: Option) -> int { 128 } #[inline] - fn min_10_exp() -> int { -37 } + fn min_10_exp(_: Option) -> int { -37 } #[inline] - fn max_10_exp() -> int { 38 } + fn max_10_exp(_: Option) -> int { 38 } /// Constructs a floating point number by multiplying `x` by 2 raised to the power of `exp` #[inline] @@ -956,9 +959,11 @@ mod tests { assert_eq!(1f32.clamp(&2f32, &4f32), 2f32); assert_eq!(8f32.clamp(&2f32, &4f32), 4f32); assert_eq!(3f32.clamp(&2f32, &4f32), 3f32); - assert!(3f32.clamp(&Float::NaN::(), &4f32).is_NaN()); - assert!(3f32.clamp(&2f32, &Float::NaN::()).is_NaN()); - assert!(Float::NaN::().clamp(&2f32, &4f32).is_NaN()); + + let nan: f32 = Float::NaN(); + assert!(3f32.clamp(&nan, &4f32).is_NaN()); + assert!(3f32.clamp(&2f32, &nan).is_NaN()); + assert!(nan.clamp(&2f32, &4f32).is_NaN()); } #[test] @@ -1035,9 +1040,13 @@ mod tests { fn test_asinh() { assert_eq!(0.0f32.asinh(), 0.0f32); assert_eq!((-0.0f32).asinh(), -0.0f32); - assert_eq!(Float::infinity::().asinh(), Float::infinity::()); - assert_eq!(Float::neg_infinity::().asinh(), Float::neg_infinity::()); - assert!(Float::NaN::().asinh().is_NaN()); + + let inf: f32 = Float::infinity(); + let neg_inf: f32 = Float::neg_infinity(); + let nan: f32 = Float::NaN(); + assert_eq!(inf.asinh(), inf); + assert_eq!(neg_inf.asinh(), neg_inf); + assert!(nan.asinh().is_NaN()); assert_approx_eq!(2.0f32.asinh(), 1.443635475178810342493276740273105f32); assert_approx_eq!((-2.0f32).asinh(), -1.443635475178810342493276740273105f32); } @@ -1046,9 +1055,13 @@ mod tests { fn test_acosh() { assert_eq!(1.0f32.acosh(), 0.0f32); assert!(0.999f32.acosh().is_NaN()); - assert_eq!(Float::infinity::().acosh(), Float::infinity::()); - assert!(Float::neg_infinity::().acosh().is_NaN()); - assert!(Float::NaN::().acosh().is_NaN()); + + let inf: f32 = Float::infinity(); + let neg_inf: f32 = Float::neg_infinity(); + let nan: f32 = Float::NaN(); + assert_eq!(inf.acosh(), inf); + assert!(neg_inf.acosh().is_NaN()); + assert!(nan.acosh().is_NaN()); assert_approx_eq!(2.0f32.acosh(), 1.31695789692481670862504634730796844f32); assert_approx_eq!(3.0f32.acosh(), 1.76274717403908605046521864995958461f32); } @@ -1057,34 +1070,61 @@ mod tests { fn test_atanh() { assert_eq!(0.0f32.atanh(), 0.0f32); assert_eq!((-0.0f32).atanh(), -0.0f32); - assert_eq!(1.0f32.atanh(), Float::infinity::()); - assert_eq!((-1.0f32).atanh(), Float::neg_infinity::()); + + let inf32: f32 = Float::infinity(); + let neg_inf32: f32 = Float::neg_infinity(); + assert_eq!(1.0f32.atanh(), inf32); + assert_eq!((-1.0f32).atanh(), neg_inf32); + assert!(2f64.atanh().atanh().is_NaN()); assert!((-2f64).atanh().atanh().is_NaN()); - assert!(Float::infinity::().atanh().is_NaN()); - assert!(Float::neg_infinity::().atanh().is_NaN()); - assert!(Float::NaN::().atanh().is_NaN()); + + let inf64: f32 = Float::infinity(); + let neg_inf64: f32 = Float::neg_infinity(); + let nan32: f32 = Float::NaN(); + assert!(inf64.atanh().is_NaN()); + assert!(neg_inf64.atanh().is_NaN()); + assert!(nan32.atanh().is_NaN()); + assert_approx_eq!(0.5f32.atanh(), 0.54930614433405484569762261846126285f32); assert_approx_eq!((-0.5f32).atanh(), -0.54930614433405484569762261846126285f32); } #[test] fn test_real_consts() { - assert_approx_eq!(Real::two_pi::(), 2f32 * Real::pi::()); - assert_approx_eq!(Real::frac_pi_2::(), Real::pi::() / 2f32); - assert_approx_eq!(Real::frac_pi_3::(), Real::pi::() / 3f32); - assert_approx_eq!(Real::frac_pi_4::(), Real::pi::() / 4f32); - assert_approx_eq!(Real::frac_pi_6::(), Real::pi::() / 6f32); - assert_approx_eq!(Real::frac_pi_8::(), Real::pi::() / 8f32); - assert_approx_eq!(Real::frac_1_pi::(), 1f32 / Real::pi::()); - assert_approx_eq!(Real::frac_2_pi::(), 2f32 / Real::pi::()); - assert_approx_eq!(Real::frac_2_sqrtpi::(), 2f32 / Real::pi::().sqrt()); - assert_approx_eq!(Real::sqrt2::(), 2f32.sqrt()); - assert_approx_eq!(Real::frac_1_sqrt2::(), 1f32 / 2f32.sqrt()); - assert_approx_eq!(Real::log2_e::(), Real::e::().log2()); - assert_approx_eq!(Real::log10_e::(), Real::e::().log10()); - assert_approx_eq!(Real::ln_2::(), 2f32.ln()); - assert_approx_eq!(Real::ln_10::(), 10f32.ln()); + let pi: f32 = Real::pi(); + let two_pi: f32 = Real::two_pi(); + let frac_pi_2: f32 = Real::frac_pi_2(); + let frac_pi_3: f32 = Real::frac_pi_3(); + let frac_pi_4: f32 = Real::frac_pi_4(); + let frac_pi_6: f32 = Real::frac_pi_6(); + let frac_pi_8: f32 = Real::frac_pi_8(); + let frac_1_pi: f32 = Real::frac_1_pi(); + let frac_2_pi: f32 = Real::frac_2_pi(); + let frac_2_sqrtpi: f32 = Real::frac_2_sqrtpi(); + let sqrt2: f32 = Real::sqrt2(); + let frac_1_sqrt2: f32 = Real::frac_1_sqrt2(); + let e: f32 = Real::e(); + let log2_e: f32 = Real::log2_e(); + let log10_e: f32 = Real::log10_e(); + let ln_2: f32 = Real::ln_2(); + let ln_10: f32 = Real::ln_10(); + + assert_approx_eq!(two_pi, 2f32 * pi); + assert_approx_eq!(frac_pi_2, pi / 2f32); + assert_approx_eq!(frac_pi_3, pi / 3f32); + assert_approx_eq!(frac_pi_4, pi / 4f32); + assert_approx_eq!(frac_pi_6, pi / 6f32); + assert_approx_eq!(frac_pi_8, pi / 8f32); + assert_approx_eq!(frac_1_pi, 1f32 / pi); + assert_approx_eq!(frac_2_pi, 2f32 / pi); + assert_approx_eq!(frac_2_sqrtpi, 2f32 / pi.sqrt()); + assert_approx_eq!(sqrt2, 2f32.sqrt()); + assert_approx_eq!(frac_1_sqrt2, 1f32 / 2f32.sqrt()); + assert_approx_eq!(log2_e, e.log2()); + assert_approx_eq!(log10_e, e.log10()); + assert_approx_eq!(ln_2, 2f32.ln()); + assert_approx_eq!(ln_10, 10f32.ln()); } #[test] @@ -1160,17 +1200,23 @@ mod tests { #[test] fn test_primitive() { - assert_eq!(Primitive::bits::(), sys::size_of::() * 8); - assert_eq!(Primitive::bytes::(), sys::size_of::()); + let none: Option = None; + assert_eq!(Primitive::bits(none), sys::size_of::() * 8); + assert_eq!(Primitive::bytes(none), sys::size_of::()); } #[test] fn test_is_normal() { - assert!(!Float::NaN::().is_normal()); - assert!(!Float::infinity::().is_normal()); - assert!(!Float::neg_infinity::().is_normal()); - assert!(!Zero::zero::().is_normal()); - assert!(!Float::neg_zero::().is_normal()); + let nan: f32 = Float::NaN(); + let inf: f32 = Float::infinity(); + let neg_inf: f32 = Float::neg_infinity(); + let zero: f32 = Zero::zero(); + let neg_zero: f32 = Float::neg_zero(); + assert!(!nan.is_normal()); + assert!(!inf.is_normal()); + assert!(!neg_inf.is_normal()); + assert!(!zero.is_normal()); + assert!(!neg_zero.is_normal()); assert!(1f32.is_normal()); assert!(1e-37f32.is_normal()); assert!(!1e-38f32.is_normal()); @@ -1178,11 +1224,16 @@ mod tests { #[test] fn test_classify() { - assert_eq!(Float::NaN::().classify(), FPNaN); - assert_eq!(Float::infinity::().classify(), FPInfinite); - assert_eq!(Float::neg_infinity::().classify(), FPInfinite); - assert_eq!(Zero::zero::().classify(), FPZero); - assert_eq!(Float::neg_zero::().classify(), FPZero); + let nan: f32 = Float::NaN(); + let inf: f32 = Float::infinity(); + let neg_inf: f32 = Float::neg_infinity(); + let zero: f32 = Zero::zero(); + let neg_zero: f32 = Float::neg_zero(); + assert_eq!(nan.classify(), FPNaN); + assert_eq!(inf.classify(), FPInfinite); + assert_eq!(neg_inf.classify(), FPInfinite); + assert_eq!(zero.classify(), FPZero); + assert_eq!(neg_zero.classify(), FPZero); assert_eq!(1f32.classify(), FPNormal); assert_eq!(1e-37f32.classify(), FPNormal); assert_eq!(1e-38f32.classify(), FPSubnormal); @@ -1199,11 +1250,13 @@ mod tests { assert_eq!(Float::ldexp(0f32, -123), 0f32); assert_eq!(Float::ldexp(-0f32, -123), -0f32); - assert_eq!(Float::ldexp(Float::infinity::(), -123), - Float::infinity::()); - assert_eq!(Float::ldexp(Float::neg_infinity::(), -123), - Float::neg_infinity::()); - assert!(Float::ldexp(Float::NaN::(), -123).is_NaN()); + + let inf: f32 = Float::infinity(); + let neg_inf: f32 = Float::neg_infinity(); + let nan: f32 = Float::NaN(); + assert_eq!(Float::ldexp(inf, -123), inf); + assert_eq!(Float::ldexp(neg_inf, -123), neg_inf); + assert!(Float::ldexp(nan, -123).is_NaN()); } #[test] @@ -1221,10 +1274,12 @@ mod tests { assert_eq!(0f32.frexp(), (0f32, 0)); assert_eq!((-0f32).frexp(), (-0f32, 0)); - assert_eq!(match Float::infinity::().frexp() { (x, _) => x }, - Float::infinity::()) - assert_eq!(match Float::neg_infinity::().frexp() { (x, _) => x }, - Float::neg_infinity::()) - assert!(match Float::NaN::().frexp() { (x, _) => x.is_NaN() }) + + let inf: f32 = Float::infinity(); + let neg_inf: f32 = Float::neg_infinity(); + let nan: f32 = Float::NaN(); + assert_eq!(match inf.frexp() { (x, _) => x }, inf) + assert_eq!(match neg_inf.frexp() { (x, _) => x }, neg_inf) + assert!(match nan.frexp() { (x, _) => x.is_NaN() }) } } diff --git a/src/libstd/num/f64.rs b/src/libstd/num/f64.rs index 91361a61c2151..3ed269698d6d7 100644 --- a/src/libstd/num/f64.rs +++ b/src/libstd/num/f64.rs @@ -205,7 +205,7 @@ impl ApproxEq for f64 { #[inline] fn approx_eq(&self, other: &f64) -> bool { - self.approx_eq_eps(other, &ApproxEq::approx_epsilon::()) + self.approx_eq_eps(other, &1.0e-6) } #[inline] @@ -578,11 +578,14 @@ impl Real for f64 { /// Converts to degrees, assuming the number is in radians #[inline] - fn to_degrees(&self) -> f64 { *self * (180.0 / Real::pi::()) } + fn to_degrees(&self) -> f64 { *self * (180.0f64 / Real::pi()) } /// Converts to radians, assuming the number is in degrees #[inline] - fn to_radians(&self) -> f64 { *self * (Real::pi::() / 180.0) } + fn to_radians(&self) -> f64 { + let value: f64 = Real::pi(); + *self * (value / 180.0) + } } impl RealExt for f64 { @@ -625,10 +628,10 @@ impl Bounded for f64 { impl Primitive for f64 { #[inline] - fn bits() -> uint { 64 } + fn bits(_: Option) -> uint { 64 } #[inline] - fn bytes() -> uint { Primitive::bits::() / 8 } + fn bytes(_: Option) -> uint { Primitive::bits(Some(0f64)) / 8 } } impl Float for f64 { @@ -685,25 +688,25 @@ impl Float for f64 { } #[inline] - fn mantissa_digits() -> uint { 53 } + fn mantissa_digits(_: Option) -> uint { 53 } #[inline] - fn digits() -> uint { 15 } + fn digits(_: Option) -> uint { 15 } #[inline] fn epsilon() -> f64 { 2.2204460492503131e-16 } #[inline] - fn min_exp() -> int { -1021 } + fn min_exp(_: Option) -> int { -1021 } #[inline] - fn max_exp() -> int { 1024 } + fn max_exp(_: Option) -> int { 1024 } #[inline] - fn min_10_exp() -> int { -307 } + fn min_10_exp(_: Option) -> int { -307 } #[inline] - fn max_10_exp() -> int { 308 } + fn max_10_exp(_: Option) -> int { 308 } /// Constructs a floating point number by multiplying `x` by 2 raised to the power of `exp` #[inline] @@ -990,16 +993,20 @@ mod tests { fn test_min() { assert_eq!(1f64.min(&2f64), 1f64); assert_eq!(2f64.min(&1f64), 1f64); - assert!(1f64.min(&Float::NaN::()).is_NaN()); - assert!(Float::NaN::().min(&1f64).is_NaN()); + + let nan: f64 = Float::NaN(); + assert!(1f64.min(&nan).is_NaN()); + assert!(nan.min(&1f64).is_NaN()); } #[test] fn test_max() { assert_eq!(1f64.max(&2f64), 2f64); assert_eq!(2f64.max(&1f64), 2f64); - assert!(1f64.max(&Float::NaN::()).is_NaN()); - assert!(Float::NaN::().max(&1f64).is_NaN()); + + let nan: f64 = Float::NaN(); + assert!(1f64.max(&nan).is_NaN()); + assert!(nan.max(&1f64).is_NaN()); } #[test] @@ -1007,9 +1014,11 @@ mod tests { assert_eq!(1f64.clamp(&2f64, &4f64), 2f64); assert_eq!(8f64.clamp(&2f64, &4f64), 4f64); assert_eq!(3f64.clamp(&2f64, &4f64), 3f64); - assert!(3f64.clamp(&Float::NaN::(), &4f64).is_NaN()); - assert!(3f64.clamp(&2f64, &Float::NaN::()).is_NaN()); - assert!(Float::NaN::().clamp(&2f64, &4f64).is_NaN()); + + let nan: f64 = Float::NaN(); + assert!(3f64.clamp(&nan, &4f64).is_NaN()); + assert!(3f64.clamp(&2f64, &nan).is_NaN()); + assert!(nan.clamp(&2f64, &4f64).is_NaN()); } #[test] @@ -1086,9 +1095,13 @@ mod tests { fn test_asinh() { assert_eq!(0.0f64.asinh(), 0.0f64); assert_eq!((-0.0f64).asinh(), -0.0f64); - assert_eq!(Float::infinity::().asinh(), Float::infinity::()); - assert_eq!(Float::neg_infinity::().asinh(), Float::neg_infinity::()); - assert!(Float::NaN::().asinh().is_NaN()); + + let inf: f64 = Float::infinity(); + let neg_inf: f64 = Float::neg_infinity(); + let nan: f64 = Float::NaN(); + assert_eq!(inf.asinh(), inf); + assert_eq!(neg_inf.asinh(), neg_inf); + assert!(nan.asinh().is_NaN()); assert_approx_eq!(2.0f64.asinh(), 1.443635475178810342493276740273105f64); assert_approx_eq!((-2.0f64).asinh(), -1.443635475178810342493276740273105f64); } @@ -1097,9 +1110,13 @@ mod tests { fn test_acosh() { assert_eq!(1.0f64.acosh(), 0.0f64); assert!(0.999f64.acosh().is_NaN()); - assert_eq!(Float::infinity::().acosh(), Float::infinity::()); - assert!(Float::neg_infinity::().acosh().is_NaN()); - assert!(Float::NaN::().acosh().is_NaN()); + + let inf: f64 = Float::infinity(); + let neg_inf: f64 = Float::neg_infinity(); + let nan: f64 = Float::NaN(); + assert_eq!(inf.acosh(), inf); + assert!(neg_inf.acosh().is_NaN()); + assert!(nan.acosh().is_NaN()); assert_approx_eq!(2.0f64.acosh(), 1.31695789692481670862504634730796844f64); assert_approx_eq!(3.0f64.acosh(), 1.76274717403908605046521864995958461f64); } @@ -1108,34 +1125,56 @@ mod tests { fn test_atanh() { assert_eq!(0.0f64.atanh(), 0.0f64); assert_eq!((-0.0f64).atanh(), -0.0f64); - assert_eq!(1.0f64.atanh(), Float::infinity::()); - assert_eq!((-1.0f64).atanh(), Float::neg_infinity::()); + + let inf: f64 = Float::infinity(); + let neg_inf: f64 = Float::neg_infinity(); + let nan: f64 = Float::NaN(); + assert_eq!(1.0f64.atanh(), inf); + assert_eq!((-1.0f64).atanh(), neg_inf); assert!(2f64.atanh().atanh().is_NaN()); assert!((-2f64).atanh().atanh().is_NaN()); - assert!(Float::infinity::().atanh().is_NaN()); - assert!(Float::neg_infinity::().atanh().is_NaN()); - assert!(Float::NaN::().atanh().is_NaN()); + assert!(inf.atanh().is_NaN()); + assert!(neg_inf.atanh().is_NaN()); + assert!(nan.atanh().is_NaN()); assert_approx_eq!(0.5f64.atanh(), 0.54930614433405484569762261846126285f64); assert_approx_eq!((-0.5f64).atanh(), -0.54930614433405484569762261846126285f64); } #[test] fn test_real_consts() { - assert_approx_eq!(Real::two_pi::(), 2.0 * Real::pi::()); - assert_approx_eq!(Real::frac_pi_2::(), Real::pi::() / 2f64); - assert_approx_eq!(Real::frac_pi_3::(), Real::pi::() / 3f64); - assert_approx_eq!(Real::frac_pi_4::(), Real::pi::() / 4f64); - assert_approx_eq!(Real::frac_pi_6::(), Real::pi::() / 6f64); - assert_approx_eq!(Real::frac_pi_8::(), Real::pi::() / 8f64); - assert_approx_eq!(Real::frac_1_pi::(), 1f64 / Real::pi::()); - assert_approx_eq!(Real::frac_2_pi::(), 2f64 / Real::pi::()); - assert_approx_eq!(Real::frac_2_sqrtpi::(), 2f64 / Real::pi::().sqrt()); - assert_approx_eq!(Real::sqrt2::(), 2f64.sqrt()); - assert_approx_eq!(Real::frac_1_sqrt2::(), 1f64 / 2f64.sqrt()); - assert_approx_eq!(Real::log2_e::(), Real::e::().log2()); - assert_approx_eq!(Real::log10_e::(), Real::e::().log10()); - assert_approx_eq!(Real::ln_2::(), 2f64.ln()); - assert_approx_eq!(Real::ln_10::(), 10f64.ln()); + let pi: f64 = Real::pi(); + let two_pi: f64 = Real::two_pi(); + let frac_pi_2: f64 = Real::frac_pi_2(); + let frac_pi_3: f64 = Real::frac_pi_3(); + let frac_pi_4: f64 = Real::frac_pi_4(); + let frac_pi_6: f64 = Real::frac_pi_6(); + let frac_pi_8: f64 = Real::frac_pi_8(); + let frac_1_pi: f64 = Real::frac_1_pi(); + let frac_2_pi: f64 = Real::frac_2_pi(); + let frac_2_sqrtpi: f64 = Real::frac_2_sqrtpi(); + let sqrt2: f64 = Real::sqrt2(); + let frac_1_sqrt2: f64 = Real::frac_1_sqrt2(); + let e: f64 = Real::e(); + let log2_e: f64 = Real::log2_e(); + let log10_e: f64 = Real::log10_e(); + let ln_2: f64 = Real::ln_2(); + let ln_10: f64 = Real::ln_10(); + + assert_approx_eq!(two_pi, 2.0 * pi); + assert_approx_eq!(frac_pi_2, pi / 2f64); + assert_approx_eq!(frac_pi_3, pi / 3f64); + assert_approx_eq!(frac_pi_4, pi / 4f64); + assert_approx_eq!(frac_pi_6, pi / 6f64); + assert_approx_eq!(frac_pi_8, pi / 8f64); + assert_approx_eq!(frac_1_pi, 1f64 / pi); + assert_approx_eq!(frac_2_pi, 2f64 / pi); + assert_approx_eq!(frac_2_sqrtpi, 2f64 / pi.sqrt()); + assert_approx_eq!(sqrt2, 2f64.sqrt()); + assert_approx_eq!(frac_1_sqrt2, 1f64 / 2f64.sqrt()); + assert_approx_eq!(log2_e, e.log2()); + assert_approx_eq!(log10_e, e.log10()); + assert_approx_eq!(ln_2, 2f64.ln()); + assert_approx_eq!(ln_10, 10f64.ln()); } #[test] @@ -1211,17 +1250,23 @@ mod tests { #[test] fn test_primitive() { - assert_eq!(Primitive::bits::(), sys::size_of::() * 8); - assert_eq!(Primitive::bytes::(), sys::size_of::()); + let none: Option = None; + assert_eq!(Primitive::bits(none), sys::size_of::() * 8); + assert_eq!(Primitive::bytes(none), sys::size_of::()); } #[test] fn test_is_normal() { - assert!(!Float::NaN::().is_normal()); - assert!(!Float::infinity::().is_normal()); - assert!(!Float::neg_infinity::().is_normal()); - assert!(!Zero::zero::().is_normal()); - assert!(!Float::neg_zero::().is_normal()); + let nan: f64 = Float::NaN(); + let inf: f64 = Float::infinity(); + let neg_inf: f64 = Float::neg_infinity(); + let zero: f64 = Zero::zero(); + let neg_zero: f64 = Float::neg_zero(); + assert!(!nan.is_normal()); + assert!(!inf.is_normal()); + assert!(!neg_inf.is_normal()); + assert!(!zero.is_normal()); + assert!(!neg_zero.is_normal()); assert!(1f64.is_normal()); assert!(1e-307f64.is_normal()); assert!(!1e-308f64.is_normal()); @@ -1229,11 +1274,16 @@ mod tests { #[test] fn test_classify() { - assert_eq!(Float::NaN::().classify(), FPNaN); - assert_eq!(Float::infinity::().classify(), FPInfinite); - assert_eq!(Float::neg_infinity::().classify(), FPInfinite); - assert_eq!(Zero::zero::().classify(), FPZero); - assert_eq!(Float::neg_zero::().classify(), FPZero); + let nan: f64 = Float::NaN(); + let inf: f64 = Float::infinity(); + let neg_inf: f64 = Float::neg_infinity(); + let zero: f64 = Zero::zero(); + let neg_zero: f64 = Float::neg_zero(); + assert_eq!(nan.classify(), FPNaN); + assert_eq!(inf.classify(), FPInfinite); + assert_eq!(neg_inf.classify(), FPInfinite); + assert_eq!(zero.classify(), FPZero); + assert_eq!(neg_zero.classify(), FPZero); assert_eq!(1e-307f64.classify(), FPNormal); assert_eq!(1e-308f64.classify(), FPSubnormal); } @@ -1249,11 +1299,13 @@ mod tests { assert_eq!(Float::ldexp(0f64, -123), 0f64); assert_eq!(Float::ldexp(-0f64, -123), -0f64); - assert_eq!(Float::ldexp(Float::infinity::(), -123), - Float::infinity::()); - assert_eq!(Float::ldexp(Float::neg_infinity::(), -123), - Float::neg_infinity::()); - assert!(Float::ldexp(Float::NaN::(), -123).is_NaN()); + + let inf: f64 = Float::infinity(); + let neg_inf: f64 = Float::neg_infinity(); + let nan: f64 = Float::NaN(); + assert_eq!(Float::ldexp(inf, -123), inf); + assert_eq!(Float::ldexp(neg_inf, -123), neg_inf); + assert!(Float::ldexp(nan, -123).is_NaN()); } #[test] @@ -1271,10 +1323,12 @@ mod tests { assert_eq!(0f64.frexp(), (0f64, 0)); assert_eq!((-0f64).frexp(), (-0f64, 0)); - assert_eq!(match Float::infinity::().frexp() { (x, _) => x }, - Float::infinity::()) - assert_eq!(match Float::neg_infinity::().frexp() { (x, _) => x }, - Float::neg_infinity::()) - assert!(match Float::NaN::().frexp() { (x, _) => x.is_NaN() }) + + let inf: f64 = Float::infinity(); + let neg_inf: f64 = Float::neg_infinity(); + let nan: f64 = Float::NaN(); + assert_eq!(match inf.frexp() { (x, _) => x }, inf) + assert_eq!(match neg_inf.frexp() { (x, _) => x }, neg_inf) + assert!(match nan.frexp() { (x, _) => x.is_NaN() }) } } diff --git a/src/libstd/num/float.rs b/src/libstd/num/float.rs index 486d35620899a..360a37ccbd1a9 100644 --- a/src/libstd/num/float.rs +++ b/src/libstd/num/float.rs @@ -349,7 +349,7 @@ impl ApproxEq for float { #[inline] fn approx_eq(&self, other: &float) -> bool { - self.approx_eq_eps(other, &ApproxEq::approx_epsilon::()) + self.approx_eq_eps(other, &1.0e-6) } #[inline] @@ -790,32 +790,56 @@ impl Signed for float { impl Bounded for float { #[inline] - fn min_value() -> float { Bounded::min_value::() as float } + fn min_value() -> float { + let x: f64 = Bounded::min_value(); + x as float + } #[inline] - fn max_value() -> float { Bounded::max_value::() as float } + fn max_value() -> float { + let x: f64 = Bounded::max_value(); + x as float + } } impl Primitive for float { #[inline] - fn bits() -> uint { Primitive::bits::() } + fn bits(_: Option) -> uint { + let bits: uint = Primitive::bits(Some(0f64)); + bits + } #[inline] - fn bytes() -> uint { Primitive::bytes::() } + fn bytes(_: Option) -> uint { + let bytes: uint = Primitive::bytes(Some(0f64)); + bytes + } } impl Float for float { #[inline] - fn NaN() -> float { Float::NaN::() as float } + fn NaN() -> float { + let value: f64 = Float::NaN(); + value as float + } #[inline] - fn infinity() -> float { Float::infinity::() as float } + fn infinity() -> float { + let value: f64 = Float::infinity(); + value as float + } #[inline] - fn neg_infinity() -> float { Float::neg_infinity::() as float } + fn neg_infinity() -> float { + let value: f64 = Float::neg_infinity(); + value as float + } #[inline] - fn neg_zero() -> float { Float::neg_zero::() as float } + fn neg_zero() -> float { + let value: f64 = Float::neg_zero(); + value as float + } /// Returns `true` if the number is NaN #[inline] @@ -839,30 +863,46 @@ impl Float for float { fn classify(&self) -> FPCategory { (*self as f64).classify() } #[inline] - fn mantissa_digits() -> uint { Float::mantissa_digits::() } + fn mantissa_digits(_: Option) -> uint { + Float::mantissa_digits(Some(0f64)) + } #[inline] - fn digits() -> uint { Float::digits::() } + fn digits(_: Option) -> uint { + Float::digits(Some(0f64)) + } #[inline] - fn epsilon() -> float { Float::epsilon::() as float } + fn epsilon() -> float { + let value: f64 = Float::epsilon(); + value as float + } #[inline] - fn min_exp() -> int { Float::min_exp::() } + fn min_exp(_: Option) -> int { + Float::min_exp(Some(0f64)) + } #[inline] - fn max_exp() -> int { Float::max_exp::() } + fn max_exp(_: Option) -> int { + Float::max_exp(Some(0f64)) + } #[inline] - fn min_10_exp() -> int { Float::min_10_exp::() } + fn min_10_exp(_: Option) -> int { + Float::min_10_exp(Some(0f64)) + } #[inline] - fn max_10_exp() -> int { Float::max_10_exp::() } + fn max_10_exp(_: Option) -> int { + Float::max_10_exp(Some(0f64)) + } /// Constructs a floating point number by multiplying `x` by 2 raised to the power of `exp` #[inline] fn ldexp(x: float, exp: int) -> float { - Float::ldexp(x as f64, exp) as float + let value: f64 = Float::ldexp(x as f64, exp); + value as float } /// @@ -944,9 +984,10 @@ mod tests { assert_eq!(1f.clamp(&2f, &4f), 2f); assert_eq!(8f.clamp(&2f, &4f), 4f); assert_eq!(3f.clamp(&2f, &4f), 3f); - assert!(3f.clamp(&Float::NaN::(), &4f).is_NaN()); - assert!(3f.clamp(&2f, &Float::NaN::()).is_NaN()); - assert!(Float::NaN::().clamp(&2f, &4f).is_NaN()); + let nan: float = Float::NaN(); + assert!(3f.clamp(&nan, &4f).is_NaN()); + assert!(3f.clamp(&2f, &nan).is_NaN()); + assert!(nan.clamp(&2f, &4f).is_NaN()); } #[test] @@ -1023,9 +1064,13 @@ mod tests { fn test_asinh() { assert_eq!(0.0f.asinh(), 0.0f); assert_eq!((-0.0f).asinh(), -0.0f); - assert_eq!(Float::infinity::().asinh(), Float::infinity::()); - assert_eq!(Float::neg_infinity::().asinh(), Float::neg_infinity::()); - assert!(Float::NaN::().asinh().is_NaN()); + + let inf: float = Float::infinity(); + let neg_inf: float = Float::neg_infinity(); + let nan: float = Float::NaN(); + assert_eq!(inf.asinh(), inf); + assert_eq!(neg_inf.asinh(), neg_inf); + assert!(nan.asinh().is_NaN()); assert_approx_eq!(2.0f.asinh(), 1.443635475178810342493276740273105f); assert_approx_eq!((-2.0f).asinh(), -1.443635475178810342493276740273105f); } @@ -1034,9 +1079,13 @@ mod tests { fn test_acosh() { assert_eq!(1.0f.acosh(), 0.0f); assert!(0.999f.acosh().is_NaN()); - assert_eq!(Float::infinity::().acosh(), Float::infinity::()); - assert!(Float::neg_infinity::().acosh().is_NaN()); - assert!(Float::NaN::().acosh().is_NaN()); + + let inf: float = Float::infinity(); + let neg_inf: float = Float::neg_infinity(); + let nan: float = Float::NaN(); + assert_eq!(inf.acosh(), inf); + assert!(neg_inf.acosh().is_NaN()); + assert!(nan.acosh().is_NaN()); assert_approx_eq!(2.0f.acosh(), 1.31695789692481670862504634730796844f); assert_approx_eq!(3.0f.acosh(), 1.76274717403908605046521864995958461f); } @@ -1045,34 +1094,58 @@ mod tests { fn test_atanh() { assert_eq!(0.0f.atanh(), 0.0f); assert_eq!((-0.0f).atanh(), -0.0f); - assert_eq!(1.0f.atanh(), Float::infinity::()); - assert_eq!((-1.0f).atanh(), Float::neg_infinity::()); + + let inf: float = Float::infinity(); + let neg_inf: float = Float::neg_infinity(); + let inf64: f64 = Float::infinity(); + let neg_inf64: f64 = Float::neg_infinity(); + let nan: float = Float::NaN(); + assert_eq!(1.0f.atanh(), inf); + assert_eq!((-1.0f).atanh(), neg_inf); assert!(2f64.atanh().atanh().is_NaN()); assert!((-2f64).atanh().atanh().is_NaN()); - assert!(Float::infinity::().atanh().is_NaN()); - assert!(Float::neg_infinity::().atanh().is_NaN()); - assert!(Float::NaN::().atanh().is_NaN()); + assert!(inf64.atanh().is_NaN()); + assert!(neg_inf64.atanh().is_NaN()); + assert!(nan.atanh().is_NaN()); assert_approx_eq!(0.5f.atanh(), 0.54930614433405484569762261846126285f); assert_approx_eq!((-0.5f).atanh(), -0.54930614433405484569762261846126285f); } #[test] fn test_real_consts() { - assert_approx_eq!(Real::two_pi::(), 2f * Real::pi::()); - assert_approx_eq!(Real::frac_pi_2::(), Real::pi::() / 2f); - assert_approx_eq!(Real::frac_pi_3::(), Real::pi::() / 3f); - assert_approx_eq!(Real::frac_pi_4::(), Real::pi::() / 4f); - assert_approx_eq!(Real::frac_pi_6::(), Real::pi::() / 6f); - assert_approx_eq!(Real::frac_pi_8::(), Real::pi::() / 8f); - assert_approx_eq!(Real::frac_1_pi::(), 1f / Real::pi::()); - assert_approx_eq!(Real::frac_2_pi::(), 2f / Real::pi::()); - assert_approx_eq!(Real::frac_2_sqrtpi::(), 2f / Real::pi::().sqrt()); - assert_approx_eq!(Real::sqrt2::(), 2f.sqrt()); - assert_approx_eq!(Real::frac_1_sqrt2::(), 1f / 2f.sqrt()); - assert_approx_eq!(Real::log2_e::(), Real::e::().log2()); - assert_approx_eq!(Real::log10_e::(), Real::e::().log10()); - assert_approx_eq!(Real::ln_2::(), 2f.ln()); - assert_approx_eq!(Real::ln_10::(), 10f.ln()); + let pi: float = Real::pi(); + let two_pi: float = Real::two_pi(); + let frac_pi_2: float = Real::frac_pi_2(); + let frac_pi_3: float = Real::frac_pi_3(); + let frac_pi_4: float = Real::frac_pi_4(); + let frac_pi_6: float = Real::frac_pi_6(); + let frac_pi_8: float = Real::frac_pi_8(); + let frac_1_pi: float = Real::frac_1_pi(); + let frac_2_pi: float = Real::frac_2_pi(); + let frac_2_sqrtpi: float = Real::frac_2_sqrtpi(); + let sqrt2: float = Real::sqrt2(); + let frac_1_sqrt2: float = Real::frac_1_sqrt2(); + let e: float = Real::e(); + let log2_e: float = Real::log2_e(); + let log10_e: float = Real::log10_e(); + let ln_2: float = Real::ln_2(); + let ln_10: float = Real::ln_10(); + + assert_approx_eq!(two_pi, 2f * pi); + assert_approx_eq!(frac_pi_2, pi / 2f); + assert_approx_eq!(frac_pi_3, pi / 3f); + assert_approx_eq!(frac_pi_4, pi / 4f); + assert_approx_eq!(frac_pi_6, pi / 6f); + assert_approx_eq!(frac_pi_8, pi / 8f); + assert_approx_eq!(frac_1_pi, 1f / pi); + assert_approx_eq!(frac_2_pi, 2f / pi); + assert_approx_eq!(frac_2_sqrtpi, 2f / pi.sqrt()); + assert_approx_eq!(sqrt2, 2f.sqrt()); + assert_approx_eq!(frac_1_sqrt2, 1f / 2f.sqrt()); + assert_approx_eq!(log2_e, e.log2()); + assert_approx_eq!(log10_e, e.log10()); + assert_approx_eq!(ln_2, 2f.ln()); + assert_approx_eq!(ln_10, 10f.ln()); } #[test] @@ -1148,17 +1221,23 @@ mod tests { #[test] fn test_primitive() { - assert_eq!(Primitive::bits::(), sys::size_of::() * 8); - assert_eq!(Primitive::bytes::(), sys::size_of::()); + let none: Option = None; + assert_eq!(Primitive::bits(none), sys::size_of::() * 8); + assert_eq!(Primitive::bytes(none), sys::size_of::()); } #[test] fn test_is_normal() { - assert!(!Float::NaN::().is_normal()); - assert!(!Float::infinity::().is_normal()); - assert!(!Float::neg_infinity::().is_normal()); - assert!(!Zero::zero::().is_normal()); - assert!(!Float::neg_zero::().is_normal()); + let nan: float = Float::NaN(); + let inf: float = Float::infinity(); + let neg_inf: float = Float::neg_infinity(); + let zero: float = Zero::zero(); + let neg_zero: float = Float::neg_zero(); + assert!(!nan.is_normal()); + assert!(!inf.is_normal()); + assert!(!neg_inf.is_normal()); + assert!(!zero.is_normal()); + assert!(!neg_zero.is_normal()); assert!(1f.is_normal()); assert!(1e-307f.is_normal()); assert!(!1e-308f.is_normal()); @@ -1166,11 +1245,16 @@ mod tests { #[test] fn test_classify() { - assert_eq!(Float::NaN::().classify(), FPNaN); - assert_eq!(Float::infinity::().classify(), FPInfinite); - assert_eq!(Float::neg_infinity::().classify(), FPInfinite); - assert_eq!(Zero::zero::().classify(), FPZero); - assert_eq!(Float::neg_zero::().classify(), FPZero); + let nan: float = Float::NaN(); + let inf: float = Float::infinity(); + let neg_inf: float = Float::neg_infinity(); + let zero: float = Zero::zero(); + let neg_zero: float = Float::neg_zero(); + assert_eq!(nan.classify(), FPNaN); + assert_eq!(inf.classify(), FPInfinite); + assert_eq!(neg_inf.classify(), FPInfinite); + assert_eq!(zero.classify(), FPZero); + assert_eq!(neg_zero.classify(), FPZero); assert_eq!(1f.classify(), FPNormal); assert_eq!(1e-307f.classify(), FPNormal); assert_eq!(1e-308f.classify(), FPSubnormal); @@ -1187,11 +1271,13 @@ mod tests { assert_eq!(Float::ldexp(0f, -123), 0f); assert_eq!(Float::ldexp(-0f, -123), -0f); - assert_eq!(Float::ldexp(Float::infinity::(), -123), - Float::infinity::()); - assert_eq!(Float::ldexp(Float::neg_infinity::(), -123), - Float::neg_infinity::()); - assert!(Float::ldexp(Float::NaN::(), -123).is_NaN()); + + let inf: float = Float::infinity(); + let neg_inf: float = Float::neg_infinity(); + let nan: float = Float::NaN(); + assert_eq!(Float::ldexp(inf, -123), inf); + assert_eq!(Float::ldexp(neg_inf, -123), neg_inf); + assert!(Float::ldexp(nan, -123).is_NaN()); } #[test] @@ -1209,11 +1295,13 @@ mod tests { assert_eq!(0f.frexp(), (0f, 0)); assert_eq!((-0f).frexp(), (-0f, 0)); - assert_eq!(match Float::infinity::().frexp() { (x, _) => x }, - Float::infinity::()) - assert_eq!(match Float::neg_infinity::().frexp() { (x, _) => x }, - Float::neg_infinity::()) - assert!(match Float::NaN::().frexp() { (x, _) => x.is_NaN() }) + + let inf: float = Float::infinity(); + let neg_inf: float = Float::neg_infinity(); + let nan: float = Float::NaN(); + assert_eq!(match inf.frexp() { (x, _) => x }, inf); + assert_eq!(match neg_inf.frexp() { (x, _) => x }, neg_inf); + assert!(match nan.frexp() { (x, _) => x.is_NaN() }) } #[test] diff --git a/src/libstd/num/int_macros.rs b/src/libstd/num/int_macros.rs index 0144f926534d0..92de791ccad57 100644 --- a/src/libstd/num/int_macros.rs +++ b/src/libstd/num/int_macros.rs @@ -466,10 +466,10 @@ impl Int for $T {} impl Primitive for $T { #[inline] - fn bits() -> uint { bits } + fn bits(_: Option<$T>) -> uint { bits } #[inline] - fn bytes() -> uint { bits / 8 } + fn bytes(_: Option<$T>) -> uint { bits / 8 } } // String conversion functions and impl str -> num @@ -764,8 +764,9 @@ mod tests { #[test] fn test_primitive() { - assert_eq!(Primitive::bits::<$T>(), sys::size_of::<$T>() * 8); - assert_eq!(Primitive::bytes::<$T>(), sys::size_of::<$T>()); + let none: Option<$T> = None; + assert_eq!(Primitive::bits(none), sys::size_of::<$T>() * 8); + assert_eq!(Primitive::bytes(none), sys::size_of::<$T>()); } #[test] diff --git a/src/libstd/num/num.rs b/src/libstd/num/num.rs index fbb8913fbfa89..80ab0caac670c 100644 --- a/src/libstd/num/num.rs +++ b/src/libstd/num/num.rs @@ -272,8 +272,8 @@ pub trait Primitive: Num + Div + Rem { // FIXME (#5527): These should be associated constants - fn bits() -> uint; - fn bytes() -> uint; + fn bits(unused_self: Option) -> uint; + fn bytes(unused_self: Option) -> uint; } /// A collection of traits relevant to primitive signed and unsigned integers @@ -314,13 +314,13 @@ pub trait Float: Real fn is_normal(&self) -> bool; fn classify(&self) -> FPCategory; - fn mantissa_digits() -> uint; - fn digits() -> uint; + fn mantissa_digits(unused_self: Option) -> uint; + fn digits(unused_self: Option) -> uint; fn epsilon() -> Self; - fn min_exp() -> int; - fn max_exp() -> int; - fn min_10_exp() -> int; - fn max_10_exp() -> int; + fn min_exp(unused_self: Option) -> int; + fn max_exp(unused_self: Option) -> int; + fn min_10_exp(unused_self: Option) -> int; + fn max_10_exp(unused_self: Option) -> int; fn ldexp(x: Self, exp: int) -> Self; fn frexp(&self) -> (Self, int); @@ -484,9 +484,9 @@ impl Saturating for T { match self.checked_add(&v) { Some(x) => x, None => if v >= Zero::zero() { - Bounded::max_value::() + Bounded::max_value() } else { - Bounded::min_value::() + Bounded::min_value() } } } @@ -496,9 +496,9 @@ impl Saturating for T { match self.checked_sub(&v) { Some(x) => x, None => if v >= Zero::zero() { - Bounded::min_value::() + Bounded::min_value() } else { - Bounded::max_value::() + Bounded::max_value() } } } diff --git a/src/libstd/num/uint_macros.rs b/src/libstd/num/uint_macros.rs index 524b035c9f309..31255328b50b1 100644 --- a/src/libstd/num/uint_macros.rs +++ b/src/libstd/num/uint_macros.rs @@ -414,10 +414,10 @@ impl ToStrRadix for $T { impl Primitive for $T { #[inline] - fn bits() -> uint { bits } + fn bits(_: Option<$T>) -> uint { bits } #[inline] - fn bytes() -> uint { bits / 8 } + fn bytes(_: Option<$T>) -> uint { bits / 8 } } impl BitCount for $T { @@ -530,8 +530,9 @@ mod tests { #[test] fn test_primitive() { - assert_eq!(Primitive::bits::<$T>(), sys::size_of::<$T>() * 8); - assert_eq!(Primitive::bytes::<$T>(), sys::size_of::<$T>()); + let none: Option<$T> = None; + assert_eq!(Primitive::bits(none), sys::size_of::<$T>() * 8); + assert_eq!(Primitive::bytes(none), sys::size_of::<$T>()); } #[test] diff --git a/src/libstd/os.rs b/src/libstd/os.rs index 4e5a0e9b9138a..6dda11c5ee420 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -1506,7 +1506,7 @@ impl MemoryMap { let r = unsafe { libc::mmap(addr, len, prot, flags, fd, offset) }; - if r == libc::MAP_FAILED { + if r.equiv(&libc::MAP_FAILED) { Err(match errno() as c_int { libc::EACCES => ErrFdNotAvail, libc::EBADF => ErrInvalidFd, diff --git a/src/libstd/ptr.rs b/src/libstd/ptr.rs index c11634034230b..2d04b9358128d 100644 --- a/src/libstd/ptr.rs +++ b/src/libstd/ptr.rs @@ -12,8 +12,11 @@ use cast; use clone::Clone; +use cmp::Equiv; use iterator::{range, Iterator}; use option::{Option, Some, None}; +#[cfg(stage0)] +use sys; use unstable::intrinsics; use util::swap; @@ -24,18 +27,28 @@ use util::swap; /// Calculate the offset from a pointer #[inline] +#[cfg(stage0)] pub fn offset(ptr: *T, count: int) -> *T { - unsafe { intrinsics::offset(ptr, count) } + (ptr as uint + (count as uint) * sys::size_of::()) as *T } -/// Calculate the offset from a const pointer +/// Calculate the offset from a mut pointer #[inline] -pub fn const_offset(ptr: *const T, count: int) -> *const T { - unsafe { intrinsics::offset(ptr as *T, count) } +#[cfg(stage0)] +pub fn mut_offset(ptr: *mut T, count: int) -> *mut T { + (ptr as uint + (count as uint) * sys::size_of::()) as *mut T +} + +/// Calculate the offset from a pointer +#[inline] +#[cfg(not(stage0))] +pub fn offset(ptr: *T, count: int) -> *T { + unsafe { intrinsics::offset(ptr, count) } } /// Calculate the offset from a mut pointer #[inline] +#[cfg(not(stage0))] pub fn mut_offset(ptr: *mut T, count: int) -> *mut T { unsafe { intrinsics::offset(ptr as *T, count) as *mut T } } @@ -73,11 +86,11 @@ pub fn mut_null() -> *mut T { 0 as *mut T } /// Returns true if the pointer is equal to the null pointer. #[inline] -pub fn is_null(ptr: *const T) -> bool { ptr == null() } +pub fn is_null>(ptr: P) -> bool { ptr.is_null() } /// Returns true if the pointer is not equal to the null pointer. #[inline] -pub fn is_not_null(ptr: *const T) -> bool { !is_null(ptr) } +pub fn is_not_null>(ptr: P) -> bool { ptr.is_not_null() } /** * Copies data from one location to another. @@ -87,8 +100,10 @@ pub fn is_not_null(ptr: *const T) -> bool { !is_null(ptr) } */ #[inline] #[cfg(target_word_size = "32")] -pub unsafe fn copy_memory(dst: *mut T, src: *const T, count: uint) { - intrinsics::memmove32(dst, src as *T, count as u32); +pub unsafe fn copy_memory>(dst: *mut T, src: P, count: uint) { + intrinsics::memmove32(dst, + cast::transmute_immut_unsafe(src), + count as u32); } /** @@ -99,8 +114,10 @@ pub unsafe fn copy_memory(dst: *mut T, src: *const T, count: uint) { */ #[inline] #[cfg(target_word_size = "64")] -pub unsafe fn copy_memory(dst: *mut T, src: *const T, count: uint) { - intrinsics::memmove64(dst, src as *T, count as u64); +pub unsafe fn copy_memory>(dst: *mut T, src: P, count: uint) { + intrinsics::memmove64(dst, + cast::transmute_immut_unsafe(src), + count as u64); } /** @@ -111,8 +128,12 @@ pub unsafe fn copy_memory(dst: *mut T, src: *const T, count: uint) { */ #[inline] #[cfg(target_word_size = "32")] -pub unsafe fn copy_nonoverlapping_memory(dst: *mut T, src: *const T, count: uint) { - intrinsics::memcpy32(dst, src as *T, count as u32); +pub unsafe fn copy_nonoverlapping_memory>(dst: *mut T, + src: P, + count: uint) { + intrinsics::memcpy32(dst, + cast::transmute_immut_unsafe(src), + count as u32); } /** @@ -123,8 +144,12 @@ pub unsafe fn copy_nonoverlapping_memory(dst: *mut T, src: *const T, count: u */ #[inline] #[cfg(target_word_size = "64")] -pub unsafe fn copy_nonoverlapping_memory(dst: *mut T, src: *const T, count: uint) { - intrinsics::memcpy64(dst, src as *T, count as u64); +pub unsafe fn copy_nonoverlapping_memory>(dst: *mut T, + src: P, + count: uint) { + intrinsics::memcpy64(dst, + cast::transmute_immut_unsafe(src), + count as u64); } /** @@ -216,12 +241,6 @@ pub fn to_unsafe_ptr(thing: &T) -> *T { thing as *T } -/// Transform a const region pointer - &const T - to a const unsafe pointer - *const T. -#[inline] -pub fn to_const_unsafe_ptr(thing: &const T) -> *const T { - thing as *const T -} - /// Transform a mutable region pointer - &mut T - to a mutable unsafe pointer - *mut T. #[inline] pub fn to_mut_unsafe_ptr(thing: &mut T) -> *mut T { @@ -269,8 +288,10 @@ pub unsafe fn array_each(arr: **T, cb: &fn(*T)) { #[allow(missing_doc)] pub trait RawPtr { + fn null() -> Self; fn is_null(&self) -> bool; fn is_not_null(&self) -> bool; + fn to_uint(&self) -> uint; unsafe fn to_option(&self) -> Option<&T>; fn offset(&self, count: int) -> Self; unsafe fn offset_inbounds(self, count: int) -> Self; @@ -278,13 +299,21 @@ pub trait RawPtr { /// Extension methods for immutable pointers impl RawPtr for *T { + /// Returns the null pointer. + #[inline] + fn null() -> *T { null() } + /// Returns true if the pointer is equal to the null pointer. #[inline] - fn is_null(&self) -> bool { is_null(*self) } + fn is_null(&self) -> bool { *self == RawPtr::null() } /// Returns true if the pointer is not equal to the null pointer. #[inline] - fn is_not_null(&self) -> bool { is_not_null(*self) } + fn is_not_null(&self) -> bool { *self != RawPtr::null() } + + /// Returns the address of this pointer. + #[inline] + fn to_uint(&self) -> uint { *self as uint } /// /// Returns `None` if the pointer is null, or else returns the value wrapped @@ -317,13 +346,21 @@ impl RawPtr for *T { /// Extension methods for mutable pointers impl RawPtr for *mut T { + /// Returns the null pointer. + #[inline] + fn null() -> *mut T { mut_null() } + /// Returns true if the pointer is equal to the null pointer. #[inline] - fn is_null(&self) -> bool { is_null(*self) } + fn is_null(&self) -> bool { *self == RawPtr::null() } /// Returns true if the pointer is not equal to the null pointer. #[inline] - fn is_not_null(&self) -> bool { is_not_null(*self) } + fn is_not_null(&self) -> bool { *self != RawPtr::null() } + + /// Returns the address of this pointer. + #[inline] + fn to_uint(&self) -> uint { *self as uint } /// /// Returns `None` if the pointer is null, or else returns the value wrapped @@ -360,32 +397,77 @@ impl RawPtr for *mut T { // Equality for pointers #[cfg(not(test))] -impl Eq for *const T { +impl Eq for *T { + #[inline] + fn eq(&self, other: &*T) -> bool { + (*self as uint) == (*other as uint) + } + #[inline] + fn ne(&self, other: &*T) -> bool { !self.eq(other) } +} + +#[cfg(not(test))] +impl Eq for *mut T { #[inline] - fn eq(&self, other: &*const T) -> bool { + fn eq(&self, other: &*mut T) -> bool { (*self as uint) == (*other as uint) } #[inline] - fn ne(&self, other: &*const T) -> bool { !self.eq(other) } + fn ne(&self, other: &*mut T) -> bool { !self.eq(other) } +} + +// Equivalence for pointers +#[cfg(not(test))] +impl Equiv<*mut T> for *T { + fn equiv(&self, other: &*mut T) -> bool { + self.to_uint() == other.to_uint() + } +} + +#[cfg(not(test))] +impl Equiv<*T> for *mut T { + fn equiv(&self, other: &*T) -> bool { + self.to_uint() == other.to_uint() + } } // Comparison for pointers #[cfg(not(test))] -impl Ord for *const T { +impl Ord for *T { + #[inline] + fn lt(&self, other: &*T) -> bool { + (*self as uint) < (*other as uint) + } + #[inline] + fn le(&self, other: &*T) -> bool { + (*self as uint) <= (*other as uint) + } + #[inline] + fn ge(&self, other: &*T) -> bool { + (*self as uint) >= (*other as uint) + } + #[inline] + fn gt(&self, other: &*T) -> bool { + (*self as uint) > (*other as uint) + } +} + +#[cfg(not(test))] +impl Ord for *mut T { #[inline] - fn lt(&self, other: &*const T) -> bool { + fn lt(&self, other: &*mut T) -> bool { (*self as uint) < (*other as uint) } #[inline] - fn le(&self, other: &*const T) -> bool { + fn le(&self, other: &*mut T) -> bool { (*self as uint) <= (*other as uint) } #[inline] - fn ge(&self, other: &*const T) -> bool { + fn ge(&self, other: &*mut T) -> bool { (*self as uint) >= (*other as uint) } #[inline] - fn gt(&self, other: &*const T) -> bool { + fn gt(&self, other: &*mut T) -> bool { (*self as uint) > (*other as uint) } } diff --git a/src/libstd/rt/borrowck.rs b/src/libstd/rt/borrowck.rs index cbac43f27c73b..e03a61226ad26 100644 --- a/src/libstd/rt/borrowck.rs +++ b/src/libstd/rt/borrowck.rs @@ -11,17 +11,18 @@ use cell::Cell; use c_str::ToCStr; use cast::transmute; -use libc::{c_char, size_t, STDERR_FILENO}; -use io; use io::{Writer, WriterUtil}; +use io; +use libc::{c_char, size_t, STDERR_FILENO}; use option::{Option, None, Some}; -use uint; +use ptr::RawPtr; use rt::env; use rt::local::Local; use rt::task::Task; -use str; use str::{OwnedStr, StrSlice}; +use str; use sys; +use uint; use unstable::raw; use vec::ImmutableVector; @@ -93,12 +94,12 @@ unsafe fn fail_borrowed(box: *mut raw::Box<()>, file: *c_char, line: size_t) { static ENABLE_DEBUG: bool = false; #[inline] -unsafe fn debug_borrow(tag: &'static str, - p: *const T, - old_bits: uint, - new_bits: uint, - filename: *c_char, - line: size_t) { +unsafe fn debug_borrow>(tag: &'static str, + p: P, + old_bits: uint, + new_bits: uint, + filename: *c_char, + line: size_t) { //! A useful debugging function that prints a pointer + tag + newline //! without allocating memory. @@ -106,15 +107,15 @@ unsafe fn debug_borrow(tag: &'static str, debug_borrow_slow(tag, p, old_bits, new_bits, filename, line); } - unsafe fn debug_borrow_slow(tag: &'static str, - p: *const T, - old_bits: uint, - new_bits: uint, - filename: *c_char, - line: size_t) { + unsafe fn debug_borrow_slow>(tag: &'static str, + p: P, + old_bits: uint, + new_bits: uint, + filename: *c_char, + line: size_t) { let dbg = STDERR_FILENO as io::fd_t; dbg.write_str(tag); - dbg.write_hex(p as uint); + dbg.write_hex(p.to_uint()); dbg.write_str(" "); dbg.write_hex(old_bits); dbg.write_str(" "); diff --git a/src/libstd/rt/comm.rs b/src/libstd/rt/comm.rs index 49cf8c239b7e6..5d51005d34e3d 100644 --- a/src/libstd/rt/comm.rs +++ b/src/libstd/rt/comm.rs @@ -144,13 +144,13 @@ impl ChanOne { match oldstate { STATE_BOTH => { // Port is not waiting yet. Nothing to do - do Local::borrow:: |sched| { + do Local::borrow |sched: &mut Scheduler| { rtdebug!("non-rendezvous send"); sched.metrics.non_rendezvous_sends += 1; } } STATE_ONE => { - do Local::borrow:: |sched| { + do Local::borrow |sched: &mut Scheduler| { rtdebug!("rendezvous send"); sched.metrics.rendezvous_sends += 1; } @@ -167,7 +167,7 @@ impl ChanOne { }; } else { let recvr = Cell::new(recvr); - do Local::borrow:: |sched| { + do Local::borrow |sched: &mut Scheduler| { sched.enqueue_blocked_task(recvr.take()); } } @@ -207,7 +207,7 @@ impl PortOne { if !this.optimistic_check() { // No data available yet. // Switch to the scheduler to put the ~Task into the Packet state. - let sched = Local::take::(); + let sched: ~Scheduler = Local::take(); do sched.deschedule_running_task_and_then |sched, task| { this.block_on(sched, task); } @@ -229,7 +229,7 @@ impl SelectInner for PortOne { // The optimistic check is never necessary for correctness. For testing // purposes, making it randomly return false simulates a racing sender. use rand::{Rand}; - let actually_check = do Local::borrow:: |sched| { + let actually_check = do Local::borrow |sched: &mut Scheduler| { Rand::rand(&mut sched.rng) }; if actually_check { diff --git a/src/libstd/rt/io/net/ip.rs b/src/libstd/rt/io/net/ip.rs index 77176088801de..7b2d38caaaf05 100644 --- a/src/libstd/rt/io/net/ip.rs +++ b/src/libstd/rt/io/net/ip.rs @@ -359,7 +359,7 @@ impl FromStr for SocketAddr { mod test { use super::*; use from_str::FromStr; - use option::{Some, None}; + use option::{Option, Some, None}; #[test] fn test_from_str_ipv4() { @@ -368,13 +368,17 @@ mod test { assert_eq!(Some(Ipv4Addr(0, 0, 0, 0)), FromStr::from_str("0.0.0.0")); // out of range - assert_eq!(None, FromStr::from_str::("256.0.0.1")); + let none: Option = FromStr::from_str("256.0.0.1"); + assert_eq!(None, none); // too short - assert_eq!(None, FromStr::from_str::("255.0.0")); + let none: Option = FromStr::from_str("255.0.0"); + assert_eq!(None, none); // too long - assert_eq!(None, FromStr::from_str::("255.0.0.1.2")); + let none: Option = FromStr::from_str("255.0.0.1.2"); + assert_eq!(None, none); // no number between dots - assert_eq!(None, FromStr::from_str::("255.0..1")); + let none: Option = FromStr::from_str("255.0..1"); + assert_eq!(None, none); } #[test] @@ -389,15 +393,20 @@ mod test { FromStr::from_str("2a02:6b8::11:11")); // too long group - assert_eq!(None, FromStr::from_str::("::00000")); + let none: Option = FromStr::from_str("::00000"); + assert_eq!(None, none); // too short - assert_eq!(None, FromStr::from_str::("1:2:3:4:5:6:7")); + let none: Option = FromStr::from_str("1:2:3:4:5:6:7"); + assert_eq!(None, none); // too long - assert_eq!(None, FromStr::from_str::("1:2:3:4:5:6:7:8:9")); + let none: Option = FromStr::from_str("1:2:3:4:5:6:7:8:9"); + assert_eq!(None, none); // triple colon - assert_eq!(None, FromStr::from_str::("1:2:::6:7:8")); + let none: Option = FromStr::from_str("1:2:::6:7:8"); + assert_eq!(None, none); // two double colons - assert_eq!(None, FromStr::from_str::("1:2::6::8")); + let none: Option = FromStr::from_str("1:2::6::8"); + assert_eq!(None, none); } #[test] @@ -412,11 +421,15 @@ mod test { FromStr::from_str("2001:db8:122:c000:2:2100:192.0.2.33")); // colon after v4 - assert_eq!(None, FromStr::from_str::("::127.0.0.1:")); + let none: Option = FromStr::from_str("::127.0.0.1:"); + assert_eq!(None, none); // not enought groups - assert_eq!(None, FromStr::from_str::("1.2.3.4.5:127.0.0.1")); + let none: Option = FromStr::from_str("1.2.3.4.5:127.0.0.1"); + assert_eq!(None, none); // too many groups - assert_eq!(None, FromStr::from_str::("1.2.3.4.5:6:7:127.0.0.1")); + let none: Option = + FromStr::from_str("1.2.3.4.5:6:7:127.0.0.1"); + assert_eq!(None, none); } #[test] @@ -429,13 +442,17 @@ mod test { FromStr::from_str("[::127.0.0.1]:22")); // without port - assert_eq!(None, FromStr::from_str::("127.0.0.1")); + let none: Option = FromStr::from_str("127.0.0.1"); + assert_eq!(None, none); // without port - assert_eq!(None, FromStr::from_str::("127.0.0.1:")); + let none: Option = FromStr::from_str("127.0.0.1:"); + assert_eq!(None, none); // wrong brackets around v4 - assert_eq!(None, FromStr::from_str::("[127.0.0.1]:22")); + let none: Option = FromStr::from_str("[127.0.0.1]:22"); + assert_eq!(None, none); // port out of range - assert_eq!(None, FromStr::from_str::("127.0.0.1:123456")); + let none: Option = FromStr::from_str("127.0.0.1:123456"); + assert_eq!(None, none); } #[test] diff --git a/src/libstd/rt/io/net/tcp.rs b/src/libstd/rt/io/net/tcp.rs index 27222542e087d..52c350951014e 100644 --- a/src/libstd/rt/io/net/tcp.rs +++ b/src/libstd/rt/io/net/tcp.rs @@ -29,7 +29,7 @@ impl TcpStream { pub fn connect(addr: SocketAddr) -> Option { let stream = unsafe { rtdebug!("borrowing io to connect"); - let io = Local::unsafe_borrow::(); + let io: *mut IoFactoryObject = Local::unsafe_borrow(); rtdebug!("about to connect"); (*io).tcp_connect(addr) }; @@ -102,7 +102,7 @@ pub struct TcpListener(~RtioTcpListenerObject); impl TcpListener { pub fn bind(addr: SocketAddr) -> Option { let listener = unsafe { - let io = Local::unsafe_borrow::(); + let io: *mut IoFactoryObject = Local::unsafe_borrow(); (*io).tcp_bind(addr) }; match listener { diff --git a/src/libstd/rt/io/net/udp.rs b/src/libstd/rt/io/net/udp.rs index 644abcbe145ec..132ca064515c1 100644 --- a/src/libstd/rt/io/net/udp.rs +++ b/src/libstd/rt/io/net/udp.rs @@ -20,7 +20,10 @@ pub struct UdpSocket(~RtioUdpSocketObject); impl UdpSocket { pub fn bind(addr: SocketAddr) -> Option { - let socket = unsafe { (*Local::unsafe_borrow::()).udp_bind(addr) }; + let socket = unsafe { + let factory: *mut IoFactoryObject = Local::unsafe_borrow(); + (*factory).udp_bind(addr) + }; match socket { Ok(s) => Some(UdpSocket(s)), Err(ioerr) => { diff --git a/src/libstd/rt/io/timer.rs b/src/libstd/rt/io/timer.rs index c7820ebf6238b..36a3e8bb08030 100644 --- a/src/libstd/rt/io/timer.rs +++ b/src/libstd/rt/io/timer.rs @@ -25,7 +25,7 @@ impl Timer { pub fn new() -> Option { let timer = unsafe { rtdebug!("Timer::init: borrowing io to init timer"); - let io = Local::unsafe_borrow::(); + let io: *mut IoFactoryObject = Local::unsafe_borrow(); rtdebug!("about to init timer"); (*io).timer_init() }; @@ -61,4 +61,4 @@ mod test { } } } -} \ No newline at end of file +} diff --git a/src/libstd/rt/local.rs b/src/libstd/rt/local.rs index 1faad913b5025..5b26b073f747a 100644 --- a/src/libstd/rt/local.rs +++ b/src/libstd/rt/local.rs @@ -19,7 +19,7 @@ use cell::Cell; pub trait Local { fn put(value: ~Self); fn take() -> ~Self; - fn exists() -> bool; + fn exists(unused_value: Option) -> bool; fn borrow(f: &fn(&mut Self) -> T) -> T; unsafe fn unsafe_borrow() -> *mut Self; unsafe fn try_unsafe_borrow() -> Option<*mut Self>; @@ -28,7 +28,7 @@ pub trait Local { impl Local for Task { fn put(value: ~Task) { unsafe { local_ptr::put(value) } } fn take() -> ~Task { unsafe { local_ptr::take() } } - fn exists() -> bool { local_ptr::exists() } + fn exists(_: Option) -> bool { local_ptr::exists() } fn borrow(f: &fn(&mut Task) -> T) -> T { let mut res: Option = None; let res_ptr: *mut Option = &mut res; @@ -52,21 +52,21 @@ impl Local for Task { impl Local for Scheduler { fn put(value: ~Scheduler) { let value = Cell::new(value); - do Local::borrow:: |task| { + do Local::borrow |task: &mut Task| { let task = task; task.sched = Some(value.take()); }; } fn take() -> ~Scheduler { - do Local::borrow:: |task| { + do Local::borrow |task: &mut Task| { let sched = task.sched.take_unwrap(); let task = task; task.sched = None; sched } } - fn exists() -> bool { - do Local::borrow:: |task| { + fn exists(_: Option) -> bool { + do Local::borrow |task: &mut Task| { match task.sched { Some(ref _task) => true, None => false @@ -74,7 +74,7 @@ impl Local for Scheduler { } } fn borrow(f: &fn(&mut Scheduler) -> T) -> T { - do Local::borrow:: |task| { + do Local::borrow |task: &mut Task| { match task.sched { Some(~ref mut task) => { f(task) @@ -86,7 +86,8 @@ impl Local for Scheduler { } } unsafe fn unsafe_borrow() -> *mut Scheduler { - match (*Local::unsafe_borrow::()).sched { + let task: *mut Task = Local::unsafe_borrow(); + match (*task).sched { Some(~ref mut sched) => { let s: *mut Scheduler = &mut *sched; return s; @@ -97,7 +98,8 @@ impl Local for Scheduler { } } unsafe fn try_unsafe_borrow() -> Option<*mut Scheduler> { - if Local::exists::() { + let no_scheduler: Option = None; + if Local::exists(no_scheduler) { Some(Local::unsafe_borrow()) } else { None @@ -109,14 +111,16 @@ impl Local for Scheduler { impl Local for IoFactoryObject { fn put(_value: ~IoFactoryObject) { rtabort!("unimpl") } fn take() -> ~IoFactoryObject { rtabort!("unimpl") } - fn exists() -> bool { rtabort!("unimpl") } + fn exists(_: Option) -> bool { rtabort!("unimpl") } fn borrow(_f: &fn(&mut IoFactoryObject) -> T) -> T { rtabort!("unimpl") } unsafe fn unsafe_borrow() -> *mut IoFactoryObject { - let sched = Local::unsafe_borrow::(); + let sched: *mut Scheduler = Local::unsafe_borrow(); let io: *mut IoFactoryObject = (*sched).event_loop.io().unwrap(); return io; } - unsafe fn try_unsafe_borrow() -> Option<*mut IoFactoryObject> { rtabort!("unimpl") } + unsafe fn try_unsafe_borrow() -> Option<*mut IoFactoryObject> { + rtabort!("unimpl") + } } @@ -182,7 +186,7 @@ mod test { let task = ~Task::new_root(&mut sched.stack_pool, None, || {}); Local::put(task); - let res = do Local::borrow:: |_task| { + let res = do Local::borrow |_task: &mut Task| { true }; assert!(res) diff --git a/src/libstd/rt/local_heap.rs b/src/libstd/rt/local_heap.rs index bca1b4a70f4c9..c11f5f1135208 100644 --- a/src/libstd/rt/local_heap.rs +++ b/src/libstd/rt/local_heap.rs @@ -13,7 +13,7 @@ use libc; use libc::{c_void, uintptr_t, size_t}; use ops::Drop; -use option::{Some, None}; +use option::{Option, None, Some}; use rt::local::Local; use rt::task::Task; use unstable::raw; @@ -91,7 +91,8 @@ impl Drop for LocalHeap { // A little compatibility function pub unsafe fn local_free(ptr: *libc::c_char) { // XXX: Unsafe borrow for speed. Lame. - match Local::try_unsafe_borrow::() { + let task_ptr: Option<*mut Task> = Local::try_unsafe_borrow(); + match task_ptr { Some(task) => { (*task).heap.free(ptr as *libc::c_void); } @@ -100,7 +101,7 @@ pub unsafe fn local_free(ptr: *libc::c_char) { } pub fn live_allocs() -> *raw::Box<()> { - let region = do Local::borrow:: |task| { + let region = do Local::borrow |task: &mut Task| { task.heap.boxed_region }; diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs index db1bfdf1bf56c..9b9add5a35214 100644 --- a/src/libstd/rt/mod.rs +++ b/src/libstd/rt/mod.rs @@ -64,7 +64,7 @@ use cell::Cell; use clone::Clone; use container::Container; use iterator::{Iterator, range}; -use option::{Some, None}; +use option::{Option, None, Some}; use ptr::RawPtr; use rt::local::Local; use rt::sched::{Scheduler, Shutdown}; @@ -412,7 +412,8 @@ fn run_(main: ~fn(), use_main_sched: bool) -> int { pub fn in_sched_context() -> bool { unsafe { - match Local::try_unsafe_borrow::() { + let task_ptr: Option<*mut Task> = Local::try_unsafe_borrow(); + match task_ptr { Some(task) => { match (*task).task_type { SchedTask => true, @@ -426,7 +427,8 @@ pub fn in_sched_context() -> bool { pub fn in_green_task_context() -> bool { unsafe { - match Local::try_unsafe_borrow::() { + let task: Option<*mut Task> = Local::try_unsafe_borrow(); + match task { Some(task) => { match (*task).task_type { GreenTask(_) => true, diff --git a/src/libstd/rt/sched.rs b/src/libstd/rt/sched.rs index e65a45f0e0749..6d8c31dacdbd2 100644 --- a/src/libstd/rt/sched.rs +++ b/src/libstd/rt/sched.rs @@ -170,7 +170,7 @@ impl Scheduler { // successfully run the input task. Start by running the // scheduler. Grab it out of TLS - performing the scheduler // action will have given it away. - let sched = Local::take::(); + let sched: ~Scheduler = Local::take(); rtdebug!("starting scheduler %u", sched.sched_id()); @@ -181,7 +181,7 @@ impl Scheduler { // cleaning up the memory it uses. As we didn't actually call // task.run() on the scheduler task we never get through all // the cleanup code it runs. - let mut stask = Local::take::(); + let mut stask: ~Task = Local::take(); rtdebug!("stopping scheduler %u", stask.sched.get_ref().sched_id()); @@ -213,7 +213,7 @@ impl Scheduler { // Our scheduler must be in the task before the event loop // is started. let self_sched = Cell::new(self_sched); - do Local::borrow:: |stask| { + do Local::borrow |stask: &mut Task| { stask.sched = Some(self_sched.take()); }; @@ -235,7 +235,7 @@ impl Scheduler { // already have a scheduler stored in our local task, so we // start off by taking it. This is the only path through the // scheduler where we get the scheduler this way. - let sched = Local::take::(); + let sched: ~Scheduler = Local::take(); // Our first task is to read mail to see if we have important // messages. @@ -307,7 +307,6 @@ impl Scheduler { /// event loop to run it later. Always use this instead of pushing /// to the work queue directly. pub fn enqueue_task(&mut self, task: ~Task) { - let this = self; // We push the task onto our local queue clone. @@ -591,7 +590,7 @@ impl Scheduler { // Task context case - use TLS. pub fn run_task(task: ~Task) { - let sched = Local::take::(); + let sched: ~Scheduler = Local::take(); let opt = do sched.schedule_task(task) |sched, next_task| { do sched.switch_running_tasks_and_then(next_task) |sched, last_task| { sched.enqueue_blocked_task(last_task); @@ -614,7 +613,7 @@ impl Scheduler { let mut this = self; // The current task is grabbed from TLS, not taken as an input. - let current_task: ~Task = Local::take::(); + let current_task: ~Task = Local::take(); // Check that the task is not in an atomically() section (e.g., // holding a pthread mutex, which could deadlock the scheduler). @@ -646,7 +645,8 @@ impl Scheduler { let current_task: &mut Task = match sched.cleanup_job { Some(GiveTask(ref task, _)) => { - transmute_mut_region(*transmute_mut_unsafe(task)) + let task_ptr: *~Task = task; + transmute_mut_region(*transmute_mut_unsafe(task_ptr)) } Some(DoNothing) => { rtabort!("no next task"); @@ -675,11 +675,11 @@ impl Scheduler { // run the cleanup job, as expected by the previously called // swap_contexts function. unsafe { - let sched = Local::unsafe_borrow::(); + let sched: *mut Scheduler = Local::unsafe_borrow(); (*sched).run_cleanup_job(); // Must happen after running the cleanup job (of course). - let task = Local::unsafe_borrow::(); + let task: *mut Task = Local::unsafe_borrow(); (*task).death.check_killed((*task).unwinder.unwinding); } } @@ -741,7 +741,7 @@ impl Scheduler { // We aren't performing a scheduler operation, so we want to // put the Scheduler back when we finish. let next_task = Cell::new(next_task); - do Local::borrow:: |sched| { + do Local::borrow |sched: &mut Scheduler| { sched.enqueue_task(next_task.take()); }; } @@ -1056,12 +1056,12 @@ mod test { // exit before emptying the work queue do run_in_newsched_task { do spawntask { - let sched = Local::take::(); + let sched: ~Scheduler = Local::take(); do sched.deschedule_running_task_and_then |sched, task| { let task = Cell::new(task); do sched.event_loop.callback_ms(10) { rtdebug!("in callback"); - let mut sched = Local::take::(); + let mut sched: ~Scheduler = Local::take(); sched.enqueue_blocked_task(task.take()); Local::put(sched); } diff --git a/src/libstd/rt/select.rs b/src/libstd/rt/select.rs index 19a4948af3c5a..6cde0a1f2169f 100644 --- a/src/libstd/rt/select.rs +++ b/src/libstd/rt/select.rs @@ -26,3 +26,4 @@ pub trait SelectInner { pub trait SelectPortInner { fn recv_ready(self) -> Option; } + diff --git a/src/libstd/rt/task.rs b/src/libstd/rt/task.rs index 95d60c11df6ed..572e7d04a35d5 100644 --- a/src/libstd/rt/task.rs +++ b/src/libstd/rt/task.rs @@ -93,7 +93,7 @@ impl Task { pub fn build_homed_child(stack_size: Option, f: ~fn(), home: SchedHome) -> ~Task { let f = Cell::new(f); let home = Cell::new(home); - do Local::borrow:: |running_task| { + do Local::borrow |running_task: &mut Task| { let mut sched = running_task.sched.take_unwrap(); let new_task = ~running_task.new_child_homed(&mut sched.stack_pool, stack_size, @@ -111,7 +111,7 @@ impl Task { pub fn build_homed_root(stack_size: Option, f: ~fn(), home: SchedHome) -> ~Task { let f = Cell::new(f); let home = Cell::new(home); - do Local::borrow:: |running_task| { + do Local::borrow |running_task: &mut Task| { let mut sched = running_task.sched.take_unwrap(); let new_task = ~Task::new_root_homed(&mut sched.stack_pool, stack_size, @@ -305,7 +305,7 @@ impl Task { // Grab both the scheduler and the task from TLS and check if the // task is executing on an appropriate scheduler. pub fn on_appropriate_sched() -> bool { - do Local::borrow:: |task| { + do Local::borrow |task: &mut Task| { let sched_id = task.sched.get_ref().sched_id(); let sched_run_anything = task.sched.get_ref().run_anything; match task.task_type { @@ -369,7 +369,7 @@ impl Coroutine { unsafe { // Again - might work while safe, or it might not. - do Local::borrow:: |sched| { + do Local::borrow |sched: &mut Scheduler| { (sched).run_cleanup_job(); } @@ -378,7 +378,7 @@ impl Coroutine { // simply unsafe_borrow it to get this reference. We // need to still have the task in TLS though, so we // need to unsafe_borrow. - let task = Local::unsafe_borrow::(); + let task: *mut Task = Local::unsafe_borrow(); do (*task).run { // N.B. Removing `start` from the start wrapper @@ -397,7 +397,7 @@ impl Coroutine { } // We remove the sched from the Task in TLS right now. - let sched = Local::take::(); + let sched: ~Scheduler = Local::take(); // ... allowing us to give it away when performing a // scheduling operation. sched.terminate_current_task() diff --git a/src/libstd/rt/tube.rs b/src/libstd/rt/tube.rs index 247893f75de00..b8e535e4c7dfd 100644 --- a/src/libstd/rt/tube.rs +++ b/src/libstd/rt/tube.rs @@ -51,7 +51,7 @@ impl Tube { // There's a waiting task. Wake it up rtdebug!("waking blocked tube"); let task = (*state).blocked_task.take_unwrap(); - let sched = Local::take::(); + let sched: ~Scheduler = Local::take(); sched.resume_blocked_task_immediately(task); } } @@ -67,7 +67,7 @@ impl Tube { rtdebug!("blocking on tube recv"); assert!(self.p.refcount() > 1); // There better be somebody to wake us up assert!((*state).blocked_task.is_none()); - let sched = Local::take::(); + let sched: ~Scheduler = Local::take(); do sched.deschedule_running_task_and_then |_, task| { (*state).blocked_task = Some(task); } @@ -102,7 +102,7 @@ mod test { let mut tube: Tube = Tube::new(); let tube_clone = tube.clone(); let tube_clone_cell = Cell::new(tube_clone); - let sched = Local::take::(); + let sched: ~Scheduler = Local::take(); do sched.deschedule_running_task_and_then |sched, task| { let mut tube_clone = tube_clone_cell.take(); tube_clone.send(1); @@ -119,7 +119,7 @@ mod test { let mut tube: Tube = Tube::new(); let tube_clone = tube.clone(); let tube_clone = Cell::new(tube_clone); - let sched = Local::take::(); + let sched: ~Scheduler = Local::take(); do sched.deschedule_running_task_and_then |sched, task| { let tube_clone = Cell::new(tube_clone.take()); do sched.event_loop.callback { @@ -143,7 +143,7 @@ mod test { let mut tube: Tube = Tube::new(); let tube_clone = tube.clone(); let tube_clone = Cell::new(tube_clone); - let sched = Local::take::(); + let sched: ~Scheduler = Local::take(); do sched.deschedule_running_task_and_then |sched, task| { callback_send(tube_clone.take(), 0); @@ -151,7 +151,7 @@ mod test { if i == 100 { return; } let tube = Cell::new(Cell::new(tube)); - do Local::borrow:: |sched| { + do Local::borrow |sched: &mut Scheduler| { let tube = tube.take(); do sched.event_loop.callback { let mut tube = tube.take(); diff --git a/src/libstd/rt/uv/uvio.rs b/src/libstd/rt/uv/uvio.rs index d4794da9b0f28..d9d73d74da45a 100644 --- a/src/libstd/rt/uv/uvio.rs +++ b/src/libstd/rt/uv/uvio.rs @@ -215,7 +215,7 @@ mod test_remote { let mut tube = Tube::new(); let tube_clone = tube.clone(); let remote_cell = Cell::new_empty(); - do Local::borrow::() |sched| { + do Local::borrow |sched: &mut Scheduler| { let tube_clone = tube_clone.clone(); let tube_clone_cell = Cell::new(tube_clone); let remote = do sched.event_loop.remote_callback { @@ -251,7 +251,7 @@ impl IoFactory for UvIoFactory { let result_cell = Cell::new_empty(); let result_cell_ptr: *Cell> = &result_cell; - let scheduler = Local::take::(); + let scheduler: ~Scheduler = Local::take(); // Block this task and take ownership, switch to scheduler context do scheduler.deschedule_running_task_and_then |_, task| { @@ -273,7 +273,7 @@ impl IoFactory for UvIoFactory { unsafe { (*result_cell_ptr).put_back(res); } // Context switch - let scheduler = Local::take::(); + let scheduler: ~Scheduler = Local::take(); scheduler.resume_blocked_task_immediately(task_cell.take()); } else { rtdebug!("status is some"); @@ -281,7 +281,7 @@ impl IoFactory for UvIoFactory { do stream_watcher.close { let res = Err(uv_error_to_io_error(status.unwrap())); unsafe { (*result_cell_ptr).put_back(res); } - let scheduler = Local::take::(); + let scheduler: ~Scheduler = Local::take(); scheduler.resume_blocked_task_immediately(task_cell.take()); } }; @@ -297,11 +297,11 @@ impl IoFactory for UvIoFactory { match watcher.bind(addr) { Ok(_) => Ok(~UvTcpListener::new(watcher)), Err(uverr) => { - let scheduler = Local::take::(); + let scheduler: ~Scheduler = Local::take(); do scheduler.deschedule_running_task_and_then |_, task| { let task_cell = Cell::new(task); do watcher.as_stream().close { - let scheduler = Local::take::(); + let scheduler: ~Scheduler = Local::take(); scheduler.resume_blocked_task_immediately(task_cell.take()); } } @@ -315,11 +315,11 @@ impl IoFactory for UvIoFactory { match watcher.bind(addr) { Ok(_) => Ok(~UvUdpSocket(watcher)), Err(uverr) => { - let scheduler = Local::take::(); + let scheduler: ~Scheduler = Local::take(); do scheduler.deschedule_running_task_and_then |_, task| { let task_cell = Cell::new(task); do watcher.close { - let scheduler = Local::take::(); + let scheduler: ~Scheduler = Local::take(); scheduler.resume_blocked_task_immediately(task_cell.take()); } } @@ -354,11 +354,11 @@ impl UvTcpListener { impl Drop for UvTcpListener { fn drop(&self) { let watcher = self.watcher(); - let scheduler = Local::take::(); + let scheduler: ~Scheduler = Local::take(); do scheduler.deschedule_running_task_and_then |_, task| { let task_cell = Cell::new(task); do watcher.as_stream().close { - let scheduler = Local::take::(); + let scheduler: ~Scheduler = Local::take(); scheduler.resume_blocked_task_immediately(task_cell.take()); } } @@ -438,11 +438,11 @@ pub struct UvTcpStream(TcpWatcher); impl Drop for UvTcpStream { fn drop(&self) { rtdebug!("closing tcp stream"); - let scheduler = Local::take::(); + let scheduler: ~Scheduler = Local::take(); do scheduler.deschedule_running_task_and_then |_, task| { let task_cell = Cell::new(task); do self.as_stream().close { - let scheduler = Local::take::(); + let scheduler: ~Scheduler = Local::take(); scheduler.resume_blocked_task_immediately(task_cell.take()); } } @@ -460,7 +460,7 @@ impl RtioTcpStream for UvTcpStream { let result_cell = Cell::new_empty(); let result_cell_ptr: *Cell> = &result_cell; - let scheduler = Local::take::(); + let scheduler: ~Scheduler = Local::take(); let buf_ptr: *&mut [u8] = &buf; do scheduler.deschedule_running_task_and_then |_sched, task| { rtdebug!("read: entered scheduler context"); @@ -488,7 +488,7 @@ impl RtioTcpStream for UvTcpStream { unsafe { (*result_cell_ptr).put_back(result); } - let scheduler = Local::take::(); + let scheduler: ~Scheduler = Local::take(); scheduler.resume_blocked_task_immediately(task_cell.take()); } } @@ -500,7 +500,7 @@ impl RtioTcpStream for UvTcpStream { fn write(&mut self, buf: &[u8]) -> Result<(), IoError> { let result_cell = Cell::new_empty(); let result_cell_ptr: *Cell> = &result_cell; - let scheduler = Local::take::(); + let scheduler: ~Scheduler = Local::take(); let buf_ptr: *&[u8] = &buf; do scheduler.deschedule_running_task_and_then |_, task| { let task_cell = Cell::new(task); @@ -515,7 +515,7 @@ impl RtioTcpStream for UvTcpStream { unsafe { (*result_cell_ptr).put_back(result); } - let scheduler = Local::take::(); + let scheduler: ~Scheduler = Local::take(); scheduler.resume_blocked_task_immediately(task_cell.take()); } } @@ -587,11 +587,11 @@ pub struct UvUdpSocket(UdpWatcher); impl Drop for UvUdpSocket { fn drop(&self) { rtdebug!("closing udp socket"); - let scheduler = Local::take::(); + let scheduler: ~Scheduler = Local::take(); do scheduler.deschedule_running_task_and_then |_, task| { let task_cell = Cell::new(task); do self.close { - let scheduler = Local::take::(); + let scheduler: ~Scheduler = Local::take(); scheduler.resume_blocked_task_immediately(task_cell.take()); } } @@ -609,7 +609,7 @@ impl RtioUdpSocket for UvUdpSocket { let result_cell = Cell::new_empty(); let result_cell_ptr: *Cell> = &result_cell; - let scheduler = Local::take::(); + let scheduler: ~Scheduler = Local::take(); let buf_ptr: *&mut [u8] = &buf; do scheduler.deschedule_running_task_and_then |_sched, task| { rtdebug!("recvfrom: entered scheduler context"); @@ -630,7 +630,7 @@ impl RtioUdpSocket for UvUdpSocket { unsafe { (*result_cell_ptr).put_back(result); } - let scheduler = Local::take::(); + let scheduler: ~Scheduler = Local::take(); scheduler.resume_blocked_task_immediately(task_cell.take()); } } @@ -642,7 +642,7 @@ impl RtioUdpSocket for UvUdpSocket { fn sendto(&mut self, buf: &[u8], dst: SocketAddr) -> Result<(), IoError> { let result_cell = Cell::new_empty(); let result_cell_ptr: *Cell> = &result_cell; - let scheduler = Local::take::(); + let scheduler: ~Scheduler = Local::take(); let buf_ptr: *&[u8] = &buf; do scheduler.deschedule_running_task_and_then |_, task| { let task_cell = Cell::new(task); @@ -656,7 +656,7 @@ impl RtioUdpSocket for UvUdpSocket { unsafe { (*result_cell_ptr).put_back(result); } - let scheduler = Local::take::(); + let scheduler: ~Scheduler = Local::take(); scheduler.resume_blocked_task_immediately(task_cell.take()); } } @@ -771,11 +771,11 @@ impl UvTimer { impl Drop for UvTimer { fn drop(&self) { rtdebug!("closing UvTimer"); - let scheduler = Local::take::(); + let scheduler: ~Scheduler = Local::take(); do scheduler.deschedule_running_task_and_then |_, task| { let task_cell = Cell::new(task); do self.close { - let scheduler = Local::take::(); + let scheduler: ~Scheduler = Local::take(); scheduler.resume_blocked_task_immediately(task_cell.take()); } } @@ -784,14 +784,14 @@ impl Drop for UvTimer { impl RtioTimer for UvTimer { fn sleep(&self, msecs: u64) { - let scheduler = Local::take::(); + let scheduler: ~Scheduler = Local::take(); do scheduler.deschedule_running_task_and_then |_sched, task| { rtdebug!("sleep: entered scheduler context"); let task_cell = Cell::new(task); let mut watcher = **self; do watcher.start(msecs, 0) |_, status| { assert!(status.is_none()); - let scheduler = Local::take::(); + let scheduler: ~Scheduler = Local::take(); scheduler.resume_blocked_task_immediately(task_cell.take()); } } @@ -804,7 +804,7 @@ impl RtioTimer for UvTimer { fn test_simple_io_no_connect() { do run_in_newsched_task { unsafe { - let io = Local::unsafe_borrow::(); + let io: *mut IoFactoryObject = Local::unsafe_borrow(); let addr = next_test_ip4(); let maybe_chan = (*io).tcp_connect(addr); assert!(maybe_chan.is_err()); @@ -816,7 +816,7 @@ fn test_simple_io_no_connect() { fn test_simple_udp_io_bind_only() { do run_in_newsched_task { unsafe { - let io = Local::unsafe_borrow::(); + let io: *mut IoFactoryObject = Local::unsafe_borrow(); let addr = next_test_ip4(); let maybe_socket = (*io).udp_bind(addr); assert!(maybe_socket.is_ok()); @@ -832,7 +832,7 @@ fn test_simple_tcp_server_and_client() { // Start the server first so it's listening when we connect do spawntask { unsafe { - let io = Local::unsafe_borrow::(); + let io: *mut IoFactoryObject = Local::unsafe_borrow(); let mut listener = (*io).tcp_bind(addr).unwrap(); let mut stream = listener.accept().unwrap(); let mut buf = [0, .. 2048]; @@ -847,7 +847,7 @@ fn test_simple_tcp_server_and_client() { do spawntask { unsafe { - let io = Local::unsafe_borrow::(); + let io: *mut IoFactoryObject = Local::unsafe_borrow(); let mut stream = (*io).tcp_connect(addr).unwrap(); stream.write([0, 1, 2, 3, 4, 5, 6, 7]); } @@ -863,7 +863,7 @@ fn test_simple_udp_server_and_client() { do spawntask { unsafe { - let io = Local::unsafe_borrow::(); + let io: *mut IoFactoryObject = Local::unsafe_borrow(); let mut server_socket = (*io).udp_bind(server_addr).unwrap(); let mut buf = [0, .. 2048]; let (nread,src) = server_socket.recvfrom(buf).unwrap(); @@ -878,7 +878,7 @@ fn test_simple_udp_server_and_client() { do spawntask { unsafe { - let io = Local::unsafe_borrow::(); + let io: *mut IoFactoryObject = Local::unsafe_borrow(); let mut client_socket = (*io).udp_bind(client_addr).unwrap(); client_socket.sendto([0, 1, 2, 3, 4, 5, 6, 7], server_addr); } @@ -892,7 +892,7 @@ fn test_read_and_block() { let addr = next_test_ip4(); do spawntask { - let io = unsafe { Local::unsafe_borrow::() }; + let io: *mut IoFactoryObject = unsafe { Local::unsafe_borrow() }; let mut listener = unsafe { (*io).tcp_bind(addr).unwrap() }; let mut stream = listener.accept().unwrap(); let mut buf = [0, .. 2048]; @@ -910,7 +910,7 @@ fn test_read_and_block() { } reads += 1; - let scheduler = Local::take::(); + let scheduler: ~Scheduler = Local::take(); // Yield to the other task in hopes that it // will trigger a read callback while we are // not ready for it @@ -926,7 +926,7 @@ fn test_read_and_block() { do spawntask { unsafe { - let io = Local::unsafe_borrow::(); + let io: *mut IoFactoryObject = Local::unsafe_borrow(); let mut stream = (*io).tcp_connect(addr).unwrap(); stream.write([0, 1, 2, 3, 4, 5, 6, 7]); stream.write([0, 1, 2, 3, 4, 5, 6, 7]); @@ -946,7 +946,7 @@ fn test_read_read_read() { do spawntask { unsafe { - let io = Local::unsafe_borrow::(); + let io: *mut IoFactoryObject = Local::unsafe_borrow(); let mut listener = (*io).tcp_bind(addr).unwrap(); let mut stream = listener.accept().unwrap(); let buf = [1, .. 2048]; @@ -960,7 +960,7 @@ fn test_read_read_read() { do spawntask { unsafe { - let io = Local::unsafe_borrow::(); + let io: *mut IoFactoryObject = Local::unsafe_borrow(); let mut stream = (*io).tcp_connect(addr).unwrap(); let mut buf = [0, .. 2048]; let mut total_bytes_read = 0; @@ -986,7 +986,7 @@ fn test_udp_twice() { do spawntask { unsafe { - let io = Local::unsafe_borrow::(); + let io: *mut IoFactoryObject = Local::unsafe_borrow(); let mut client = (*io).udp_bind(client_addr).unwrap(); assert!(client.sendto([1], server_addr).is_ok()); assert!(client.sendto([2], server_addr).is_ok()); @@ -995,7 +995,7 @@ fn test_udp_twice() { do spawntask { unsafe { - let io = Local::unsafe_borrow::(); + let io: *mut IoFactoryObject = Local::unsafe_borrow(); let mut server = (*io).udp_bind(server_addr).unwrap(); let mut buf1 = [0]; let mut buf2 = [0]; @@ -1023,7 +1023,7 @@ fn test_udp_many_read() { do spawntask { unsafe { - let io = Local::unsafe_borrow::(); + let io: *mut IoFactoryObject = Local::unsafe_borrow(); let mut server_out = (*io).udp_bind(server_out_addr).unwrap(); let mut server_in = (*io).udp_bind(server_in_addr).unwrap(); let msg = [1, .. 2048]; @@ -1046,7 +1046,7 @@ fn test_udp_many_read() { do spawntask { unsafe { - let io = Local::unsafe_borrow::(); + let io: *mut IoFactoryObject = Local::unsafe_borrow(); let mut client_out = (*io).udp_bind(client_out_addr).unwrap(); let mut client_in = (*io).udp_bind(client_in_addr).unwrap(); let mut total_bytes_recv = 0; @@ -1073,7 +1073,7 @@ fn test_udp_many_read() { fn test_timer_sleep_simple_impl() { unsafe { - let io = Local::unsafe_borrow::(); + let io: *mut IoFactoryObject = Local::unsafe_borrow(); let timer = (*io).timer_init(); match timer { Ok(t) => t.sleep(1), diff --git a/src/libstd/select.rs b/src/libstd/select.rs index f537a1f6c33a2..3a3a1b59665e2 100644 --- a/src/libstd/select.rs +++ b/src/libstd/select.rs @@ -60,7 +60,7 @@ pub fn select(ports: &mut [A]) -> uint { do (|| { let c = Cell::new(c.take()); - let sched = Local::take::(); + let sched: ~Scheduler = Local::take(); do sched.deschedule_running_task_and_then |sched, task| { let task_handles = task.make_selectable(ports.len()); diff --git a/src/libstd/sys.rs b/src/libstd/sys.rs index bfb9bee78028c..cb0753fb2e5de 100644 --- a/src/libstd/sys.rs +++ b/src/libstd/sys.rs @@ -143,7 +143,7 @@ pub fn begin_unwind_(msg: *c_char, file: *c_char, line: size_t) -> ! { if in_green_task_context() { // XXX: Logging doesn't work here - the check to call the log // function never passes - so calling the log function directly. - do Local::borrow:: |task| { + do Local::borrow |task: &mut Task| { let msg = match task.name { Some(ref name) => fmt!("task '%s' failed at '%s', %s:%i", @@ -160,7 +160,7 @@ pub fn begin_unwind_(msg: *c_char, file: *c_char, line: size_t) -> ! { msg, file, line as int); } - let task = Local::unsafe_borrow::(); + let task: *mut Task = Local::unsafe_borrow(); if (*task).unwinder.unwinding { rtabort!("unwinding again"); } diff --git a/src/libstd/task/local_data_priv.rs b/src/libstd/task/local_data_priv.rs index 8132bfe53778b..2c2dfd8f689c2 100644 --- a/src/libstd/task/local_data_priv.rs +++ b/src/libstd/task/local_data_priv.rs @@ -28,7 +28,7 @@ impl Handle { pub fn new() -> Handle { use rt::local::Local; unsafe { - let task = Local::unsafe_borrow::(); + let task: *mut Task = Local::unsafe_borrow(); NewHandle(&mut (*task).storage) } } diff --git a/src/libstd/task/mod.rs b/src/libstd/task/mod.rs index 0d2e62a77003e..b4dd40ba8eceb 100644 --- a/src/libstd/task/mod.rs +++ b/src/libstd/task/mod.rs @@ -526,7 +526,7 @@ pub fn with_task_name(blk: &fn(Option<&str>) -> U) -> U { use rt::task::Task; if in_green_task_context() { - do Local::borrow:: |task| { + do Local::borrow |task: &mut Task| { match task.name { Some(ref name) => blk(Some(name.as_slice())), None => blk(None) @@ -545,7 +545,7 @@ pub fn deschedule() { // XXX: What does yield really mean in newsched? // FIXME(#7544): Optimize this, since we know we won't block. - let sched = Local::take::(); + let sched: ~Scheduler = Local::take(); do sched.deschedule_running_task_and_then |sched, task| { sched.enqueue_blocked_task(task); } @@ -556,7 +556,7 @@ pub fn failing() -> bool { use rt::task::Task; - do Local::borrow:: |local| { + do Local::borrow |local: &mut Task| { local.unwinder.unwinding } } @@ -582,7 +582,7 @@ pub fn unkillable(f: &fn() -> U) -> U { unsafe { if in_green_task_context() { // The inhibits/allows might fail and need to borrow the task. - let t = Local::unsafe_borrow::(); + let t: *mut Task = Local::unsafe_borrow(); do (|| { (*t).death.inhibit_kill((*t).unwinder.unwinding); f() @@ -602,7 +602,7 @@ pub unsafe fn rekillable(f: &fn() -> U) -> U { use rt::task::Task; if in_green_task_context() { - let t = Local::unsafe_borrow::(); + let t: *mut Task = Local::unsafe_borrow(); do (|| { (*t).death.allow_kill((*t).unwinder.unwinding); f() @@ -989,7 +989,7 @@ fn test_try_fail() { #[cfg(test)] fn get_sched_id() -> int { - do Local::borrow::<::rt::sched::Scheduler, int> |sched| { + do Local::borrow |sched: &mut ::rt::sched::Scheduler| { sched.sched_id() as int } } diff --git a/src/libstd/task/spawn.rs b/src/libstd/task/spawn.rs index e0efc14a8871f..216a9e9e4264d 100644 --- a/src/libstd/task/spawn.rs +++ b/src/libstd/task/spawn.rs @@ -450,7 +450,7 @@ impl RuntimeGlue { let mut handle = handle; do handle.kill().map_move |killed_task| { let killed_task = Cell::new(killed_task); - do Local::borrow:: |sched| { + do Local::borrow |sched: &mut Scheduler| { sched.enqueue_task(killed_task.take()); } }; @@ -461,7 +461,7 @@ impl RuntimeGlue { unsafe { // Can't use safe borrow, because the taskgroup destructor needs to // access the scheduler again to send kill signals to other tasks. - let me = Local::unsafe_borrow::(); + let me: *mut Task = Local::unsafe_borrow(); blk((*me).death.kill_handle.get_ref(), (*me).unwinder.unwinding) } } else { @@ -474,7 +474,7 @@ impl RuntimeGlue { unsafe { // Can't use safe borrow, because creating new hashmaps for the // tasksets requires an rng, which needs to borrow the sched. - let me = Local::unsafe_borrow::(); + let me: *mut Task = Local::unsafe_borrow(); blk(match (*me).taskgroup { None => { // First task in its (unlinked/unsupervised) taskgroup. @@ -587,7 +587,7 @@ fn spawn_raw_newsched(mut opts: TaskOpts, f: ~fn()) { // If child data is 'None', the enlist is vacuously successful. let enlist_success = do child_data.take().map_move_default(true) |child_data| { let child_data = Cell::new(child_data); // :( - do Local::borrow:: |me| { + do Local::borrow |me: &mut Task| { let (child_tg, ancestors) = child_data.take(); let mut ancestors = ancestors; let handle = me.death.kill_handle.get_ref(); @@ -621,7 +621,7 @@ fn spawn_raw_newsched(mut opts: TaskOpts, f: ~fn()) { } else { unsafe { // Creating a 1:1 task:thread ... - let sched = Local::unsafe_borrow::(); + let sched: *mut Scheduler = Local::unsafe_borrow(); let sched_handle = (*sched).make_handle(); // Since this is a 1:1 scheduler we create a queue not in diff --git a/src/libstd/to_bytes.rs b/src/libstd/to_bytes.rs index 198c09964bb6f..01f57c231dade 100644 --- a/src/libstd/to_bytes.rs +++ b/src/libstd/to_bytes.rs @@ -343,7 +343,14 @@ impl IterBytes for ~A { // NB: raw-pointer IterBytes does _not_ dereference // to the target; it just gives you the pointer-bytes. -impl IterBytes for *const A { +impl IterBytes for *A { + #[inline] + fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { + (*self as uint).iter_bytes(lsb0, f) + } +} + +impl IterBytes for *mut A { #[inline] fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { (*self as uint).iter_bytes(lsb0, f) diff --git a/src/libstd/tuple.rs b/src/libstd/tuple.rs index 12073a1f4f095..5d9ca6202e262 100644 --- a/src/libstd/tuple.rs +++ b/src/libstd/tuple.rs @@ -176,7 +176,7 @@ macro_rules! tuple_impls { impl<$($T:Zero),+> Zero for ($($T,)+) { #[inline] fn zero() -> ($($T,)+) { - ($(Zero::zero::<$T>(),)+) + ($({ let x: $T = Zero::zero(); x},)+) } #[inline] fn is_zero(&self) -> bool { diff --git a/src/libstd/unstable/atomics.rs b/src/libstd/unstable/atomics.rs index f286235ca0e18..f9380e7ad1241 100644 --- a/src/libstd/unstable/atomics.rs +++ b/src/libstd/unstable/atomics.rs @@ -538,7 +538,8 @@ mod test { #[test] fn option_empty() { - assert!(AtomicOption::empty::<()>().is_empty(SeqCst)); + let mut option: AtomicOption<()> = AtomicOption::empty(); + assert!(option.is_empty(SeqCst)); } #[test] diff --git a/src/libstd/unstable/lang.rs b/src/libstd/unstable/lang.rs index e47a3c49f96bf..1d839b55195be 100644 --- a/src/libstd/unstable/lang.rs +++ b/src/libstd/unstable/lang.rs @@ -13,7 +13,7 @@ use c_str::ToCStr; use cast::transmute; use libc::{c_char, c_void, size_t, uintptr_t}; -use option::{Some, None}; +use option::{Option, None, Some}; use sys; use rt::task::Task; use rt::local::Local; @@ -37,7 +37,8 @@ pub fn fail_bounds_check(file: *c_char, line: size_t, #[lang="malloc"] pub unsafe fn local_malloc(td: *c_char, size: uintptr_t) -> *c_char { // XXX: Unsafe borrow for speed. Lame. - match Local::try_unsafe_borrow::() { + let task: Option<*mut Task> = Local::try_unsafe_borrow(); + match task { Some(task) => { (*task).heap.alloc(td as *c_void, size as uint) as *c_char } diff --git a/src/libstd/unstable/sync.rs b/src/libstd/unstable/sync.rs index 29be094121c3b..cf8701a39b6b1 100644 --- a/src/libstd/unstable/sync.rs +++ b/src/libstd/unstable/sync.rs @@ -286,7 +286,7 @@ pub unsafe fn atomically(f: &fn() -> U) -> U { use rt::in_green_task_context; if in_green_task_context() { - let t = Local::unsafe_borrow::(); + let t: *mut Task = Local::unsafe_borrow(); do (|| { (*t).death.inhibit_deschedule(); f() diff --git a/src/libstd/util.rs b/src/libstd/util.rs index b46876ad3fe44..5085f337d4bba 100644 --- a/src/libstd/util.rs +++ b/src/libstd/util.rs @@ -54,8 +54,10 @@ pub fn swap(x: &mut T, y: &mut T) { let t: *mut T = &mut tmp; // Perform the swap, `&mut` pointers never alias - ptr::copy_nonoverlapping_memory(t, x, 1); - ptr::copy_nonoverlapping_memory(x, y, 1); + let x_raw: *mut T = x; + let y_raw: *mut T = y; + ptr::copy_nonoverlapping_memory(t, x_raw, 1); + ptr::copy_nonoverlapping_memory(x, y_raw, 1); ptr::copy_nonoverlapping_memory(y, t, 1); // y and t now point to the same thing, but we need to completely forget `tmp` diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 7c8046a64b2c2..6e89b06f55164 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -1062,14 +1062,7 @@ impl<'self,T> ImmutableVector<'self, T> for &'self [T] { * foreign interop. */ #[inline] - fn as_imm_buf(&self, - /* NB---this CANNOT be const, see below */ - f: &fn(*T, uint) -> U) -> U { - // NB---Do not change the type of s to `&const [T]`. This is - // unsound. The reason is that we are going to create immutable pointers - // into `s` and pass them to `f()`, but in fact they are potentially - // pointing at *mutable memory*. Use `as_mut_buf` instead! - + fn as_imm_buf(&self, f: &fn(*T, uint) -> U) -> U { let s = self.repr(); f(s.data, s.len / sys::nonzero_size_of::()) } diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index b01c19a59c186..03313aad92b52 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -109,12 +109,21 @@ pub struct Path { /// A `::foo` path, is relative to the crate root rather than current /// module (like paths in an import). global: bool, - /// The segments in the path (the things separated by ::) - idents: ~[ident], - /// "Region parameter", currently only one lifetime is allowed in a path. - rp: Option, - /// These are the type parameters, ie, the `a, b` in `foo::bar::` - types: ~[Ty], + /// The segments in the path: the things separated by `::`. + segments: ~[PathSegment], +} + +/// A segment of a path: an identifier, an optional lifetime, and a set of +/// types. +#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)] +pub struct PathSegment { + /// The identifier portion of this path segment. + identifier: ident, + /// The lifetime parameter for this path segment. Currently only one + /// lifetime parameter is allowed. + lifetime: Option, + /// The type parameters for this path segment, if present. + types: OptVec, } pub type CrateNum = int; @@ -165,12 +174,16 @@ impl Generics { } } +#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)] +pub enum MethodProvenance { + FromTrait(def_id), + FromImpl(def_id), +} + #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)] pub enum def { def_fn(def_id, purity), - def_static_method(/* method */ def_id, - /* trait */ Option, - purity), + def_static_method(/* method */ def_id, MethodProvenance, purity), def_self(NodeId, bool /* is_implicit */), def_self_ty(/* trait id */ NodeId), def_mod(def_id), @@ -298,7 +311,10 @@ pub enum pat_ { } #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)] -pub enum mutability { m_mutbl, m_imm, m_const, } +pub enum mutability { + m_mutbl, + m_imm, +} #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)] pub enum Sigil { @@ -704,7 +720,7 @@ impl ToStr for float_ty { } // NB Eq method appears below. -#[deriving(Clone, Eq, Encodable, Decodable,IterBytes)] +#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)] pub struct Ty { id: NodeId, node: ty_, diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index cfbe61ca65e68..585db7171a2d0 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -28,8 +28,8 @@ pub fn path_name_i(idents: &[ident]) -> ~str { idents.map(|i| token::interner_get(i.name)).connect("::") } -pub fn path_to_ident(p: &Path) -> ident { - *p.idents.last() +pub fn path_to_ident(path: &Path) -> ident { + path.segments.last().identifier } pub fn local_def(id: NodeId) -> def_id { @@ -217,12 +217,18 @@ pub fn default_block( } } -pub fn ident_to_path(s: span, i: ident) -> Path { - ast::Path { span: s, - global: false, - idents: ~[i], - rp: None, - types: ~[] } +pub fn ident_to_path(s: span, identifier: ident) -> Path { + ast::Path { + span: s, + global: false, + segments: ~[ + ast::PathSegment { + identifier: identifier, + lifetime: None, + types: opt_vec::Empty, + } + ], + } } pub fn ident_to_pat(id: NodeId, s: span, i: ident) -> @pat { @@ -420,7 +426,7 @@ impl IdVisitor { impl Visitor<()> for IdVisitor { fn visit_mod(&mut self, module: &_mod, - _span: span, + _: span, node_id: NodeId, env: ()) { (self.visit_callback)(node_id); diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index dfaffa0c2759d..d666cf68e1563 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -325,20 +325,6 @@ pub fn expr_to_str(cx: @ExtCtxt, expr: @ast::expr, err_msg: &str) -> @str { } } -pub fn expr_to_ident(cx: @ExtCtxt, - expr: @ast::expr, - err_msg: &str) -> ast::ident { - match expr.node { - ast::expr_path(ref p) => { - if p.types.len() > 0u || p.idents.len() != 1u { - cx.span_fatal(expr.span, err_msg); - } - return p.idents[0]; - } - _ => cx.span_fatal(expr.span, err_msg) - } -} - pub fn check_zero_tts(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree], name: &str) { if tts.len() != 0 { @@ -349,15 +335,15 @@ pub fn check_zero_tts(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree], pub fn get_single_str_from_tts(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree], - name: &str) -> @str { + name: &str) + -> @str { if tts.len() != 1 { cx.span_fatal(sp, fmt!("%s takes 1 argument.", name)); } match tts[0] { ast::tt_tok(_, token::LIT_STR(ident)) => cx.str_of(ident), - _ => - cx.span_fatal(sp, fmt!("%s requires a string.", name)) + _ => cx.span_fatal(sp, fmt!("%s requires a string.", name)), } } diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 9f179672422cd..21d67493cbffb 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -74,6 +74,13 @@ pub trait AstBuilder { // statements fn stmt_expr(&self, expr: @ast::expr) -> @ast::stmt; fn stmt_let(&self, sp: span, mutbl: bool, ident: ast::ident, ex: @ast::expr) -> @ast::stmt; + fn stmt_let_typed(&self, + sp: span, + mutbl: bool, + ident: ast::ident, + typ: ast::Ty, + ex: @ast::expr) + -> @ast::stmt; // blocks fn block(&self, span: span, stmts: ~[@ast::stmt], expr: Option<@ast::expr>) -> ast::Block; @@ -233,18 +240,31 @@ impl AstBuilder for @ExtCtxt { fn path_global(&self, span: span, strs: ~[ast::ident]) -> ast::Path { self.path_all(span, true, strs, None, ~[]) } - fn path_all(&self, sp: span, + fn path_all(&self, + sp: span, global: bool, - idents: ~[ast::ident], + mut idents: ~[ast::ident], rp: Option, types: ~[ast::Ty]) - -> ast::Path { + -> ast::Path { + let last_identifier = idents.pop(); + let mut segments: ~[ast::PathSegment] = idents.move_iter() + .map(|ident| { + ast::PathSegment { + identifier: ident, + lifetime: None, + types: opt_vec::Empty, + } + }).collect(); + segments.push(ast::PathSegment { + identifier: last_identifier, + lifetime: rp, + types: opt_vec::from(types), + }); ast::Path { span: sp, global: global, - idents: idents, - rp: rp, - types: types + segments: segments, } } @@ -387,6 +407,26 @@ impl AstBuilder for @ExtCtxt { @respan(sp, ast::stmt_decl(@decl, self.next_id())) } + fn stmt_let_typed(&self, + sp: span, + mutbl: bool, + ident: ast::ident, + typ: ast::Ty, + ex: @ast::expr) + -> @ast::stmt { + let pat = self.pat_ident(sp, ident); + let local = @ast::Local { + is_mutbl: mutbl, + ty: typ, + pat: pat, + init: Some(ex), + id: self.next_id(), + span: sp, + }; + let decl = respan(sp, ast::decl_local(local)); + @respan(sp, ast::stmt_decl(@decl, self.next_id())) + } + fn block(&self, span: span, stmts: ~[@ast::stmt], expr: Option<@expr>) -> ast::Block { self.block_all(span, ~[], stmts, expr) } diff --git a/src/libsyntax/ext/concat_idents.rs b/src/libsyntax/ext/concat_idents.rs index edb5c634d5698..477f3fde99c73 100644 --- a/src/libsyntax/ext/concat_idents.rs +++ b/src/libsyntax/ext/concat_idents.rs @@ -12,6 +12,7 @@ use ast; use codemap::span; use ext::base::*; use ext::base; +use opt_vec; use parse::token; use parse::token::{str_to_ident}; @@ -39,9 +40,13 @@ pub fn expand_syntax_ext(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree]) ast::Path { span: sp, global: false, - idents: ~[res], - rp: None, - types: ~[], + segments: ~[ + ast::PathSegment { + identifier: res, + lifetime: None, + types: opt_vec::Empty, + } + ] } ), span: sp, diff --git a/src/libsyntax/ext/deriving/rand.rs b/src/libsyntax/ext/deriving/rand.rs index e55a96f77ff9b..b8cf3de635f04 100644 --- a/src/libsyntax/ext/deriving/rand.rs +++ b/src/libsyntax/ext/deriving/rand.rs @@ -76,24 +76,33 @@ fn rand_substructure(cx: @ExtCtxt, span: span, substr: &Substructure) -> @expr { let variant_count = cx.expr_uint(span, variants.len()); - // need to specify the uint-ness of the random number - let uint_ty = cx.ty_ident(span, cx.ident_of("uint")); - let r_ty = cx.ty_ident(span, cx.ident_of("R")); let rand_name = cx.path_all(span, true, rand_ident.clone(), None, - ~[ uint_ty, r_ty ]); + ~[]); let rand_name = cx.expr_path(rand_name); - // ::std::rand::Rand::rand::(rng) + // ::std::rand::Rand::rand(rng) let rv_call = cx.expr_call(span, rand_name, ~[ rng[0].duplicate(cx) ]); + // need to specify the uint-ness of the random number + let uint_ty = cx.ty_ident(span, cx.ident_of("uint")); + let value_ident = cx.ident_of("__value"); + let let_statement = cx.stmt_let_typed(span, + false, + value_ident, + uint_ty, + rv_call); + // rand() % variants.len() - let rand_variant = cx.expr_binary(span, ast::rem, - rv_call, variant_count); + let value_ref = cx.expr_ident(span, value_ident); + let rand_variant = cx.expr_binary(span, + ast::rem, + value_ref, + variant_count); let mut arms = do variants.iter().enumerate().map |(i, id_sum)| { let i_expr = cx.expr_uint(span, i); @@ -111,7 +120,10 @@ fn rand_substructure(cx: @ExtCtxt, span: span, substr: &Substructure) -> @expr { // _ => {} at the end. Should never occur arms.push(cx.arm_unreachable(span)); - cx.expr_match(span, rand_variant, arms) + let match_expr = cx.expr_match(span, rand_variant, arms); + + let block = cx.block(span, ~[ let_statement ], Some(match_expr)); + cx.expr_block(block) } _ => cx.bug("Non-static method in `deriving(Rand)`") }; diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 4bea1dc23e737..7dd5c3c450c9e 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -19,6 +19,7 @@ use codemap; use codemap::{span, spanned, ExpnInfo, NameAndSpan}; use ext::base::*; use fold::*; +use opt_vec; use parse; use parse::{parse_item_from_source_str}; use parse::token; @@ -42,13 +43,13 @@ pub fn expand_expr(extsbox: @mut SyntaxEnv, match (*mac).node { // Token-tree macros: mac_invoc_tt(ref pth, ref tts) => { - if (pth.idents.len() > 1u) { + if (pth.segments.len() > 1u) { cx.span_fatal( pth.span, fmt!("expected macro name without module \ separators")); } - let extname = &pth.idents[0]; + let extname = &pth.segments[0].identifier; let extnamestr = ident_to_str(extname); // leaving explicit deref here to highlight unbox op: match (*extsbox).find(&extname.name) { @@ -143,9 +144,13 @@ pub fn expand_expr(extsbox: @mut SyntaxEnv, ast::Path { span: span, global: false, - idents: ~[ident], - rp: None, - types: ~[] + segments: ~[ + ast::PathSegment { + identifier: ident, + lifetime: None, + types: opt_vec::Empty, + } + ], } } @@ -368,7 +373,7 @@ pub fn expand_item_mac(extsbox: @mut SyntaxEnv, _ => cx.span_bug(it.span, "invalid item macro invocation") }; - let extname = &pth.idents[0]; + let extname = &pth.segments[0].identifier; let extnamestr = ident_to_str(extname); let expanded = match (*extsbox).find(&extname.name) { None => cx.span_fatal(pth.span, @@ -459,13 +464,13 @@ pub fn expand_stmt(extsbox: @mut SyntaxEnv, } _ => return orig(s, sp, fld) }; - if (pth.idents.len() > 1u) { + if (pth.segments.len() > 1u) { cx.span_fatal( pth.span, fmt!("expected macro name without module \ separators")); } - let extname = &pth.idents[0]; + let extname = &pth.segments[0].identifier; let extnamestr = ident_to_str(extname); let (fully_expanded, sp) = match (*extsbox).find(&extname.name) { None => @@ -534,10 +539,14 @@ impl Visitor<()> for NewNameFinderContext { // a path of length one: &ast::Path { global: false, - idents: [id], span: _, - rp: _, - types: _ + segments: [ + ast::PathSegment { + identifier: id, + lifetime: _, + types: _ + } + ] } => self.ident_accumulator.push(id), // I believe these must be enums... _ => () diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs index c208a7f7e3e40..327ee331c3814 100644 --- a/src/libsyntax/ext/tt/macro_parser.rs +++ b/src/libsyntax/ext/tt/macro_parser.rs @@ -16,8 +16,8 @@ use codemap::{BytePos, mk_sp}; use codemap; use parse::lexer::*; //resolve bug? use parse::ParseSess; -use parse::parser::Parser; use parse::attr::parser_attr; +use parse::parser::{LifetimeAndTypesWithoutColons, Parser}; use parse::token::{Token, EOF, to_str, nonterminal, get_ident_interner, ident_to_str}; use parse::token; @@ -430,7 +430,9 @@ pub fn parse_nt(p: &Parser, name: &str) -> nonterminal { _ => p.fatal(~"expected ident, found " + token::to_str(get_ident_interner(), p.token)) }, - "path" => token::nt_path(~p.parse_path_with_tps(false)), + "path" => { + token::nt_path(~p.parse_path(LifetimeAndTypesWithoutColons).path) + } "attr" => token::nt_attr(@p.parse_attribute(false)), "tt" => { *p.quote_depth += 1u; //but in theory, non-quoted tts might be useful diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 65694f013f751..458737e2fbf0b 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -765,9 +765,11 @@ fn noop_fold_path(p: &Path, fld: @ast_fold) -> Path { ast::Path { span: fld.new_span(p.span), global: p.global, - idents: p.idents.map(|x| fld.fold_ident(*x)), - rp: p.rp, - types: p.types.map(|x| fld.fold_ty(x)), + segments: p.segments.map(|segment| ast::PathSegment { + identifier: fld.fold_ident(segment.identifier), + lifetime: segment.lifetime, + types: segment.types.map(|typ| fld.fold_ty(typ)), + }) } } diff --git a/src/libsyntax/oldvisit.rs b/src/libsyntax/oldvisit.rs index 295003c6ef538..56576ee359960 100644 --- a/src/libsyntax/oldvisit.rs +++ b/src/libsyntax/oldvisit.rs @@ -284,7 +284,11 @@ pub fn visit_ty(t: &Ty, (e, v): (E, vt)) { } pub fn visit_path(p: &Path, (e, v): (E, vt)) { - for tp in p.types.iter() { (v.visit_ty)(tp, (e.clone(), v)); } + for segment in p.segments.iter() { + for typ in segment.types.iter() { + (v.visit_ty)(typ, (e.clone(), v)) + } + } } pub fn visit_pat(p: &pat, (e, v): (E, vt)) { diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 23c6a8b97208b..81113f2432923 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -361,27 +361,47 @@ mod test { span{lo:BytePos(a),hi:BytePos(b),expn_info:None} } - #[test] fn path_exprs_1 () { + #[test] fn path_exprs_1() { assert_eq!(string_to_expr(@"a"), - @ast::expr{id:1, - node:ast::expr_path(ast::Path {span:sp(0,1), - global:false, - idents:~[str_to_ident("a")], - rp:None, - types:~[]}), - span:sp(0,1)}) + @ast::expr{ + id: 1, + node: ast::expr_path(ast::Path { + span: sp(0, 1), + global: false, + segments: ~[ + ast::PathSegment { + identifier: str_to_ident("a"), + lifetime: None, + types: opt_vec::Empty, + } + ], + }), + span: sp(0, 1) + }) } #[test] fn path_exprs_2 () { assert_eq!(string_to_expr(@"::a::b"), - @ast::expr{id:1, - node:ast::expr_path( - ast::Path {span:sp(0,6), - global:true, - idents:strs_to_idents(~["a","b"]), - rp:None, - types:~[]}), - span:sp(0,6)}) + @ast::expr { + id:1, + node: ast::expr_path(ast::Path { + span: sp(0, 6), + global: true, + segments: ~[ + ast::PathSegment { + identifier: str_to_ident("a"), + lifetime: None, + types: opt_vec::Empty, + }, + ast::PathSegment { + identifier: str_to_ident("b"), + lifetime: None, + types: opt_vec::Empty, + } + ] + }), + span: sp(0, 6) + }) } #[should_fail] @@ -420,32 +440,43 @@ mod test { #[test] fn ret_expr() { assert_eq!(string_to_expr(@"return d"), - @ast::expr{id:2, - node:ast::expr_ret( - Some(@ast::expr{id:1, - node:ast::expr_path( - ast::Path{span:sp(7,8), - global:false, - idents:~[str_to_ident("d")], - rp:None, - types:~[] - }), - span:sp(7,8)})), - span:sp(0,8)}) + @ast::expr{ + id:2, + node:ast::expr_ret(Some(@ast::expr{ + id:1, + node:ast::expr_path(ast::Path{ + span: sp(7, 8), + global: false, + segments: ~[ + ast::PathSegment { + identifier: str_to_ident("d"), + lifetime: None, + types: opt_vec::Empty, + } + ], + }), + span:sp(7,8) + })), + span:sp(0,8) + }) } #[test] fn parse_stmt_1 () { assert_eq!(string_to_stmt(@"b;"), @spanned{ - node: ast::stmt_expr(@ast::expr{ + node: ast::stmt_expr(@ast::expr { id: 1, - node: ast::expr_path( - ast::Path{ - span:sp(0,1), - global:false, - idents:~[str_to_ident("b")], - rp:None, - types: ~[]}), + node: ast::expr_path(ast::Path { + span:sp(0,1), + global:false, + segments: ~[ + ast::PathSegment { + identifier: str_to_ident("b"), + lifetime: None, + types: opt_vec::Empty, + } + ], + }), span: sp(0,1)}, 2), // fixme span: sp(0,1)}) @@ -460,49 +491,24 @@ mod test { let parser = string_to_parser(@"b"); assert_eq!(parser.parse_pat(), @ast::pat{id:1, // fixme - node: ast::pat_ident(ast::bind_infer, - ast::Path{ - span:sp(0,1), - global:false, - idents:~[str_to_ident("b")], - rp: None, - types: ~[]}, - None // no idea - ), + node: ast::pat_ident( + ast::bind_infer, + ast::Path { + span:sp(0,1), + global:false, + segments: ~[ + ast::PathSegment { + identifier: str_to_ident("b"), + lifetime: None, + types: opt_vec::Empty, + } + ], + }, + None /* no idea */), span: sp(0,1)}); parser_done(parser); } - #[test] fn parse_arg () { - let parser = string_to_parser(@"b : int"); - assert_eq!(parser.parse_arg_general(true), - ast::arg{ - is_mutbl: false, - ty: ast::Ty{id:3, // fixme - node: ast::ty_path(ast::Path{ - span:sp(4,4), // this is bizarre... - // check this in the original parser? - global:false, - idents:~[str_to_ident("int")], - rp: None, - types: ~[]}, - None, 2), - span:sp(4,7)}, - pat: @ast::pat{id:1, - node: ast::pat_ident(ast::bind_infer, - ast::Path{ - span:sp(0,1), - global:false, - idents:~[str_to_ident("b")], - rp: None, - types: ~[]}, - None // no idea - ), - span: sp(0,1)}, - id: 4 // fixme - }) - } - // check the contents of the tt manually: #[test] fn parse_fundecl () { // this test depends on the intern order of "fn" and "int", and on the @@ -519,23 +525,37 @@ mod test { node: ast::ty_path(ast::Path{ span:sp(10,13), global:false, - idents:~[str_to_ident("int")], - rp: None, - types: ~[]}, - None, 2), - span:sp(10,13)}, - pat: @ast::pat{id:1, // fixme - node: ast::pat_ident( - ast::bind_infer, - ast::Path{ - span:sp(6,7), - global:false, - idents:~[str_to_ident("b")], - rp: None, - types: ~[]}, - None // no idea - ), - span: sp(6,7)}, + segments: ~[ + ast::PathSegment { + identifier: + str_to_ident("int"), + lifetime: None, + types: opt_vec::Empty, + } + ], + }, None, 2), + span:sp(10,13) + }, + pat: @ast::pat { + id:1, // fixme + node: ast::pat_ident( + ast::bind_infer, + ast::Path { + span:sp(6,7), + global:false, + segments: ~[ + ast::PathSegment { + identifier: + str_to_ident("b"), + lifetime: None, + types: opt_vec::Empty, + } + ], + }, + None // no idea + ), + span: sp(6,7) + }, id: 4 // fixme }], output: ast::Ty{id:5, // fixme @@ -558,9 +578,18 @@ mod test { ast::Path{ span:sp(17,18), global:false, - idents:~[str_to_ident("b")], - rp:None, - types: ~[]}), + segments: ~[ + ast::PathSegment { + identifier: + str_to_ident( + "b"), + lifetime: + None, + types: + opt_vec::Empty + } + ], + }), span: sp(17,18)}, 7), // fixme span: sp(17,18)}], diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs index 01c1af7464db6..6e43e7ca8684a 100644 --- a/src/libsyntax/parse/obsolete.rs +++ b/src/libsyntax/parse/obsolete.rs @@ -54,7 +54,6 @@ pub enum ObsoleteSyntax { ObsoleteMode, ObsoleteImplicitSelf, ObsoleteLifetimeNotation, - ObsoleteConstManagedPointer, ObsoletePurity, ObsoleteStaticMethod, ObsoleteConstItem, @@ -66,6 +65,7 @@ pub enum ObsoleteSyntax { ObsoleteUnsafeExternFn, ObsoletePrivVisibility, ObsoleteTraitFuncVisibility, + ObsoleteConstPointer, } impl to_bytes::IterBytes for ObsoleteSyntax { @@ -209,10 +209,6 @@ impl ParserObsoleteMethods for Parser { "instead of `&foo/bar`, write `&'foo bar`; instead of \ `bar/&foo`, write `&bar<'foo>" ), - ObsoleteConstManagedPointer => ( - "const `@` pointer", - "instead of `@const Foo`, write `@Foo`" - ), ObsoletePurity => ( "pure function", "remove `pure`" @@ -263,6 +259,11 @@ impl ParserObsoleteMethods for Parser { "visibility not necessary", "trait functions inherit the visibility of the trait itself" ), + ObsoleteConstPointer => ( + "const pointer", + "instead of `&const Foo` or `@const Foo`, write `&Foo` or \ + `@Foo`" + ), }; self.report(sp, kind, kind_str, desc); diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index de7abb8d1f46d..d7b22ea1ad9c5 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -38,7 +38,7 @@ use ast::{ident, impure_fn, inherited, item, item_, item_static}; use ast::{item_enum, item_fn, item_foreign_mod, item_impl}; use ast::{item_mac, item_mod, item_struct, item_trait, item_ty, lit, lit_}; use ast::{lit_bool, lit_float, lit_float_unsuffixed, lit_int}; -use ast::{lit_int_unsuffixed, lit_nil, lit_str, lit_uint, Local, m_const}; +use ast::{lit_int_unsuffixed, lit_nil, lit_str, lit_uint, Local}; use ast::{m_imm, m_mutbl, mac_, mac_invoc_tt, matcher, match_nonterminal}; use ast::{match_seq, match_tok, method, mt, mul, mutability}; use ast::{named_field, neg, NodeId, noreturn, not, pat, pat_box, pat_enum}; @@ -97,6 +97,37 @@ enum restriction { type arg_or_capture_item = Either; type item_info = (ident, item_, Option<~[Attribute]>); +/// How to parse a path. There are four different kinds of paths, all of which +/// are parsed somewhat differently. +#[deriving(Eq)] +pub enum PathParsingMode { + /// A path with no type parameters; e.g. `foo::bar::Baz` + NoTypesAllowed, + /// A path with a lifetime and type parameters, with no double colons + /// before the type parameters; e.g. `foo::bar<'self>::Baz` + LifetimeAndTypesWithoutColons, + /// A path with a lifetime and type parameters with double colons before + /// the type parameters; e.g. `foo::bar::<'self>::Baz::` + LifetimeAndTypesWithColons, + /// A path with a lifetime and type parameters with bounds before the last + /// set of type parameters only; e.g. `foo::bar<'self>::Baz:X+Y` This + /// form does not use extra double colons. + LifetimeAndTypesAndBounds, +} + +/// A pair of a path segment and group of type parameter bounds. (See `ast.rs` +/// for the definition of a path segment.) +struct PathSegmentAndBoundSet { + segment: ast::PathSegment, + bound_set: Option>, +} + +/// A path paired with optional type bounds. +struct PathAndBounds { + path: ast::Path, + bounds: Option>, +} + pub enum item_or_view_item { // Indicates a failure to parse any kind of item. The attributes are // returned. @@ -1108,7 +1139,10 @@ impl Parser { } else if *self.token == token::MOD_SEP || is_ident_or_path(self.token) { // NAMED TYPE - let (path, bounds) = self.parse_type_path(); + let PathAndBounds { + path, + bounds + } = self.parse_path(LifetimeAndTypesAndBounds); ty_path(path, bounds, self.get_id()) } else { self.fatal(fmt!("expected type, found token %?", @@ -1154,9 +1188,6 @@ impl Parser { if mt.mutbl != m_imm && sigil == OwnedSigil { self.obsolete(*self.last_span, ObsoleteMutOwnedPointer); } - if mt.mutbl == m_const && sigil == ManagedSigil { - self.obsolete(*self.last_span, ObsoleteConstManagedPointer); - } ctor(mt) } @@ -1333,139 +1364,155 @@ impl Parser { } } - // parse a path into a vector of idents, whether the path starts - // with ::, and a span. - pub fn parse_path(&self) -> (~[ast::ident],bool,span) { + /// Parses a path and optional type parameter bounds, depending on the + /// mode. The `mode` parameter determines whether lifetimes, types, and/or + /// bounds are permitted and whether `::` must precede type parameter + /// groups. + pub fn parse_path(&self, mode: PathParsingMode) -> PathAndBounds { + // Check for a whole path... + let found = match *self.token { + INTERPOLATED(token::nt_path(_)) => Some(self.bump_and_get()), + _ => None, + }; + match found { + Some(INTERPOLATED(token::nt_path(~path))) => { + return PathAndBounds { + path: path, + bounds: None, + } + } + _ => {} + } + let lo = self.span.lo; let is_global = self.eat(&token::MOD_SEP); - let (ids,span{lo:_,hi,expn_info}) = self.parse_path_non_global(); - (ids,is_global,span{lo:lo,hi:hi,expn_info:expn_info}) - } - // parse a path beginning with an identifier into a vector of idents and a span - pub fn parse_path_non_global(&self) -> (~[ast::ident],span) { - let lo = self.span.lo; - let mut ids = ~[]; - // must be at least one to begin: - ids.push(self.parse_ident()); + // Parse any number of segments and bound sets. A segment is an + // identifier followed by an optional lifetime and a set of types. + // A bound set is a set of type parameter bounds. + let mut segments = ~[]; loop { + // First, parse an identifier. match *self.token { - token::MOD_SEP => { - let is_ident = do self.look_ahead(1) |t| { - match *t { - token::IDENT(*) => true, - _ => false, - } - }; - if is_ident { - self.bump(); - ids.push(self.parse_ident()); - } else { - break - } - } - _ => break + token::IDENT(*) => {} + _ => break, } - } - (ids, mk_sp(lo, self.last_span.hi)) - } + let identifier = self.parse_ident(); - // parse a path that doesn't have type parameters attached - pub fn parse_path_without_tps(&self) -> ast::Path { - maybe_whole!(deref self, nt_path); - let (ids,is_global,sp) = self.parse_path(); - ast::Path { span: sp, - global: is_global, - idents: ids, - rp: None, - types: ~[] } - } + // Next, parse a colon and bounded type parameters, if applicable. + let bound_set = if mode == LifetimeAndTypesAndBounds { + self.parse_optional_ty_param_bounds() + } else { + None + }; - pub fn parse_bounded_path_with_tps(&self, colons: bool, - before_tps: Option<&fn()>) -> ast::Path { - debug!("parse_path_with_tps(colons=%b)", colons); + // Parse the '::' before type parameters if it's required. If + // it is required and wasn't present, then we're done. + if mode == LifetimeAndTypesWithColons && + !self.eat(&token::MOD_SEP) { + segments.push(PathSegmentAndBoundSet { + segment: ast::PathSegment { + identifier: identifier, + lifetime: None, + types: opt_vec::Empty, + }, + bound_set: bound_set + }); + break + } - maybe_whole!(deref self, nt_path); - let lo = self.span.lo; - let path = self.parse_path_without_tps(); - if colons && !self.eat(&token::MOD_SEP) { - return path; - } - - // If the path might have bounds on it, they should be parsed before - // the parameters, e.g. module::TraitName:B1+B2 - before_tps.map_move(|callback| callback()); - - // Parse the (obsolete) trailing region parameter, if any, which will - // be written "foo/&x" - let rp_slash = { - if *self.token == token::BINOP(token::SLASH) - && self.look_ahead(1, |t| *t == token::BINOP(token::AND)) - { - self.bump(); self.bump(); - self.obsolete(*self.last_span, ObsoleteLifetimeNotation); - match *self.token { - token::IDENT(sid, _) => { - let span = self.span; - self.bump(); - Some(ast::Lifetime { - id: self.get_id(), - span: *span, - ident: sid - }) + // Parse the `<` before the lifetime and types, if applicable. + let (any_lifetime_or_types, optional_lifetime, types) = + if mode != NoTypesAllowed && self.eat(&token::LT) { + // Parse an optional lifetime. + let optional_lifetime = match *self.token { + token::LIFETIME(*) => Some(self.parse_lifetime()), + _ => None, + }; + + // Parse type parameters. + let mut types = opt_vec::Empty; + let mut need_comma = optional_lifetime.is_some(); + loop { + // We're done if we see a `>`. + match *self.token { + token::GT | token::BINOP(token::SHR) => { + self.expect_gt(); + break + } + _ => {} // Go on. } - _ => { - self.fatal(fmt!("Expected a lifetime name")); + + if need_comma { + self.expect(&token::COMMA) + } else { + need_comma = true } + + types.push(self.parse_ty(false)) } + + (true, optional_lifetime, types) } else { - None - } - }; + (false, None, opt_vec::Empty) + }; - // Parse any lifetime or type parameters which may appear: - let (lifetimes, tps) = self.parse_generic_values(); - let hi = self.span.lo; + // Assemble and push the result. + segments.push(PathSegmentAndBoundSet { + segment: ast::PathSegment { + identifier: identifier, + lifetime: optional_lifetime, + types: types, + }, + bound_set: bound_set + }); - let rp = match (&rp_slash, &lifetimes) { - (&Some(_), _) => rp_slash, - (&None, v) => { - if v.len() == 0 { - None - } else if v.len() == 1 { - Some(*v.get(0)) - } else { - self.fatal(fmt!("Expected at most one \ - lifetime name (for now)")); + // We're done if we don't see a '::', unless the mode required + // a double colon to get here in the first place. + if !(mode == LifetimeAndTypesWithColons && + !any_lifetime_or_types) { + if !self.eat(&token::MOD_SEP) { + break } } - }; - - ast::Path { - span: mk_sp(lo, hi), - rp: rp, - types: tps, - .. path.clone() } - } - // parse a path optionally with type parameters. If 'colons' - // is true, then type parameters must be preceded by colons, - // as in a::t:: - pub fn parse_path_with_tps(&self, colons: bool) -> ast::Path { - self.parse_bounded_path_with_tps(colons, None) - } + // Assemble the span. + let span = mk_sp(lo, self.last_span.hi); - // Like the above, but can also parse kind bounds in the case of a - // path to be used as a type that might be a trait. - pub fn parse_type_path(&self) -> (ast::Path, Option>) { + // Assemble the path segments. + let mut path_segments = ~[]; let mut bounds = None; - let path = self.parse_bounded_path_with_tps(false, Some(|| { - // Note: this closure might not even get called in the case of a - // macro-generated path. But that's the macro parser's job. - bounds = self.parse_optional_ty_param_bounds(); - })); - (path, bounds) + let last_segment_index = segments.len() - 1; + for (i, segment_and_bounds) in segments.move_iter().enumerate() { + let PathSegmentAndBoundSet { + segment: segment, + bound_set: bound_set + } = segment_and_bounds; + path_segments.push(segment); + + if bound_set.is_some() { + if i != last_segment_index { + self.span_err(span, + "type parameter bounds are allowed only \ + before the last segment in a path") + } + + bounds = bound_set + } + } + + // Assemble the result. + let path_and_bounds = PathAndBounds { + path: ast::Path { + span: span, + global: is_global, + segments: path_segments, + }, + bounds: bounds, + }; + + path_and_bounds } /// parses 0 or 1 lifetime @@ -1569,7 +1616,8 @@ impl Parser { if self.eat_keyword(keywords::Mut) { m_mutbl } else if self.eat_keyword(keywords::Const) { - m_const + self.obsolete(*self.last_span, ObsoleteConstPointer); + m_imm } else { m_imm } @@ -1728,7 +1776,7 @@ impl Parser { } else if *self.token == token::LBRACKET { self.bump(); let mutbl = self.parse_mutability(); - if mutbl == m_mutbl || mutbl == m_const { + if mutbl == m_mutbl { self.obsolete(*self.last_span, ObsoleteMutVector); } @@ -1792,7 +1840,7 @@ impl Parser { } else if *self.token == token::MOD_SEP || is_ident(&*self.token) && !self.is_keyword(keywords::True) && !self.is_keyword(keywords::False) { - let pth = self.parse_path_with_tps(true); + let pth = self.parse_path(LifetimeAndTypesWithColons).path; // `!`, as an operator, is prefix, so we know this isn't that if *self.token == token::NOT { @@ -2183,10 +2231,6 @@ impl Parser { token::AT => { self.bump(); let m = self.parse_mutability(); - if m == m_const { - self.obsolete(*self.last_span, ObsoleteConstManagedPointer); - } - let e = self.parse_prefix_expr(); hi = e.span.hi; // HACK: turn @[...] into a @-evec @@ -2887,7 +2931,8 @@ impl Parser { let val = self.parse_literal_maybe_minus(); if self.eat(&token::DOTDOT) { let end = if is_ident_or_path(tok) { - let path = self.parse_path_with_tps(true); + let path = self.parse_path(LifetimeAndTypesWithColons) + .path; let hi = self.span.hi; self.mk_expr(lo, hi, expr_path(path)) } else { @@ -2916,7 +2961,7 @@ impl Parser { let end = self.parse_expr_res(RESTRICT_NO_BAR_OP); pat = pat_range(start, end); } else if is_plain_ident(&*self.token) && !can_be_enum_or_struct { - let name = self.parse_path_without_tps(); + let name = self.parse_path(NoTypesAllowed).path; let sub; if self.eat(&token::AT) { // parse foo @ pat @@ -2928,7 +2973,8 @@ impl Parser { pat = pat_ident(bind_infer, name, sub); } else { // parse an enum pat - let enum_path = self.parse_path_with_tps(true); + let enum_path = self.parse_path(LifetimeAndTypesWithColons) + .path; match *self.token { token::LBRACE => { self.bump(); @@ -2964,7 +3010,7 @@ impl Parser { } }, _ => { - if enum_path.idents.len()==1u { + if enum_path.segments.len() == 1 { // it could still be either an enum // or an identifier pattern, resolve // will sort it out: @@ -2999,7 +3045,7 @@ impl Parser { "expected identifier, found path"); } // why a path here, and not just an identifier? - let name = self.parse_path_without_tps(); + let name = self.parse_path(NoTypesAllowed).path; let sub = if self.eat(&token::AT) { Some(self.parse_pat()) } else { @@ -3116,7 +3162,7 @@ impl Parser { // Potential trouble: if we allow macros with paths instead of // idents, we'd need to look ahead past the whole path here... - let pth = self.parse_path_without_tps(); + let pth = self.parse_path(NoTypesAllowed).path; self.bump(); let id = if *self.token == token::LPAREN { @@ -3792,7 +3838,7 @@ impl Parser { // parse a::B<~str,int> fn parse_trait_ref(&self) -> trait_ref { ast::trait_ref { - path: self.parse_path_with_tps(false), + path: self.parse_path(LifetimeAndTypesWithoutColons).path, ref_id: self.get_id(), } } @@ -4712,7 +4758,7 @@ impl Parser { } // item macro. - let pth = self.parse_path_without_tps(); + let pth = self.parse_path(NoTypesAllowed).path; self.expect(&token::NOT); // a 'special' identifier (like what `macro_rules!` uses) @@ -4796,11 +4842,17 @@ impl Parser { let id = self.parse_ident(); path.push(id); } - let path = ast::Path { span: mk_sp(lo, self.span.hi), - global: false, - idents: path, - rp: None, - types: ~[] }; + let path = ast::Path { + span: mk_sp(lo, self.span.hi), + global: false, + segments: path.move_iter().map(|identifier| { + ast::PathSegment { + identifier: identifier, + lifetime: None, + types: opt_vec::Empty, + } + }).collect() + }; return @spanned(lo, self.span.hi, view_path_simple(first_ident, path, @@ -4826,11 +4878,17 @@ impl Parser { seq_sep_trailing_allowed(token::COMMA), |p| p.parse_path_list_ident() ); - let path = ast::Path { span: mk_sp(lo, self.span.hi), - global: false, - idents: path, - rp: None, - types: ~[] }; + let path = ast::Path { + span: mk_sp(lo, self.span.hi), + global: false, + segments: path.move_iter().map(|identifier| { + ast::PathSegment { + identifier: identifier, + lifetime: None, + types: opt_vec::Empty, + } + }).collect() + }; return @spanned(lo, self.span.hi, view_path_list(path, idents, self.get_id())); } @@ -4838,11 +4896,17 @@ impl Parser { // foo::bar::* token::BINOP(token::STAR) => { self.bump(); - let path = ast::Path { span: mk_sp(lo, self.span.hi), - global: false, - idents: path, - rp: None, - types: ~[] }; + let path = ast::Path { + span: mk_sp(lo, self.span.hi), + global: false, + segments: path.move_iter().map(|identifier| { + ast::PathSegment { + identifier: identifier, + lifetime: None, + types: opt_vec::Empty, + } + }).collect() + }; return @spanned(lo, self.span.hi, view_path_glob(path, self.get_id())); } @@ -4854,11 +4918,17 @@ impl Parser { _ => () } let last = path[path.len() - 1u]; - let path = ast::Path { span: mk_sp(lo, self.span.hi), - global: false, - idents: path, - rp: None, - types: ~[] }; + let path = ast::Path { + span: mk_sp(lo, self.span.hi), + global: false, + segments: path.move_iter().map(|identifier| { + ast::PathSegment { + identifier: identifier, + lifetime: None, + types: opt_vec::Empty, + } + }).collect() + }; return @spanned(lo, self.last_span.hi, view_path_simple(last, path, self.get_id())); diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 6a3d829aca0b0..f7f2f27ab0ed6 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -387,7 +387,6 @@ pub fn print_type(s: @ps, ty: &ast::Ty) { word(s.s, "["); match mt.mutbl { ast::m_mutbl => word_space(s, "mut"), - ast::m_const => word_space(s, "const"), ast::m_imm => () } print_type(s, mt.ty); @@ -430,7 +429,6 @@ pub fn print_type(s: @ps, ty: &ast::Ty) { word(s.s, "["); match mt.mutbl { ast::m_mutbl => word_space(s, "mut"), - ast::m_const => word_space(s, "const"), ast::m_imm => () } print_type(s, mt.ty); @@ -1504,34 +1502,52 @@ pub fn print_for_decl(s: @ps, loc: &ast::Local, coll: &ast::expr) { print_expr(s, coll); } -fn print_path_(s: @ps, path: &ast::Path, colons_before_params: bool, +fn print_path_(s: @ps, + path: &ast::Path, + colons_before_params: bool, opt_bounds: &Option>) { maybe_print_comment(s, path.span.lo); - if path.global { word(s.s, "::"); } - let mut first = true; - for id in path.idents.iter() { - if first { first = false; } else { word(s.s, "::"); } - print_ident(s, *id); + if path.global { + word(s.s, "::"); } - do opt_bounds.map |bounds| { - print_bounds(s, bounds, true); - }; - if path.rp.is_some() || !path.types.is_empty() { - if colons_before_params { word(s.s, "::"); } - if path.rp.is_some() || !path.types.is_empty() { + let mut first = true; + for (i, segment) in path.segments.iter().enumerate() { + if first { + first = false + } else { + word(s.s, "::") + } + + print_ident(s, segment.identifier); + + if segment.lifetime.is_some() || !segment.types.is_empty() { + // If this is the last segment, print the bounds. + if i == path.segments.len() - 1 { + match *opt_bounds { + None => {} + Some(ref bounds) => print_bounds(s, bounds, true), + } + } + + if colons_before_params { + word(s.s, "::") + } word(s.s, "<"); - for r in path.rp.iter() { - print_lifetime(s, r); - if !path.types.is_empty() { - word_space(s, ","); + for lifetime in segment.lifetime.iter() { + print_lifetime(s, lifetime); + if !segment.types.is_empty() { + word_space(s, ",") } } - commasep(s, inconsistent, path.types, print_type); + commasep(s, + inconsistent, + segment.types.map_to_vec(|t| (*t).clone()), + print_type); - word(s.s, ">"); + word(s.s, ">") } } } @@ -1822,7 +1838,7 @@ pub fn print_meta_item(s: @ps, item: &ast::MetaItem) { pub fn print_view_path(s: @ps, vp: &ast::view_path) { match vp.node { ast::view_path_simple(ident, ref path, _) => { - if path.idents[path.idents.len()-1u] != ident { + if path.segments.last().identifier != ident { print_ident(s, ident); space(s.s); word_space(s, "="); @@ -1883,7 +1899,6 @@ pub fn print_view_item(s: @ps, item: &ast::view_item) { pub fn print_mutability(s: @ps, mutbl: ast::mutability) { match mutbl { ast::m_mutbl => word_nbsp(s, "mut"), - ast::m_const => word_nbsp(s, "const"), ast::m_imm => {/* nothing */ } } } @@ -1903,8 +1918,9 @@ pub fn print_arg(s: @ps, input: &ast::arg) { _ => { match input.pat.node { ast::pat_ident(_, ref path, _) if - path.idents.len() == 1 && - path.idents[0] == parse::token::special_idents::invalid => { + path.segments.len() == 1 && + path.segments[0].identifier == + parse::token::special_idents::invalid => { // Do nothing. } _ => { diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 8178e7f3760b7..2a0630d332ca7 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -319,8 +319,10 @@ pub fn walk_ty>(visitor: &mut V, typ: &Ty, env: E) { } pub fn walk_path>(visitor: &mut V, path: &Path, env: E) { - for typ in path.types.iter() { - visitor.visit_ty(typ, env.clone()) + for segment in path.segments.iter() { + for typ in segment.types.iter() { + visitor.visit_ty(typ, env.clone()) + } } } @@ -671,26 +673,35 @@ pub fn walk_arm>(visitor: &mut V, arm: &arm, env: E) { // calls the given functions on the nodes. pub trait SimpleVisitor { - fn visit_mod(&mut self, &_mod, span, NodeId); - fn visit_view_item(&mut self, &view_item); - fn visit_foreign_item(&mut self, @foreign_item); - fn visit_item(&mut self, @item); - fn visit_local(&mut self, @Local); - fn visit_block(&mut self, &Block); - fn visit_stmt(&mut self, @stmt); - fn visit_arm(&mut self, &arm); - fn visit_pat(&mut self, @pat); - fn visit_decl(&mut self, @decl); - fn visit_expr(&mut self, @expr); - fn visit_expr_post(&mut self, @expr); - fn visit_ty(&mut self, &Ty); - fn visit_generics(&mut self, &Generics); - fn visit_fn(&mut self, &fn_kind, &fn_decl, &Block, span, NodeId); - fn visit_ty_method(&mut self, &TypeMethod); - fn visit_trait_method(&mut self, &trait_method); - fn visit_struct_def(&mut self, @struct_def, ident, &Generics, NodeId); - fn visit_struct_field(&mut self, @struct_field); - fn visit_struct_method(&mut self, @method); + fn visit_mod(&mut self, _m: &_mod, _s: span, _n: NodeId) {} + fn visit_view_item(&mut self, _vi: &view_item) {} + fn visit_foreign_item(&mut self, _fi: @foreign_item) {} + fn visit_item(&mut self, _i: @item) {} + fn visit_local(&mut self, _l: @Local) {} + fn visit_block(&mut self, _b: &Block) {} + fn visit_stmt(&mut self, _s: @stmt) {} + fn visit_arm(&mut self, _a: &arm) {} + fn visit_pat(&mut self, _p: @pat) {} + fn visit_decl(&mut self, _d: @decl) {} + fn visit_expr(&mut self, _e: @expr) {} + fn visit_expr_post(&mut self, _e: @expr) {} + fn visit_ty(&mut self, _t: &Ty) {} + fn visit_generics(&mut self, _g: &Generics) {} + fn visit_fn(&mut self, + _fk: &fn_kind, + _fd: &fn_decl, + _b: &Block, + _s: span, + _n: NodeId) {} + fn visit_ty_method(&mut self, _t: &TypeMethod) {} + fn visit_trait_method(&mut self, _t: &trait_method) {} + fn visit_struct_def(&mut self, + _s: @struct_def, + _i: ident, + _g: &Generics, + _n: NodeId) {} + fn visit_struct_field(&mut self, _s: @struct_field) {} + fn visit_struct_method(&mut self, _m: @method) {} } pub struct SimpleVisitorVisitor { diff --git a/src/test/compile-fail/bad-mid-path-type-params.rs b/src/test/compile-fail/bad-mid-path-type-params.rs new file mode 100644 index 0000000000000..e4833345d311c --- /dev/null +++ b/src/test/compile-fail/bad-mid-path-type-params.rs @@ -0,0 +1,37 @@ +#[no_std]; + +struct S { + contents: T, +} + +impl S { + fn new(x: T, _: U) -> S { + S { + contents: x, + } + } +} + +trait Trait { + fn new(x: T, y: U) -> Self; +} + +struct S2 { + contents: int, +} + +impl Trait for S2 { + fn new(x: int, _: U) -> S2 { + S2 { + contents: x, + } + } +} + +fn main() { + let _ = S::new::(1, 1.0); //~ ERROR the impl referenced by this path has 1 type parameter, but 0 type parameters were supplied + let _ = S::<'self,int>::new::(1, 1.0); //~ ERROR this impl has no lifetime parameter + let _: S2 = Trait::new::(1, 1.0); //~ ERROR the trait referenced by this path has 1 type parameter, but 0 type parameters were supplied + let _: S2 = Trait::<'self,int>::new::(1, 1.0); //~ ERROR this trait has no lifetime parameter +} + diff --git a/src/test/compile-fail/borrowck-alias-mut-base-ptr.rs b/src/test/compile-fail/borrowck-alias-mut-base-ptr.rs deleted file mode 100644 index c51cf5b9538d9..0000000000000 --- a/src/test/compile-fail/borrowck-alias-mut-base-ptr.rs +++ /dev/null @@ -1,15 +0,0 @@ -// Test that attempt to alias `&mut` pointer while pointee is borrowed -// yields an error. -// -// Example from src/middle/borrowck/doc.rs - -use std::util::swap; - -fn foo(t0: &mut int) { - let p: &int = &*t0; // Freezes `*t0` - let q: &const &mut int = &const t0; //~ ERROR cannot borrow `t0` - **q = 22; //~ ERROR cannot assign to an `&mut` in a `&const` pointer -} - -fn main() { -} \ No newline at end of file diff --git a/src/test/compile-fail/borrowck-borrow-mut-base-ptr-in-aliasable-loc.rs b/src/test/compile-fail/borrowck-borrow-mut-base-ptr-in-aliasable-loc.rs index 7e9c298ba4732..843b5436d842c 100644 --- a/src/test/compile-fail/borrowck-borrow-mut-base-ptr-in-aliasable-loc.rs +++ b/src/test/compile-fail/borrowck-borrow-mut-base-ptr-in-aliasable-loc.rs @@ -11,16 +11,6 @@ fn foo(t0: & &mut int) { **t1 = 22; //~ ERROR cannot assign } -fn foo2(t0: &const &mut int) { - // Note: reborrowing from an &const actually yields two errors, since it - // is unsafe in two ways: we can't control the aliasing, and we can't - // control the mutation. - let t1 = t0; - let p: &int = &**t0; //~ ERROR cannot borrow an `&mut` in a `&const` pointer - //~^ ERROR unsafe borrow of aliasable, const value - **t1 = 22; //~ ERROR cannot assign -} - fn foo3(t0: &mut &mut int) { let t1 = &mut *t0; let p: &int = &**t0; //~ ERROR cannot borrow @@ -28,4 +18,4 @@ fn foo3(t0: &mut &mut int) { } fn main() { -} \ No newline at end of file +} diff --git a/src/test/compile-fail/borrowck-call-method-from-mut-aliasable.rs b/src/test/compile-fail/borrowck-call-method-from-mut-aliasable.rs index 0aa7cbf50b7a3..537e52120d9f1 100644 --- a/src/test/compile-fail/borrowck-call-method-from-mut-aliasable.rs +++ b/src/test/compile-fail/borrowck-call-method-from-mut-aliasable.rs @@ -14,29 +14,18 @@ struct Foo { impl Foo { pub fn f(&self) {} - pub fn g(&const self) {} pub fn h(&mut self) {} } fn a(x: &mut Foo) { x.f(); - x.g(); x.h(); } fn b(x: &Foo) { x.f(); - x.g(); x.h(); //~ ERROR cannot borrow } -fn c(x: &const Foo) { - x.f(); //~ ERROR cannot borrow - //~^ ERROR unsafe borrow - x.g(); - x.h(); //~ ERROR cannot borrow - //~^ ERROR unsafe borrow -} - fn main() { } diff --git a/src/test/compile-fail/borrowck-lend-flow.rs b/src/test/compile-fail/borrowck-lend-flow.rs index 59cac0c5d953a..ea840a28b4e6a 100644 --- a/src/test/compile-fail/borrowck-lend-flow.rs +++ b/src/test/compile-fail/borrowck-lend-flow.rs @@ -32,14 +32,6 @@ fn pre_freeze() { borrow_mut(v); //~ ERROR cannot borrow } -fn pre_const() { - // In this instance, the freeze starts before the mut borrow. - - let mut v = ~3; - let _w = &const v; - borrow_mut(v); -} - fn post_freeze() { // In this instance, the const alias starts after the borrow. diff --git a/src/test/compile-fail/borrowck-loan-vec-content.rs b/src/test/compile-fail/borrowck-loan-vec-content.rs index 6a8e64377aab2..8a4a2cdedb230 100644 --- a/src/test/compile-fail/borrowck-loan-vec-content.rs +++ b/src/test/compile-fail/borrowck-loan-vec-content.rs @@ -29,16 +29,5 @@ fn has_mut_vec_but_tries_to_change_it() { } } -fn takes_const_elt(_v: &const int, f: &fn()) { - f(); -} - -fn has_mut_vec_and_tries_to_change_it() { - let mut v = ~[1, 2, 3]; - do takes_const_elt(&const v[0]) { - v[1] = 4; - } -} - fn main() { } diff --git a/src/test/compile-fail/borrowck-pat-by-value-binding.rs b/src/test/compile-fail/borrowck-pat-by-value-binding.rs deleted file mode 100644 index e77f5245d7d8b..0000000000000 --- a/src/test/compile-fail/borrowck-pat-by-value-binding.rs +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2012 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -fn process(_t: T) {} - -fn match_const_opt_by_mut_ref(v: &const Option) { - match *v { - Some(ref mut i) => process(i), //~ ERROR cannot borrow - //~^ ERROR unsafe borrow of aliasable, const value - None => () - } -} - -fn match_const_opt_by_const_ref(v: &const Option) { - match *v { - Some(ref const i) => process(i), - //~^ ERROR unsafe borrow of aliasable, const value - None => () - } -} - -fn match_const_opt_by_imm_ref(v: &const Option) { - match *v { - Some(ref i) => process(i), //~ ERROR cannot borrow - //~^ ERROR unsafe borrow of aliasable, const value - None => () - } -} - -fn match_const_opt_by_value(v: &const Option) { - match *v { - Some(i) => process(i), - None => () - } -} - -fn main() { -} diff --git a/src/test/compile-fail/borrowck-uniq-via-lend.rs b/src/test/compile-fail/borrowck-uniq-via-lend.rs index 43459acaaf185..c87428cd300a7 100644 --- a/src/test/compile-fail/borrowck-uniq-via-lend.rs +++ b/src/test/compile-fail/borrowck-uniq-via-lend.rs @@ -35,12 +35,6 @@ fn aliased_imm() { borrow(v); } -fn aliased_const() { - let mut v = ~3; - let _w = &const v; - borrow(v); -} - fn aliased_mut() { let mut v = ~3; let _w = &mut v; diff --git a/src/test/compile-fail/fn-variance-3.rs b/src/test/compile-fail/fn-variance-3.rs index 630eb4b538d58..e42c6b658e4f7 100644 --- a/src/test/compile-fail/fn-variance-3.rs +++ b/src/test/compile-fail/fn-variance-3.rs @@ -23,13 +23,10 @@ fn main() { // @int <: X // - // This constraint forces X to be - // @const int. - r(@3); + // Here the type check fails because @const is gone and there is no + // supertype. + r(@3); //~ ERROR mismatched types - // Here the type check succeeds but the - // mutability check will fail, because the - // type of r has been inferred to be - // fn(@const int) -> @const int - *r(@mut 3) = 4; //~ ERROR cannot assign to const dereference of @ pointer + // Here the type check succeeds. + *r(@mut 3) = 4; } diff --git a/src/test/compile-fail/issue-3969.rs b/src/test/compile-fail/issue-3969.rs deleted file mode 100644 index b60a54a44bbfd..0000000000000 --- a/src/test/compile-fail/issue-3969.rs +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2012 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -struct Bike { - name: ~str, -} - -trait BikeMethods { - fn woops(&const self) -> ~str; -} - -impl BikeMethods for Bike { - fn woops() -> ~str { ~"foo" } - //~^ ERROR has a `&const self` declaration in the trait, but not in the impl -} - -pub fn main() { -} diff --git a/src/test/compile-fail/issue-4096.rs b/src/test/compile-fail/issue-4096.rs deleted file mode 100644 index 3f1172b6de8f6..0000000000000 --- a/src/test/compile-fail/issue-4096.rs +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2013 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -pub trait Nummy { - fn from_inty() -> Self; -} - -impl Nummy for float { - fn from_inty() -> float { 0.0 } -} - -fn main() { - let _1:float = Nummy::from_inty::(); //~ ERROR not enough type - //~^ NOTE Static methods have an extra implicit type parameter -} diff --git a/src/test/compile-fail/mutable-huh-ptr-assign.rs b/src/test/compile-fail/mutable-huh-ptr-assign.rs deleted file mode 100644 index 4460da72e2059..0000000000000 --- a/src/test/compile-fail/mutable-huh-ptr-assign.rs +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2012 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -extern mod extra; - -fn main() { - unsafe fn f(v: *const int) { - *v = 1 //~ ERROR cannot assign - } - - unsafe { - let mut a = 0; - let v = &mut a; - f(v); - } -} diff --git a/src/test/compile-fail/prim-with-args.rs b/src/test/compile-fail/prim-with-args.rs index 40d5a44124177..e60fbf4fc49a8 100644 --- a/src/test/compile-fail/prim-with-args.rs +++ b/src/test/compile-fail/prim-with-args.rs @@ -23,17 +23,17 @@ let x: u64; //~ ERROR type parameters are not allowed on this type let x: float; //~ ERROR type parameters are not allowed on this type let x: char; //~ ERROR type parameters are not allowed on this type -let x: int<'static>; //~ ERROR region parameters are not allowed on this type -let x: i8<'static>; //~ ERROR region parameters are not allowed on this type -let x: i16<'static>; //~ ERROR region parameters are not allowed on this type -let x: i32<'static>; //~ ERROR region parameters are not allowed on this type -let x: i64<'static>; //~ ERROR region parameters are not allowed on this type -let x: uint<'static>; //~ ERROR region parameters are not allowed on this type -let x: u8<'static>; //~ ERROR region parameters are not allowed on this type -let x: u16<'static>; //~ ERROR region parameters are not allowed on this type -let x: u32<'static>; //~ ERROR region parameters are not allowed on this type -let x: u64<'static>; //~ ERROR region parameters are not allowed on this type -let x: float<'static>; //~ ERROR region parameters are not allowed on this type -let x: char<'static>; //~ ERROR region parameters are not allowed on this type +let x: int<'static>; //~ ERROR lifetime parameters are not allowed on this type +let x: i8<'static>; //~ ERROR lifetime parameters are not allowed on this type +let x: i16<'static>; //~ ERROR lifetime parameters are not allowed on this type +let x: i32<'static>; //~ ERROR lifetime parameters are not allowed on this type +let x: i64<'static>; //~ ERROR lifetime parameters are not allowed on this type +let x: uint<'static>; //~ ERROR lifetime parameters are not allowed on this type +let x: u8<'static>; //~ ERROR lifetime parameters are not allowed on this type +let x: u16<'static>; //~ ERROR lifetime parameters are not allowed on this type +let x: u32<'static>; //~ ERROR lifetime parameters are not allowed on this type +let x: u64<'static>; //~ ERROR lifetime parameters are not allowed on this type +let x: float<'static>; //~ ERROR lifetime parameters are not allowed on this type +let x: char<'static>; //~ ERROR lifetime parameters are not allowed on this type } diff --git a/src/test/compile-fail/regions-bounds.rs b/src/test/compile-fail/regions-bounds.rs index ab2ac6cc0e5b9..ab365c1bf6fb3 100644 --- a/src/test/compile-fail/regions-bounds.rs +++ b/src/test/compile-fail/regions-bounds.rs @@ -25,8 +25,4 @@ fn a_fn3<'a,'b>(e: a_class<'a>) -> a_class<'b> { //~^ ERROR cannot infer an appropriate lifetime } -fn a_fn4<'a,'b>() { - let _: int<'a> = 1; //~ ERROR region parameters are not allowed on this type -} - fn main() { } diff --git a/src/test/compile-fail/resolve-inconsistent-binding-mode.rs b/src/test/compile-fail/resolve-inconsistent-binding-mode.rs index 65fbbfc6e1985..351daf461d2fe 100644 --- a/src/test/compile-fail/resolve-inconsistent-binding-mode.rs +++ b/src/test/compile-fail/resolve-inconsistent-binding-mode.rs @@ -26,13 +26,6 @@ fn matcher2(x: opts) { } } -fn matcher3(x: opts) { - match x { - a(ref mut i) | b(ref const i) => {} //~ ERROR variable `i` is bound with different mode in pattern #2 than in pattern #1 - c(_) => {} - } -} - fn matcher4(x: opts) { match x { a(ref mut i) | b(ref i) => {} //~ ERROR variable `i` is bound with different mode in pattern #2 than in pattern #1 diff --git a/src/test/compile-fail/static-method-privacy.rs b/src/test/compile-fail/static-method-privacy.rs index 0fd82b5ace3a7..b637037f60e8f 100644 --- a/src/test/compile-fail/static-method-privacy.rs +++ b/src/test/compile-fail/static-method-privacy.rs @@ -6,5 +6,5 @@ mod a { } fn main() { - let _ = a::S::new(); //~ ERROR function `new` is private + let _ = a::S::new(); //~ ERROR method `new` is private } diff --git a/src/test/debug-info/generic-trait-generic-static-default-method.rs b/src/test/debug-info/generic-trait-generic-static-default-method.rs index ef75c93a56bea..cd03182967584 100644 --- a/src/test/debug-info/generic-trait-generic-static-default-method.rs +++ b/src/test/debug-info/generic-trait-generic-static-default-method.rs @@ -1,3 +1,5 @@ +// xfail-test + // Copyright 2013 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. diff --git a/src/test/debug-info/trait-generic-static-default-method.rs b/src/test/debug-info/trait-generic-static-default-method.rs index 33468c974eba7..301411f1ffe7f 100644 --- a/src/test/debug-info/trait-generic-static-default-method.rs +++ b/src/test/debug-info/trait-generic-static-default-method.rs @@ -1,3 +1,5 @@ +// xfail-test + // Copyright 2013 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. diff --git a/src/test/run-pass/auto-ref-slice-plus-ref.rs b/src/test/run-pass/auto-ref-slice-plus-ref.rs index 58a477900c324..d35341516f2a7 100644 --- a/src/test/run-pass/auto-ref-slice-plus-ref.rs +++ b/src/test/run-pass/auto-ref-slice-plus-ref.rs @@ -13,17 +13,14 @@ trait MyIter { fn test_imm(&self); - fn test_const(&const self); } impl<'self> MyIter for &'self [int] { fn test_imm(&self) { assert_eq!(self[0], 1) } - fn test_const(&const self) { assert_eq!(self[0], 1) } } impl<'self> MyIter for &'self str { fn test_imm(&self) { assert_eq!(*self, "test") } - fn test_const(&const self) { assert_eq!(self[0], 't' as u8) } } pub fn main() { @@ -40,15 +37,6 @@ pub fn main() { // XXX: Other types of mutable vecs don't currently exist - ([1]).test_const(); - (~[1]).test_const(); - (@[1]).test_const(); - (&[1]).test_const(); - ("test").test_const(); - (~"test").test_const(); - (@"test").test_const(); - (&"test").test_const(); - // NB: We don't do this double autoreffing for &mut self because that would // allow creating a mutable pointer to a temporary, which would be a source // of confusion diff --git a/src/test/run-pass/autoderef-and-borrow-method-receiver.rs b/src/test/run-pass/autoderef-and-borrow-method-receiver.rs index b00d8980c69fe..fc643ec594089 100644 --- a/src/test/run-pass/autoderef-and-borrow-method-receiver.rs +++ b/src/test/run-pass/autoderef-and-borrow-method-receiver.rs @@ -13,7 +13,7 @@ struct Foo { } impl Foo { - pub fn f(&const self) {} + pub fn f(&self) {} } fn g(x: &mut Foo) { diff --git a/src/test/compile-fail/borrowck-pat-enum.rs b/src/test/run-pass/borrowck-pat-enum.rs similarity index 65% rename from src/test/compile-fail/borrowck-pat-enum.rs rename to src/test/run-pass/borrowck-pat-enum.rs index f1cca89b227d6..f320de39c8c3b 100644 --- a/src/test/compile-fail/borrowck-pat-enum.rs +++ b/src/test/run-pass/borrowck-pat-enum.rs @@ -1,3 +1,5 @@ +// xfail-pretty + // Copyright 2012 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. @@ -24,32 +26,9 @@ fn match_ref_unused(v: Option) { } } -fn match_const_reg(v: &const Option) -> int { - match *v { - Some(ref i) => {*i} //~ ERROR cannot borrow - //~^ ERROR unsafe borrow - None => {0} - } -} - fn impure(_i: int) { } -fn match_const_reg_unused(v: &const Option) { - match *v { - Some(_) => {impure(0)} // OK because nothing is captured - None => {} - } -} - -fn match_const_reg_impure(v: &const Option) { - match *v { - Some(ref i) => {impure(*i)} //~ ERROR cannot borrow - //~^ ERROR unsafe borrow - None => {} - } -} - fn match_imm_reg(v: &Option) { match *v { Some(ref i) => {impure(*i)} // OK because immutable diff --git a/src/test/compile-fail/borrowck-uniq-via-ref.rs b/src/test/run-pass/borrowck-uniq-via-ref.rs similarity index 77% rename from src/test/compile-fail/borrowck-uniq-via-ref.rs rename to src/test/run-pass/borrowck-uniq-via-ref.rs index 8bf627d991911..44f3a8f518a15 100644 --- a/src/test/compile-fail/borrowck-uniq-via-ref.rs +++ b/src/test/run-pass/borrowck-uniq-via-ref.rs @@ -25,7 +25,6 @@ struct Innermost { } fn borrow(_v: &int) {} -fn borrow_const(_v: &const int) {} fn box_mut(v: &mut ~int) { borrow(*v); // OK: &mut -> &imm @@ -51,17 +50,5 @@ fn box_imm_recs(v: &Outer) { borrow(v.f.g.h); // OK } -fn box_const(v: &const ~int) { - borrow_const(*v); //~ ERROR unsafe borrow -} - -fn box_const_rec(v: &const Rec) { - borrow_const(v.f); //~ ERROR unsafe borrow -} - -fn box_const_recs(v: &const Outer) { - borrow_const(v.f.g.h); //~ ERROR unsafe borrow -} - fn main() { } diff --git a/src/test/run-pass/class-impl-very-parameterized-trait.rs b/src/test/run-pass/class-impl-very-parameterized-trait.rs index 01907da38ad9d..03dd33b08e235 100644 --- a/src/test/run-pass/class-impl-very-parameterized-trait.rs +++ b/src/test/run-pass/class-impl-very-parameterized-trait.rs @@ -49,8 +49,8 @@ impl cat { } impl Container for cat { - fn len(&const self) -> uint { self.meows as uint } - fn is_empty(&const self) -> bool { self.meows == 0 } + fn len(&self) -> uint { self.meows as uint } + fn is_empty(&self) -> bool { self.meows == 0 } } impl Mutable for cat { diff --git a/src/test/run-pass/coerce-reborrow-imm-ptr-rcvr.rs b/src/test/run-pass/coerce-reborrow-imm-ptr-rcvr.rs index 5525062581c1a..52fa1399363cd 100644 --- a/src/test/run-pass/coerce-reborrow-imm-ptr-rcvr.rs +++ b/src/test/run-pass/coerce-reborrow-imm-ptr-rcvr.rs @@ -3,14 +3,14 @@ struct SpeechMaker { } impl SpeechMaker { - pub fn how_many(&const self) -> uint { self.speeches } + pub fn how_many(&self) -> uint { self.speeches } } -fn foo(speaker: &const SpeechMaker) -> uint { +fn foo(speaker: &SpeechMaker) -> uint { speaker.how_many() + 33 } pub fn main() { let lincoln = SpeechMaker {speeches: 22}; - assert_eq!(foo(&const lincoln), 55); + assert_eq!(foo(&lincoln), 55); } diff --git a/src/test/run-pass/const-vec-syntax.rs b/src/test/run-pass/const-vec-syntax.rs index 625f6ec30cc13..84ee54cfdde6d 100644 --- a/src/test/run-pass/const-vec-syntax.rs +++ b/src/test/run-pass/const-vec-syntax.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn f(_: &const [int]) {} +fn f(_: &[int]) {} pub fn main() { let v = [ 1, 2, 3 ]; diff --git a/src/test/run-pass/deriving-zero.rs b/src/test/run-pass/deriving-zero.rs index 54895d1796f40..1dfb03f3c783b 100644 --- a/src/test/run-pass/deriving-zero.rs +++ b/src/test/run-pass/deriving-zero.rs @@ -38,5 +38,6 @@ struct Lots { } fn main() { - assert!(Zero::zero::().is_zero()); + let lots: Lots = Zero::zero(); + assert!(lots.is_zero()); } diff --git a/src/test/run-pass/float-nan.rs b/src/test/run-pass/float-nan.rs index 29a180db1855d..d59b8c77d0067 100644 --- a/src/test/run-pass/float-nan.rs +++ b/src/test/run-pass/float-nan.rs @@ -13,11 +13,12 @@ extern mod extra; use std::num::Float; pub fn main() { - let nan = Float::NaN::(); + let nan: float = Float::NaN(); assert!((nan).is_NaN()); - let inf = Float::infinity::(); - assert_eq!(-inf, Float::neg_infinity::()); + let inf: float = Float::infinity(); + let neg_inf: float = Float::neg_infinity(); + assert_eq!(-inf, neg_inf); assert!( nan != nan); assert!( nan != -nan); diff --git a/src/test/run-pass/issue-6898.rs b/src/test/run-pass/issue-6898.rs index 2d612bb742eb3..8e9502d6d49e6 100644 --- a/src/test/run-pass/issue-6898.rs +++ b/src/test/run-pass/issue-6898.rs @@ -1,3 +1,5 @@ +// xfail-test + // Copyright 2013 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. diff --git a/src/test/run-pass/mid-path-type-params.rs b/src/test/run-pass/mid-path-type-params.rs new file mode 100644 index 0000000000000..1bc37a035e046 --- /dev/null +++ b/src/test/run-pass/mid-path-type-params.rs @@ -0,0 +1,33 @@ +struct S { + contents: T, +} + +impl S { + fn new(x: T, _: U) -> S { + S { + contents: x, + } + } +} + +trait Trait { + fn new(x: T, y: U) -> Self; +} + +struct S2 { + contents: int, +} + +impl Trait for S2 { + fn new(x: int, _: U) -> S2 { + S2 { + contents: x, + } + } +} + +fn main() { + let _ = S::::new::(1, 1.0); + let _: S2 = Trait::::new::(1, 1.0); +} + diff --git a/src/test/run-pass/trait-default-method-xc.rs b/src/test/run-pass/trait-default-method-xc.rs index 0c334909b259c..baf4cf45b3ce8 100644 --- a/src/test/run-pass/trait-default-method-xc.rs +++ b/src/test/run-pass/trait-default-method-xc.rs @@ -59,7 +59,7 @@ fn main () { assert_eq!(0i.thing(3.14, 1), (3.14, 1)); assert_eq!(B::staticthing(&0i, 3.14, 1), (3.14, 1)); - assert_eq!(B::staticthing::(&0i, 3.14, 1), (3.14, 1)); + assert_eq!(B::::staticthing::(&0i, 3.14, 1), (3.14, 1)); assert_eq!(g(0i, 3.14, 1), (3.14, 1)); assert_eq!(g(false, 3.14, 1), (3.14, 1)); diff --git a/src/test/run-pass/trait-static-method-overwriting.rs b/src/test/run-pass/trait-static-method-overwriting.rs index e95b80447e481..5ac26e65d8880 100644 --- a/src/test/run-pass/trait-static-method-overwriting.rs +++ b/src/test/run-pass/trait-static-method-overwriting.rs @@ -14,7 +14,7 @@ mod base { use std::io; pub trait HasNew { - fn new() -> T; + fn new() -> Self; } pub struct Foo { @@ -41,6 +41,6 @@ mod base { } pub fn main() { - let _f: base::Foo = base::HasNew::new::(); - let _b: base::Bar = base::HasNew::new::(); + let _f: base::Foo = base::HasNew::::new(); + let _b: base::Bar = base::HasNew::::new(); }