auto merge of #14712 : alexcrichton/rust/rollup, r=alexcrichton
Closes #14675 (rustc: Encode argument names for traits) Closes #14681 (rustc: Avoid UB with signed division/remainder) Closes #14682 (librustc: Update AutoObject adjustment in writeback.) Closes #14683 (Avoid 16-byte filenames in rlibs) Closes #14687 (rustdoc: Inline static documentation across crates) Closes #14689 (Remove reference to ~str in documentation) Closes #14692 (Rename Iterator::len to count) Closes #14693 (Implement Eq for HashSet and HashMap) Closes #14699 (url: encode small bytes correctly.) Closes #14700 (rustdoc: Submit examples to play.rust-lang.org) Closes #14701 (mk: Run doc tests with --cfg dox) Closes #14710 (rustc: Preserve reachable extern fns with LTO) Closes #14711 (Removing unused wrapper to libc::close.)
This commit is contained in:
commit
e87e18064e
77 changed files with 645 additions and 234 deletions
|
|
@ -43,7 +43,9 @@ L10N_LANGS := ja
|
|||
|
||||
# The options are passed to the documentation generators.
|
||||
RUSTDOC_HTML_OPTS_NO_CSS = --markdown-before-content=doc/version_info.html \
|
||||
--markdown-in-header=doc/favicon.inc --markdown-after-content=doc/footer.inc
|
||||
--markdown-in-header=doc/favicon.inc \
|
||||
--markdown-after-content=doc/footer.inc \
|
||||
--markdown-playground-url='http://play.rust-lang.org/'
|
||||
|
||||
RUSTDOC_HTML_OPTS = $(RUSTDOC_HTML_OPTS_NO_CSS) --markdown-css rust.css
|
||||
|
||||
|
|
|
|||
|
|
@ -818,7 +818,7 @@ endif
|
|||
ifeq ($(2),$$(CFG_BUILD))
|
||||
$$(call TEST_OK_FILE,$(1),$(2),$(3),doc-crate-$(4)): $$(CRATEDOCTESTDEP_$(1)_$(2)_$(3)_$(4))
|
||||
@$$(call E, run doc-crate-$(4) [$(2)])
|
||||
$$(Q)$$(RUSTDOC_$(1)_T_$(2)_H_$(3)) --test \
|
||||
$$(Q)$$(RUSTDOC_$(1)_T_$(2)_H_$(3)) --test --cfg dox \
|
||||
$$(CRATEFILE_$(4)) --test-args "$$(TESTARGS)" && touch $$@
|
||||
else
|
||||
$$(call TEST_OK_FILE,$(1),$(2),$(3),doc-crate-$(4)):
|
||||
|
|
|
|||
|
|
@ -1545,7 +1545,7 @@ fn disassemble_extract(config: &Config, _props: &TestProps,
|
|||
fn count_extracted_lines(p: &Path) -> uint {
|
||||
let x = File::open(&p.with_extension("ll")).read_to_end().unwrap();
|
||||
let x = str::from_utf8(x.as_slice()).unwrap();
|
||||
x.lines().len()
|
||||
x.lines().count()
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -5,3 +5,5 @@ or the <a href="http://opensource.org/licenses/MIT">MIT license</a>, at your opt
|
|||
</p><p>
|
||||
This file may not be copied, modified, or distributed except according to those terms.
|
||||
</p></footer>
|
||||
<script type="text/javascript" src="jquery.js"></script>
|
||||
<script type="text/javascript" src="playpen.js"></script>
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ which both pattern-match on their input and both return early in one case,
|
|||
doing nothing otherwise:
|
||||
|
||||
~~~~
|
||||
# enum T { SpecialA(uint), SpecialB(uint) };
|
||||
# enum T { SpecialA(uint), SpecialB(uint) }
|
||||
# fn f() -> uint {
|
||||
# let input_1 = SpecialA(0);
|
||||
# let input_2 = SpecialA(0);
|
||||
|
|
@ -37,7 +37,8 @@ lightweight custom syntax extensions, themselves defined using the
|
|||
the pattern in the above code:
|
||||
|
||||
~~~~
|
||||
# enum T { SpecialA(uint), SpecialB(uint) };
|
||||
# #![feature(macro_rules)]
|
||||
# enum T { SpecialA(uint), SpecialB(uint) }
|
||||
# fn f() -> uint {
|
||||
# let input_1 = SpecialA(0);
|
||||
# let input_2 = SpecialA(0);
|
||||
|
|
@ -55,6 +56,7 @@ early_return!(input_1 SpecialA);
|
|||
early_return!(input_2 SpecialB);
|
||||
# return 0;
|
||||
# }
|
||||
# fn main() {}
|
||||
~~~~
|
||||
|
||||
Macros are defined in pattern-matching style: in the above example, the text
|
||||
|
|
@ -155,7 +157,8 @@ separator token (a comma-separated list could be written `$(...),*`), and `+`
|
|||
instead of `*` to mean "at least one".
|
||||
|
||||
~~~~
|
||||
# enum T { SpecialA(uint),SpecialB(uint),SpecialC(uint),SpecialD(uint)};
|
||||
# #![feature(macro_rules)]
|
||||
# enum T { SpecialA(uint),SpecialB(uint),SpecialC(uint),SpecialD(uint)}
|
||||
# fn f() -> uint {
|
||||
# let input_1 = SpecialA(0);
|
||||
# let input_2 = SpecialA(0);
|
||||
|
|
@ -175,6 +178,7 @@ early_return!(input_1, [SpecialA|SpecialC|SpecialD]);
|
|||
early_return!(input_2, [SpecialB]);
|
||||
# return 0;
|
||||
# }
|
||||
# fn main() {}
|
||||
~~~~
|
||||
|
||||
### Transcription
|
||||
|
|
@ -215,9 +219,10 @@ solves the problem.
|
|||
Now consider code like the following:
|
||||
|
||||
~~~~
|
||||
# enum T1 { Good1(T2, uint), Bad1};
|
||||
# #![feature(macro_rules)]
|
||||
# enum T1 { Good1(T2, uint), Bad1}
|
||||
# struct T2 { body: T3 }
|
||||
# enum T3 { Good2(uint), Bad2};
|
||||
# enum T3 { Good2(uint), Bad2}
|
||||
# fn f(x: T1) -> uint {
|
||||
match x {
|
||||
Good1(g1, val) => {
|
||||
|
|
@ -232,6 +237,7 @@ match x {
|
|||
_ => return 0 // default value
|
||||
}
|
||||
# }
|
||||
# fn main() {}
|
||||
~~~~
|
||||
|
||||
All the complicated stuff is deeply indented, and the error-handling code is
|
||||
|
|
@ -240,6 +246,7 @@ a match, but with a syntax that suits the problem better. The following macro
|
|||
can solve the problem:
|
||||
|
||||
~~~~
|
||||
# #![feature(macro_rules)]
|
||||
macro_rules! biased_match (
|
||||
// special case: `let (x) = ...` is illegal, so use `let x = ...` instead
|
||||
( ($e:expr) ~ ($p:pat) else $err:stmt ;
|
||||
|
|
@ -261,9 +268,9 @@ macro_rules! biased_match (
|
|||
)
|
||||
)
|
||||
|
||||
# enum T1 { Good1(T2, uint), Bad1};
|
||||
# enum T1 { Good1(T2, uint), Bad1}
|
||||
# struct T2 { body: T3 }
|
||||
# enum T3 { Good2(uint), Bad2};
|
||||
# enum T3 { Good2(uint), Bad2}
|
||||
# fn f(x: T1) -> uint {
|
||||
biased_match!((x) ~ (Good1(g1, val)) else { return 0 };
|
||||
binds g1, val )
|
||||
|
|
@ -273,6 +280,7 @@ biased_match!((g1.body) ~ (Good2(result) )
|
|||
// complicated stuff goes here
|
||||
return result + val;
|
||||
# }
|
||||
# fn main() {}
|
||||
~~~~
|
||||
|
||||
This solves the indentation problem. But if we have a lot of chained matches
|
||||
|
|
@ -280,6 +288,8 @@ like this, we might prefer to write a single macro invocation. The input
|
|||
pattern we want is clear:
|
||||
|
||||
~~~~
|
||||
# #![feature(macro_rules)]
|
||||
# fn main() {}
|
||||
# macro_rules! b(
|
||||
( $( ($e:expr) ~ ($p:pat) else $err:stmt ; )*
|
||||
binds $( $bind_res:ident ),*
|
||||
|
|
@ -301,14 +311,18 @@ process the semicolon-terminated lines, one-by-one. So, we want the following
|
|||
input patterns:
|
||||
|
||||
~~~~
|
||||
# #![feature(macro_rules)]
|
||||
# macro_rules! b(
|
||||
( binds $( $bind_res:ident ),* )
|
||||
# => (0))
|
||||
# fn main() {}
|
||||
~~~~
|
||||
|
||||
...and:
|
||||
|
||||
~~~~
|
||||
# #![feature(macro_rules)]
|
||||
# fn main() {}
|
||||
# macro_rules! b(
|
||||
( ($e :expr) ~ ($p :pat) else $err :stmt ;
|
||||
$( ($e_rest:expr) ~ ($p_rest:pat) else $err_rest:stmt ; )*
|
||||
|
|
@ -322,6 +336,8 @@ The resulting macro looks like this. Note that the separation into
|
|||
piece of syntax (the `let`) which we only want to transcribe once.
|
||||
|
||||
~~~~
|
||||
# #![feature(macro_rules)]
|
||||
# fn main() {
|
||||
|
||||
macro_rules! biased_match_rec (
|
||||
// Handle the first layer
|
||||
|
|
@ -365,9 +381,9 @@ macro_rules! biased_match (
|
|||
)
|
||||
|
||||
|
||||
# enum T1 { Good1(T2, uint), Bad1};
|
||||
# enum T1 { Good1(T2, uint), Bad1}
|
||||
# struct T2 { body: T3 }
|
||||
# enum T3 { Good2(uint), Bad2};
|
||||
# enum T3 { Good2(uint), Bad2}
|
||||
# fn f(x: T1) -> uint {
|
||||
biased_match!(
|
||||
(x) ~ (Good1(g1, val)) else { return 0 };
|
||||
|
|
@ -376,6 +392,7 @@ biased_match!(
|
|||
// complicated stuff goes here
|
||||
return result + val;
|
||||
# }
|
||||
# }
|
||||
~~~~
|
||||
|
||||
This technique applies to many cases where transcribing a result all at once is not possible.
|
||||
|
|
|
|||
|
|
@ -523,6 +523,7 @@ vectors provided from C, using idiomatic Rust practices.
|
|||
|
||||
```
|
||||
#![no_std]
|
||||
#![feature(globs)]
|
||||
|
||||
# extern crate libc;
|
||||
extern crate core;
|
||||
|
|
|
|||
|
|
@ -313,6 +313,19 @@ table th {
|
|||
padding: 5px;
|
||||
}
|
||||
|
||||
/* Code snippets */
|
||||
|
||||
.rusttest { display: none; }
|
||||
pre.rust { position: relative; }
|
||||
pre.rust a { transform: scaleX(-1); }
|
||||
.test-arrow {
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 10px;
|
||||
font-size: 150%;
|
||||
}
|
||||
|
||||
@media (min-width: 1170px) {
|
||||
pre {
|
||||
font-size: 15px;
|
||||
|
|
|
|||
|
|
@ -1260,6 +1260,8 @@ a = Cat;
|
|||
Enumeration constructors can have either named or unnamed fields:
|
||||
|
||||
~~~~
|
||||
# #![feature(struct_variant)]
|
||||
# fn main() {
|
||||
enum Animal {
|
||||
Dog (String, f64),
|
||||
Cat { name: String, weight: f64 }
|
||||
|
|
@ -1267,6 +1269,7 @@ enum Animal {
|
|||
|
||||
let mut a: Animal = Dog("Cocoa".to_string(), 37.2);
|
||||
a = Cat { name: "Spotty".to_string(), weight: 2.7 };
|
||||
# }
|
||||
~~~~
|
||||
|
||||
In this example, `Cat` is a _struct-like enum variant_,
|
||||
|
|
|
|||
|
|
@ -774,6 +774,7 @@ fn point_from_direction(dir: Direction) -> Point {
|
|||
Enum variants may also be structs. For example:
|
||||
|
||||
~~~~
|
||||
# #![feature(struct_variant)]
|
||||
use std::f64;
|
||||
# struct Point { x: f64, y: f64 }
|
||||
# fn square(x: f64) -> f64 { x * x }
|
||||
|
|
@ -789,6 +790,7 @@ fn area(sh: Shape) -> f64 {
|
|||
}
|
||||
}
|
||||
}
|
||||
# fn main() {}
|
||||
~~~~
|
||||
|
||||
> *Note:* This feature of the compiler is currently gated behind the
|
||||
|
|
@ -3046,6 +3048,7 @@ use farm::{chicken, cow};
|
|||
2. Import everything in a module with a wildcard:
|
||||
|
||||
~~~
|
||||
# #![feature(globs)]
|
||||
use farm::*;
|
||||
# mod farm {
|
||||
# pub fn cow() { println!("Bat-chicken? What a stupid name!") }
|
||||
|
|
|
|||
|
|
@ -241,17 +241,17 @@ enum Op {Union, Intersect, Assign, Difference}
|
|||
/// bv.set(5, true);
|
||||
/// bv.set(7, true);
|
||||
/// println!("{}", bv.to_str());
|
||||
/// println!("total bits set to true: {}", bv.iter().count(|x| x));
|
||||
/// println!("total bits set to true: {}", bv.iter().filter(|x| *x).count());
|
||||
///
|
||||
/// // flip all values in bitvector, producing non-primes less than 10
|
||||
/// bv.negate();
|
||||
/// println!("{}", bv.to_str());
|
||||
/// println!("total bits set to true: {}", bv.iter().count(|x| x));
|
||||
/// println!("total bits set to true: {}", bv.iter().filter(|x| *x).count());
|
||||
///
|
||||
/// // reset bitvector to empty
|
||||
/// bv.clear();
|
||||
/// println!("{}", bv.to_str());
|
||||
/// println!("total bits set to true: {}", bv.iter().count(|x| x));
|
||||
/// println!("total bits set to true: {}", bv.iter().filter(|x| *x).count());
|
||||
/// ```
|
||||
#[deriving(Clone)]
|
||||
pub struct Bitv {
|
||||
|
|
@ -461,7 +461,7 @@ impl Bitv {
|
|||
/// bv.set(5, true);
|
||||
/// bv.set(8, true);
|
||||
/// // Count bits set to 1; result should be 5
|
||||
/// println!("{}", bv.iter().count(|x| x));
|
||||
/// println!("{}", bv.iter().filter(|x| *x).count());
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn iter<'a>(&'a self) -> Bits<'a> {
|
||||
|
|
|
|||
|
|
@ -1131,7 +1131,7 @@ mod tests {
|
|||
let v = &[0, ..128];
|
||||
let m: DList<int> = v.iter().map(|&x|x).collect();
|
||||
b.iter(|| {
|
||||
assert!(m.iter().len() == 128);
|
||||
assert!(m.iter().count() == 128);
|
||||
})
|
||||
}
|
||||
#[bench]
|
||||
|
|
@ -1139,7 +1139,7 @@ mod tests {
|
|||
let v = &[0, ..128];
|
||||
let mut m: DList<int> = v.iter().map(|&x|x).collect();
|
||||
b.iter(|| {
|
||||
assert!(m.mut_iter().len() == 128);
|
||||
assert!(m.mut_iter().count() == 128);
|
||||
})
|
||||
}
|
||||
#[bench]
|
||||
|
|
@ -1147,7 +1147,7 @@ mod tests {
|
|||
let v = &[0, ..128];
|
||||
let m: DList<int> = v.iter().map(|&x|x).collect();
|
||||
b.iter(|| {
|
||||
assert!(m.iter().rev().len() == 128);
|
||||
assert!(m.iter().rev().count() == 128);
|
||||
})
|
||||
}
|
||||
#[bench]
|
||||
|
|
@ -1155,7 +1155,7 @@ mod tests {
|
|||
let v = &[0, ..128];
|
||||
let mut m: DList<int> = v.iter().map(|&x|x).collect();
|
||||
b.iter(|| {
|
||||
assert!(m.mut_iter().rev().len() == 128);
|
||||
assert!(m.mut_iter().rev().count() == 128);
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,8 @@
|
|||
#![license = "MIT/ASL2"]
|
||||
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
|
||||
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
|
||||
html_root_url = "http://doc.rust-lang.org/")]
|
||||
html_root_url = "http://doc.rust-lang.org/",
|
||||
html_playground_url = "http://play.rust-lang.org/")]
|
||||
|
||||
#![feature(macro_rules, managed_boxes, default_type_params, phase, globs)]
|
||||
#![no_std]
|
||||
|
|
|
|||
|
|
@ -2155,7 +2155,7 @@ mod tests {
|
|||
#[test]
|
||||
fn test_mut_splitator() {
|
||||
let mut xs = [0,1,0,2,3,0,0,4,5,0];
|
||||
assert_eq!(xs.mut_split(|x| *x == 0).len(), 6);
|
||||
assert_eq!(xs.mut_split(|x| *x == 0).count(), 6);
|
||||
for slice in xs.mut_split(|x| *x == 0) {
|
||||
slice.reverse();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ pub struct SmallIntMap<T> {
|
|||
impl<V> Container for SmallIntMap<V> {
|
||||
/// Return the number of elements in the map
|
||||
fn len(&self) -> uint {
|
||||
self.v.iter().count(|elt| elt.is_some())
|
||||
self.v.iter().filter(|elt| elt.is_some()).count()
|
||||
}
|
||||
|
||||
/// Return true if there are no elements in the map
|
||||
|
|
|
|||
|
|
@ -2181,7 +2181,7 @@ mod bench {
|
|||
let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
|
||||
let len = s.char_len();
|
||||
|
||||
b.iter(|| assert_eq!(s.chars().len(), len));
|
||||
b.iter(|| assert_eq!(s.chars().count(), len));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
|
|
@ -2194,7 +2194,7 @@ mod bench {
|
|||
Mary had a little lamb, Little lamb";
|
||||
let len = s.char_len();
|
||||
|
||||
b.iter(|| assert_eq!(s.chars().len(), len));
|
||||
b.iter(|| assert_eq!(s.chars().count(), len));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
|
|
@ -2202,7 +2202,7 @@ mod bench {
|
|||
let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
|
||||
let len = s.char_len();
|
||||
|
||||
b.iter(|| assert_eq!(s.chars().rev().len(), len));
|
||||
b.iter(|| assert_eq!(s.chars().rev().count(), len));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
|
|
@ -2210,7 +2210,7 @@ mod bench {
|
|||
let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
|
||||
let len = s.char_len();
|
||||
|
||||
b.iter(|| assert_eq!(s.char_indices().len(), len));
|
||||
b.iter(|| assert_eq!(s.char_indices().count(), len));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
|
|
@ -2218,14 +2218,14 @@ mod bench {
|
|||
let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
|
||||
let len = s.char_len();
|
||||
|
||||
b.iter(|| assert_eq!(s.char_indices().rev().len(), len));
|
||||
b.iter(|| assert_eq!(s.char_indices().rev().count(), len));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn split_unicode_ascii(b: &mut Bencher) {
|
||||
let s = "ประเทศไทย中华Việt Namประเทศไทย中华Việt Nam";
|
||||
|
||||
b.iter(|| assert_eq!(s.split('V').len(), 3));
|
||||
b.iter(|| assert_eq!(s.split('V').count(), 3));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
|
|
@ -2240,16 +2240,16 @@ mod bench {
|
|||
}
|
||||
let s = "ประเทศไทย中华Việt Namประเทศไทย中华Việt Nam";
|
||||
|
||||
b.iter(|| assert_eq!(s.split(NotAscii('V')).len(), 3));
|
||||
b.iter(|| assert_eq!(s.split(NotAscii('V')).count(), 3));
|
||||
}
|
||||
|
||||
|
||||
#[bench]
|
||||
fn split_ascii(b: &mut Bencher) {
|
||||
let s = "Mary had a little lamb, Little lamb, little-lamb.";
|
||||
let len = s.split(' ').len();
|
||||
let len = s.split(' ').count();
|
||||
|
||||
b.iter(|| assert_eq!(s.split(' ').len(), len));
|
||||
b.iter(|| assert_eq!(s.split(' ').count(), len));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
|
|
@ -2264,34 +2264,34 @@ mod bench {
|
|||
fn only_ascii(&self) -> bool { false }
|
||||
}
|
||||
let s = "Mary had a little lamb, Little lamb, little-lamb.";
|
||||
let len = s.split(' ').len();
|
||||
let len = s.split(' ').count();
|
||||
|
||||
b.iter(|| assert_eq!(s.split(NotAscii(' ')).len(), len));
|
||||
b.iter(|| assert_eq!(s.split(NotAscii(' ')).count(), len));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn split_extern_fn(b: &mut Bencher) {
|
||||
let s = "Mary had a little lamb, Little lamb, little-lamb.";
|
||||
let len = s.split(' ').len();
|
||||
let len = s.split(' ').count();
|
||||
fn pred(c: char) -> bool { c == ' ' }
|
||||
|
||||
b.iter(|| assert_eq!(s.split(pred).len(), len));
|
||||
b.iter(|| assert_eq!(s.split(pred).count(), len));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn split_closure(b: &mut Bencher) {
|
||||
let s = "Mary had a little lamb, Little lamb, little-lamb.";
|
||||
let len = s.split(' ').len();
|
||||
let len = s.split(' ').count();
|
||||
|
||||
b.iter(|| assert_eq!(s.split(|c: char| c == ' ').len(), len));
|
||||
b.iter(|| assert_eq!(s.split(|c: char| c == ' ').count(), len));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn split_slice(b: &mut Bencher) {
|
||||
let s = "Mary had a little lamb, Little lamb, little-lamb.";
|
||||
let len = s.split(' ').len();
|
||||
let len = s.split(' ').count();
|
||||
|
||||
b.iter(|| assert_eq!(s.split(&[' ']).len(), len));
|
||||
b.iter(|| assert_eq!(s.split(&[' ']).count(), len));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
|
|
|
|||
|
|
@ -1772,23 +1772,23 @@ mod tests {
|
|||
assert_eq!(v.pop(), Some(()));
|
||||
assert_eq!(v.pop(), None);
|
||||
|
||||
assert_eq!(v.iter().len(), 0);
|
||||
assert_eq!(v.iter().count(), 0);
|
||||
v.push(());
|
||||
assert_eq!(v.iter().len(), 1);
|
||||
assert_eq!(v.iter().count(), 1);
|
||||
v.push(());
|
||||
assert_eq!(v.iter().len(), 2);
|
||||
assert_eq!(v.iter().count(), 2);
|
||||
|
||||
for &() in v.iter() {}
|
||||
|
||||
assert_eq!(v.mut_iter().len(), 2);
|
||||
assert_eq!(v.mut_iter().count(), 2);
|
||||
v.push(());
|
||||
assert_eq!(v.mut_iter().len(), 3);
|
||||
assert_eq!(v.mut_iter().count(), 3);
|
||||
v.push(());
|
||||
assert_eq!(v.mut_iter().len(), 4);
|
||||
assert_eq!(v.mut_iter().count(), 4);
|
||||
|
||||
for &() in v.mut_iter() {}
|
||||
unsafe { v.set_len(0); }
|
||||
assert_eq!(v.mut_iter().len(), 0);
|
||||
assert_eq!(v.mut_iter().count(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
|
|
@ -529,11 +529,11 @@ pub trait Iterator<A> {
|
|||
/// ```rust
|
||||
/// let a = [1, 2, 3, 4, 5];
|
||||
/// let mut it = a.iter();
|
||||
/// assert!(it.len() == 5);
|
||||
/// assert!(it.len() == 0);
|
||||
/// assert!(it.count() == 5);
|
||||
/// assert!(it.count() == 0);
|
||||
/// ```
|
||||
#[inline]
|
||||
fn len(&mut self) -> uint {
|
||||
fn count(&mut self) -> uint {
|
||||
self.fold(0, |cnt, _x| cnt + 1)
|
||||
}
|
||||
|
||||
|
|
@ -591,16 +591,6 @@ pub trait Iterator<A> {
|
|||
None
|
||||
}
|
||||
|
||||
/// Count the number of elements satisfying the specified predicate
|
||||
#[inline]
|
||||
fn count(&mut self, predicate: |A| -> bool) -> uint {
|
||||
let mut i = 0;
|
||||
for x in *self {
|
||||
if predicate(x) { i += 1 }
|
||||
}
|
||||
i
|
||||
}
|
||||
|
||||
/// Return the element that gives the maximum value from the
|
||||
/// specified function.
|
||||
///
|
||||
|
|
@ -738,6 +728,14 @@ pub trait ExactSize<A> : DoubleEndedIterator<A> {
|
|||
}
|
||||
None
|
||||
}
|
||||
|
||||
#[inline]
|
||||
/// Return the exact length of the iterator.
|
||||
fn len(&self) -> uint {
|
||||
let (lower, upper) = self.size_hint();
|
||||
assert!(upper == Some(lower));
|
||||
lower
|
||||
}
|
||||
}
|
||||
|
||||
// All adaptors that preserve the size of the wrapped iterator are fine
|
||||
|
|
@ -2594,9 +2592,9 @@ mod tests {
|
|||
#[test]
|
||||
fn test_iterator_len() {
|
||||
let v = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
||||
assert_eq!(v.slice(0, 4).iter().len(), 4);
|
||||
assert_eq!(v.slice(0, 10).iter().len(), 10);
|
||||
assert_eq!(v.slice(0, 0).iter().len(), 0);
|
||||
assert_eq!(v.slice(0, 4).iter().count(), 4);
|
||||
assert_eq!(v.slice(0, 10).iter().count(), 10);
|
||||
assert_eq!(v.slice(0, 0).iter().count(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -2712,9 +2710,9 @@ mod tests {
|
|||
#[test]
|
||||
fn test_count() {
|
||||
let xs = &[1, 2, 2, 1, 5, 9, 0, 2];
|
||||
assert_eq!(xs.iter().count(|x| *x == 2), 3);
|
||||
assert_eq!(xs.iter().count(|x| *x == 5), 1);
|
||||
assert_eq!(xs.iter().count(|x| *x == 95), 0);
|
||||
assert_eq!(xs.iter().filter(|x| **x == 2).count(), 3);
|
||||
assert_eq!(xs.iter().filter(|x| **x == 5).count(), 1);
|
||||
assert_eq!(xs.iter().filter(|x| **x == 95).count(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -3044,10 +3042,10 @@ mod tests {
|
|||
assert!(range(-10i, -1).collect::<Vec<int>>() ==
|
||||
vec![-10, -9, -8, -7, -6, -5, -4, -3, -2]);
|
||||
assert!(range(0i, 5).rev().collect::<Vec<int>>() == vec![4, 3, 2, 1, 0]);
|
||||
assert_eq!(range(200, -5).len(), 0);
|
||||
assert_eq!(range(200, -5).rev().len(), 0);
|
||||
assert_eq!(range(200, 200).len(), 0);
|
||||
assert_eq!(range(200, 200).rev().len(), 0);
|
||||
assert_eq!(range(200, -5).count(), 0);
|
||||
assert_eq!(range(200, -5).rev().count(), 0);
|
||||
assert_eq!(range(200, 200).count(), 0);
|
||||
assert_eq!(range(200, 200).rev().count(), 0);
|
||||
|
||||
assert_eq!(range(0i, 100).size_hint(), (100, Some(100)));
|
||||
// this test is only meaningful when sizeof uint < sizeof u64
|
||||
|
|
@ -3062,8 +3060,8 @@ mod tests {
|
|||
vec![0i, 1, 2, 3, 4, 5]);
|
||||
assert!(range_inclusive(0i, 5).rev().collect::<Vec<int>>() ==
|
||||
vec![5i, 4, 3, 2, 1, 0]);
|
||||
assert_eq!(range_inclusive(200, -5).len(), 0);
|
||||
assert_eq!(range_inclusive(200, -5).rev().len(), 0);
|
||||
assert_eq!(range_inclusive(200, -5).count(), 0);
|
||||
assert_eq!(range_inclusive(200, -5).rev().count(), 0);
|
||||
assert!(range_inclusive(200, 200).collect::<Vec<int>>() == vec![200]);
|
||||
assert!(range_inclusive(200, 200).rev().collect::<Vec<int>>() == vec![200]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,7 +50,8 @@
|
|||
#![crate_type = "rlib"]
|
||||
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
|
||||
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
|
||||
html_root_url = "http://doc.rust-lang.org/")]
|
||||
html_root_url = "http://doc.rust-lang.org/",
|
||||
html_playground_url = "http://play.rust-lang.org/")]
|
||||
|
||||
#![no_std]
|
||||
#![feature(globs, macro_rules, managed_boxes, phase, simd)]
|
||||
|
|
|
|||
|
|
@ -252,7 +252,7 @@ pub mod traits {
|
|||
use super::*;
|
||||
|
||||
use cmp::{PartialEq, PartialOrd, Eq, Ord, Ordering, Equiv};
|
||||
use iter::{order, Iterator};
|
||||
use iter::order;
|
||||
use container::Container;
|
||||
|
||||
impl<'a,T:PartialEq> PartialEq for &'a [T] {
|
||||
|
|
@ -1141,7 +1141,6 @@ impl<'a, T:Clone> MutableCloneableVector<T> for &'a mut [T] {
|
|||
/// Unsafe operations
|
||||
pub mod raw {
|
||||
use mem::transmute;
|
||||
use iter::Iterator;
|
||||
use ptr::RawPtr;
|
||||
use raw::Slice;
|
||||
use option::{None, Option, Some};
|
||||
|
|
|
|||
|
|
@ -867,7 +867,6 @@ static TAG_CONT_U8: u8 = 128u8;
|
|||
pub mod raw {
|
||||
use mem;
|
||||
use container::Container;
|
||||
use iter::Iterator;
|
||||
use ptr::RawPtr;
|
||||
use raw::Slice;
|
||||
use slice::{ImmutableVector};
|
||||
|
|
@ -1725,7 +1724,7 @@ impl<'a> StrSlice<'a> for &'a str {
|
|||
fn is_alphanumeric(&self) -> bool { self.chars().all(char::is_alphanumeric) }
|
||||
|
||||
#[inline]
|
||||
fn char_len(&self) -> uint { self.chars().len() }
|
||||
fn char_len(&self) -> uint { self.chars().count() }
|
||||
|
||||
#[inline]
|
||||
fn slice(&self, begin: uint, end: uint) -> &'a str {
|
||||
|
|
|
|||
|
|
@ -84,7 +84,8 @@
|
|||
#![license = "MIT/ASL2"]
|
||||
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
|
||||
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
|
||||
html_root_url = "http://doc.rust-lang.org/")]
|
||||
html_root_url = "http://doc.rust-lang.org/",
|
||||
html_playground_url = "http://play.rust-lang.org/")]
|
||||
#![feature(globs, phase)]
|
||||
#![deny(missing_doc)]
|
||||
#![deny(deprecated_owned_vector)]
|
||||
|
|
|
|||
|
|
@ -29,8 +29,8 @@
|
|||
#![license = "MIT/ASL2"]
|
||||
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
|
||||
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
|
||||
html_root_url = "http://doc.rust-lang.org/")]
|
||||
|
||||
html_root_url = "http://doc.rust-lang.org/",
|
||||
html_playground_url = "http://play.rust-lang.org/")]
|
||||
#![deny(deprecated_owned_vector)]
|
||||
|
||||
use std::cell::Cell;
|
||||
|
|
|
|||
|
|
@ -203,7 +203,8 @@
|
|||
#![crate_type = "dylib"]
|
||||
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
|
||||
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
|
||||
html_root_url = "http://doc.rust-lang.org/")]
|
||||
html_root_url = "http://doc.rust-lang.org/",
|
||||
html_playground_url = "http://play.rust-lang.org/")]
|
||||
|
||||
// NB this does *not* include globs, please keep it that way.
|
||||
#![feature(macro_rules, phase)]
|
||||
|
|
|
|||
|
|
@ -111,7 +111,8 @@ if logging is disabled, none of the components of the log will be executed.
|
|||
#![crate_type = "dylib"]
|
||||
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
|
||||
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
|
||||
html_root_url = "http://doc.rust-lang.org/")]
|
||||
html_root_url = "http://doc.rust-lang.org/",
|
||||
html_playground_url = "http://play.rust-lang.org/")]
|
||||
|
||||
#![feature(macro_rules)]
|
||||
#![deny(missing_doc, deprecated_owned_vector)]
|
||||
|
|
|
|||
|
|
@ -50,7 +50,8 @@
|
|||
#![license = "MIT/ASL2"]
|
||||
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
|
||||
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
|
||||
html_root_url = "http://doc.rust-lang.org/")]
|
||||
html_root_url = "http://doc.rust-lang.org/",
|
||||
html_playground_url = "http://play.rust-lang.org/")]
|
||||
|
||||
#![deny(deprecated_owned_vector)]
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,8 @@
|
|||
#![crate_type = "rlib"]
|
||||
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk.png",
|
||||
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
|
||||
html_root_url = "http://doc.rust-lang.org/")]
|
||||
html_root_url = "http://doc.rust-lang.org/",
|
||||
html_playground_url = "http://play.rust-lang.org/")]
|
||||
|
||||
#![feature(macro_rules, phase, globs)]
|
||||
#![no_std]
|
||||
|
|
|
|||
|
|
@ -360,7 +360,8 @@
|
|||
#![license = "MIT/ASL2"]
|
||||
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
|
||||
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
|
||||
html_root_url = "http://doc.rust-lang.org/")]
|
||||
html_root_url = "http://doc.rust-lang.org/",
|
||||
html_playground_url = "http://play.rust-lang.org/")]
|
||||
|
||||
#![feature(macro_rules, phase)]
|
||||
#![deny(missing_doc, deprecated_owned_vector)]
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ impl<'a> Archive<'a> {
|
|||
pub fn add_rlib(&mut self, rlib: &Path, name: &str,
|
||||
lto: bool) -> io::IoResult<()> {
|
||||
let object = format!("{}.o", name);
|
||||
let bytecode = format!("{}.bc.deflate", name);
|
||||
let bytecode = format!("{}.bytecode.deflate", name);
|
||||
let mut ignore = vec!(bytecode.as_slice(), METADATA_FILENAME);
|
||||
if lto {
|
||||
ignore.push(object.as_slice());
|
||||
|
|
@ -166,6 +166,15 @@ impl<'a> Archive<'a> {
|
|||
if filename.contains(".SYMDEF") { continue }
|
||||
|
||||
let filename = format!("r-{}-{}", name, filename);
|
||||
// LLDB (as mentioned in back::link) crashes on filenames of exactly
|
||||
// 16 bytes in length. If we're including an object file with
|
||||
// exactly 16-bytes of characters, give it some prefix so that it's
|
||||
// not 16 bytes.
|
||||
let filename = if filename.len() == 16 {
|
||||
format!("lldb-fix-{}", filename)
|
||||
} else {
|
||||
filename
|
||||
};
|
||||
let new_filename = file.with_filename(filename);
|
||||
try!(fs::rename(file, &new_filename));
|
||||
inputs.push(new_filename);
|
||||
|
|
|
|||
|
|
@ -958,8 +958,13 @@ fn link_rlib<'a>(sess: &'a Session,
|
|||
|
||||
// For LTO purposes, the bytecode of this library is also inserted
|
||||
// into the archive.
|
||||
//
|
||||
// Note that we make sure that the bytecode filename in the archive
|
||||
// is never exactly 16 bytes long by adding a 16 byte extension to
|
||||
// it. This is to work around a bug in LLDB that would cause it to
|
||||
// crash if the name of a file in an archive was exactly 16 bytes.
|
||||
let bc = obj_filename.with_extension("bc");
|
||||
let bc_deflated = obj_filename.with_extension("bc.deflate");
|
||||
let bc_deflated = obj_filename.with_extension("bytecode.deflate");
|
||||
match fs::File::open(&bc).read_to_end().and_then(|data| {
|
||||
fs::File::create(&bc_deflated)
|
||||
.write(match flate::deflate_bytes(data.as_slice()) {
|
||||
|
|
|
|||
|
|
@ -55,10 +55,10 @@ pub fn run(sess: &session::Session, llmod: ModuleRef,
|
|||
let archive = ArchiveRO::open(&path).expect("wanted an rlib");
|
||||
debug!("reading {}", name);
|
||||
let bc = time(sess.time_passes(),
|
||||
format!("read {}.bc.deflate", name).as_slice(),
|
||||
format!("read {}.bytecode.deflate", name).as_slice(),
|
||||
(),
|
||||
|_| {
|
||||
archive.read(format!("{}.bc.deflate",
|
||||
archive.read(format!("{}.bytecode.deflate",
|
||||
name).as_slice())
|
||||
});
|
||||
let bc = bc.expect("missing compressed bytecode in archive!");
|
||||
|
|
|
|||
|
|
@ -209,6 +209,9 @@ pub static tag_dylib_dependency_formats: uint = 0x67;
|
|||
pub static tag_method_argument_names: uint = 0x8e;
|
||||
pub static tag_method_argument_name: uint = 0x8f;
|
||||
|
||||
pub static tag_reachable_extern_fns: uint = 0x90;
|
||||
pub static tag_reachable_extern_fn_id: uint = 0x91;
|
||||
|
||||
#[deriving(Clone, Show)]
|
||||
pub struct LinkMeta {
|
||||
pub crateid: CrateId,
|
||||
|
|
|
|||
|
|
@ -314,3 +314,10 @@ pub fn get_method_arg_names(cstore: &cstore::CStore, did: ast::DefId)
|
|||
let cdata = cstore.get_crate_data(did.krate);
|
||||
decoder::get_method_arg_names(&*cdata, did.node)
|
||||
}
|
||||
|
||||
pub fn get_reachable_extern_fns(cstore: &cstore::CStore, cnum: ast::CrateNum)
|
||||
-> Vec<ast::DefId>
|
||||
{
|
||||
let cdata = cstore.get_crate_data(cnum);
|
||||
decoder::get_reachable_extern_fns(&*cdata)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1325,3 +1325,17 @@ pub fn get_method_arg_names(cdata: Cmd, id: ast::NodeId) -> Vec<String> {
|
|||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
pub fn get_reachable_extern_fns(cdata: Cmd) -> Vec<ast::DefId> {
|
||||
let mut ret = Vec::new();
|
||||
let items = reader::get_doc(ebml::Doc::new(cdata.data()),
|
||||
tag_reachable_extern_fns);
|
||||
reader::tagged_docs(items, tag_reachable_extern_fn_id, |doc| {
|
||||
ret.push(ast::DefId {
|
||||
krate: cdata.cnum,
|
||||
node: reader::doc_as_u32(doc),
|
||||
});
|
||||
true
|
||||
});
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,6 +75,7 @@ pub struct EncodeParams<'a> {
|
|||
pub link_meta: &'a LinkMeta,
|
||||
pub cstore: &'a cstore::CStore,
|
||||
pub encode_inlined_item: EncodeInlinedItem<'a>,
|
||||
pub reachable: &'a NodeSet,
|
||||
}
|
||||
|
||||
pub struct EncodeContext<'a> {
|
||||
|
|
@ -87,6 +88,7 @@ pub struct EncodeContext<'a> {
|
|||
pub cstore: &'a cstore::CStore,
|
||||
pub encode_inlined_item: RefCell<EncodeInlinedItem<'a>>,
|
||||
pub type_abbrevs: tyencode::abbrev_map,
|
||||
pub reachable: &'a NodeSet,
|
||||
}
|
||||
|
||||
fn encode_name(ebml_w: &mut Encoder, name: Name) {
|
||||
|
|
@ -351,7 +353,7 @@ fn encode_enum_variant_info(ecx: &EncodeContext,
|
|||
fn encode_path<PI: Iterator<PathElem> + Clone>(ebml_w: &mut Encoder,
|
||||
mut path: PI) {
|
||||
ebml_w.start_tag(tag_path);
|
||||
ebml_w.wr_tagged_u32(tag_path_len, path.clone().len() as u32);
|
||||
ebml_w.wr_tagged_u32(tag_path_len, path.clone().count() as u32);
|
||||
for pe in path {
|
||||
let tag = match pe {
|
||||
ast_map::PathMod(_) => tag_path_elem_mod,
|
||||
|
|
@ -1196,6 +1198,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
|
|||
&Required(ref tm) => {
|
||||
encode_attributes(ebml_w, tm.attrs.as_slice());
|
||||
encode_method_sort(ebml_w, 'r');
|
||||
encode_method_argument_names(ebml_w, &*tm.decl);
|
||||
}
|
||||
|
||||
&Provided(m) => {
|
||||
|
|
@ -1210,6 +1213,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
|
|||
encode_method_sort(ebml_w, 'p');
|
||||
encode_inlined_item(ecx, ebml_w,
|
||||
IIMethodRef(def_id, true, m));
|
||||
encode_method_argument_names(ebml_w, &*m.decl);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1700,6 +1704,26 @@ fn encode_misc_info(ecx: &EncodeContext,
|
|||
ebml_w.end_tag();
|
||||
}
|
||||
|
||||
fn encode_reachable_extern_fns(ecx: &EncodeContext, ebml_w: &mut Encoder) {
|
||||
ebml_w.start_tag(tag_reachable_extern_fns);
|
||||
|
||||
for id in ecx.reachable.iter() {
|
||||
match ecx.tcx.map.find(*id) {
|
||||
Some(ast_map::NodeItem(i)) => {
|
||||
match i.node {
|
||||
ast::ItemFn(_, _, abi, _, _) if abi != abi::Rust => {
|
||||
ebml_w.wr_tagged_u32(tag_reachable_extern_fn_id, *id);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
ebml_w.end_tag();
|
||||
}
|
||||
|
||||
fn encode_crate_dep(ebml_w: &mut Encoder,
|
||||
dep: decoder::CrateDep) {
|
||||
ebml_w.start_tag(tag_crate_dep);
|
||||
|
|
@ -1799,6 +1823,7 @@ fn encode_metadata_inner(wr: &mut MemWriter, parms: EncodeParams, krate: &Crate)
|
|||
encode_inlined_item,
|
||||
link_meta,
|
||||
non_inlineable_statics,
|
||||
reachable,
|
||||
..
|
||||
} = parms;
|
||||
let ecx = EncodeContext {
|
||||
|
|
@ -1811,6 +1836,7 @@ fn encode_metadata_inner(wr: &mut MemWriter, parms: EncodeParams, krate: &Crate)
|
|||
cstore: cstore,
|
||||
encode_inlined_item: RefCell::new(encode_inlined_item),
|
||||
type_abbrevs: RefCell::new(HashMap::new()),
|
||||
reachable: reachable,
|
||||
};
|
||||
|
||||
let mut ebml_w = writer::Encoder::new(wr);
|
||||
|
|
@ -1862,6 +1888,7 @@ fn encode_metadata_inner(wr: &mut MemWriter, parms: EncodeParams, krate: &Crate)
|
|||
// Encode miscellaneous info.
|
||||
i = ebml_w.writer.tell().unwrap();
|
||||
encode_misc_info(&ecx, krate, &mut ebml_w);
|
||||
encode_reachable_extern_fns(&ecx, &mut ebml_w);
|
||||
stats.misc_bytes = ebml_w.writer.tell().unwrap() - i;
|
||||
|
||||
// Encode and index the items.
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ fn find_item(item: &Item, ctxt: &mut EntryContext) {
|
|||
ItemFn(..) => {
|
||||
if item.ident.name == ctxt.main_name {
|
||||
ctxt.ast_map.with_path(item.id, |mut path| {
|
||||
if path.len() == 1 {
|
||||
if path.count() == 1 {
|
||||
// This is a top-level function so can be 'main'
|
||||
if ctxt.main_fn.is_none() {
|
||||
ctxt.main_fn = Some((item.id, item.span));
|
||||
|
|
|
|||
|
|
@ -80,6 +80,7 @@ use libc::{c_uint, uint64_t};
|
|||
use std::c_str::ToCStr;
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::rc::Rc;
|
||||
use std::{i8, i16, i32, i64};
|
||||
use syntax::abi::{X86, X86_64, Arm, Mips, Rust, RustIntrinsic};
|
||||
use syntax::ast_util::{local_def, is_local};
|
||||
use syntax::attr::AttrMetaMethods;
|
||||
|
|
@ -777,35 +778,77 @@ pub fn cast_shift_rhs(op: ast::BinOp,
|
|||
}
|
||||
}
|
||||
|
||||
pub fn fail_if_zero<'a>(
|
||||
pub fn fail_if_zero_or_overflows<'a>(
|
||||
cx: &'a Block<'a>,
|
||||
span: Span,
|
||||
divrem: ast::BinOp,
|
||||
lhs: ValueRef,
|
||||
rhs: ValueRef,
|
||||
rhs_t: ty::t)
|
||||
-> &'a Block<'a> {
|
||||
let text = if divrem == ast::BiDiv {
|
||||
"attempted to divide by zero"
|
||||
let (zero_text, overflow_text) = if divrem == ast::BiDiv {
|
||||
("attempted to divide by zero",
|
||||
"attempted to divide with overflow")
|
||||
} else {
|
||||
"attempted remainder with a divisor of zero"
|
||||
("attempted remainder with a divisor of zero",
|
||||
"attempted remainder with overflow")
|
||||
};
|
||||
let is_zero = match ty::get(rhs_t).sty {
|
||||
ty::ty_int(t) => {
|
||||
let zero = C_integral(Type::int_from_ty(cx.ccx(), t), 0u64, false);
|
||||
ICmp(cx, lib::llvm::IntEQ, rhs, zero)
|
||||
}
|
||||
ty::ty_uint(t) => {
|
||||
let zero = C_integral(Type::uint_from_ty(cx.ccx(), t), 0u64, false);
|
||||
ICmp(cx, lib::llvm::IntEQ, rhs, zero)
|
||||
}
|
||||
_ => {
|
||||
cx.sess().bug(format!("fail-if-zero on unexpected type: {}",
|
||||
ty_to_str(cx.tcx(), rhs_t)).as_slice());
|
||||
}
|
||||
let (is_zero, is_signed) = match ty::get(rhs_t).sty {
|
||||
ty::ty_int(t) => {
|
||||
let zero = C_integral(Type::int_from_ty(cx.ccx(), t), 0u64, false);
|
||||
(ICmp(cx, lib::llvm::IntEQ, rhs, zero), true)
|
||||
}
|
||||
ty::ty_uint(t) => {
|
||||
let zero = C_integral(Type::uint_from_ty(cx.ccx(), t), 0u64, false);
|
||||
(ICmp(cx, lib::llvm::IntEQ, rhs, zero), false)
|
||||
}
|
||||
_ => {
|
||||
cx.sess().bug(format!("fail-if-zero on unexpected type: {}",
|
||||
ty_to_str(cx.tcx(), rhs_t)).as_slice());
|
||||
}
|
||||
};
|
||||
with_cond(cx, is_zero, |bcx| {
|
||||
controlflow::trans_fail(bcx, span, InternedString::new(text))
|
||||
})
|
||||
let bcx = with_cond(cx, is_zero, |bcx| {
|
||||
controlflow::trans_fail(bcx, span, InternedString::new(zero_text))
|
||||
});
|
||||
|
||||
// To quote LLVM's documentation for the sdiv instruction:
|
||||
//
|
||||
// Division by zero leads to undefined behavior. Overflow also leads
|
||||
// to undefined behavior; this is a rare case, but can occur, for
|
||||
// example, by doing a 32-bit division of -2147483648 by -1.
|
||||
//
|
||||
// In order to avoid undefined behavior, we perform runtime checks for
|
||||
// signed division/remainder which would trigger overflow. For unsigned
|
||||
// integers, no action beyond checking for zero need be taken.
|
||||
if is_signed {
|
||||
let (llty, min) = match ty::get(rhs_t).sty {
|
||||
ty::ty_int(t) => {
|
||||
let llty = Type::int_from_ty(cx.ccx(), t);
|
||||
let min = match t {
|
||||
ast::TyI if llty == Type::i32(cx.ccx()) => i32::MIN as u64,
|
||||
ast::TyI => i64::MIN as u64,
|
||||
ast::TyI8 => i8::MIN as u64,
|
||||
ast::TyI16 => i16::MIN as u64,
|
||||
ast::TyI32 => i32::MIN as u64,
|
||||
ast::TyI64 => i64::MIN as u64,
|
||||
};
|
||||
(llty, min)
|
||||
}
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let minus_one = ICmp(bcx, lib::llvm::IntEQ, rhs,
|
||||
C_integral(llty, -1, false));
|
||||
with_cond(bcx, minus_one, |bcx| {
|
||||
let is_min = ICmp(bcx, lib::llvm::IntEQ, lhs,
|
||||
C_integral(llty, min, true));
|
||||
with_cond(bcx, is_min, |bcx| {
|
||||
controlflow::trans_fail(bcx, span,
|
||||
InternedString::new(overflow_text))
|
||||
})
|
||||
})
|
||||
} else {
|
||||
bcx
|
||||
}
|
||||
}
|
||||
|
||||
pub fn trans_external_path(ccx: &CrateContext, did: ast::DefId, t: ty::t) -> ValueRef {
|
||||
|
|
@ -2195,6 +2238,7 @@ pub fn crate_ctxt_to_encode_parms<'r>(cx: &'r CrateContext, ie: encoder::EncodeI
|
|||
link_meta: &cx.link_meta,
|
||||
cstore: &cx.sess().cstore,
|
||||
encode_inlined_item: ie,
|
||||
reachable: &cx.reachable,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2331,6 +2375,16 @@ pub fn trans_crate(krate: ast::Crate,
|
|||
ccx.item_symbols.borrow().find(id).map(|s| s.to_string())
|
||||
}).collect();
|
||||
|
||||
// For the purposes of LTO, we add to the reachable set all of the upstream
|
||||
// reachable extern fns. These functions are all part of the public ABI of
|
||||
// the final product, so LTO needs to preserve them.
|
||||
ccx.sess().cstore.iter_crate_data(|cnum, _| {
|
||||
let syms = csearch::get_reachable_extern_fns(&ccx.sess().cstore, cnum);
|
||||
reachable.extend(syms.move_iter().map(|did| {
|
||||
csearch::get_symbol(&ccx.sess().cstore, did)
|
||||
}));
|
||||
});
|
||||
|
||||
// Make sure that some other crucial symbols are not eliminated from the
|
||||
// module. This includes the main function, the crate map (used for debug
|
||||
// log settings and I/O), and finally the curious rust_stack_exhausted
|
||||
|
|
|
|||
|
|
@ -1297,8 +1297,8 @@ fn trans_eager_binop<'a>(
|
|||
FDiv(bcx, lhs, rhs)
|
||||
} else {
|
||||
// Only zero-check integers; fp /0 is NaN
|
||||
bcx = base::fail_if_zero(bcx, binop_expr.span,
|
||||
op, rhs, rhs_t);
|
||||
bcx = base::fail_if_zero_or_overflows(bcx, binop_expr.span,
|
||||
op, lhs, rhs, rhs_t);
|
||||
if is_signed {
|
||||
SDiv(bcx, lhs, rhs)
|
||||
} else {
|
||||
|
|
@ -1311,8 +1311,8 @@ fn trans_eager_binop<'a>(
|
|||
FRem(bcx, lhs, rhs)
|
||||
} else {
|
||||
// Only zero-check integers; fp %0 is NaN
|
||||
bcx = base::fail_if_zero(bcx, binop_expr.span,
|
||||
op, rhs, rhs_t);
|
||||
bcx = base::fail_if_zero_or_overflows(bcx, binop_expr.span,
|
||||
op, lhs, rhs, rhs_t);
|
||||
if is_signed {
|
||||
SRem(bcx, lhs, rhs)
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -191,11 +191,11 @@ fn ast_path_substs<AC:AstConv,RS:RegionScope>(
|
|||
};
|
||||
|
||||
// Convert the type parameters supplied by the user.
|
||||
let supplied_ty_param_count = path.segments.iter().flat_map(|s| s.types.iter()).len();
|
||||
let supplied_ty_param_count = path.segments.iter().flat_map(|s| s.types.iter()).count();
|
||||
let formal_ty_param_count = decl_generics.type_param_defs().len();
|
||||
let required_ty_param_count = decl_generics.type_param_defs().iter()
|
||||
.take_while(|x| x.default.is_none())
|
||||
.len();
|
||||
.count();
|
||||
if supplied_ty_param_count < required_ty_param_count {
|
||||
let expected = if required_ty_param_count < formal_ty_param_count {
|
||||
"expected at least"
|
||||
|
|
@ -407,7 +407,7 @@ pub fn ast_ty_to_builtin_ty<AC:AstConv,
|
|||
if path.segments
|
||||
.iter()
|
||||
.flat_map(|s| s.types.iter())
|
||||
.len() > 1 {
|
||||
.count() > 1 {
|
||||
this.tcx()
|
||||
.sess
|
||||
.span_err(path.span,
|
||||
|
|
|
|||
|
|
@ -1615,7 +1615,7 @@ fn check_type_parameter_positions_in_path(function_context: &FnCtxt,
|
|||
let formal_ty_param_count = generics.type_param_defs().len();
|
||||
let required_ty_param_count = generics.type_param_defs().iter()
|
||||
.take_while(|x| x.default.is_none())
|
||||
.len();
|
||||
.count();
|
||||
let supplied_ty_param_count = trait_segment.types.len();
|
||||
if supplied_ty_param_count < required_ty_param_count {
|
||||
let msg = if required_ty_param_count < generics.type_param_defs().len() {
|
||||
|
|
@ -3876,7 +3876,7 @@ pub fn instantiate_path(fcx: &FnCtxt,
|
|||
let ty_param_count = tpt.generics.type_param_defs().len();
|
||||
let ty_param_req = tpt.generics.type_param_defs().iter()
|
||||
.take_while(|x| x.default.is_none())
|
||||
.len();
|
||||
.count();
|
||||
let mut ty_substs_len = 0;
|
||||
for segment in pth.segments.iter() {
|
||||
ty_substs_len += segment.types.len()
|
||||
|
|
|
|||
|
|
@ -432,7 +432,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
|
|||
// function check_cast_for_escaping_regions() in kind.rs
|
||||
// explaining how it goes about doing that.
|
||||
|
||||
let source_ty = rcx.fcx.expr_ty(expr);
|
||||
let source_ty = rcx.resolve_node_type(expr.id);
|
||||
constrain_regions_in_type(rcx, trait_region,
|
||||
infer::RelateObjectBound(expr.span), source_ty);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -260,7 +260,14 @@ impl<'cx> WritebackCx<'cx> {
|
|||
})
|
||||
}
|
||||
|
||||
adjustment => adjustment
|
||||
ty::AutoObject(trait_store, bb, def_id, substs) => {
|
||||
ty::AutoObject(
|
||||
self.resolve(&trait_store, reason),
|
||||
self.resolve(&bb, reason),
|
||||
def_id,
|
||||
self.resolve(&substs, reason)
|
||||
)
|
||||
}
|
||||
};
|
||||
debug!("Adjustments for node {}: {:?}", id, resolved_adjustment);
|
||||
self.tcx().adjustments.borrow_mut().insert(
|
||||
|
|
|
|||
|
|
@ -456,7 +456,7 @@ pub fn parameterized(cx: &ctxt,
|
|||
Some(default) => default.subst(cx, &substs) == actual,
|
||||
None => false
|
||||
}
|
||||
}).len()
|
||||
}).count()
|
||||
} else {
|
||||
0
|
||||
};
|
||||
|
|
|
|||
|
|
@ -88,6 +88,10 @@ fn try_inline_def(cx: &core::DocContext,
|
|||
record_extern_fqn(cx, did, clean::TypeModule);
|
||||
clean::ModuleItem(build_module(cx, tcx, did))
|
||||
}
|
||||
def::DefStatic(did, mtbl) => {
|
||||
record_extern_fqn(cx, did, clean::TypeStatic);
|
||||
clean::StaticItem(build_static(tcx, did, mtbl))
|
||||
}
|
||||
_ => return None,
|
||||
};
|
||||
let fqn = csearch::get_item_path(tcx, did);
|
||||
|
|
@ -343,3 +347,13 @@ fn build_module(cx: &core::DocContext, tcx: &ty::ctxt,
|
|||
is_crate: false,
|
||||
}
|
||||
}
|
||||
|
||||
fn build_static(tcx: &ty::ctxt,
|
||||
did: ast::DefId,
|
||||
mutable: bool) -> clean::Static {
|
||||
clean::Static {
|
||||
type_: ty::lookup_item_type(tcx, did).ty.clean(),
|
||||
mutability: if mutable {clean::Mutable} else {clean::Immutable},
|
||||
expr: "\n\n\n".to_string(), // trigger the "[definition]" links
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,6 +35,8 @@ pub struct VisSpace(pub Option<ast::Visibility>);
|
|||
pub struct FnStyleSpace(pub ast::FnStyle);
|
||||
/// Wrapper struct for properly emitting a method declaration.
|
||||
pub struct Method<'a>(pub &'a clean::SelfTy, pub &'a clean::FnDecl);
|
||||
/// Similar to VisSpace, but used for mutability
|
||||
pub struct MutableSpace(pub clean::Mutability);
|
||||
|
||||
impl VisSpace {
|
||||
pub fn get(&self) -> Option<ast::Visibility> {
|
||||
|
|
@ -438,24 +440,14 @@ impl fmt::Show for clean::Type {
|
|||
clean::Unique(ref t) => write!(f, "~{}", **t),
|
||||
clean::Managed(ref t) => write!(f, "@{}", **t),
|
||||
clean::RawPointer(m, ref t) => {
|
||||
write!(f, "*{}{}",
|
||||
match m {
|
||||
clean::Mutable => "mut ",
|
||||
clean::Immutable => "",
|
||||
}, **t)
|
||||
write!(f, "*{}{}", MutableSpace(m), **t)
|
||||
}
|
||||
clean::BorrowedRef{ lifetime: ref l, mutability, type_: ref ty} => {
|
||||
let lt = match *l {
|
||||
Some(ref l) => format!("{} ", *l),
|
||||
_ => "".to_string(),
|
||||
};
|
||||
write!(f, "&{}{}{}",
|
||||
lt,
|
||||
match mutability {
|
||||
clean::Mutable => "mut ",
|
||||
clean::Immutable => "",
|
||||
},
|
||||
**ty)
|
||||
write!(f, "&{}{}{}", lt, MutableSpace(mutability), **ty)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -494,17 +486,13 @@ impl<'a> fmt::Show for Method<'a> {
|
|||
clean::SelfStatic => {},
|
||||
clean::SelfValue => args.push_str("self"),
|
||||
clean::SelfOwned => args.push_str("~self"),
|
||||
clean::SelfBorrowed(Some(ref lt), clean::Immutable) => {
|
||||
args.push_str(format!("&{} self", *lt).as_slice());
|
||||
clean::SelfBorrowed(Some(ref lt), mtbl) => {
|
||||
args.push_str(format!("&{} {}self", *lt,
|
||||
MutableSpace(mtbl)).as_slice());
|
||||
}
|
||||
clean::SelfBorrowed(Some(ref lt), clean::Mutable) => {
|
||||
args.push_str(format!("&{} mut self", *lt).as_slice());
|
||||
}
|
||||
clean::SelfBorrowed(None, clean::Mutable) => {
|
||||
args.push_str("&mut self");
|
||||
}
|
||||
clean::SelfBorrowed(None, clean::Immutable) => {
|
||||
args.push_str("&self");
|
||||
clean::SelfBorrowed(None, mtbl) => {
|
||||
args.push_str(format!("&{}self",
|
||||
MutableSpace(mtbl)).as_slice());
|
||||
}
|
||||
}
|
||||
for (i, input) in d.inputs.values.iter().enumerate() {
|
||||
|
|
@ -605,3 +593,12 @@ impl fmt::Show for clean::ViewListIdent {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Show for MutableSpace {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
MutableSpace(clean::Immutable) => Ok(()),
|
||||
MutableSpace(clean::Mutable) => write!(f, "mut "),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ use html::escape::Escape;
|
|||
use t = syntax::parse::token;
|
||||
|
||||
/// Highlights some source code, returning the HTML output.
|
||||
pub fn highlight(src: &str, class: Option<&str>) -> String {
|
||||
pub fn highlight(src: &str, class: Option<&str>, id: Option<&str>) -> String {
|
||||
debug!("highlighting: ================\n{}\n==============", src);
|
||||
let sess = parse::new_parse_sess();
|
||||
let fm = parse::string_to_filemap(&sess,
|
||||
|
|
@ -36,6 +36,7 @@ pub fn highlight(src: &str, class: Option<&str>) -> String {
|
|||
doit(&sess,
|
||||
lexer::StringReader::new(&sess.span_diagnostic, fm),
|
||||
class,
|
||||
id,
|
||||
&mut out).unwrap();
|
||||
str::from_utf8_lossy(out.unwrap().as_slice()).to_string()
|
||||
}
|
||||
|
|
@ -47,11 +48,17 @@ pub fn highlight(src: &str, class: Option<&str>) -> String {
|
|||
/// it's used. All source code emission is done as slices from the source map,
|
||||
/// not from the tokens themselves, in order to stay true to the original
|
||||
/// source.
|
||||
fn doit(sess: &parse::ParseSess, mut lexer: lexer::StringReader, class: Option<&str>,
|
||||
fn doit(sess: &parse::ParseSess, mut lexer: lexer::StringReader,
|
||||
class: Option<&str>, id: Option<&str>,
|
||||
out: &mut Writer) -> io::IoResult<()> {
|
||||
use syntax::parse::lexer::Reader;
|
||||
|
||||
try!(write!(out, "<pre class='rust {}'>\n", class.unwrap_or("")));
|
||||
try!(write!(out, "<pre "));
|
||||
match id {
|
||||
Some(id) => try!(write!(out, "id='{}' ", id)),
|
||||
None => {}
|
||||
}
|
||||
try!(write!(out, "class='rust {}'>\n", class.unwrap_or("")));
|
||||
let mut last = BytePos(0);
|
||||
let mut is_attribute = false;
|
||||
let mut is_macro = false;
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ pub struct Layout {
|
|||
pub logo: String,
|
||||
pub favicon: String,
|
||||
pub krate: String,
|
||||
pub playground_url: String,
|
||||
}
|
||||
|
||||
pub struct Page<'a> {
|
||||
|
|
@ -108,11 +109,13 @@ r##"<!DOCTYPE html>
|
|||
</div>
|
||||
|
||||
<script>
|
||||
var rootPath = "{root_path}";
|
||||
var currentCrate = "{krate}";
|
||||
window.rootPath = "{root_path}";
|
||||
window.currentCrate = "{krate}";
|
||||
window.playgroundUrl = "{play_url}";
|
||||
</script>
|
||||
<script src="{root_path}jquery.js"></script>
|
||||
<script src="{root_path}main.js"></script>
|
||||
{play_js}
|
||||
<script async src="{root_path}search-index.js"></script>
|
||||
</body>
|
||||
</html>"##,
|
||||
|
|
@ -124,6 +127,12 @@ r##"<!DOCTYPE html>
|
|||
favicon = nonestr(layout.favicon.as_slice()),
|
||||
sidebar = *sidebar,
|
||||
krate = layout.krate,
|
||||
play_url = layout.playground_url,
|
||||
play_js = if layout.playground_url.len() == 0 {
|
||||
"".to_string()
|
||||
} else {
|
||||
format!(r#"<script src="{}playpen.js"></script>"#, page.root_path)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
#![allow(non_camel_case_types)]
|
||||
|
||||
use libc;
|
||||
use std::cell::RefCell;
|
||||
use std::cell::{RefCell, Cell};
|
||||
use std::fmt;
|
||||
use std::slice;
|
||||
use std::str;
|
||||
|
|
@ -35,6 +35,8 @@ use std::collections::HashMap;
|
|||
|
||||
use html::toc::TocBuilder;
|
||||
use html::highlight;
|
||||
use html::escape::Escape;
|
||||
use test;
|
||||
|
||||
/// A unit struct which has the `fmt::Show` trait implemented. When
|
||||
/// formatted, this struct will emit the HTML corresponding to the rendered
|
||||
|
|
@ -139,6 +141,9 @@ fn stripped_filtered_line<'a>(s: &'a str) -> Option<&'a str> {
|
|||
}
|
||||
|
||||
local_data_key!(used_header_map: RefCell<HashMap<String, uint>>)
|
||||
local_data_key!(test_idx: Cell<uint>)
|
||||
// None == render an example, but there's no crate name
|
||||
local_data_key!(pub playground_krate: Option<String>)
|
||||
|
||||
pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result {
|
||||
extern fn block(ob: *mut hoedown_buffer, text: *hoedown_buffer,
|
||||
|
|
@ -149,9 +154,9 @@ pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result {
|
|||
let opaque = opaque as *mut hoedown_html_renderer_state;
|
||||
let my_opaque: &MyOpaque = &*((*opaque).opaque as *MyOpaque);
|
||||
slice::raw::buf_as_slice((*text).data, (*text).size as uint, |text| {
|
||||
let text = str::from_utf8(text).unwrap();
|
||||
let origtext = str::from_utf8(text).unwrap();
|
||||
debug!("docblock: ==============\n{}\n=======", text);
|
||||
let mut lines = text.lines().filter(|l| {
|
||||
let mut lines = origtext.lines().filter(|l| {
|
||||
stripped_filtered_line(*l).is_none()
|
||||
});
|
||||
let text = lines.collect::<Vec<&str>>().connect("\n");
|
||||
|
|
@ -180,9 +185,26 @@ pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result {
|
|||
};
|
||||
|
||||
if !rendered {
|
||||
let output = highlight::highlight(text.as_slice(),
|
||||
None).as_slice()
|
||||
.to_c_str();
|
||||
let mut s = String::new();
|
||||
let id = playground_krate.get().map(|krate| {
|
||||
let idx = test_idx.get().unwrap();
|
||||
let i = idx.get();
|
||||
idx.set(i + 1);
|
||||
|
||||
let test = origtext.lines().map(|l| {
|
||||
stripped_filtered_line(l).unwrap_or(l)
|
||||
}).collect::<Vec<&str>>().connect("\n");
|
||||
let krate = krate.as_ref().map(|s| s.as_slice());
|
||||
let test = test::maketest(test.as_slice(), krate, false);
|
||||
s.push_str(format!("<span id='rust-example-raw-{}' \
|
||||
class='rusttest'>{}</span>",
|
||||
i, Escape(test.as_slice())).as_slice());
|
||||
format!("rust-example-rendered-{}", i)
|
||||
});
|
||||
let id = id.as_ref().map(|a| a.as_slice());
|
||||
s.push_str(highlight::highlight(text.as_slice(), None, id)
|
||||
.as_slice());
|
||||
let output = s.to_c_str();
|
||||
output.with_ref(|r| {
|
||||
hoedown_buffer_puts(ob, r)
|
||||
})
|
||||
|
|
@ -377,6 +399,7 @@ fn parse_lang_string(string: &str) -> (bool,bool,bool,bool) {
|
|||
/// previous state (if any).
|
||||
pub fn reset_headers() {
|
||||
used_header_map.replace(Some(RefCell::new(HashMap::new())));
|
||||
test_idx.replace(Some(Cell::new(0)));
|
||||
}
|
||||
|
||||
impl<'a> fmt::Show for Markdown<'a> {
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ use rustc::util::nodemap::NodeSet;
|
|||
use clean;
|
||||
use doctree;
|
||||
use fold::DocFolder;
|
||||
use html::format::{VisSpace, Method, FnStyleSpace};
|
||||
use html::format::{VisSpace, Method, FnStyleSpace, MutableSpace};
|
||||
use html::highlight;
|
||||
use html::item_type::{ItemType, shortty};
|
||||
use html::item_type;
|
||||
|
|
@ -230,6 +230,7 @@ pub fn run(mut krate: clean::Crate, dst: Path) -> io::IoResult<()> {
|
|||
logo: "".to_string(),
|
||||
favicon: "".to_string(),
|
||||
krate: krate.name.clone(),
|
||||
playground_url: "".to_string(),
|
||||
},
|
||||
include_sources: true,
|
||||
render_redirect_pages: false,
|
||||
|
|
@ -250,6 +251,14 @@ pub fn run(mut krate: clean::Crate, dst: Path) -> io::IoResult<()> {
|
|||
if "html_logo_url" == x.as_slice() => {
|
||||
cx.layout.logo = s.to_string();
|
||||
}
|
||||
clean::NameValue(ref x, ref s)
|
||||
if "html_playground_url" == x.as_slice() => {
|
||||
cx.layout.playground_url = s.to_string();
|
||||
let name = krate.name.clone();
|
||||
if markdown::playground_krate.get().is_none() {
|
||||
markdown::playground_krate.replace(Some(Some(name)));
|
||||
}
|
||||
}
|
||||
clean::Word(ref x)
|
||||
if "html_no_source" == x.as_slice() => {
|
||||
cx.include_sources = false;
|
||||
|
|
@ -450,6 +459,7 @@ fn write_shared(cx: &Context,
|
|||
try!(write(cx.dst.join("jquery.js"),
|
||||
include_bin!("static/jquery-2.1.0.min.js")));
|
||||
try!(write(cx.dst.join("main.js"), include_bin!("static/main.js")));
|
||||
try!(write(cx.dst.join("playpen.js"), include_bin!("static/playpen.js")));
|
||||
try!(write(cx.dst.join("main.css"), include_bin!("static/main.css")));
|
||||
try!(write(cx.dst.join("normalize.css"),
|
||||
include_bin!("static/normalize.css")));
|
||||
|
|
@ -1441,11 +1451,12 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
|
|||
|
||||
try!(write!(w, "
|
||||
<tr>
|
||||
<td><code>{}static {}: {}</code>{}</td>
|
||||
<td><code>{}static {}{}: {}</code>{}</td>
|
||||
<td class='docblock'>{} </td>
|
||||
</tr>
|
||||
",
|
||||
VisSpace(myitem.visibility),
|
||||
MutableSpace(s.mutability),
|
||||
*myitem.name.get_ref(),
|
||||
s.type_,
|
||||
Initializer(s.expr.as_slice(), Item { cx: cx, item: myitem }),
|
||||
|
|
@ -2042,7 +2053,7 @@ fn build_sidebar(m: &clean::Module) -> HashMap<String, Vec<String>> {
|
|||
impl<'a> fmt::Show for Source<'a> {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
let Source(s) = *self;
|
||||
let lines = s.lines().len();
|
||||
let lines = s.lines().count();
|
||||
let mut cols = 0;
|
||||
let mut tmp = lines;
|
||||
while tmp > 0 {
|
||||
|
|
@ -2054,14 +2065,15 @@ impl<'a> fmt::Show for Source<'a> {
|
|||
try!(write!(fmt, "<span id='{0:u}'>{0:1$u}</span>\n", i, cols));
|
||||
}
|
||||
try!(write!(fmt, "</pre>"));
|
||||
try!(write!(fmt, "{}", highlight::highlight(s.as_slice(), None)));
|
||||
try!(write!(fmt, "{}", highlight::highlight(s.as_slice(), None, None)));
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn item_macro(w: &mut fmt::Formatter, it: &clean::Item,
|
||||
t: &clean::Macro) -> fmt::Result {
|
||||
try!(w.write(highlight::highlight(t.source.as_slice(), Some("macro")).as_bytes()));
|
||||
try!(w.write(highlight::highlight(t.source.as_slice(), Some("macro"),
|
||||
None).as_bytes()));
|
||||
document(w, it)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -156,7 +156,7 @@ nav.sub {
|
|||
padding: 0 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.block h2 {
|
||||
.block h2 {
|
||||
margin-top: 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
|
@ -396,6 +396,17 @@ pre.rust .doccomment { color: #4D4D4C; }
|
|||
pre.rust .macro, pre.rust .macro-nonterminal { color: #3E999F; }
|
||||
pre.rust .lifetime { color: #B76514; }
|
||||
|
||||
.rusttest { display: none; }
|
||||
pre.rust { position: relative; }
|
||||
pre.rust a { transform: scaleX(-1); }
|
||||
.test-arrow {
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 10px;
|
||||
font-size: 150%;
|
||||
}
|
||||
|
||||
.methods .section-header {
|
||||
/* Override parent class attributes. */
|
||||
border-bottom: none !important;
|
||||
|
|
|
|||
|
|
@ -678,7 +678,7 @@
|
|||
window.register_implementors(window.pending_implementors);
|
||||
}
|
||||
|
||||
// See documentaiton in html/render.rs for what this is doing.
|
||||
// See documentation in html/render.rs for what this is doing.
|
||||
var query = getQueryStringParams();
|
||||
if (query['gotosrc']) {
|
||||
window.location = $('#src-' + query['gotosrc']).attr('href');
|
||||
|
|
|
|||
29
src/librustdoc/html/static/playpen.js
Normal file
29
src/librustdoc/html/static/playpen.js
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
/*jslint browser: true, es5: true */
|
||||
/*globals $: true, rootPath: true */
|
||||
|
||||
(function() {
|
||||
if (window.playgroundUrl) {
|
||||
$('pre.rust').hover(function() {
|
||||
var id = '#' + $(this).attr('id').replace('rendered', 'raw');
|
||||
var a = $('<a>').text('⇱').attr('class', 'test-arrow');
|
||||
var code = $(id).text();
|
||||
a.attr('href', window.playgroundUrl + '?code=' +
|
||||
encodeURIComponent(code));
|
||||
a.attr('target', '_blank');
|
||||
$(this).append(a);
|
||||
}, function() {
|
||||
$(this).find('a').remove();
|
||||
});
|
||||
}
|
||||
}());
|
||||
|
||||
|
|
@ -32,7 +32,7 @@ pub struct Toc {
|
|||
|
||||
impl Toc {
|
||||
fn count_entries_with_level(&self, level: u32) -> uint {
|
||||
self.entries.iter().count(|e| e.level == level)
|
||||
self.entries.iter().filter(|e| e.level == level).count()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -126,7 +126,9 @@ pub fn opts() -> Vec<getopts::OptGroup> {
|
|||
optmulti("", "markdown-after-content",
|
||||
"files to include inline between the content and </body> of a rendered \
|
||||
Markdown file",
|
||||
"FILES")
|
||||
"FILES"),
|
||||
optopt("", "markdown-playground-url",
|
||||
"URL to send code snippets to", "URL")
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ use getopts;
|
|||
use testing;
|
||||
|
||||
use html::escape::Escape;
|
||||
use html::markdown;
|
||||
use html::markdown::{MarkdownWithToc, find_testable_code, reset_headers};
|
||||
use test::Collector;
|
||||
|
||||
|
|
@ -84,6 +85,11 @@ pub fn render(input: &str, mut output: Path, matches: &getopts::Matches) -> int
|
|||
}
|
||||
|
||||
let input_str = load_or_return!(input, 1, 2);
|
||||
let playground = matches.opt_str("markdown-playground-url");
|
||||
if playground.is_some() {
|
||||
markdown::playground_krate.replace(Some(None));
|
||||
}
|
||||
let playground = playground.unwrap_or("".to_string());
|
||||
|
||||
let (in_header, before_content, after_content) =
|
||||
match (load_external_files(matches.opt_strs("markdown-in-header")
|
||||
|
|
@ -148,6 +154,9 @@ pub fn render(input: &str, mut output: Path, matches: &getopts::Matches) -> int
|
|||
{before_content}
|
||||
<h1 class="title">{title}</h1>
|
||||
{text}
|
||||
<script type="text/javascript">
|
||||
window.playgroundUrl = "{playground}";
|
||||
</script>
|
||||
{after_content}
|
||||
</body>
|
||||
</html>"#,
|
||||
|
|
@ -156,7 +165,9 @@ pub fn render(input: &str, mut output: Path, matches: &getopts::Matches) -> int
|
|||
in_header = in_header,
|
||||
before_content = before_content,
|
||||
text = MarkdownWithToc(text),
|
||||
after_content = after_content);
|
||||
after_content = after_content,
|
||||
playground = playground,
|
||||
);
|
||||
|
||||
match err {
|
||||
Err(e) => {
|
||||
|
|
@ -173,7 +184,7 @@ pub fn render(input: &str, mut output: Path, matches: &getopts::Matches) -> int
|
|||
pub fn test(input: &str, libs: HashSet<Path>, mut test_args: Vec<String>) -> int {
|
||||
let input_str = load_or_return!(input, 1, 2);
|
||||
|
||||
let mut collector = Collector::new(input.to_string(), libs, true, true);
|
||||
let mut collector = Collector::new(input.to_string(), libs, true);
|
||||
find_testable_code(input_str.as_slice(), &mut collector);
|
||||
test_args.unshift("rustdoctest".to_string());
|
||||
testing::test_main(test_args.as_slice(), collector.tests);
|
||||
|
|
|
|||
|
|
@ -91,7 +91,6 @@ pub fn run(input: &str,
|
|||
|
||||
let mut collector = Collector::new(krate.name.to_string(),
|
||||
libs,
|
||||
false,
|
||||
false);
|
||||
collector.fold_crate(krate);
|
||||
|
||||
|
|
@ -103,8 +102,8 @@ pub fn run(input: &str,
|
|||
}
|
||||
|
||||
fn runtest(test: &str, cratename: &str, libs: HashSet<Path>, should_fail: bool,
|
||||
no_run: bool, loose_feature_gating: bool) {
|
||||
let test = maketest(test, cratename, loose_feature_gating);
|
||||
no_run: bool) {
|
||||
let test = maketest(test, Some(cratename), true);
|
||||
let input = driver::StrInput(test.to_string());
|
||||
|
||||
let sessopts = config::Options {
|
||||
|
|
@ -201,29 +200,31 @@ fn runtest(test: &str, cratename: &str, libs: HashSet<Path>, should_fail: bool,
|
|||
}
|
||||
}
|
||||
|
||||
fn maketest(s: &str, cratename: &str, loose_feature_gating: bool) -> String {
|
||||
let mut prog = String::from_str(r"
|
||||
pub fn maketest(s: &str, cratename: Option<&str>, lints: bool) -> String {
|
||||
let mut prog = String::new();
|
||||
if lints {
|
||||
prog.push_str(r"
|
||||
#![deny(warnings)]
|
||||
#![allow(unused_variable, dead_assignment, unused_mut, attribute_usage, dead_code)]
|
||||
");
|
||||
|
||||
if loose_feature_gating {
|
||||
// FIXME #12773: avoid inserting these when the tutorial & manual
|
||||
// etc. have been updated to not use them so prolifically.
|
||||
prog.push_str("#![feature(macro_rules, globs, struct_variant, managed_boxes) ]\n");
|
||||
}
|
||||
|
||||
if !s.contains("extern crate") {
|
||||
if s.contains(cratename) {
|
||||
prog.push_str(format!("extern crate {};\n",
|
||||
cratename).as_slice());
|
||||
match cratename {
|
||||
Some(cratename) => {
|
||||
if s.contains(cratename) {
|
||||
prog.push_str(format!("extern crate {};\n",
|
||||
cratename).as_slice());
|
||||
}
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
if s.contains("fn main") {
|
||||
prog.push_str(s);
|
||||
} else {
|
||||
prog.push_str("fn main() {\n");
|
||||
prog.push_str(s);
|
||||
prog.push_str("fn main() {\n ");
|
||||
prog.push_str(s.replace("\n", "\n ").as_slice());
|
||||
prog.push_str("\n}");
|
||||
}
|
||||
|
||||
|
|
@ -238,13 +239,11 @@ pub struct Collector {
|
|||
use_headers: bool,
|
||||
current_header: Option<String>,
|
||||
cratename: String,
|
||||
|
||||
loose_feature_gating: bool
|
||||
}
|
||||
|
||||
impl Collector {
|
||||
pub fn new(cratename: String, libs: HashSet<Path>,
|
||||
use_headers: bool, loose_feature_gating: bool) -> Collector {
|
||||
use_headers: bool) -> Collector {
|
||||
Collector {
|
||||
tests: Vec::new(),
|
||||
names: Vec::new(),
|
||||
|
|
@ -253,8 +252,6 @@ impl Collector {
|
|||
use_headers: use_headers,
|
||||
current_header: None,
|
||||
cratename: cratename,
|
||||
|
||||
loose_feature_gating: loose_feature_gating
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -268,7 +265,6 @@ impl Collector {
|
|||
self.cnt += 1;
|
||||
let libs = self.libs.clone();
|
||||
let cratename = self.cratename.to_string();
|
||||
let loose_feature_gating = self.loose_feature_gating;
|
||||
debug!("Creating test {}: {}", name, test);
|
||||
self.tests.push(testing::TestDescAndFn {
|
||||
desc: testing::TestDesc {
|
||||
|
|
@ -281,8 +277,7 @@ impl Collector {
|
|||
cratename.as_slice(),
|
||||
libs,
|
||||
should_fail,
|
||||
no_run,
|
||||
loose_feature_gating);
|
||||
no_run);
|
||||
}),
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,8 @@ Core encoding and decoding interfaces.
|
|||
#![license = "MIT/ASL2"]
|
||||
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
|
||||
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
|
||||
html_root_url = "http://doc.rust-lang.org/")]
|
||||
html_root_url = "http://doc.rust-lang.org/",
|
||||
html_playground_url = "http://play.rust-lang.org/")]
|
||||
#![feature(macro_rules, managed_boxes, default_type_params, phase)]
|
||||
|
||||
// test harness access
|
||||
|
|
|
|||
|
|
@ -684,8 +684,8 @@ impl DefaultResizePolicy {
|
|||
/// denial-of-service attacks (Hash DoS). This behaviour can be
|
||||
/// overridden with one of the constructors.
|
||||
///
|
||||
/// It is required that the keys implement the `PartialEq` and `Hash` traits, although
|
||||
/// this can frequently be achieved by using `#[deriving(PartialEq, Hash)]`.
|
||||
/// It is required that the keys implement the `Eq` and `Hash` traits, although
|
||||
/// this can frequently be achieved by using `#[deriving(Eq, Hash)]`.
|
||||
///
|
||||
/// Relevant papers/articles:
|
||||
///
|
||||
|
|
@ -1422,6 +1422,8 @@ impl<K: Eq + Hash<S>, V: PartialEq, S, H: Hasher<S>> PartialEq for HashMap<K, V,
|
|||
}
|
||||
}
|
||||
|
||||
impl<K: Eq + Hash<S>, V: Eq, S, H: Hasher<S>> Eq for HashMap<K, V, H> {}
|
||||
|
||||
impl<K: Eq + Hash<S> + Show, V: Show, S, H: Hasher<S>> Show for HashMap<K, V, H> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
try!(write!(f, r"\{"));
|
||||
|
|
@ -1486,7 +1488,7 @@ pub type SetMoveItems<K> =
|
|||
|
||||
/// An implementation of a hash set using the underlying representation of a
|
||||
/// HashMap where the value is (). As with the `HashMap` type, a `HashSet`
|
||||
/// requires that the elements implement the `PartialEq` and `Hash` traits.
|
||||
/// requires that the elements implement the `Eq` and `Hash` traits.
|
||||
#[deriving(Clone)]
|
||||
pub struct HashSet<T, H = sip::SipHasher> {
|
||||
map: HashMap<T, (), H>
|
||||
|
|
@ -1500,6 +1502,8 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> PartialEq for HashSet<T, H> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T: Eq + Hash<S>, S, H: Hasher<S>> Eq for HashSet<T, H> {}
|
||||
|
||||
impl<T: Eq + Hash<S>, S, H: Hasher<S>> Container for HashSet<T, H> {
|
||||
fn len(&self) -> uint { self.map.len() }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -101,7 +101,8 @@
|
|||
#![crate_type = "dylib"]
|
||||
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
|
||||
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
|
||||
html_root_url = "http://doc.rust-lang.org/")]
|
||||
html_root_url = "http://doc.rust-lang.org/",
|
||||
html_playground_url = "http://play.rust-lang.org/")]
|
||||
#![feature(macro_rules, globs, asm, managed_boxes, thread_local, link_args,
|
||||
linkage, default_type_params, phase, concat_idents, quad_precision_float)]
|
||||
|
||||
|
|
|
|||
|
|
@ -212,7 +212,7 @@ macro_rules! unimplemented(
|
|||
() => (fail!("not yet implemented"))
|
||||
)
|
||||
|
||||
/// Use the syntax described in `std::fmt` to create a value of type `~str`.
|
||||
/// Use the syntax described in `std::fmt` to create a value of type `String`.
|
||||
/// See `std::fmt` for more information.
|
||||
///
|
||||
/// # Example
|
||||
|
|
@ -465,7 +465,7 @@ pub mod builtin {
|
|||
/// ```
|
||||
/// let rust = bytes!("r", 'u', "st", 255);
|
||||
/// assert_eq!(rust[1], 'u' as u8);
|
||||
/// assert_eq!(rust[5], 255);
|
||||
/// assert_eq!(rust[4], 255);
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! bytes( ($($e:expr),*) => ({ /* compiler built-in */ }) )
|
||||
|
|
@ -482,10 +482,14 @@ pub mod builtin {
|
|||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(concat_idents)]
|
||||
///
|
||||
/// # fn main() {
|
||||
/// fn foobar() -> int { 23 }
|
||||
///
|
||||
/// let f = concat_idents!(foo, bar);
|
||||
/// println!("{}", f());
|
||||
/// # }
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! concat_idents( ($($e:ident),*) => ({ /* compiler built-in */ }) )
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@
|
|||
use char;
|
||||
use clone::Clone;
|
||||
use container::Container;
|
||||
use iter::Iterator;
|
||||
use num::{NumCast, Zero, One, cast, Int};
|
||||
use num::{Float, FPNaN, FPInfinite, ToPrimitive};
|
||||
use num;
|
||||
|
|
|
|||
|
|
@ -56,12 +56,6 @@ use libc::c_char;
|
|||
#[cfg(windows)]
|
||||
use str::OwnedStr;
|
||||
|
||||
/// Delegates to the libc close() function, returning the same return value.
|
||||
pub fn close(fd: int) -> int {
|
||||
unsafe {
|
||||
libc::close(fd as c_int) as int
|
||||
}
|
||||
}
|
||||
|
||||
pub static TMPBUF_SZ : uint = 1000u;
|
||||
static BUF_BYTES : uint = 2048u;
|
||||
|
|
|
|||
|
|
@ -353,17 +353,17 @@ mod test {
|
|||
#[test]
|
||||
fn test_gen_ascii_str() {
|
||||
let mut r = task_rng();
|
||||
assert_eq!(r.gen_ascii_chars().take(0).len(), 0u);
|
||||
assert_eq!(r.gen_ascii_chars().take(10).len(), 10u);
|
||||
assert_eq!(r.gen_ascii_chars().take(16).len(), 16u);
|
||||
assert_eq!(r.gen_ascii_chars().take(0).count(), 0u);
|
||||
assert_eq!(r.gen_ascii_chars().take(10).count(), 10u);
|
||||
assert_eq!(r.gen_ascii_chars().take(16).count(), 16u);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_gen_vec() {
|
||||
let mut r = task_rng();
|
||||
assert_eq!(r.gen_iter::<u8>().take(0).len(), 0u);
|
||||
assert_eq!(r.gen_iter::<u8>().take(10).len(), 10u);
|
||||
assert_eq!(r.gen_iter::<f64>().take(16).len(), 16u);
|
||||
assert_eq!(r.gen_iter::<u8>().take(0).count(), 0u);
|
||||
assert_eq!(r.gen_iter::<u8>().take(10).count(), 10u);
|
||||
assert_eq!(r.gen_iter::<f64>().take(16).count(), 16u);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ fn demangle(writer: &mut Writer, s: &str) -> IoResult<()> {
|
|||
if i == 0 {
|
||||
valid = chars.next().is_none();
|
||||
break
|
||||
} else if chars.by_ref().take(i - 1).len() != i - 1 {
|
||||
} else if chars.by_ref().take(i - 1).count() != i - 1 {
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
|
|
@ -505,7 +505,6 @@ mod imp {
|
|||
use c_str::CString;
|
||||
use container::Container;
|
||||
use io::{IoResult, Writer};
|
||||
use iter::Iterator;
|
||||
use libc;
|
||||
use mem;
|
||||
use ops::Drop;
|
||||
|
|
|
|||
|
|
@ -18,7 +18,8 @@
|
|||
#![license = "MIT/ASL2"]
|
||||
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
|
||||
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
|
||||
html_root_url = "http://doc.rust-lang.org/")]
|
||||
html_root_url = "http://doc.rust-lang.org/",
|
||||
html_playground_url = "http://play.rust-lang.org/")]
|
||||
#![feature(phase)]
|
||||
#![deny(deprecated_owned_vector)]
|
||||
|
||||
|
|
|
|||
|
|
@ -45,7 +45,8 @@
|
|||
#![crate_type = "dylib"]
|
||||
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
|
||||
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
|
||||
html_root_url = "http://doc.rust-lang.org/")]
|
||||
html_root_url = "http://doc.rust-lang.org/",
|
||||
html_playground_url = "http://play.rust-lang.org/")]
|
||||
|
||||
#![feature(macro_rules, phase)]
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,8 @@
|
|||
#![license = "MIT/ASL2"]
|
||||
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
|
||||
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
|
||||
html_root_url = "http://doc.rust-lang.org/")]
|
||||
html_root_url = "http://doc.rust-lang.org/",
|
||||
html_playground_url = "http://play.rust-lang.org/")]
|
||||
#![feature(phase)]
|
||||
#![deny(deprecated_owned_vector)]
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,8 @@
|
|||
#![license = "MIT/ASL2"]
|
||||
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
|
||||
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
|
||||
html_root_url = "http://doc.rust-lang.org/")]
|
||||
html_root_url = "http://doc.rust-lang.org/",
|
||||
html_playground_url = "http://play.rust-lang.org/")]
|
||||
#![feature(default_type_params)]
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
|
@ -161,10 +162,10 @@ fn encode_inner(s: &str, full_url: bool) -> String {
|
|||
out.push_char(ch);
|
||||
}
|
||||
|
||||
_ => out.push_str(format!("%{:X}", ch as uint).as_slice())
|
||||
_ => out.push_str(format!("%{:02X}", ch as uint).as_slice())
|
||||
}
|
||||
} else {
|
||||
out.push_str(format!("%{:X}", ch as uint).as_slice());
|
||||
out.push_str(format!("%{:02X}", ch as uint).as_slice());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1178,6 +1179,8 @@ mod tests {
|
|||
assert_eq!(encode("@"), "@".to_string());
|
||||
assert_eq!(encode("["), "[".to_string());
|
||||
assert_eq!(encode("]"), "]".to_string());
|
||||
assert_eq!(encode("\0"), "%00".to_string());
|
||||
assert_eq!(encode("\n"), "%0A".to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -1207,6 +1210,8 @@ mod tests {
|
|||
assert_eq!(encode_component("@"), "%40".to_string());
|
||||
assert_eq!(encode_component("["), "%5B".to_string());
|
||||
assert_eq!(encode_component("]"), "%5D".to_string());
|
||||
assert_eq!(encode_component("\0"), "%00".to_string());
|
||||
assert_eq!(encode_component("\n"), "%0A".to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
|
|
@ -60,7 +60,8 @@ Examples of string representations:
|
|||
#![license = "MIT/ASL2"]
|
||||
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
|
||||
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
|
||||
html_root_url = "http://doc.rust-lang.org/")]
|
||||
html_root_url = "http://doc.rust-lang.org/",
|
||||
html_playground_url = "http://play.rust-lang.org/")]
|
||||
|
||||
#![feature(default_type_params)]
|
||||
|
||||
|
|
|
|||
14
src/test/run-make/issue-14500/Makefile
Normal file
14
src/test/run-make/issue-14500/Makefile
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
-include ../tools.mk
|
||||
|
||||
# Test to make sure that reachable extern fns are always available in final
|
||||
# productcs, including when LTO is used. In this test, the `foo` crate has a
|
||||
# reahable symbol, and is a dependency of the `bar` crate. When the `bar` crate
|
||||
# is compiled with LTO, it shouldn't strip the symbol from `foo`, and that's the
|
||||
# only way that `foo.c` will successfully compile.
|
||||
|
||||
all:
|
||||
$(RUSTC) foo.rs --crate-type=rlib
|
||||
$(RUSTC) bar.rs --crate-type=staticlib -Zlto -L. -o $(TMPDIR)/libbar.a
|
||||
$(CC) foo.c -lbar -o $(call RUN_BINFILE,foo) $(EXTRACFLAGS)
|
||||
$(call RUN,foo)
|
||||
|
||||
11
src/test/run-make/issue-14500/bar.rs
Normal file
11
src/test/run-make/issue-14500/bar.rs
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
extern crate foo;
|
||||
16
src/test/run-make/issue-14500/foo.c
Normal file
16
src/test/run-make/issue-14500/foo.c
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
extern void foo();
|
||||
|
||||
int main() {
|
||||
foo();
|
||||
return 0;
|
||||
}
|
||||
12
src/test/run-make/issue-14500/foo.rs
Normal file
12
src/test/run-make/issue-14500/foo.rs
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#[no_mangle]
|
||||
pub extern fn foo() {}
|
||||
|
|
@ -1,23 +1,10 @@
|
|||
-include ../tools.mk
|
||||
|
||||
ifdef IS_WINDOWS
|
||||
EXTRAFLAGS :=
|
||||
else
|
||||
ifeq ($(shell uname),Darwin)
|
||||
else
|
||||
ifeq ($(shell uname),FreeBSD)
|
||||
EXTRAFLAGS := -lm -lpthread -lgcc_s
|
||||
else
|
||||
EXTRAFLAGS := -lm -lrt -ldl -lpthread
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
# Apparently older versions of GCC segfault if -g is passed...
|
||||
CC := $(CC:-g=)
|
||||
|
||||
all:
|
||||
$(RUSTC) foo.rs -Z lto
|
||||
ln -s $(call STATICLIB,foo-*) $(call STATICLIB,foo)
|
||||
$(CC) bar.c -lfoo -o $(call RUN_BINFILE,bar) $(EXTRAFLAGS) -lstdc++
|
||||
$(CC) bar.c -lfoo -o $(call RUN_BINFILE,bar) $(EXTRACFLAGS) -lstdc++
|
||||
$(call RUN,bar)
|
||||
|
|
|
|||
|
|
@ -53,6 +53,20 @@ RPATH_LINK_SEARCH = -Wl,-rpath-link=$(1)
|
|||
endif
|
||||
endif
|
||||
|
||||
# Extra flags needed to compile a working executable with the standard library
|
||||
ifdef IS_WINDOWS
|
||||
EXTRACFLAGS :=
|
||||
else
|
||||
ifeq ($(shell uname),Darwin)
|
||||
else
|
||||
ifeq ($(shell uname),FreeBSD)
|
||||
EXTRACFLAGS := -lm -lpthread -lgcc_s
|
||||
else
|
||||
EXTRACFLAGS := -lm -lrt -ldl -lpthread
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
REMOVE_DYLIBS = rm $(TMPDIR)/$(call DYLIB_GLOB,$(1))
|
||||
REMOVE_RLIBS = rm $(TMPDIR)/$(call RLIB_GLOB,$(1))
|
||||
|
||||
|
|
|
|||
30
src/test/run-pass/issue-11612.rs
Normal file
30
src/test/run-pass/issue-11612.rs
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// #11612
|
||||
// We weren't updating the auto adjustments with all the resolved
|
||||
// type information after type check.
|
||||
|
||||
trait A {}
|
||||
|
||||
struct B<'a, T> {
|
||||
f: &'a T
|
||||
}
|
||||
|
||||
impl<'a, T> A for B<'a, T> {}
|
||||
|
||||
fn foo(_: &A) {}
|
||||
|
||||
fn bar<G>(b: &B<G>) {
|
||||
foo(b); // Coercion should work
|
||||
foo(b as &A); // Explicit cast should work as well
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -14,7 +14,7 @@
|
|||
pub trait Foo {
|
||||
fn bar<'a, I: Iterator<&'a ()>>(&self, it: I) -> uint {
|
||||
let mut xs = it.filter(|_| true);
|
||||
xs.len()
|
||||
xs.count()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
35
src/test/run-pass/issue-8460.rs
Normal file
35
src/test/run-pass/issue-8460.rs
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use std::{int, i8, i16, i32, i64};
|
||||
use std::task;
|
||||
|
||||
fn main() {
|
||||
assert!(task::try(proc() int::MIN / -1).is_err());
|
||||
assert!(task::try(proc() i8::MIN / -1).is_err());
|
||||
assert!(task::try(proc() i16::MIN / -1).is_err());
|
||||
assert!(task::try(proc() i32::MIN / -1).is_err());
|
||||
assert!(task::try(proc() i64::MIN / -1).is_err());
|
||||
assert!(task::try(proc() 1i / 0).is_err());
|
||||
assert!(task::try(proc() 1i8 / 0).is_err());
|
||||
assert!(task::try(proc() 1i16 / 0).is_err());
|
||||
assert!(task::try(proc() 1i32 / 0).is_err());
|
||||
assert!(task::try(proc() 1i64 / 0).is_err());
|
||||
assert!(task::try(proc() int::MIN % -1).is_err());
|
||||
assert!(task::try(proc() i8::MIN % -1).is_err());
|
||||
assert!(task::try(proc() i16::MIN % -1).is_err());
|
||||
assert!(task::try(proc() i32::MIN % -1).is_err());
|
||||
assert!(task::try(proc() i64::MIN % -1).is_err());
|
||||
assert!(task::try(proc() 1i % 0).is_err());
|
||||
assert!(task::try(proc() 1i8 % 0).is_err());
|
||||
assert!(task::try(proc() 1i16 % 0).is_err());
|
||||
assert!(task::try(proc() 1i32 % 0).is_err());
|
||||
assert!(task::try(proc() 1i64 % 0).is_err());
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue