mirror of
https://github.com/rust-lang/rust.git
synced 2024-12-26 07:25:48 +00:00
commit
f1bb6c2f46
@ -129,21 +129,21 @@ doc/:
|
||||
HTML_DEPS += doc/rust.css
|
||||
doc/rust.css: $(D)/rust.css | doc/
|
||||
@$(call E, cp: $@)
|
||||
$(Q)cp -a $< $@ 2> /dev/null
|
||||
$(Q)cp -PRp $< $@ 2> /dev/null
|
||||
|
||||
HTML_DEPS += doc/favicon.inc
|
||||
doc/favicon.inc: $(D)/favicon.inc | doc/
|
||||
@$(call E, cp: $@)
|
||||
$(Q)cp -a $< $@ 2> /dev/null
|
||||
$(Q)cp -PRp $< $@ 2> /dev/null
|
||||
|
||||
doc/full-toc.inc: $(D)/full-toc.inc | doc/
|
||||
@$(call E, cp: $@)
|
||||
$(Q)cp -a $< $@ 2> /dev/null
|
||||
$(Q)cp -PRp $< $@ 2> /dev/null
|
||||
|
||||
HTML_DEPS += doc/footer.inc
|
||||
doc/footer.inc: $(D)/footer.inc | doc/
|
||||
@$(call E, cp: $@)
|
||||
$(Q)cp -a $< $@ 2> /dev/null
|
||||
$(Q)cp -PRp $< $@ 2> /dev/null
|
||||
|
||||
# The (english) documentation for each doc item.
|
||||
|
||||
|
10
mk/tests.mk
10
mk/tests.mk
@ -38,16 +38,11 @@ ifdef CHECK_IGNORED
|
||||
TESTARGS += --ignored
|
||||
endif
|
||||
|
||||
|
||||
# Arguments to the cfail/rfail/rpass/bench tests
|
||||
ifdef CFG_VALGRIND
|
||||
CTEST_RUNTOOL = --runtool "$(CFG_VALGRIND)"
|
||||
endif
|
||||
|
||||
ifdef PLEASE_BENCH
|
||||
TESTARGS += --bench
|
||||
endif
|
||||
|
||||
# Arguments to the perf tests
|
||||
ifdef CFG_PERF_TOOL
|
||||
CTEST_PERF_RUNTOOL = --runtool "$(CFG_PERF_TOOL)"
|
||||
@ -55,6 +50,11 @@ endif
|
||||
|
||||
CTEST_TESTARGS := $(TESTARGS)
|
||||
|
||||
# --bench is only relevant for crate tests, not for the compile tests
|
||||
ifdef PLEASE_BENCH
|
||||
TESTARGS += --bench
|
||||
endif
|
||||
|
||||
ifdef VERBOSE
|
||||
CTEST_TESTARGS += --verbose
|
||||
endif
|
||||
|
@ -648,7 +648,7 @@ All of the above extensions are expressions with values.
|
||||
|
||||
Users of `rustc` can define new syntax extensions in two ways:
|
||||
|
||||
* [Compiler plugins](book/syntax-extensions.html) can include arbitrary
|
||||
* [Compiler plugins][plugin] can include arbitrary
|
||||
Rust code that manipulates syntax trees at compile time.
|
||||
|
||||
* [Macros](book/macros.html) define new syntax in a higher-level,
|
||||
@ -818,9 +818,8 @@ item : extern_crate_decl | use_decl | mod_item | fn_item | type_item
|
||||
| extern_block ;
|
||||
```
|
||||
|
||||
An _item_ is a component of a crate; some module items can be defined in crate
|
||||
files, but most are defined in source files. Items are organized within a crate
|
||||
by a nested set of [modules](#modules). Every crate has a single "outermost"
|
||||
An _item_ is a component of a crate. Items are organized within a crate by a
|
||||
nested set of [modules](#modules). Every crate has a single "outermost"
|
||||
anonymous module; all further items within the crate have [paths](#paths)
|
||||
within the module tree of the crate.
|
||||
|
||||
|
@ -37,3 +37,4 @@
|
||||
* [Macros](macros.md)
|
||||
* [Compiler Plugins](plugins.md)
|
||||
* [Conclusion](conclusion.md)
|
||||
* [Glossary](glossary.md)
|
||||
|
@ -47,7 +47,8 @@ This pattern is very powerful, and we'll see it repeated more later.
|
||||
|
||||
There are also a few things you can do with a tuple as a whole, without
|
||||
destructuring. You can assign one tuple into another, if they have the same
|
||||
arity and contained types.
|
||||
contained types and arity. Tuples have the same arity when they have the same
|
||||
length.
|
||||
|
||||
```rust
|
||||
let mut x = (1, 2); // x: (i32, i32)
|
||||
|
16
src/doc/trpl/glossary.md
Normal file
16
src/doc/trpl/glossary.md
Normal file
@ -0,0 +1,16 @@
|
||||
% Glossary
|
||||
|
||||
Not every Rustacean has a background in systems programming, nor in computer
|
||||
science, so we've added explanations of terms that might be unfamiliar.
|
||||
|
||||
### Arity
|
||||
|
||||
Arity refers to the number of arguments a function or operation takes.
|
||||
|
||||
```rust
|
||||
let x = (2, 3);
|
||||
let y = (4, 6);
|
||||
let z = (8, 2, 6);
|
||||
```
|
||||
|
||||
In the example above `x` and `y` have arity 2. `z` has arity 3.
|
@ -89,7 +89,7 @@ This line does all of the work in our little program. There are a number of
|
||||
details that are important here. The first is that it's indented with four
|
||||
spaces, not tabs. Please configure your editor of choice to insert four spaces
|
||||
with the tab key. We provide some [sample configurations for various
|
||||
editors](https://github.com/rust-lang/rust/tree/master/src/etc).
|
||||
editors](https://github.com/rust-lang/rust/tree/master/src/etc/CONFIGS.md).
|
||||
|
||||
The second point is the `println!()` part. This is calling a Rust *macro*,
|
||||
which is how metaprogramming is done in Rust. If it were a function instead, it
|
||||
|
@ -39,6 +39,16 @@ If present, arguments passed as `#![plugin(foo(... args ...))]` are not
|
||||
interpreted by rustc itself. They are provided to the plugin through the
|
||||
`Registry`'s [`args` method](../rustc/plugin/registry/struct.Registry.html#method.args).
|
||||
|
||||
In the vast majority of cases, a plugin should *only* be used through
|
||||
`#![plugin]` and not through an `extern crate` item. Linking a plugin would
|
||||
pull in all of libsyntax and librustc as dependencies of your crate. This is
|
||||
generally unwanted unless you are building another plugin. The
|
||||
`plugin_as_library` lint checks these guidelines.
|
||||
|
||||
The usual practice is to put compiler plugins in their own crate, separate from
|
||||
any `macro_rules!` macros or ordinary Rust code meant to be used by consumers
|
||||
of a library.
|
||||
|
||||
# Syntax extensions
|
||||
|
||||
Plugins can extend Rust's syntax in various ways. One kind of syntax extension
|
||||
|
@ -40,6 +40,11 @@ let x: i32 = 5;
|
||||
If I asked you to read this out loud to the rest of the class, you'd say "`x`
|
||||
is a binding with the type `i32` and the value `five`."
|
||||
|
||||
In this case we chose to represent `x` as a 32-bit signed integer. Rust has
|
||||
many different primitive integer types. They begin with `i` for signed integers
|
||||
and `u` for unsigned integers. The possible integer sizes are 8, 16, 32, and 64
|
||||
bits.
|
||||
|
||||
In future examples, we may annotate the type in a comment. The examples will
|
||||
look like this:
|
||||
|
||||
|
10
src/etc/CONFIGS.md
Normal file
10
src/etc/CONFIGS.md
Normal file
@ -0,0 +1,10 @@
|
||||
# Configs
|
||||
|
||||
Here are some links to repos with configs which ease the use of rust:
|
||||
|
||||
* [rust.vim](https://github.com/rust-lang/rust.vim)
|
||||
* [emacs rust-mode](https://github.com/rust-lang/rust-mode)
|
||||
* [gedit-config](https://github.com/rust-lang/gedit-config)
|
||||
* [kate-config](https://github.com/rust-lang/kate-config)
|
||||
* [nano-config](https://github.com/rust-lang/nano-config)
|
||||
* [zsh-config](https://github.com/rust-lang/zsh-config)
|
@ -241,6 +241,9 @@ create_tmp_dir() {
|
||||
echo $TMP_DIR
|
||||
}
|
||||
|
||||
# Make `tr` locale independent
|
||||
LC_CTYPE=C
|
||||
|
||||
probe_need CFG_CURL curl
|
||||
probe_need CFG_TAR tar
|
||||
probe_need CFG_FILE file
|
||||
|
@ -655,6 +655,8 @@ impl<T: Ord> FromIterator<T> for BinaryHeap<T> {
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(stage0): remove impl after a snapshot
|
||||
#[cfg(stage0)]
|
||||
impl<T: Ord> IntoIterator for BinaryHeap<T> {
|
||||
type IntoIter = IntoIter<T>;
|
||||
|
||||
@ -663,6 +665,18 @@ impl<T: Ord> IntoIterator for BinaryHeap<T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
|
||||
impl<T: Ord> IntoIterator for BinaryHeap<T> {
|
||||
type Item = T;
|
||||
type IntoIter = IntoIter<T>;
|
||||
|
||||
fn into_iter(self) -> IntoIter<T> {
|
||||
self.into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(stage0): remove impl after a snapshot
|
||||
#[cfg(stage0)]
|
||||
impl<'a, T> IntoIterator for &'a BinaryHeap<T> where T: Ord {
|
||||
type IntoIter = Iter<'a, T>;
|
||||
|
||||
@ -671,6 +685,16 @@ impl<'a, T> IntoIterator for &'a BinaryHeap<T> where T: Ord {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
|
||||
impl<'a, T> IntoIterator for &'a BinaryHeap<T> where T: Ord {
|
||||
type Item = &'a T;
|
||||
type IntoIter = Iter<'a, T>;
|
||||
|
||||
fn into_iter(self) -> Iter<'a, T> {
|
||||
self.iter()
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: Ord> Extend<T> for BinaryHeap<T> {
|
||||
fn extend<Iter: Iterator<Item=T>>(&mut self, iter: Iter) {
|
||||
|
@ -1070,6 +1070,8 @@ impl<'a> RandomAccessIterator for Iter<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(stage0): remove impl after a snapshot
|
||||
#[cfg(stage0)]
|
||||
impl<'a> IntoIterator for &'a Bitv {
|
||||
type IntoIter = Iter<'a>;
|
||||
|
||||
@ -1078,6 +1080,16 @@ impl<'a> IntoIterator for &'a Bitv {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
|
||||
impl<'a> IntoIterator for &'a Bitv {
|
||||
type Item = bool;
|
||||
type IntoIter = Iter<'a>;
|
||||
|
||||
fn into_iter(self) -> Iter<'a> {
|
||||
self.iter()
|
||||
}
|
||||
}
|
||||
|
||||
/// An implementation of a set using a bit vector as an underlying
|
||||
/// representation for holding unsigned numerical elements.
|
||||
///
|
||||
@ -1882,6 +1894,8 @@ impl<'a> Iterator for SymmetricDifference<'a> {
|
||||
#[inline] fn size_hint(&self) -> (usize, Option<usize>) { self.0.size_hint() }
|
||||
}
|
||||
|
||||
// NOTE(stage0): remove impl after a snapshot
|
||||
#[cfg(stage0)]
|
||||
impl<'a> IntoIterator for &'a BitvSet {
|
||||
type IntoIter = SetIter<'a>;
|
||||
|
||||
@ -1890,6 +1904,16 @@ impl<'a> IntoIterator for &'a BitvSet {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
|
||||
impl<'a> IntoIterator for &'a BitvSet {
|
||||
type Item = usize;
|
||||
type IntoIter = SetIter<'a>;
|
||||
|
||||
fn into_iter(self) -> SetIter<'a> {
|
||||
self.iter()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use prelude::*;
|
||||
|
@ -462,6 +462,8 @@ impl<K: Ord, V> BTreeMap<K, V> {
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(stage0): remove impl after a snapshot
|
||||
#[cfg(stage0)]
|
||||
impl<K, V> IntoIterator for BTreeMap<K, V> {
|
||||
type IntoIter = IntoIter<K, V>;
|
||||
|
||||
@ -470,6 +472,18 @@ impl<K, V> IntoIterator for BTreeMap<K, V> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
|
||||
impl<K, V> IntoIterator for BTreeMap<K, V> {
|
||||
type Item = (K, V);
|
||||
type IntoIter = IntoIter<K, V>;
|
||||
|
||||
fn into_iter(self) -> IntoIter<K, V> {
|
||||
self.into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(stage0): remove impl after a snapshot
|
||||
#[cfg(stage0)]
|
||||
impl<'a, K, V> IntoIterator for &'a BTreeMap<K, V> {
|
||||
type IntoIter = Iter<'a, K, V>;
|
||||
|
||||
@ -478,6 +492,18 @@ impl<'a, K, V> IntoIterator for &'a BTreeMap<K, V> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
|
||||
impl<'a, K, V> IntoIterator for &'a BTreeMap<K, V> {
|
||||
type Item = (&'a K, &'a V);
|
||||
type IntoIter = Iter<'a, K, V>;
|
||||
|
||||
fn into_iter(self) -> Iter<'a, K, V> {
|
||||
self.iter()
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(stage0): remove impl after a snapshot
|
||||
#[cfg(stage0)]
|
||||
impl<'a, K, V> IntoIterator for &'a mut BTreeMap<K, V> {
|
||||
type IntoIter = IterMut<'a, K, V>;
|
||||
|
||||
@ -486,6 +512,16 @@ impl<'a, K, V> IntoIterator for &'a mut BTreeMap<K, V> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
|
||||
impl<'a, K, V> IntoIterator for &'a mut BTreeMap<K, V> {
|
||||
type Item = (&'a K, &'a mut V);
|
||||
type IntoIter = IterMut<'a, K, V>;
|
||||
|
||||
fn into_iter(mut self) -> IterMut<'a, K, V> {
|
||||
self.iter_mut()
|
||||
}
|
||||
}
|
||||
|
||||
/// A helper enum useful for deciding whether to continue a loop since we can't
|
||||
/// return from a closure
|
||||
enum Continuation<A, B> {
|
||||
|
@ -480,6 +480,8 @@ impl<T: Ord> FromIterator<T> for BTreeSet<T> {
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(stage0): remove impl after a snapshot
|
||||
#[cfg(stage0)]
|
||||
impl<T> IntoIterator for BTreeSet<T> {
|
||||
type IntoIter = IntoIter<T>;
|
||||
|
||||
@ -488,6 +490,18 @@ impl<T> IntoIterator for BTreeSet<T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
|
||||
impl<T> IntoIterator for BTreeSet<T> {
|
||||
type Item = T;
|
||||
type IntoIter = IntoIter<T>;
|
||||
|
||||
fn into_iter(self) -> IntoIter<T> {
|
||||
self.into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(stage0): remove impl after a snapshot
|
||||
#[cfg(stage0)]
|
||||
impl<'a, T> IntoIterator for &'a BTreeSet<T> {
|
||||
type IntoIter = Iter<'a, T>;
|
||||
|
||||
@ -496,6 +510,16 @@ impl<'a, T> IntoIterator for &'a BTreeSet<T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
|
||||
impl<'a, T> IntoIterator for &'a BTreeSet<T> {
|
||||
type Item = &'a T;
|
||||
type IntoIter = Iter<'a, T>;
|
||||
|
||||
fn into_iter(self) -> Iter<'a, T> {
|
||||
self.iter()
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: Ord> Extend<T> for BTreeSet<T> {
|
||||
#[inline]
|
||||
|
@ -837,6 +837,8 @@ impl<A> FromIterator<A> for DList<A> {
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(stage0): remove impl after a snapshot
|
||||
#[cfg(stage0)]
|
||||
impl<T> IntoIterator for DList<T> {
|
||||
type IntoIter = IntoIter<T>;
|
||||
|
||||
@ -845,6 +847,18 @@ impl<T> IntoIterator for DList<T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
|
||||
impl<T> IntoIterator for DList<T> {
|
||||
type Item = T;
|
||||
type IntoIter = IntoIter<T>;
|
||||
|
||||
fn into_iter(self) -> IntoIter<T> {
|
||||
self.into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(stage0): remove impl after a snapshot
|
||||
#[cfg(stage0)]
|
||||
impl<'a, T> IntoIterator for &'a DList<T> {
|
||||
type IntoIter = Iter<'a, T>;
|
||||
|
||||
@ -853,6 +867,18 @@ impl<'a, T> IntoIterator for &'a DList<T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
|
||||
impl<'a, T> IntoIterator for &'a DList<T> {
|
||||
type Item = &'a T;
|
||||
type IntoIter = Iter<'a, T>;
|
||||
|
||||
fn into_iter(self) -> Iter<'a, T> {
|
||||
self.iter()
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(stage0): remove impl after a snapshot
|
||||
#[cfg(stage0)]
|
||||
impl<'a, T> IntoIterator for &'a mut DList<T> {
|
||||
type IntoIter = IterMut<'a, T>;
|
||||
|
||||
@ -861,6 +887,16 @@ impl<'a, T> IntoIterator for &'a mut DList<T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
|
||||
impl<'a, T> IntoIterator for &'a mut DList<T> {
|
||||
type Item = &'a mut T;
|
||||
type IntoIter = IterMut<'a, T>;
|
||||
|
||||
fn into_iter(mut self) -> IterMut<'a, T> {
|
||||
self.iter_mut()
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<A> Extend<A> for DList<A> {
|
||||
fn extend<T: Iterator<Item=A>>(&mut self, iterator: T) {
|
||||
|
@ -257,6 +257,8 @@ impl<E:CLike> FromIterator<E> for EnumSet<E> {
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(stage0): remove impl after a snapshot
|
||||
#[cfg(stage0)]
|
||||
impl<'a, E> IntoIterator for &'a EnumSet<E> where E: CLike {
|
||||
type IntoIter = Iter<E>;
|
||||
|
||||
@ -265,6 +267,16 @@ impl<'a, E> IntoIterator for &'a EnumSet<E> where E: CLike {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
|
||||
impl<'a, E> IntoIterator for &'a EnumSet<E> where E: CLike {
|
||||
type Item = E;
|
||||
type IntoIter = Iter<E>;
|
||||
|
||||
fn into_iter(self) -> Iter<E> {
|
||||
self.iter()
|
||||
}
|
||||
}
|
||||
|
||||
impl<E:CLike> Extend<E> for EnumSet<E> {
|
||||
fn extend<I: Iterator<Item=E>>(&mut self, iterator: I) {
|
||||
for element in iterator {
|
||||
|
@ -1699,6 +1699,8 @@ impl<A> FromIterator<A> for RingBuf<A> {
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(stage0): remove impl after a snapshot
|
||||
#[cfg(stage0)]
|
||||
impl<T> IntoIterator for RingBuf<T> {
|
||||
type IntoIter = IntoIter<T>;
|
||||
|
||||
@ -1707,6 +1709,18 @@ impl<T> IntoIterator for RingBuf<T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
|
||||
impl<T> IntoIterator for RingBuf<T> {
|
||||
type Item = T;
|
||||
type IntoIter = IntoIter<T>;
|
||||
|
||||
fn into_iter(self) -> IntoIter<T> {
|
||||
self.into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(stage0): remove impl after a snapshot
|
||||
#[cfg(stage0)]
|
||||
impl<'a, T> IntoIterator for &'a RingBuf<T> {
|
||||
type IntoIter = Iter<'a, T>;
|
||||
|
||||
@ -1715,6 +1729,18 @@ impl<'a, T> IntoIterator for &'a RingBuf<T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
|
||||
impl<'a, T> IntoIterator for &'a RingBuf<T> {
|
||||
type Item = &'a T;
|
||||
type IntoIter = Iter<'a, T>;
|
||||
|
||||
fn into_iter(self) -> Iter<'a, T> {
|
||||
self.iter()
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(stage0): remove impl after a snapshot
|
||||
#[cfg(stage0)]
|
||||
impl<'a, T> IntoIterator for &'a mut RingBuf<T> {
|
||||
type IntoIter = IterMut<'a, T>;
|
||||
|
||||
@ -1723,6 +1749,16 @@ impl<'a, T> IntoIterator for &'a mut RingBuf<T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
|
||||
impl<'a, T> IntoIterator for &'a mut RingBuf<T> {
|
||||
type Item = &'a mut T;
|
||||
type IntoIter = IterMut<'a, T>;
|
||||
|
||||
fn into_iter(mut self) -> IterMut<'a, T> {
|
||||
self.iter_mut()
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<A> Extend<A> for RingBuf<A> {
|
||||
fn extend<T: Iterator<Item=A>>(&mut self, iterator: T) {
|
||||
|
@ -1285,7 +1285,8 @@ pub trait StrExt: Index<RangeFull, Output = str> {
|
||||
/// let v: Vec<&str> = some_words.words().collect();
|
||||
/// assert_eq!(v, vec!["Mary", "had", "a", "little", "lamb"]);
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[unstable(feature = "str_words",
|
||||
reason = "the precise algorithm to use is unclear")]
|
||||
fn words(&self) -> Words {
|
||||
UnicodeStr::words(&self[])
|
||||
}
|
||||
|
@ -1387,6 +1387,17 @@ impl<T> FromIterator<T> for Vec<T> {
|
||||
let (lower, _) = iterator.size_hint();
|
||||
let mut vector = Vec::with_capacity(lower);
|
||||
|
||||
// This function should be the moral equivalent of:
|
||||
//
|
||||
// for item in iterator {
|
||||
// vector.push(item);
|
||||
// }
|
||||
//
|
||||
// This equivalent crucially runs the iterator precisely once. The
|
||||
// optimization below (eliding bound/growth checks) means that we
|
||||
// actually run the iterator twice. To ensure the "moral equivalent" we
|
||||
// do a `fuse()` operation to ensure that the iterator continues to
|
||||
// return `None` after seeing the first `None`.
|
||||
let mut i = iterator.fuse();
|
||||
for element in i.by_ref().take(vector.capacity()) {
|
||||
let len = vector.len();
|
||||
@ -1403,6 +1414,8 @@ impl<T> FromIterator<T> for Vec<T> {
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(stage0): remove impl after a snapshot
|
||||
#[cfg(stage0)]
|
||||
impl<T> IntoIterator for Vec<T> {
|
||||
type IntoIter = IntoIter<T>;
|
||||
|
||||
@ -1411,6 +1424,18 @@ impl<T> IntoIterator for Vec<T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
|
||||
impl<T> IntoIterator for Vec<T> {
|
||||
type Item = T;
|
||||
type IntoIter = IntoIter<T>;
|
||||
|
||||
fn into_iter(self) -> IntoIter<T> {
|
||||
self.into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(stage0): remove impl after a snapshot
|
||||
#[cfg(stage0)]
|
||||
impl<'a, T> IntoIterator for &'a Vec<T> {
|
||||
type IntoIter = slice::Iter<'a, T>;
|
||||
|
||||
@ -1419,6 +1444,18 @@ impl<'a, T> IntoIterator for &'a Vec<T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
|
||||
impl<'a, T> IntoIterator for &'a Vec<T> {
|
||||
type Item = &'a T;
|
||||
type IntoIter = slice::Iter<'a, T>;
|
||||
|
||||
fn into_iter(self) -> slice::Iter<'a, T> {
|
||||
self.iter()
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(stage0): remove impl after a snapshot
|
||||
#[cfg(stage0)]
|
||||
impl<'a, T> IntoIterator for &'a mut Vec<T> {
|
||||
type IntoIter = slice::IterMut<'a, T>;
|
||||
|
||||
@ -1427,6 +1464,16 @@ impl<'a, T> IntoIterator for &'a mut Vec<T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
|
||||
impl<'a, T> IntoIterator for &'a mut Vec<T> {
|
||||
type Item = &'a mut T;
|
||||
type IntoIter = slice::IterMut<'a, T>;
|
||||
|
||||
fn into_iter(mut self) -> slice::IterMut<'a, T> {
|
||||
self.iter_mut()
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "collections", reason = "waiting on Extend stability")]
|
||||
impl<T> Extend<T> for Vec<T> {
|
||||
#[inline]
|
||||
|
@ -668,6 +668,8 @@ impl<V> FromIterator<(usize, V)> for VecMap<V> {
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(stage0): remove impl after a snapshot
|
||||
#[cfg(stage0)]
|
||||
impl<T> IntoIterator for VecMap<T> {
|
||||
type IntoIter = IntoIter<T>;
|
||||
|
||||
@ -676,6 +678,18 @@ impl<T> IntoIterator for VecMap<T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
|
||||
impl<T> IntoIterator for VecMap<T> {
|
||||
type Item = (usize, T);
|
||||
type IntoIter = IntoIter<T>;
|
||||
|
||||
fn into_iter(self) -> IntoIter<T> {
|
||||
self.into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(stage0): remove impl after a snapshot
|
||||
#[cfg(stage0)]
|
||||
impl<'a, T> IntoIterator for &'a VecMap<T> {
|
||||
type IntoIter = Iter<'a, T>;
|
||||
|
||||
@ -684,6 +698,18 @@ impl<'a, T> IntoIterator for &'a VecMap<T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
|
||||
impl<'a, T> IntoIterator for &'a VecMap<T> {
|
||||
type Item = (usize, &'a T);
|
||||
type IntoIter = Iter<'a, T>;
|
||||
|
||||
fn into_iter(self) -> Iter<'a, T> {
|
||||
self.iter()
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(stage0): remove impl after a snapshot
|
||||
#[cfg(stage0)]
|
||||
impl<'a, T> IntoIterator for &'a mut VecMap<T> {
|
||||
type IntoIter = IterMut<'a, T>;
|
||||
|
||||
@ -692,6 +718,16 @@ impl<'a, T> IntoIterator for &'a mut VecMap<T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
|
||||
impl<'a, T> IntoIterator for &'a mut VecMap<T> {
|
||||
type Item = (usize, &'a mut T);
|
||||
type IntoIter = IterMut<'a, T>;
|
||||
|
||||
fn into_iter(mut self) -> IterMut<'a, T> {
|
||||
self.iter_mut()
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<V> Extend<(usize, V)> for VecMap<V> {
|
||||
fn extend<Iter: Iterator<Item=(usize, V)>>(&mut self, iter: Iter) {
|
||||
|
@ -48,6 +48,8 @@ macro_rules! array_impls {
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(stage0): remove impl after a snapshot
|
||||
#[cfg(stage0)]
|
||||
impl<'a, T> IntoIterator for &'a [T; $N] {
|
||||
type IntoIter = Iter<'a, T>;
|
||||
|
||||
@ -56,6 +58,18 @@ macro_rules! array_impls {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
|
||||
impl<'a, T> IntoIterator for &'a [T; $N] {
|
||||
type Item = &'a T;
|
||||
type IntoIter = Iter<'a, T>;
|
||||
|
||||
fn into_iter(self) -> Iter<'a, T> {
|
||||
self.iter()
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(stage0): remove impl after a snapshot
|
||||
#[cfg(stage0)]
|
||||
impl<'a, T> IntoIterator for &'a mut [T; $N] {
|
||||
type IntoIter = IterMut<'a, T>;
|
||||
|
||||
@ -64,6 +78,16 @@ macro_rules! array_impls {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
|
||||
impl<'a, T> IntoIterator for &'a mut [T; $N] {
|
||||
type Item = &'a mut T;
|
||||
type IntoIter = IterMut<'a, T>;
|
||||
|
||||
fn into_iter(self) -> IterMut<'a, T> {
|
||||
self.iter_mut()
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<A, B> PartialEq<[B; $N]> for [A; $N] where A: PartialEq<B> {
|
||||
#[inline]
|
||||
|
@ -72,7 +72,7 @@ impl<T, F> Finally<T> for F where F: FnMut() -> T {
|
||||
/// ```
|
||||
/// use std::finally::try_finally;
|
||||
///
|
||||
/// struct State<'a> { buffer: &'a mut [u8], len: uint }
|
||||
/// struct State<'a> { buffer: &'a mut [u8], len: usize }
|
||||
/// # let mut buf = [];
|
||||
/// let mut state = State { buffer: &mut buf, len: 0 };
|
||||
/// try_finally(
|
||||
|
@ -118,6 +118,8 @@ pub trait FromIterator<A> {
|
||||
fn from_iter<T: Iterator<Item=A>>(iterator: T) -> Self;
|
||||
}
|
||||
|
||||
// NOTE(stage0): remove trait after a snapshot
|
||||
#[cfg(stage0)]
|
||||
/// Conversion into an `Iterator`
|
||||
pub trait IntoIterator {
|
||||
type IntoIter: Iterator;
|
||||
@ -127,6 +129,19 @@ pub trait IntoIterator {
|
||||
fn into_iter(self) -> Self::IntoIter;
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
|
||||
/// Conversion into an `Iterator`
|
||||
pub trait IntoIterator {
|
||||
type Item;
|
||||
type IntoIter: Iterator<Item=Self::Item>;
|
||||
|
||||
/// Consumes `Self` and returns an iterator over it
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn into_iter(self) -> Self::IntoIter;
|
||||
}
|
||||
|
||||
// NOTE(stage0): remove impl after a snapshot
|
||||
#[cfg(stage0)]
|
||||
impl<I> IntoIterator for I where I: Iterator {
|
||||
type IntoIter = I;
|
||||
|
||||
@ -135,6 +150,16 @@ impl<I> IntoIterator for I where I: Iterator {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
|
||||
impl<I: Iterator> IntoIterator for I {
|
||||
type Item = I::Item;
|
||||
type IntoIter = I;
|
||||
|
||||
fn into_iter(self) -> I {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
/// A type growable from an `Iterator` implementation
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub trait Extend<A> {
|
||||
@ -1055,6 +1080,7 @@ pub trait RandomAccessIterator: Iterator {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub trait ExactSizeIterator: Iterator {
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
/// Return the exact length of the iterator.
|
||||
fn len(&self) -> usize {
|
||||
let (lower, upper) = self.size_hint();
|
||||
|
@ -37,8 +37,8 @@
|
||||
//!
|
||||
//! #[derive(Debug)]
|
||||
//! struct Point {
|
||||
//! x: int,
|
||||
//! y: int
|
||||
//! x: i32,
|
||||
//! y: i32
|
||||
//! }
|
||||
//!
|
||||
//! impl Add for Point {
|
||||
@ -206,7 +206,7 @@ macro_rules! add_impl {
|
||||
)*)
|
||||
}
|
||||
|
||||
add_impl! { uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64 }
|
||||
add_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }
|
||||
|
||||
/// The `Sub` trait is used to specify the functionality of `-`.
|
||||
///
|
||||
@ -259,7 +259,7 @@ macro_rules! sub_impl {
|
||||
)*)
|
||||
}
|
||||
|
||||
sub_impl! { uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64 }
|
||||
sub_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }
|
||||
|
||||
/// The `Mul` trait is used to specify the functionality of `*`.
|
||||
///
|
||||
@ -312,7 +312,7 @@ macro_rules! mul_impl {
|
||||
)*)
|
||||
}
|
||||
|
||||
mul_impl! { uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64 }
|
||||
mul_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }
|
||||
|
||||
/// The `Div` trait is used to specify the functionality of `/`.
|
||||
///
|
||||
@ -365,7 +365,7 @@ macro_rules! div_impl {
|
||||
)*)
|
||||
}
|
||||
|
||||
div_impl! { uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64 }
|
||||
div_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }
|
||||
|
||||
/// The `Rem` trait is used to specify the functionality of `%`.
|
||||
///
|
||||
@ -435,7 +435,7 @@ macro_rules! rem_float_impl {
|
||||
}
|
||||
}
|
||||
|
||||
rem_impl! { uint u8 u16 u32 u64 int i8 i16 i32 i64 }
|
||||
rem_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
|
||||
rem_float_impl! { f32, fmodf }
|
||||
rem_float_impl! { f64, fmod }
|
||||
|
||||
@ -506,9 +506,9 @@ macro_rules! neg_uint_impl {
|
||||
}
|
||||
}
|
||||
|
||||
neg_impl! { int i8 i16 i32 i64 f32 f64 }
|
||||
neg_impl! { isize i8 i16 i32 i64 f32 f64 }
|
||||
|
||||
neg_uint_impl! { uint, int }
|
||||
neg_uint_impl! { usize, isize }
|
||||
neg_uint_impl! { u8, i8 }
|
||||
neg_uint_impl! { u16, i16 }
|
||||
neg_uint_impl! { u32, i32 }
|
||||
@ -566,7 +566,7 @@ macro_rules! not_impl {
|
||||
)*)
|
||||
}
|
||||
|
||||
not_impl! { bool uint u8 u16 u32 u64 int i8 i16 i32 i64 }
|
||||
not_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
|
||||
|
||||
/// The `BitAnd` trait is used to specify the functionality of `&`.
|
||||
///
|
||||
@ -619,7 +619,7 @@ macro_rules! bitand_impl {
|
||||
)*)
|
||||
}
|
||||
|
||||
bitand_impl! { bool uint u8 u16 u32 u64 int i8 i16 i32 i64 }
|
||||
bitand_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
|
||||
|
||||
/// The `BitOr` trait is used to specify the functionality of `|`.
|
||||
///
|
||||
@ -672,7 +672,7 @@ macro_rules! bitor_impl {
|
||||
)*)
|
||||
}
|
||||
|
||||
bitor_impl! { bool uint u8 u16 u32 u64 int i8 i16 i32 i64 }
|
||||
bitor_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
|
||||
|
||||
/// The `BitXor` trait is used to specify the functionality of `^`.
|
||||
///
|
||||
@ -725,7 +725,7 @@ macro_rules! bitxor_impl {
|
||||
)*)
|
||||
}
|
||||
|
||||
bitxor_impl! { bool uint u8 u16 u32 u64 int i8 i16 i32 i64 }
|
||||
bitxor_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
|
||||
|
||||
/// The `Shl` trait is used to specify the functionality of `<<`.
|
||||
///
|
||||
|
@ -60,19 +60,19 @@
|
||||
//! the optional owned box, `Option<Box<T>>`.
|
||||
//!
|
||||
//! The following example uses `Option` to create an optional box of
|
||||
//! `int`. Notice that in order to use the inner `int` value first the
|
||||
//! `i32`. Notice that in order to use the inner `i32` value first the
|
||||
//! `check_optional` function needs to use pattern matching to
|
||||
//! determine whether the box has a value (i.e. it is `Some(...)`) or
|
||||
//! not (`None`).
|
||||
//!
|
||||
//! ```
|
||||
//! let optional: Option<Box<int>> = None;
|
||||
//! let optional: Option<Box<i32>> = None;
|
||||
//! check_optional(&optional);
|
||||
//!
|
||||
//! let optional: Option<Box<int>> = Some(Box::new(9000));
|
||||
//! let optional: Option<Box<i32>> = Some(Box::new(9000));
|
||||
//! check_optional(&optional);
|
||||
//!
|
||||
//! fn check_optional(optional: &Option<Box<int>>) {
|
||||
//! fn check_optional(optional: &Option<Box<i32>>) {
|
||||
//! match *optional {
|
||||
//! Some(ref p) => println!("have value {}", p),
|
||||
//! None => println!("have no value")
|
||||
@ -108,7 +108,7 @@
|
||||
//! Initialize a result to `None` before a loop:
|
||||
//!
|
||||
//! ```
|
||||
//! enum Kingdom { Plant(uint, &'static str), Animal(uint, &'static str) }
|
||||
//! enum Kingdom { Plant(u32, &'static str), Animal(u32, &'static str) }
|
||||
//!
|
||||
//! // A list of data to search through.
|
||||
//! let all_the_big_things = [
|
||||
@ -188,10 +188,10 @@ impl<T> Option<T> {
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// let x: Option<uint> = Some(2);
|
||||
/// let x: Option<u32> = Some(2);
|
||||
/// assert_eq!(x.is_some(), true);
|
||||
///
|
||||
/// let x: Option<uint> = None;
|
||||
/// let x: Option<u32> = None;
|
||||
/// assert_eq!(x.is_some(), false);
|
||||
/// ```
|
||||
#[inline]
|
||||
@ -208,10 +208,10 @@ impl<T> Option<T> {
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// let x: Option<uint> = Some(2);
|
||||
/// let x: Option<u32> = Some(2);
|
||||
/// assert_eq!(x.is_none(), false);
|
||||
///
|
||||
/// let x: Option<uint> = None;
|
||||
/// let x: Option<u32> = None;
|
||||
/// assert_eq!(x.is_none(), true);
|
||||
/// ```
|
||||
#[inline]
|
||||
@ -228,7 +228,7 @@ impl<T> Option<T> {
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// Convert an `Option<String>` into an `Option<int>`, preserving the original.
|
||||
/// Convert an `Option<String>` into an `Option<usize>`, preserving the original.
|
||||
/// The `map` method takes the `self` argument by value, consuming the original,
|
||||
/// so this technique uses `as_ref` to first take an `Option` to a reference
|
||||
/// to the value inside the original.
|
||||
@ -237,7 +237,7 @@ impl<T> Option<T> {
|
||||
/// let num_as_str: Option<String> = Some("10".to_string());
|
||||
/// // First, cast `Option<String>` to `Option<&String>` with `as_ref`,
|
||||
/// // then consume *that* with `map`, leaving `num_as_str` on the stack.
|
||||
/// let num_as_int: Option<uint> = num_as_str.as_ref().map(|n| n.len());
|
||||
/// let num_as_int: Option<usize> = num_as_str.as_ref().map(|n| n.len());
|
||||
/// println!("still can print num_as_str: {:?}", num_as_str);
|
||||
/// ```
|
||||
#[inline]
|
||||
@ -406,12 +406,12 @@ impl<T> Option<T> {
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// Convert an `Option<String>` into an `Option<uint>`, consuming the original:
|
||||
/// Convert an `Option<String>` into an `Option<usize>`, consuming the original:
|
||||
///
|
||||
/// ```
|
||||
/// let num_as_str: Option<String> = Some("10".to_string());
|
||||
/// // `Option::map` takes self *by value*, consuming `num_as_str`
|
||||
/// let num_as_int: Option<uint> = num_as_str.map(|n| n.len());
|
||||
/// let num_as_int: Option<usize> = num_as_str.map(|n| n.len());
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
@ -518,7 +518,7 @@ impl<T> Option<T> {
|
||||
/// let x = Some(4);
|
||||
/// assert_eq!(x.iter().next(), Some(&4));
|
||||
///
|
||||
/// let x: Option<uint> = None;
|
||||
/// let x: Option<u32> = None;
|
||||
/// assert_eq!(x.iter().next(), None);
|
||||
/// ```
|
||||
#[inline]
|
||||
@ -539,7 +539,7 @@ impl<T> Option<T> {
|
||||
/// }
|
||||
/// assert_eq!(x, Some(42));
|
||||
///
|
||||
/// let mut x: Option<uint> = None;
|
||||
/// let mut x: Option<u32> = None;
|
||||
/// assert_eq!(x.iter_mut().next(), None);
|
||||
/// ```
|
||||
#[inline]
|
||||
@ -581,7 +581,7 @@ impl<T> Option<T> {
|
||||
/// let y: Option<&str> = None;
|
||||
/// assert_eq!(x.and(y), None);
|
||||
///
|
||||
/// let x: Option<uint> = None;
|
||||
/// let x: Option<u32> = None;
|
||||
/// let y = Some("foo");
|
||||
/// assert_eq!(x.and(y), None);
|
||||
///
|
||||
@ -589,7 +589,7 @@ impl<T> Option<T> {
|
||||
/// let y = Some("foo");
|
||||
/// assert_eq!(x.and(y), Some("foo"));
|
||||
///
|
||||
/// let x: Option<uint> = None;
|
||||
/// let x: Option<u32> = None;
|
||||
/// let y: Option<&str> = None;
|
||||
/// assert_eq!(x.and(y), None);
|
||||
/// ```
|
||||
@ -608,8 +608,8 @@ impl<T> Option<T> {
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// fn sq(x: uint) -> Option<uint> { Some(x * x) }
|
||||
/// fn nope(_: uint) -> Option<uint> { None }
|
||||
/// fn sq(x: u32) -> Option<u32> { Some(x * x) }
|
||||
/// fn nope(_: u32) -> Option<u32> { None }
|
||||
///
|
||||
/// assert_eq!(Some(2).and_then(sq).and_then(sq), Some(16));
|
||||
/// assert_eq!(Some(2).and_then(sq).and_then(nope), None);
|
||||
@ -642,7 +642,7 @@ impl<T> Option<T> {
|
||||
/// let y = Some(100);
|
||||
/// assert_eq!(x.or(y), Some(2));
|
||||
///
|
||||
/// let x: Option<uint> = None;
|
||||
/// let x: Option<u32> = None;
|
||||
/// let y = None;
|
||||
/// assert_eq!(x.or(y), None);
|
||||
/// ```
|
||||
@ -690,7 +690,7 @@ impl<T> Option<T> {
|
||||
/// x.take();
|
||||
/// assert_eq!(x, None);
|
||||
///
|
||||
/// let mut x: Option<uint> = None;
|
||||
/// let mut x: Option<u32> = None;
|
||||
/// x.take();
|
||||
/// assert_eq!(x, None);
|
||||
/// ```
|
||||
@ -789,7 +789,7 @@ impl<A> Iterator for Item<A> {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn size_hint(&self) -> (uint, Option<uint>) {
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
match self.opt {
|
||||
Some(_) => (1, Some(1)),
|
||||
None => (0, Some(0)),
|
||||
@ -817,7 +817,7 @@ impl<'a, A> Iterator for Iter<'a, A> {
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<&'a A> { self.inner.next() }
|
||||
#[inline]
|
||||
fn size_hint(&self) -> (uint, Option<uint>) { self.inner.size_hint() }
|
||||
fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
@ -847,7 +847,7 @@ impl<'a, A> Iterator for IterMut<'a, A> {
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<&'a mut A> { self.inner.next() }
|
||||
#[inline]
|
||||
fn size_hint(&self) -> (uint, Option<uint>) { self.inner.size_hint() }
|
||||
fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
@ -870,7 +870,7 @@ impl<A> Iterator for IntoIter<A> {
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<A> { self.inner.next() }
|
||||
#[inline]
|
||||
fn size_hint(&self) -> (uint, Option<uint>) { self.inner.size_hint() }
|
||||
fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
@ -896,11 +896,11 @@ impl<A, V: FromIterator<A>> FromIterator<Option<A>> for Option<V> {
|
||||
/// checking for overflow:
|
||||
///
|
||||
/// ```rust
|
||||
/// use std::uint;
|
||||
/// use std::u16;
|
||||
///
|
||||
/// let v = vec!(1, 2);
|
||||
/// let res: Option<Vec<uint>> = v.iter().map(|&x: &uint|
|
||||
/// if x == uint::MAX { None }
|
||||
/// let res: Option<Vec<u16>> = v.iter().map(|&x: &u16|
|
||||
/// if x == u16::MAX { None }
|
||||
/// else { Some(x + 1) }
|
||||
/// ).collect();
|
||||
/// assert!(res == Some(vec!(2, 3)));
|
||||
|
@ -27,10 +27,10 @@
|
||||
//! ## 1. Coerce a reference (`&T`) or mutable reference (`&mut T`).
|
||||
//!
|
||||
//! ```
|
||||
//! let my_num: int = 10;
|
||||
//! let my_num_ptr: *const int = &my_num;
|
||||
//! let mut my_speed: int = 88;
|
||||
//! let my_speed_ptr: *mut int = &mut my_speed;
|
||||
//! let my_num: i32 = 10;
|
||||
//! let my_num_ptr: *const i32 = &my_num;
|
||||
//! let mut my_speed: i32 = 88;
|
||||
//! let my_speed_ptr: *mut i32 = &mut my_speed;
|
||||
//! ```
|
||||
//!
|
||||
//! This does not take ownership of the original allocation
|
||||
@ -49,15 +49,15 @@
|
||||
//! use std::mem;
|
||||
//!
|
||||
//! unsafe {
|
||||
//! let my_num: Box<int> = Box::new(10);
|
||||
//! let my_num: *const int = mem::transmute(my_num);
|
||||
//! let my_speed: Box<int> = Box::new(88);
|
||||
//! let my_speed: *mut int = mem::transmute(my_speed);
|
||||
//! let my_num: Box<i32> = Box::new(10);
|
||||
//! let my_num: *const i32 = mem::transmute(my_num);
|
||||
//! let my_speed: Box<i32> = Box::new(88);
|
||||
//! let my_speed: *mut i32 = mem::transmute(my_speed);
|
||||
//!
|
||||
//! // By taking ownership of the original `Box<T>` though
|
||||
//! // we are obligated to transmute it back later to be destroyed.
|
||||
//! drop(mem::transmute::<_, Box<int>>(my_speed));
|
||||
//! drop(mem::transmute::<_, Box<int>>(my_num));
|
||||
//! drop(mem::transmute::<_, Box<i32>>(my_speed));
|
||||
//! drop(mem::transmute::<_, Box<i32>>(my_num));
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
@ -73,7 +73,7 @@
|
||||
//!
|
||||
//! fn main() {
|
||||
//! unsafe {
|
||||
//! let my_num: *mut int = libc::malloc(mem::size_of::<int>() as libc::size_t) as *mut int;
|
||||
//! let my_num: *mut i32 = libc::malloc(mem::size_of::<i32>() as libc::size_t) as *mut i32;
|
||||
//! if my_num.is_null() {
|
||||
//! panic!("failed to allocate memory");
|
||||
//! }
|
||||
@ -117,7 +117,7 @@ pub use intrinsics::set_memory;
|
||||
/// ```
|
||||
/// use std::ptr;
|
||||
///
|
||||
/// let p: *const int = ptr::null();
|
||||
/// let p: *const i32 = ptr::null();
|
||||
/// assert!(p.is_null());
|
||||
/// ```
|
||||
#[inline]
|
||||
@ -131,7 +131,7 @@ pub fn null<T>() -> *const T { 0 as *const T }
|
||||
/// ```
|
||||
/// use std::ptr;
|
||||
///
|
||||
/// let p: *mut int = ptr::null_mut();
|
||||
/// let p: *mut i32 = ptr::null_mut();
|
||||
/// assert!(p.is_null());
|
||||
/// ```
|
||||
#[inline]
|
||||
@ -148,7 +148,7 @@ pub fn null_mut<T>() -> *mut T { 0 as *mut T }
|
||||
#[inline]
|
||||
#[unstable(feature = "core",
|
||||
reason = "may play a larger role in std::ptr future extensions")]
|
||||
pub unsafe fn zero_memory<T>(dst: *mut T, count: uint) {
|
||||
pub unsafe fn zero_memory<T>(dst: *mut T, count: usize) {
|
||||
set_memory(dst, 0, count);
|
||||
}
|
||||
|
||||
@ -276,7 +276,7 @@ pub trait PtrExt: Sized {
|
||||
/// Otherwise `offset` invokes Undefined Behaviour, regardless of whether
|
||||
/// the pointer is used.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
unsafe fn offset(self, count: int) -> Self;
|
||||
unsafe fn offset(self, count: isize) -> Self;
|
||||
}
|
||||
|
||||
/// Methods on mutable raw pointers
|
||||
@ -303,11 +303,11 @@ impl<T> PtrExt for *const T {
|
||||
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn is_null(self) -> bool { self as uint == 0 }
|
||||
fn is_null(self) -> bool { self as usize == 0 }
|
||||
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
unsafe fn offset(self, count: int) -> *const T {
|
||||
unsafe fn offset(self, count: isize) -> *const T {
|
||||
intrinsics::offset(self, count)
|
||||
}
|
||||
|
||||
@ -330,11 +330,11 @@ impl<T> PtrExt for *mut T {
|
||||
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn is_null(self) -> bool { self as uint == 0 }
|
||||
fn is_null(self) -> bool { self as usize == 0 }
|
||||
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
unsafe fn offset(self, count: int) -> *mut T {
|
||||
unsafe fn offset(self, count: isize) -> *mut T {
|
||||
intrinsics::offset(self, count) as *mut T
|
||||
}
|
||||
|
||||
@ -553,7 +553,7 @@ impl<T> Unique<T> {
|
||||
/// Return an (unsafe) pointer into the memory owned by `self`.
|
||||
#[unstable(feature = "core",
|
||||
reason = "recently added to this module")]
|
||||
pub unsafe fn offset(self, offset: int) -> *mut T {
|
||||
pub unsafe fn offset(self, offset: isize) -> *mut T {
|
||||
self.ptr.offset(offset)
|
||||
}
|
||||
}
|
||||
|
@ -311,10 +311,10 @@ impl<T, E> Result<T, E> {
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// let x: Result<uint, &str> = Ok(2);
|
||||
/// let x: Result<u32, &str> = Ok(2);
|
||||
/// assert_eq!(x.ok(), Some(2));
|
||||
///
|
||||
/// let x: Result<uint, &str> = Err("Nothing here");
|
||||
/// let x: Result<u32, &str> = Err("Nothing here");
|
||||
/// assert_eq!(x.ok(), None);
|
||||
/// ```
|
||||
#[inline]
|
||||
@ -334,10 +334,10 @@ impl<T, E> Result<T, E> {
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// let x: Result<uint, &str> = Ok(2);
|
||||
/// let x: Result<u32, &str> = Ok(2);
|
||||
/// assert_eq!(x.err(), None);
|
||||
///
|
||||
/// let x: Result<uint, &str> = Err("Nothing here");
|
||||
/// let x: Result<u32, &str> = Err("Nothing here");
|
||||
/// assert_eq!(x.err(), Some("Nothing here"));
|
||||
/// ```
|
||||
#[inline]
|
||||
@ -359,10 +359,10 @@ impl<T, E> Result<T, E> {
|
||||
/// into the original, leaving the original in place.
|
||||
///
|
||||
/// ```
|
||||
/// let x: Result<uint, &str> = Ok(2);
|
||||
/// let x: Result<u32, &str> = Ok(2);
|
||||
/// assert_eq!(x.as_ref(), Ok(&2));
|
||||
///
|
||||
/// let x: Result<uint, &str> = Err("Error");
|
||||
/// let x: Result<u32, &str> = Err("Error");
|
||||
/// assert_eq!(x.as_ref(), Err(&"Error"));
|
||||
/// ```
|
||||
#[inline]
|
||||
@ -404,7 +404,7 @@ impl<T, E> Result<T, E> {
|
||||
/// Convert from `Result<T, E>` to `&mut [T]` (without copying)
|
||||
///
|
||||
/// ```
|
||||
/// let mut x: Result<&str, uint> = Ok("Gold");
|
||||
/// let mut x: Result<&str, u32> = Ok("Gold");
|
||||
/// {
|
||||
/// let v = x.as_mut_slice();
|
||||
/// assert!(v == ["Gold"]);
|
||||
@ -413,7 +413,7 @@ impl<T, E> Result<T, E> {
|
||||
/// }
|
||||
/// assert_eq!(x, Ok("Silver"));
|
||||
///
|
||||
/// let mut x: Result<&str, uint> = Err(45);
|
||||
/// let mut x: Result<&str, u32> = Err(45);
|
||||
/// assert!(x.as_mut_slice().is_empty());
|
||||
/// ```
|
||||
#[inline]
|
||||
@ -481,12 +481,12 @@ impl<T, E> Result<T, E> {
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// fn stringify(x: uint) -> String { format!("error code: {}", x) }
|
||||
/// fn stringify(x: u32) -> String { format!("error code: {}", x) }
|
||||
///
|
||||
/// let x: Result<uint, uint> = Ok(2);
|
||||
/// let x: Result<u32, u32> = Ok(2);
|
||||
/// assert_eq!(x.map_err(stringify), Ok(2));
|
||||
///
|
||||
/// let x: Result<uint, uint> = Err(13);
|
||||
/// let x: Result<u32, u32> = Err(13);
|
||||
/// assert_eq!(x.map_err(stringify), Err("error code: 13".to_string()));
|
||||
/// ```
|
||||
#[inline]
|
||||
@ -507,10 +507,10 @@ impl<T, E> Result<T, E> {
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// let x: Result<uint, &str> = Ok(7);
|
||||
/// let x: Result<u32, &str> = Ok(7);
|
||||
/// assert_eq!(x.iter().next(), Some(&7));
|
||||
///
|
||||
/// let x: Result<uint, &str> = Err("nothing!");
|
||||
/// let x: Result<u32, &str> = Err("nothing!");
|
||||
/// assert_eq!(x.iter().next(), None);
|
||||
/// ```
|
||||
#[inline]
|
||||
@ -524,14 +524,14 @@ impl<T, E> Result<T, E> {
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// let mut x: Result<uint, &str> = Ok(7);
|
||||
/// let mut x: Result<u32, &str> = Ok(7);
|
||||
/// match x.iter_mut().next() {
|
||||
/// Some(&mut ref mut x) => *x = 40,
|
||||
/// None => {},
|
||||
/// }
|
||||
/// assert_eq!(x, Ok(40));
|
||||
///
|
||||
/// let mut x: Result<uint, &str> = Err("nothing!");
|
||||
/// let mut x: Result<u32, &str> = Err("nothing!");
|
||||
/// assert_eq!(x.iter_mut().next(), None);
|
||||
/// ```
|
||||
#[inline]
|
||||
@ -545,12 +545,12 @@ impl<T, E> Result<T, E> {
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// let x: Result<uint, &str> = Ok(5);
|
||||
/// let v: Vec<uint> = x.into_iter().collect();
|
||||
/// let x: Result<u32, &str> = Ok(5);
|
||||
/// let v: Vec<u32> = x.into_iter().collect();
|
||||
/// assert_eq!(v, vec![5]);
|
||||
///
|
||||
/// let x: Result<uint, &str> = Err("nothing!");
|
||||
/// let v: Vec<uint> = x.into_iter().collect();
|
||||
/// let x: Result<u32, &str> = Err("nothing!");
|
||||
/// let v: Vec<u32> = x.into_iter().collect();
|
||||
/// assert_eq!(v, vec![]);
|
||||
/// ```
|
||||
#[inline]
|
||||
@ -568,19 +568,19 @@ impl<T, E> Result<T, E> {
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// let x: Result<uint, &str> = Ok(2);
|
||||
/// let x: Result<u32, &str> = Ok(2);
|
||||
/// let y: Result<&str, &str> = Err("late error");
|
||||
/// assert_eq!(x.and(y), Err("late error"));
|
||||
///
|
||||
/// let x: Result<uint, &str> = Err("early error");
|
||||
/// let x: Result<u32, &str> = Err("early error");
|
||||
/// let y: Result<&str, &str> = Ok("foo");
|
||||
/// assert_eq!(x.and(y), Err("early error"));
|
||||
///
|
||||
/// let x: Result<uint, &str> = Err("not a 2");
|
||||
/// let x: Result<u32, &str> = Err("not a 2");
|
||||
/// let y: Result<&str, &str> = Err("late error");
|
||||
/// assert_eq!(x.and(y), Err("not a 2"));
|
||||
///
|
||||
/// let x: Result<uint, &str> = Ok(2);
|
||||
/// let x: Result<u32, &str> = Ok(2);
|
||||
/// let y: Result<&str, &str> = Ok("different result type");
|
||||
/// assert_eq!(x.and(y), Ok("different result type"));
|
||||
/// ```
|
||||
@ -600,8 +600,8 @@ impl<T, E> Result<T, E> {
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// fn sq(x: uint) -> Result<uint, uint> { Ok(x * x) }
|
||||
/// fn err(x: uint) -> Result<uint, uint> { Err(x) }
|
||||
/// fn sq(x: u32) -> Result<u32, u32> { Ok(x * x) }
|
||||
/// fn err(x: u32) -> Result<u32, u32> { Err(x) }
|
||||
///
|
||||
/// assert_eq!(Ok(2).and_then(sq).and_then(sq), Ok(16));
|
||||
/// assert_eq!(Ok(2).and_then(sq).and_then(err), Err(4));
|
||||
@ -622,20 +622,20 @@ impl<T, E> Result<T, E> {
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// let x: Result<uint, &str> = Ok(2);
|
||||
/// let y: Result<uint, &str> = Err("late error");
|
||||
/// let x: Result<u32, &str> = Ok(2);
|
||||
/// let y: Result<u32, &str> = Err("late error");
|
||||
/// assert_eq!(x.or(y), Ok(2));
|
||||
///
|
||||
/// let x: Result<uint, &str> = Err("early error");
|
||||
/// let y: Result<uint, &str> = Ok(2);
|
||||
/// let x: Result<u32, &str> = Err("early error");
|
||||
/// let y: Result<u32, &str> = Ok(2);
|
||||
/// assert_eq!(x.or(y), Ok(2));
|
||||
///
|
||||
/// let x: Result<uint, &str> = Err("not a 2");
|
||||
/// let y: Result<uint, &str> = Err("late error");
|
||||
/// let x: Result<u32, &str> = Err("not a 2");
|
||||
/// let y: Result<u32, &str> = Err("late error");
|
||||
/// assert_eq!(x.or(y), Err("late error"));
|
||||
///
|
||||
/// let x: Result<uint, &str> = Ok(2);
|
||||
/// let y: Result<uint, &str> = Ok(100);
|
||||
/// let x: Result<u32, &str> = Ok(2);
|
||||
/// let y: Result<u32, &str> = Ok(100);
|
||||
/// assert_eq!(x.or(y), Ok(2));
|
||||
/// ```
|
||||
#[inline]
|
||||
@ -654,8 +654,8 @@ impl<T, E> Result<T, E> {
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// fn sq(x: uint) -> Result<uint, uint> { Ok(x * x) }
|
||||
/// fn err(x: uint) -> Result<uint, uint> { Err(x) }
|
||||
/// fn sq(x: u32) -> Result<u32, u32> { Ok(x * x) }
|
||||
/// fn err(x: u32) -> Result<u32, u32> { Err(x) }
|
||||
///
|
||||
/// assert_eq!(Ok(2).or_else(sq).or_else(sq), Ok(2));
|
||||
/// assert_eq!(Ok(2).or_else(err).or_else(sq), Ok(2));
|
||||
@ -678,10 +678,10 @@ impl<T, E> Result<T, E> {
|
||||
///
|
||||
/// ```
|
||||
/// let optb = 2;
|
||||
/// let x: Result<uint, &str> = Ok(9);
|
||||
/// let x: Result<u32, &str> = Ok(9);
|
||||
/// assert_eq!(x.unwrap_or(optb), 9);
|
||||
///
|
||||
/// let x: Result<uint, &str> = Err("error");
|
||||
/// let x: Result<u32, &str> = Err("error");
|
||||
/// assert_eq!(x.unwrap_or(optb), optb);
|
||||
/// ```
|
||||
#[inline]
|
||||
@ -699,7 +699,7 @@ impl<T, E> Result<T, E> {
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// fn count(x: &str) -> uint { x.len() }
|
||||
/// fn count(x: &str) -> usize { x.len() }
|
||||
///
|
||||
/// assert_eq!(Ok(2).unwrap_or_else(count), 2);
|
||||
/// assert_eq!(Err("foo").unwrap_or_else(count), 3);
|
||||
@ -726,12 +726,12 @@ impl<T, E: fmt::Debug> Result<T, E> {
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// let x: Result<uint, &str> = Ok(2);
|
||||
/// let x: Result<u32, &str> = Ok(2);
|
||||
/// assert_eq!(x.unwrap(), 2);
|
||||
/// ```
|
||||
///
|
||||
/// ```{.should_fail}
|
||||
/// let x: Result<uint, &str> = Err("emergency failure");
|
||||
/// let x: Result<u32, &str> = Err("emergency failure");
|
||||
/// x.unwrap(); // panics with `emergency failure`
|
||||
/// ```
|
||||
#[inline]
|
||||
@ -757,12 +757,12 @@ impl<T: fmt::Debug, E> Result<T, E> {
|
||||
/// # Example
|
||||
///
|
||||
/// ```{.should_fail}
|
||||
/// let x: Result<uint, &str> = Ok(2);
|
||||
/// let x: Result<u32, &str> = Ok(2);
|
||||
/// x.unwrap_err(); // panics with `2`
|
||||
/// ```
|
||||
///
|
||||
/// ```
|
||||
/// let x: Result<uint, &str> = Err("emergency failure");
|
||||
/// let x: Result<u32, &str> = Err("emergency failure");
|
||||
/// assert_eq!(x.unwrap_err(), "emergency failure");
|
||||
/// ```
|
||||
#[inline]
|
||||
@ -811,7 +811,7 @@ impl<'a, T> Iterator for Iter<'a, T> {
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<&'a T> { self.inner.take() }
|
||||
#[inline]
|
||||
fn size_hint(&self) -> (uint, Option<uint>) {
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
let n = if self.inner.is_some() {1} else {0};
|
||||
(n, Some(n))
|
||||
}
|
||||
@ -841,7 +841,7 @@ impl<'a, T> Iterator for IterMut<'a, T> {
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<&'a mut T> { self.inner.take() }
|
||||
#[inline]
|
||||
fn size_hint(&self) -> (uint, Option<uint>) {
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
let n = if self.inner.is_some() {1} else {0};
|
||||
(n, Some(n))
|
||||
}
|
||||
@ -867,7 +867,7 @@ impl<T> Iterator for IntoIter<T> {
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<T> { self.inner.take() }
|
||||
#[inline]
|
||||
fn size_hint(&self) -> (uint, Option<uint>) {
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
let n = if self.inner.is_some() {1} else {0};
|
||||
(n, Some(n))
|
||||
}
|
||||
@ -896,11 +896,11 @@ impl<A, E, V: FromIterator<A>> FromIterator<Result<A, E>> for Result<V, E> {
|
||||
/// checking for overflow:
|
||||
///
|
||||
/// ```rust
|
||||
/// use std::uint;
|
||||
/// use std::u32;
|
||||
///
|
||||
/// let v = vec!(1, 2);
|
||||
/// let res: Result<Vec<uint>, &'static str> = v.iter().map(|&x: &uint|
|
||||
/// if x == uint::MAX { Err("Overflow!") }
|
||||
/// let res: Result<Vec<u32>, &'static str> = v.iter().map(|&x: &u32|
|
||||
/// if x == u32::MAX { Err("Overflow!") }
|
||||
/// else { Ok(x + 1) }
|
||||
/// ).collect();
|
||||
/// assert!(res == Ok(vec!(2, 3)));
|
||||
|
@ -626,6 +626,8 @@ impl<'a, T> Default for &'a [T] {
|
||||
// Iterators
|
||||
//
|
||||
|
||||
// NOTE(stage0): remove impl after a snapshot
|
||||
#[cfg(stage0)]
|
||||
impl<'a, T> IntoIterator for &'a [T] {
|
||||
type IntoIter = Iter<'a, T>;
|
||||
|
||||
@ -634,6 +636,18 @@ impl<'a, T> IntoIterator for &'a [T] {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
|
||||
impl<'a, T> IntoIterator for &'a [T] {
|
||||
type Item = &'a T;
|
||||
type IntoIter = Iter<'a, T>;
|
||||
|
||||
fn into_iter(self) -> Iter<'a, T> {
|
||||
self.iter()
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(stage0): remove impl after a snapshot
|
||||
#[cfg(stage0)]
|
||||
impl<'a, T> IntoIterator for &'a mut [T] {
|
||||
type IntoIter = IterMut<'a, T>;
|
||||
|
||||
@ -642,6 +656,16 @@ impl<'a, T> IntoIterator for &'a mut [T] {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
|
||||
impl<'a, T> IntoIterator for &'a mut [T] {
|
||||
type Item = &'a mut T;
|
||||
type IntoIter = IterMut<'a, T>;
|
||||
|
||||
fn into_iter(self) -> IterMut<'a, T> {
|
||||
self.iter_mut()
|
||||
}
|
||||
}
|
||||
|
||||
// The shared definition of the `Iter` and `IterMut` iterators
|
||||
macro_rules! iterator {
|
||||
(struct $name:ident -> $ptr:ty, $elem:ty) => {
|
||||
|
@ -2005,7 +2005,7 @@ pub mod types {
|
||||
use types::common::c95::{c_void};
|
||||
use types::os::arch::c95::{c_char, c_int, c_uint};
|
||||
|
||||
pub type socklen_t = c_int;
|
||||
pub type socklen_t = u32;
|
||||
pub type sa_family_t = u8;
|
||||
pub type in_port_t = u16;
|
||||
pub type in_addr_t = u32;
|
||||
@ -2114,8 +2114,8 @@ pub mod types {
|
||||
pub type c_double = f64;
|
||||
pub type size_t = u32;
|
||||
pub type ptrdiff_t = i32;
|
||||
pub type clock_t = u32;
|
||||
pub type time_t = i32;
|
||||
pub type clock_t = c_ulong;
|
||||
pub type time_t = c_long;
|
||||
pub type suseconds_t = i32;
|
||||
pub type wchar_t = i32;
|
||||
}
|
||||
@ -2128,6 +2128,8 @@ pub mod types {
|
||||
pub type uintmax_t = u64;
|
||||
}
|
||||
pub mod posix88 {
|
||||
use types::os::arch::c95::c_long;
|
||||
|
||||
pub type off_t = i64;
|
||||
pub type dev_t = i32;
|
||||
pub type ino_t = u64;
|
||||
@ -2136,7 +2138,7 @@ pub mod types {
|
||||
pub type gid_t = u32;
|
||||
pub type useconds_t = u32;
|
||||
pub type mode_t = u16;
|
||||
pub type ssize_t = i32;
|
||||
pub type ssize_t = c_long;
|
||||
}
|
||||
pub mod posix01 {
|
||||
use types::common::c99::{int32_t, int64_t, uint32_t};
|
||||
@ -2145,8 +2147,8 @@ pub mod types {
|
||||
mode_t, off_t, uid_t};
|
||||
|
||||
pub type nlink_t = u16;
|
||||
pub type blksize_t = i64;
|
||||
pub type blkcnt_t = i32;
|
||||
pub type blksize_t = i32;
|
||||
pub type blkcnt_t = i64;
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy)] pub struct stat {
|
||||
@ -2217,8 +2219,8 @@ pub mod types {
|
||||
pub type c_double = f64;
|
||||
pub type size_t = u64;
|
||||
pub type ptrdiff_t = i64;
|
||||
pub type clock_t = u64;
|
||||
pub type time_t = i64;
|
||||
pub type clock_t = c_ulong;
|
||||
pub type time_t = c_long;
|
||||
pub type suseconds_t = i32;
|
||||
pub type wchar_t = i32;
|
||||
}
|
||||
@ -2231,6 +2233,8 @@ pub mod types {
|
||||
pub type uintmax_t = u64;
|
||||
}
|
||||
pub mod posix88 {
|
||||
use types::os::arch::c95::c_long;
|
||||
|
||||
pub type off_t = i64;
|
||||
pub type dev_t = i32;
|
||||
pub type ino_t = u64;
|
||||
@ -2239,7 +2243,7 @@ pub mod types {
|
||||
pub type gid_t = u32;
|
||||
pub type useconds_t = u32;
|
||||
pub type mode_t = u16;
|
||||
pub type ssize_t = i64;
|
||||
pub type ssize_t = c_long;
|
||||
}
|
||||
pub mod posix01 {
|
||||
use types::common::c99::{int32_t, int64_t};
|
||||
@ -2249,8 +2253,8 @@ pub mod types {
|
||||
use types::os::arch::posix88::{mode_t, off_t, uid_t};
|
||||
|
||||
pub type nlink_t = u16;
|
||||
pub type blksize_t = i64;
|
||||
pub type blkcnt_t = i32;
|
||||
pub type blksize_t = i32;
|
||||
pub type blkcnt_t = i64;
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy)] pub struct stat {
|
||||
|
@ -26,7 +26,7 @@
|
||||
//! a `pub fn new()`.
|
||||
use self::MethodContext::*;
|
||||
|
||||
use metadata::csearch;
|
||||
use metadata::{csearch, decoder};
|
||||
use middle::def::*;
|
||||
use middle::subst::Substs;
|
||||
use middle::ty::{self, Ty};
|
||||
@ -1964,6 +1964,48 @@ impl LintPass for UnconditionalRecursion {
|
||||
}
|
||||
}
|
||||
|
||||
declare_lint! {
|
||||
PLUGIN_AS_LIBRARY,
|
||||
Warn,
|
||||
"compiler plugin used as ordinary library in non-plugin crate"
|
||||
}
|
||||
|
||||
#[derive(Copy)]
|
||||
pub struct PluginAsLibrary;
|
||||
|
||||
impl LintPass for PluginAsLibrary {
|
||||
fn get_lints(&self) -> LintArray {
|
||||
lint_array![PLUGIN_AS_LIBRARY]
|
||||
}
|
||||
|
||||
fn check_item(&mut self, cx: &Context, it: &ast::Item) {
|
||||
if cx.sess().plugin_registrar_fn.get().is_some() {
|
||||
// We're compiling a plugin; it's fine to link other plugins.
|
||||
return;
|
||||
}
|
||||
|
||||
match it.node {
|
||||
ast::ItemExternCrate(..) => (),
|
||||
_ => return,
|
||||
};
|
||||
|
||||
let md = match cx.sess().cstore.find_extern_mod_stmt_cnum(it.id) {
|
||||
Some(cnum) => cx.sess().cstore.get_crate_data(cnum),
|
||||
None => {
|
||||
// Probably means we aren't linking the crate for some reason.
|
||||
//
|
||||
// Not sure if / when this could happen.
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
if decoder::get_plugin_registrar_fn(md.data()).is_some() {
|
||||
cx.span_lint(PLUGIN_AS_LIBRARY, it.span,
|
||||
"compiler plugin used as an ordinary library");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
declare_lint! {
|
||||
pub UNUSED_IMPORTS,
|
||||
Warn,
|
||||
|
@ -214,6 +214,7 @@ impl LintStore {
|
||||
Stability,
|
||||
UnconditionalRecursion,
|
||||
InvalidNoMangleItems,
|
||||
PluginAsLibrary,
|
||||
);
|
||||
|
||||
add_builtin_with_new!(sess,
|
||||
|
@ -121,12 +121,10 @@ fn register_native_lib(sess: &Session,
|
||||
sess.cstore.add_used_library(name, kind);
|
||||
}
|
||||
|
||||
pub struct PluginMetadata<'a> {
|
||||
sess: &'a Session,
|
||||
// Extra info about a crate loaded for plugins or exported macros.
|
||||
struct ExtensionCrate {
|
||||
metadata: PMDSource,
|
||||
dylib: Option<Path>,
|
||||
info: CrateInfo,
|
||||
vi_span: Span,
|
||||
target_only: bool,
|
||||
}
|
||||
|
||||
@ -451,21 +449,7 @@ impl<'a> CrateReader<'a> {
|
||||
}).collect()
|
||||
}
|
||||
|
||||
pub fn read_plugin_metadata<'b>(&'b mut self,
|
||||
krate: CrateOrString<'b>) -> PluginMetadata<'b> {
|
||||
let (info, span) = match krate {
|
||||
CrateOrString::Krate(c) => {
|
||||
(self.extract_crate_info(c).unwrap(), c.span)
|
||||
}
|
||||
CrateOrString::Str(sp, s) => {
|
||||
(CrateInfo {
|
||||
name: s.to_string(),
|
||||
ident: s.to_string(),
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
should_link: false,
|
||||
}, sp)
|
||||
}
|
||||
};
|
||||
fn read_extension_crate(&mut self, span: Span, info: &CrateInfo) -> ExtensionCrate {
|
||||
let target_triple = &self.sess.opts.target_triple[];
|
||||
let is_cross = target_triple != config::host_triple();
|
||||
let mut should_link = info.should_link && !is_cross;
|
||||
@ -517,30 +501,21 @@ impl<'a> CrateReader<'a> {
|
||||
PMDSource::Owned(library.metadata)
|
||||
};
|
||||
|
||||
PluginMetadata {
|
||||
sess: self.sess,
|
||||
ExtensionCrate {
|
||||
metadata: metadata,
|
||||
dylib: dylib.map(|p| p.0),
|
||||
info: info,
|
||||
vi_span: span,
|
||||
target_only: target_only,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy)]
|
||||
pub enum CrateOrString<'a> {
|
||||
Krate(&'a ast::Item),
|
||||
Str(Span, &'a str)
|
||||
}
|
||||
/// Read exported macros.
|
||||
pub fn read_exported_macros(&mut self, krate: &ast::Item) -> Vec<ast::MacroDef> {
|
||||
let ci = self.extract_crate_info(krate).unwrap();
|
||||
let ekrate = self.read_extension_crate(krate.span, &ci);
|
||||
|
||||
impl<'a> PluginMetadata<'a> {
|
||||
/// Read exported macros
|
||||
pub fn exported_macros(&self) -> Vec<ast::MacroDef> {
|
||||
let imported_from = Some(token::intern(&self.info.ident[]).ident());
|
||||
let source_name = format!("<{} macros>", &self.info.ident[]);
|
||||
let source_name = format!("<{} macros>", krate.ident);
|
||||
let mut macros = vec![];
|
||||
decoder::each_exported_macro(self.metadata.as_slice(),
|
||||
decoder::each_exported_macro(ekrate.metadata.as_slice(),
|
||||
&*self.sess.cstore.intr,
|
||||
|name, attrs, body| {
|
||||
// NB: Don't use parse::parse_tts_from_source_str because it parses with
|
||||
@ -558,7 +533,7 @@ impl<'a> PluginMetadata<'a> {
|
||||
attrs: attrs,
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
span: span,
|
||||
imported_from: imported_from,
|
||||
imported_from: Some(krate.ident),
|
||||
// overridden in plugin/load.rs
|
||||
export: false,
|
||||
use_locally: false,
|
||||
@ -572,28 +547,35 @@ impl<'a> PluginMetadata<'a> {
|
||||
}
|
||||
|
||||
/// Look for a plugin registrar. Returns library path and symbol name.
|
||||
pub fn plugin_registrar(&self) -> Option<(Path, String)> {
|
||||
if self.target_only {
|
||||
pub fn find_plugin_registrar(&mut self, span: Span, name: &str) -> Option<(Path, String)> {
|
||||
let ekrate = self.read_extension_crate(span, &CrateInfo {
|
||||
name: name.to_string(),
|
||||
ident: name.to_string(),
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
should_link: false,
|
||||
});
|
||||
|
||||
if ekrate.target_only {
|
||||
// Need to abort before syntax expansion.
|
||||
let message = format!("plugin crate `{}` is not available for triple `{}` \
|
||||
let message = format!("plugin `{}` is not available for triple `{}` \
|
||||
(only found {})",
|
||||
self.info.ident,
|
||||
name,
|
||||
config::host_triple(),
|
||||
self.sess.opts.target_triple);
|
||||
self.sess.span_err(self.vi_span, &message[]);
|
||||
self.sess.span_err(span, &message[]);
|
||||
self.sess.abort_if_errors();
|
||||
}
|
||||
|
||||
let registrar = decoder::get_plugin_registrar_fn(self.metadata.as_slice())
|
||||
.map(|id| decoder::get_symbol(self.metadata.as_slice(), id));
|
||||
let registrar = decoder::get_plugin_registrar_fn(ekrate.metadata.as_slice())
|
||||
.map(|id| decoder::get_symbol(ekrate.metadata.as_slice(), id));
|
||||
|
||||
match (self.dylib.as_ref(), registrar) {
|
||||
match (ekrate.dylib.as_ref(), registrar) {
|
||||
(Some(dylib), Some(reg)) => Some((dylib.clone(), reg)),
|
||||
(None, Some(_)) => {
|
||||
let message = format!("plugin crate `{}` only found in rlib format, \
|
||||
let message = format!("plugin `{}` only found in rlib format, \
|
||||
but must be available in dylib format",
|
||||
self.info.ident);
|
||||
self.sess.span_err(self.vi_span, &message[]);
|
||||
name);
|
||||
self.sess.span_err(span, &message[]);
|
||||
// No need to abort because the loading code will just ignore this
|
||||
// empty dylib.
|
||||
None
|
||||
|
186
src/librustc/metadata/macro_import.rs
Normal file
186
src/librustc/metadata/macro_import.rs
Normal file
@ -0,0 +1,186 @@
|
||||
// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! Used by `rustc` when loading a crate with exported macros.
|
||||
|
||||
use session::Session;
|
||||
use metadata::creader::CrateReader;
|
||||
|
||||
use std::collections::{HashSet, HashMap};
|
||||
use syntax::ast;
|
||||
use syntax::attr;
|
||||
use syntax::codemap::Span;
|
||||
use syntax::parse::token;
|
||||
use syntax::visit;
|
||||
use syntax::visit::Visitor;
|
||||
use syntax::attr::AttrMetaMethods;
|
||||
|
||||
struct MacroLoader<'a> {
|
||||
sess: &'a Session,
|
||||
span_whitelist: HashSet<Span>,
|
||||
reader: CrateReader<'a>,
|
||||
macros: Vec<ast::MacroDef>,
|
||||
}
|
||||
|
||||
impl<'a> MacroLoader<'a> {
|
||||
fn new(sess: &'a Session) -> MacroLoader<'a> {
|
||||
MacroLoader {
|
||||
sess: sess,
|
||||
span_whitelist: HashSet::new(),
|
||||
reader: CrateReader::new(sess),
|
||||
macros: vec![],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Read exported macros.
|
||||
pub fn read_macro_defs(sess: &Session, krate: &ast::Crate) -> Vec<ast::MacroDef> {
|
||||
let mut loader = MacroLoader::new(sess);
|
||||
|
||||
// We need to error on `#[macro_use] extern crate` when it isn't at the
|
||||
// crate root, because `$crate` won't work properly. Identify these by
|
||||
// spans, because the crate map isn't set up yet.
|
||||
for item in &krate.module.items {
|
||||
if let ast::ItemExternCrate(_) = item.node {
|
||||
loader.span_whitelist.insert(item.span);
|
||||
}
|
||||
}
|
||||
|
||||
visit::walk_crate(&mut loader, krate);
|
||||
|
||||
loader.macros
|
||||
}
|
||||
|
||||
pub type MacroSelection = HashMap<token::InternedString, Span>;
|
||||
|
||||
// note that macros aren't expanded yet, and therefore macros can't add macro imports.
|
||||
impl<'a, 'v> Visitor<'v> for MacroLoader<'a> {
|
||||
fn visit_item(&mut self, item: &ast::Item) {
|
||||
// We're only interested in `extern crate`.
|
||||
match item.node {
|
||||
ast::ItemExternCrate(_) => {}
|
||||
_ => {
|
||||
visit::walk_item(self, item);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Parse the attributes relating to macros.
|
||||
let mut import = Some(HashMap::new()); // None => load all
|
||||
let mut reexport = HashMap::new();
|
||||
|
||||
for attr in &item.attrs {
|
||||
let mut used = true;
|
||||
match &attr.name()[] {
|
||||
"phase" => {
|
||||
self.sess.span_err(attr.span, "#[phase] is deprecated");
|
||||
}
|
||||
"plugin" => {
|
||||
self.sess.span_err(attr.span, "#[plugin] on `extern crate` is deprecated");
|
||||
self.sess.span_help(attr.span, &format!("use a crate attribute instead, \
|
||||
i.e. #![plugin({})]",
|
||||
item.ident.as_str())[]);
|
||||
}
|
||||
"macro_use" => {
|
||||
let names = attr.meta_item_list();
|
||||
if names.is_none() {
|
||||
// no names => load all
|
||||
import = None;
|
||||
}
|
||||
if let (Some(sel), Some(names)) = (import.as_mut(), names) {
|
||||
for attr in names {
|
||||
if let ast::MetaWord(ref name) = attr.node {
|
||||
sel.insert(name.clone(), attr.span);
|
||||
} else {
|
||||
self.sess.span_err(attr.span, "bad macro import");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"macro_reexport" => {
|
||||
let names = match attr.meta_item_list() {
|
||||
Some(names) => names,
|
||||
None => {
|
||||
self.sess.span_err(attr.span, "bad macro reexport");
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
for attr in names {
|
||||
if let ast::MetaWord(ref name) = attr.node {
|
||||
reexport.insert(name.clone(), attr.span);
|
||||
} else {
|
||||
self.sess.span_err(attr.span, "bad macro reexport");
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => used = false,
|
||||
}
|
||||
if used {
|
||||
attr::mark_used(attr);
|
||||
}
|
||||
}
|
||||
|
||||
self.load_macros(item, import, reexport)
|
||||
}
|
||||
|
||||
fn visit_mac(&mut self, _: &ast::Mac) {
|
||||
// bummer... can't see macro imports inside macros.
|
||||
// do nothing.
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> MacroLoader<'a> {
|
||||
fn load_macros<'b>(&mut self,
|
||||
vi: &ast::Item,
|
||||
import: Option<MacroSelection>,
|
||||
reexport: MacroSelection) {
|
||||
if let Some(sel) = import.as_ref() {
|
||||
if sel.is_empty() && reexport.is_empty() {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if !self.span_whitelist.contains(&vi.span) {
|
||||
self.sess.span_err(vi.span, "an `extern crate` loading macros must be at \
|
||||
the crate root");
|
||||
return;
|
||||
}
|
||||
|
||||
let macros = self.reader.read_exported_macros(vi);
|
||||
let mut seen = HashSet::new();
|
||||
|
||||
for mut def in macros {
|
||||
let name = token::get_ident(def.ident);
|
||||
seen.insert(name.clone());
|
||||
|
||||
def.use_locally = match import.as_ref() {
|
||||
None => true,
|
||||
Some(sel) => sel.contains_key(&name),
|
||||
};
|
||||
def.export = reexport.contains_key(&name);
|
||||
self.macros.push(def);
|
||||
}
|
||||
|
||||
if let Some(sel) = import.as_ref() {
|
||||
for (name, span) in sel.iter() {
|
||||
if !seen.contains(name) {
|
||||
self.sess.span_err(*span, "imported macro not found");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (name, span) in reexport.iter() {
|
||||
if !seen.contains(name) {
|
||||
self.sess.span_err(*span, "reexported macro not found");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -18,3 +18,4 @@ pub mod cstore;
|
||||
pub mod csearch;
|
||||
pub mod loader;
|
||||
pub mod filesearch;
|
||||
pub mod macro_import;
|
||||
|
@ -530,6 +530,8 @@ impl<'a,T> Iterator for EnumeratedItems<'a,T> {
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(stage0): remove impl after a snapshot
|
||||
#[cfg(stage0)]
|
||||
impl<T> IntoIterator for VecPerParamSpace<T> {
|
||||
type IntoIter = IntoIter<T>;
|
||||
|
||||
@ -538,6 +540,18 @@ impl<T> IntoIterator for VecPerParamSpace<T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
|
||||
impl<T> IntoIterator for VecPerParamSpace<T> {
|
||||
type Item = T;
|
||||
type IntoIter = IntoIter<T>;
|
||||
|
||||
fn into_iter(self) -> IntoIter<T> {
|
||||
self.into_vec().into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(stage0): remove impl after a snapshot
|
||||
#[cfg(stage0)]
|
||||
impl<'a,T> IntoIterator for &'a VecPerParamSpace<T> {
|
||||
type IntoIter = Iter<'a, T>;
|
||||
|
||||
@ -546,6 +560,16 @@ impl<'a,T> IntoIterator for &'a VecPerParamSpace<T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
|
||||
impl<'a,T> IntoIterator for &'a VecPerParamSpace<T> {
|
||||
type Item = &'a T;
|
||||
type IntoIter = Iter<'a, T>;
|
||||
|
||||
fn into_iter(self) -> Iter<'a, T> {
|
||||
self.as_slice().into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Public trait `Subst`
|
||||
|
@ -8,24 +8,19 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! Used by `rustc` when loading a plugin, or a crate with exported macros.
|
||||
//! Used by `rustc` when loading a plugin.
|
||||
|
||||
use session::Session;
|
||||
use metadata::creader::{CrateOrString, CrateReader};
|
||||
use metadata::creader::CrateReader;
|
||||
use plugin::registry::Registry;
|
||||
|
||||
use std::mem;
|
||||
use std::env;
|
||||
use std::dynamic_lib::DynamicLibrary;
|
||||
use std::collections::{HashSet, HashMap};
|
||||
use std::borrow::ToOwned;
|
||||
use syntax::ast;
|
||||
use syntax::attr;
|
||||
use syntax::codemap::{Span, COMMAND_LINE_SP};
|
||||
use syntax::parse::token;
|
||||
use syntax::ptr::P;
|
||||
use syntax::visit;
|
||||
use syntax::visit::Visitor;
|
||||
use syntax::attr::AttrMetaMethods;
|
||||
|
||||
/// Pointer to a registrar function.
|
||||
@ -37,51 +32,17 @@ pub struct PluginRegistrar {
|
||||
pub args: Vec<P<ast::MetaItem>>,
|
||||
}
|
||||
|
||||
/// Information about loaded plugins.
|
||||
pub struct Plugins {
|
||||
/// Imported macros.
|
||||
pub macros: Vec<ast::MacroDef>,
|
||||
/// Registrars, as function pointers.
|
||||
pub registrars: Vec<PluginRegistrar>,
|
||||
}
|
||||
|
||||
pub struct PluginLoader<'a> {
|
||||
struct PluginLoader<'a> {
|
||||
sess: &'a Session,
|
||||
span_whitelist: HashSet<Span>,
|
||||
reader: CrateReader<'a>,
|
||||
pub plugins: Plugins,
|
||||
}
|
||||
|
||||
impl<'a> PluginLoader<'a> {
|
||||
fn new(sess: &'a Session) -> PluginLoader<'a> {
|
||||
PluginLoader {
|
||||
sess: sess,
|
||||
reader: CrateReader::new(sess),
|
||||
span_whitelist: HashSet::new(),
|
||||
plugins: Plugins {
|
||||
macros: vec!(),
|
||||
registrars: vec!(),
|
||||
},
|
||||
}
|
||||
}
|
||||
plugins: Vec<PluginRegistrar>,
|
||||
}
|
||||
|
||||
/// Read plugin metadata and dynamically load registrar functions.
|
||||
pub fn load_plugins(sess: &Session, krate: &ast::Crate,
|
||||
addl_plugins: Option<Vec<String>>) -> Plugins {
|
||||
addl_plugins: Option<Vec<String>>) -> Vec<PluginRegistrar> {
|
||||
let mut loader = PluginLoader::new(sess);
|
||||
|
||||
// We need to error on `#[macro_use] extern crate` when it isn't at the
|
||||
// crate root, because `$crate` won't work properly. Identify these by
|
||||
// spans, because the crate map isn't set up yet.
|
||||
for item in &krate.module.items {
|
||||
if let ast::ItemExternCrate(_) = item.node {
|
||||
loader.span_whitelist.insert(item.span);
|
||||
}
|
||||
}
|
||||
|
||||
visit::walk_crate(&mut loader, krate);
|
||||
|
||||
for attr in &krate.attrs {
|
||||
if !attr.check_name("plugin") {
|
||||
continue;
|
||||
@ -102,156 +63,34 @@ pub fn load_plugins(sess: &Session, krate: &ast::Crate,
|
||||
}
|
||||
|
||||
let args = plugin.meta_item_list().map(ToOwned::to_owned).unwrap_or_default();
|
||||
loader.load_plugin(CrateOrString::Str(plugin.span, &*plugin.name()),
|
||||
args);
|
||||
loader.load_plugin(plugin.span, &*plugin.name(), args);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(plugins) = addl_plugins {
|
||||
for plugin in plugins {
|
||||
loader.load_plugin(CrateOrString::Str(COMMAND_LINE_SP, &plugin), vec![]);
|
||||
loader.load_plugin(COMMAND_LINE_SP, &plugin, vec![]);
|
||||
}
|
||||
}
|
||||
|
||||
return loader.plugins;
|
||||
}
|
||||
|
||||
pub type MacroSelection = HashMap<token::InternedString, Span>;
|
||||
|
||||
// note that macros aren't expanded yet, and therefore macros can't add plugins.
|
||||
impl<'a, 'v> Visitor<'v> for PluginLoader<'a> {
|
||||
fn visit_item(&mut self, item: &ast::Item) {
|
||||
// We're only interested in `extern crate`.
|
||||
match item.node {
|
||||
ast::ItemExternCrate(_) => {}
|
||||
_ => {
|
||||
visit::walk_item(self, item);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Parse the attributes relating to macro loading.
|
||||
let mut import = Some(HashMap::new()); // None => load all
|
||||
let mut reexport = HashMap::new();
|
||||
for attr in &item.attrs {
|
||||
let mut used = true;
|
||||
match &attr.name()[] {
|
||||
"phase" => {
|
||||
self.sess.span_err(attr.span, "#[phase] is deprecated");
|
||||
}
|
||||
"plugin" => {
|
||||
self.sess.span_err(attr.span, "#[plugin] on `extern crate` is deprecated");
|
||||
self.sess.span_help(attr.span, &format!("use a crate attribute instead, \
|
||||
i.e. #![plugin({})]",
|
||||
item.ident.as_str())[]);
|
||||
}
|
||||
"macro_use" => {
|
||||
let names = attr.meta_item_list();
|
||||
if names.is_none() {
|
||||
// no names => load all
|
||||
import = None;
|
||||
}
|
||||
if let (Some(sel), Some(names)) = (import.as_mut(), names) {
|
||||
for attr in names {
|
||||
if let ast::MetaWord(ref name) = attr.node {
|
||||
sel.insert(name.clone(), attr.span);
|
||||
} else {
|
||||
self.sess.span_err(attr.span, "bad macro import");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"macro_reexport" => {
|
||||
let names = match attr.meta_item_list() {
|
||||
Some(names) => names,
|
||||
None => {
|
||||
self.sess.span_err(attr.span, "bad macro reexport");
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
for attr in names {
|
||||
if let ast::MetaWord(ref name) = attr.node {
|
||||
reexport.insert(name.clone(), attr.span);
|
||||
} else {
|
||||
self.sess.span_err(attr.span, "bad macro reexport");
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => used = false,
|
||||
}
|
||||
if used {
|
||||
attr::mark_used(attr);
|
||||
}
|
||||
}
|
||||
|
||||
self.load_macros(item, import, reexport)
|
||||
}
|
||||
|
||||
fn visit_mac(&mut self, _: &ast::Mac) {
|
||||
// bummer... can't see plugins inside macros.
|
||||
// do nothing.
|
||||
}
|
||||
loader.plugins
|
||||
}
|
||||
|
||||
impl<'a> PluginLoader<'a> {
|
||||
pub fn load_macros<'b>(&mut self,
|
||||
vi: &ast::Item,
|
||||
import: Option<MacroSelection>,
|
||||
reexport: MacroSelection) {
|
||||
if let Some(sel) = import.as_ref() {
|
||||
if sel.is_empty() && reexport.is_empty() {
|
||||
return;
|
||||
fn new(sess: &'a Session) -> PluginLoader<'a> {
|
||||
PluginLoader {
|
||||
sess: sess,
|
||||
reader: CrateReader::new(sess),
|
||||
plugins: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
if !self.span_whitelist.contains(&vi.span) {
|
||||
self.sess.span_err(vi.span, "an `extern crate` loading macros must be at \
|
||||
the crate root");
|
||||
return;
|
||||
}
|
||||
|
||||
let pmd = self.reader.read_plugin_metadata(CrateOrString::Krate(vi));
|
||||
|
||||
let mut seen = HashSet::new();
|
||||
for mut def in pmd.exported_macros() {
|
||||
let name = token::get_ident(def.ident);
|
||||
seen.insert(name.clone());
|
||||
|
||||
def.use_locally = match import.as_ref() {
|
||||
None => true,
|
||||
Some(sel) => sel.contains_key(&name),
|
||||
};
|
||||
def.export = reexport.contains_key(&name);
|
||||
self.plugins.macros.push(def);
|
||||
}
|
||||
|
||||
if let Some(sel) = import.as_ref() {
|
||||
for (name, span) in sel.iter() {
|
||||
if !seen.contains(name) {
|
||||
self.sess.span_err(*span, "imported macro not found");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (name, span) in reexport.iter() {
|
||||
if !seen.contains(name) {
|
||||
self.sess.span_err(*span, "reexported macro not found");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn load_plugin<'b>(&mut self,
|
||||
c: CrateOrString<'b>,
|
||||
args: Vec<P<ast::MetaItem>>) {
|
||||
let registrar = {
|
||||
let pmd = self.reader.read_plugin_metadata(c);
|
||||
pmd.plugin_registrar()
|
||||
};
|
||||
fn load_plugin(&mut self, span: Span, name: &str, args: Vec<P<ast::MetaItem>>) {
|
||||
let registrar = self.reader.find_plugin_registrar(span, name);
|
||||
|
||||
if let Some((lib, symbol)) = registrar {
|
||||
let fun = self.dylink_registrar(c, lib, symbol);
|
||||
self.plugins.registrars.push(PluginRegistrar {
|
||||
let fun = self.dylink_registrar(span, lib, symbol);
|
||||
self.plugins.push(PluginRegistrar {
|
||||
fun: fun,
|
||||
args: args,
|
||||
});
|
||||
@ -259,8 +98,8 @@ impl<'a> PluginLoader<'a> {
|
||||
}
|
||||
|
||||
// Dynamically link a registrar function into the compiler process.
|
||||
fn dylink_registrar<'b>(&mut self,
|
||||
c: CrateOrString<'b>,
|
||||
fn dylink_registrar(&mut self,
|
||||
span: Span,
|
||||
path: Path,
|
||||
symbol: String) -> PluginRegistrarFun {
|
||||
// Make sure the path contains a / or the linker will search for it.
|
||||
@ -272,11 +111,7 @@ impl<'a> PluginLoader<'a> {
|
||||
// inside this crate, so continue would spew "macro undefined"
|
||||
// errors
|
||||
Err(err) => {
|
||||
if let CrateOrString::Krate(cr) = c {
|
||||
self.sess.span_fatal(cr.span, &err[])
|
||||
} else {
|
||||
self.sess.fatal(&err[])
|
||||
}
|
||||
self.sess.span_fatal(span, &err[])
|
||||
}
|
||||
};
|
||||
|
||||
@ -288,11 +123,7 @@ impl<'a> PluginLoader<'a> {
|
||||
}
|
||||
// again fatal if we can't register macros
|
||||
Err(err) => {
|
||||
if let CrateOrString::Krate(cr) = c {
|
||||
self.sess.span_fatal(cr.span, &err[])
|
||||
} else {
|
||||
self.sess.fatal(&err[])
|
||||
}
|
||||
self.sess.span_fatal(span, &err[])
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -12,11 +12,11 @@ use rustc::session::Session;
|
||||
use rustc::session::config::{self, Input, OutputFilenames};
|
||||
use rustc::session::search_paths::PathKind;
|
||||
use rustc::lint;
|
||||
use rustc::metadata;
|
||||
use rustc::metadata::creader::CrateReader;
|
||||
use rustc::middle::{stability, ty, reachable};
|
||||
use rustc::middle::dependency_format;
|
||||
use rustc::middle;
|
||||
use rustc::plugin::load::Plugins;
|
||||
use rustc::plugin::registry::Registry;
|
||||
use rustc::plugin;
|
||||
use rustc::util::common::time;
|
||||
@ -409,9 +409,11 @@ pub fn phase_2_configure_and_expand(sess: &Session,
|
||||
syntax::std_inject::maybe_inject_crates_ref(krate,
|
||||
sess.opts.alt_std_name.clone()));
|
||||
|
||||
let macros = time(time_passes, "macro loading", (), |_|
|
||||
metadata::macro_import::read_macro_defs(sess, &krate));
|
||||
|
||||
let mut addl_plugins = Some(addl_plugins);
|
||||
let Plugins { macros, registrars }
|
||||
= time(time_passes, "plugin loading", (), |_|
|
||||
let registrars = time(time_passes, "plugin loading", (), |_|
|
||||
plugin::load::load_plugins(sess, &krate, addl_plugins.take().unwrap()));
|
||||
|
||||
let mut registry = Registry::new(sess, &krate);
|
||||
|
@ -436,50 +436,73 @@ pub enum DiagnosticKind {
|
||||
}
|
||||
|
||||
// Opaque pointer types
|
||||
#[allow(missing_copy_implementations)]
|
||||
pub enum Module_opaque {}
|
||||
pub type ModuleRef = *mut Module_opaque;
|
||||
#[allow(missing_copy_implementations)]
|
||||
pub enum Context_opaque {}
|
||||
pub type ContextRef = *mut Context_opaque;
|
||||
#[allow(missing_copy_implementations)]
|
||||
pub enum Type_opaque {}
|
||||
pub type TypeRef = *mut Type_opaque;
|
||||
#[allow(missing_copy_implementations)]
|
||||
pub enum Value_opaque {}
|
||||
pub type ValueRef = *mut Value_opaque;
|
||||
#[allow(missing_copy_implementations)]
|
||||
pub enum Metadata_opaque {}
|
||||
pub type MetadataRef = *mut Metadata_opaque;
|
||||
#[allow(missing_copy_implementations)]
|
||||
pub enum BasicBlock_opaque {}
|
||||
pub type BasicBlockRef = *mut BasicBlock_opaque;
|
||||
#[allow(missing_copy_implementations)]
|
||||
pub enum Builder_opaque {}
|
||||
pub type BuilderRef = *mut Builder_opaque;
|
||||
#[allow(missing_copy_implementations)]
|
||||
pub enum ExecutionEngine_opaque {}
|
||||
pub type ExecutionEngineRef = *mut ExecutionEngine_opaque;
|
||||
#[allow(missing_copy_implementations)]
|
||||
pub enum RustJITMemoryManager_opaque {}
|
||||
pub type RustJITMemoryManagerRef = *mut RustJITMemoryManager_opaque;
|
||||
#[allow(missing_copy_implementations)]
|
||||
pub enum MemoryBuffer_opaque {}
|
||||
pub type MemoryBufferRef = *mut MemoryBuffer_opaque;
|
||||
#[allow(missing_copy_implementations)]
|
||||
pub enum PassManager_opaque {}
|
||||
pub type PassManagerRef = *mut PassManager_opaque;
|
||||
#[allow(missing_copy_implementations)]
|
||||
pub enum PassManagerBuilder_opaque {}
|
||||
pub type PassManagerBuilderRef = *mut PassManagerBuilder_opaque;
|
||||
#[allow(missing_copy_implementations)]
|
||||
pub enum Use_opaque {}
|
||||
pub type UseRef = *mut Use_opaque;
|
||||
#[allow(missing_copy_implementations)]
|
||||
pub enum TargetData_opaque {}
|
||||
pub type TargetDataRef = *mut TargetData_opaque;
|
||||
#[allow(missing_copy_implementations)]
|
||||
pub enum ObjectFile_opaque {}
|
||||
pub type ObjectFileRef = *mut ObjectFile_opaque;
|
||||
#[allow(missing_copy_implementations)]
|
||||
pub enum SectionIterator_opaque {}
|
||||
pub type SectionIteratorRef = *mut SectionIterator_opaque;
|
||||
#[allow(missing_copy_implementations)]
|
||||
pub enum Pass_opaque {}
|
||||
pub type PassRef = *mut Pass_opaque;
|
||||
#[allow(missing_copy_implementations)]
|
||||
pub enum TargetMachine_opaque {}
|
||||
pub type TargetMachineRef = *mut TargetMachine_opaque;
|
||||
#[allow(missing_copy_implementations)]
|
||||
pub enum Archive_opaque {}
|
||||
pub type ArchiveRef = *mut Archive_opaque;
|
||||
#[allow(missing_copy_implementations)]
|
||||
pub enum Twine_opaque {}
|
||||
pub type TwineRef = *mut Twine_opaque;
|
||||
#[allow(missing_copy_implementations)]
|
||||
pub enum DiagnosticInfo_opaque {}
|
||||
pub type DiagnosticInfoRef = *mut DiagnosticInfo_opaque;
|
||||
#[allow(missing_copy_implementations)]
|
||||
pub enum DebugLoc_opaque {}
|
||||
pub type DebugLocRef = *mut DebugLoc_opaque;
|
||||
#[allow(missing_copy_implementations)]
|
||||
pub enum SMDiagnostic_opaque {}
|
||||
pub type SMDiagnosticRef = *mut SMDiagnostic_opaque;
|
||||
|
||||
@ -490,6 +513,7 @@ pub mod debuginfo {
|
||||
pub use self::DIDescriptorFlags::*;
|
||||
use super::{MetadataRef};
|
||||
|
||||
#[allow(missing_copy_implementations)]
|
||||
pub enum DIBuilder_opaque {}
|
||||
pub type DIBuilderRef = *mut DIBuilder_opaque;
|
||||
|
||||
@ -2192,6 +2216,7 @@ pub fn get_param(llfn: ValueRef, index: c_uint) -> ValueRef {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(missing_copy_implementations)]
|
||||
pub enum RustString_opaque {}
|
||||
pub type RustStringRef = *mut RustString_opaque;
|
||||
type RustStringRepr = *mut RefCell<Vec<u8>>;
|
||||
|
@ -339,7 +339,7 @@ pub fn trans_ret<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
let mut bcx = bcx;
|
||||
let dest = match (fcx.llretslotptr.get(), retval_expr) {
|
||||
(Some(_), Some(retval_expr)) => {
|
||||
let ret_ty = expr_ty(bcx, &*retval_expr);
|
||||
let ret_ty = expr_ty_adjusted(bcx, &*retval_expr);
|
||||
expr::SaveIn(fcx.get_ret_slot(bcx, ty::FnConverging(ret_ty), "ret_slot"))
|
||||
}
|
||||
_ => expr::Ignore,
|
||||
|
@ -88,15 +88,10 @@ impl<'cx, 'tcx,'v> visit::Visitor<'v> for OrphanChecker<'cx, 'tcx> {
|
||||
Err(traits::OrphanCheckErr::UncoveredTy(param_ty)) => {
|
||||
if !ty::has_attr(self.tcx, trait_def_id, "old_orphan_check") {
|
||||
span_err!(self.tcx.sess, item.span, E0210,
|
||||
"type parameter `{}` is not constrained by any local type; \
|
||||
only traits defined in the current crate can be implemented \
|
||||
for a type parameter",
|
||||
"type parameter `{}` must be used as the type parameter for \
|
||||
some local type (e.g. `MyStruct<T>`); only traits defined in \
|
||||
the current crate can be implemented for a type parameter",
|
||||
param_ty.user_string(self.tcx));
|
||||
self.tcx.sess.span_note(
|
||||
item.span,
|
||||
&format!("for a limited time, you can add \
|
||||
`#![feature(old_orphan_check)]` to your crate \
|
||||
to disable this rule"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2022,10 +2022,6 @@ fn enforce_impl_ty_params_are_constrained<'tcx>(tcx: &ty::ctxt<'tcx>,
|
||||
"the type parameter `{}` is not constrained by the \
|
||||
impl trait, self type, or predicates",
|
||||
param_ty.user_string(tcx));
|
||||
tcx.sess.span_help(
|
||||
ty_param.span,
|
||||
&format!("you can temporarily opt out of this rule by placing \
|
||||
the `#[old_impl_check]` attribute on the impl"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2490,6 +2490,7 @@ pub struct Stability {
|
||||
pub level: attr::StabilityLevel,
|
||||
pub feature: String,
|
||||
pub since: String,
|
||||
pub deprecated_since: String,
|
||||
pub reason: String
|
||||
}
|
||||
|
||||
@ -2500,6 +2501,8 @@ impl Clean<Stability> for attr::Stability {
|
||||
feature: self.feature.to_string(),
|
||||
since: self.since.as_ref().map_or("".to_string(),
|
||||
|interned| interned.to_string()),
|
||||
deprecated_since: self.deprecated_since.as_ref().map_or("".to_string(),
|
||||
|istr| istr.to_string()),
|
||||
reason: self.reason.as_ref().map_or("".to_string(),
|
||||
|interned| interned.to_string()),
|
||||
}
|
||||
|
@ -711,7 +711,11 @@ impl<'a> fmt::Display for Stability<'a> {
|
||||
match *stab {
|
||||
Some(ref stability) => {
|
||||
write!(f, "<a class='stability {lvl}' title='{reason}'>{lvl}</a>",
|
||||
lvl = stability.level,
|
||||
lvl = if stability.deprecated_since.is_empty() {
|
||||
format!("{}", stability.level)
|
||||
} else {
|
||||
"Deprecated".to_string()
|
||||
},
|
||||
reason = stability.reason)
|
||||
}
|
||||
None => Ok(())
|
||||
@ -725,7 +729,11 @@ impl<'a> fmt::Display for ConciseStability<'a> {
|
||||
match *stab {
|
||||
Some(ref stability) => {
|
||||
write!(f, "<a class='stability {lvl}' title='{lvl}{colon}{reason}'></a>",
|
||||
lvl = stability.level,
|
||||
lvl = if stability.deprecated_since.is_empty() {
|
||||
format!("{}", stability.level)
|
||||
} else {
|
||||
"Deprecated".to_string()
|
||||
},
|
||||
colon = if stability.reason.len() > 0 { ": " } else { "" },
|
||||
reason = stability.reason)
|
||||
}
|
||||
@ -763,6 +771,9 @@ impl fmt::Display for ModuleSummary {
|
||||
try!(write!(f, "<span class='summary Unstable' \
|
||||
style='width: {:.4}%; display: inline-block'> </span>",
|
||||
(100 * cnt.unstable) as f64/tot as f64));
|
||||
try!(write!(f, "<span class='summary Deprecated' \
|
||||
style='width: {:.4}%; display: inline-block'> </span>",
|
||||
(100 * cnt.deprecated) as f64/tot as f64));
|
||||
try!(write!(f, "<span class='summary Unmarked' \
|
||||
style='width: {:.4}%; display: inline-block'> </span>",
|
||||
(100 * cnt.unmarked) as f64/tot as f64));
|
||||
@ -778,11 +789,12 @@ impl fmt::Display for ModuleSummary {
|
||||
let mut context = Vec::new();
|
||||
|
||||
let tot = self.counts.total();
|
||||
let (stable, unstable, unmarked) = if tot == 0 {
|
||||
(0, 0, 0)
|
||||
let (stable, unstable, deprecated, unmarked) = if tot == 0 {
|
||||
(0, 0, 0, 0)
|
||||
} else {
|
||||
((100 * self.counts.stable)/tot,
|
||||
(100 * self.counts.unstable)/tot,
|
||||
(100 * self.counts.deprecated)/tot,
|
||||
(100 * self.counts.unmarked)/tot)
|
||||
};
|
||||
|
||||
@ -794,11 +806,12 @@ its children (percentages total for {name}):
|
||||
<blockquote>
|
||||
<a class='stability Stable'></a> stable ({}%),<br/>
|
||||
<a class='stability Unstable'></a> unstable ({}%),<br/>
|
||||
<a class='stability Deprecated'></a> deprecated ({}%),<br/>
|
||||
<a class='stability Unmarked'></a> unmarked ({}%)
|
||||
</blockquote>
|
||||
The counts do not include methods or trait
|
||||
implementations that are visible only through a re-exported type.",
|
||||
stable, unstable, unmarked,
|
||||
stable, unstable, deprecated, unmarked,
|
||||
name=self.name));
|
||||
try!(write!(f, "<table>"));
|
||||
try!(fmt_inner(f, &mut context, self));
|
||||
|
@ -292,6 +292,27 @@ nav.sub {
|
||||
.content td p:first-child { margin-top: 0; }
|
||||
.content td h1, .content td h2 { margin-left: 0; font-size: 1.1em; }
|
||||
|
||||
.docblock table {
|
||||
border: 1px solid #ddd;
|
||||
margin: .5em 0;
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.docblock table td {
|
||||
padding: .5em;
|
||||
border-top: 1px dashed #ddd;
|
||||
border-bottom: 1px dashed #ddd;
|
||||
|
||||
}
|
||||
|
||||
.docblock table th {
|
||||
padding: .5em;
|
||||
text-align: left;
|
||||
border-top: 1px solid #ddd;
|
||||
border-bottom: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.content .item-list {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
|
@ -29,11 +29,12 @@ use html::render::cache;
|
||||
/// The counts for each stability level.
|
||||
#[derive(Copy)]
|
||||
pub struct Counts {
|
||||
pub unstable: uint,
|
||||
pub stable: uint,
|
||||
pub deprecated: u64,
|
||||
pub unstable: u64,
|
||||
pub stable: u64,
|
||||
|
||||
/// No stability level, inherited or otherwise.
|
||||
pub unmarked: uint,
|
||||
pub unmarked: u64,
|
||||
}
|
||||
|
||||
impl Add for Counts {
|
||||
@ -41,6 +42,7 @@ impl Add for Counts {
|
||||
|
||||
fn add(self, other: Counts) -> Counts {
|
||||
Counts {
|
||||
deprecated: self.deprecated + other.deprecated,
|
||||
unstable: self.unstable + other.unstable,
|
||||
stable: self.stable + other.stable,
|
||||
unmarked: self.unmarked + other.unmarked,
|
||||
@ -51,14 +53,15 @@ impl Add for Counts {
|
||||
impl Counts {
|
||||
fn zero() -> Counts {
|
||||
Counts {
|
||||
deprecated: 0,
|
||||
unstable: 0,
|
||||
stable: 0,
|
||||
unmarked: 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn total(&self) -> uint {
|
||||
self.unstable + self.stable + self.unmarked
|
||||
pub fn total(&self) -> u64 {
|
||||
self.deprecated + self.unstable + self.stable + self.unmarked
|
||||
}
|
||||
}
|
||||
|
||||
@ -94,11 +97,16 @@ fn visible(item: &Item) -> bool {
|
||||
fn count_stability(stab: Option<&Stability>) -> Counts {
|
||||
match stab {
|
||||
None => Counts { unmarked: 1, .. Counts::zero() },
|
||||
Some(ref stab) => match stab.level {
|
||||
Some(ref stab) => {
|
||||
if !stab.deprecated_since.is_empty() {
|
||||
return Counts { deprecated: 1, .. Counts::zero() };
|
||||
}
|
||||
match stab.level {
|
||||
Unstable => Counts { unstable: 1, .. Counts::zero() },
|
||||
Stable => Counts { stable: 1, .. Counts::zero() },
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn summarize_methods(item: &Item) -> Counts {
|
||||
|
@ -1372,6 +1372,8 @@ enum VacantEntryState<K, V, M> {
|
||||
NoElem(EmptyBucket<K, V, M>),
|
||||
}
|
||||
|
||||
// NOTE(stage0): remove impl after a snapshot
|
||||
#[cfg(stage0)]
|
||||
impl<'a, K, V, S, H> IntoIterator for &'a HashMap<K, V, S>
|
||||
where K: Eq + Hash<H>,
|
||||
S: HashState<Hasher=H>,
|
||||
@ -1384,6 +1386,22 @@ impl<'a, K, V, S, H> IntoIterator for &'a HashMap<K, V, S>
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
|
||||
impl<'a, K, V, S, H> IntoIterator for &'a HashMap<K, V, S>
|
||||
where K: Eq + Hash<H>,
|
||||
S: HashState<Hasher=H>,
|
||||
H: hash::Hasher<Output=u64>
|
||||
{
|
||||
type Item = (&'a K, &'a V);
|
||||
type IntoIter = Iter<'a, K, V>;
|
||||
|
||||
fn into_iter(self) -> Iter<'a, K, V> {
|
||||
self.iter()
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(stage0): remove impl after a snapshot
|
||||
#[cfg(stage0)]
|
||||
impl<'a, K, V, S, H> IntoIterator for &'a mut HashMap<K, V, S>
|
||||
where K: Eq + Hash<H>,
|
||||
S: HashState<Hasher=H>,
|
||||
@ -1396,6 +1414,22 @@ impl<'a, K, V, S, H> IntoIterator for &'a mut HashMap<K, V, S>
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
|
||||
impl<'a, K, V, S, H> IntoIterator for &'a mut HashMap<K, V, S>
|
||||
where K: Eq + Hash<H>,
|
||||
S: HashState<Hasher=H>,
|
||||
H: hash::Hasher<Output=u64>
|
||||
{
|
||||
type Item = (&'a K, &'a mut V);
|
||||
type IntoIter = IterMut<'a, K, V>;
|
||||
|
||||
fn into_iter(mut self) -> IterMut<'a, K, V> {
|
||||
self.iter_mut()
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(stage0): remove impl after a snapshot
|
||||
#[cfg(stage0)]
|
||||
impl<K, V, S, H> IntoIterator for HashMap<K, V, S>
|
||||
where K: Eq + Hash<H>,
|
||||
S: HashState<Hasher=H>,
|
||||
@ -1408,6 +1442,20 @@ impl<K, V, S, H> IntoIterator for HashMap<K, V, S>
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
|
||||
impl<K, V, S, H> IntoIterator for HashMap<K, V, S>
|
||||
where K: Eq + Hash<H>,
|
||||
S: HashState<Hasher=H>,
|
||||
H: hash::Hasher<Output=u64>
|
||||
{
|
||||
type Item = (K, V);
|
||||
type IntoIter = IntoIter<K, V>;
|
||||
|
||||
fn into_iter(self) -> IntoIter<K, V> {
|
||||
self.into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<'a, K, V> Iterator for Iter<'a, K, V> {
|
||||
type Item = (&'a K, &'a V);
|
||||
|
@ -835,6 +835,8 @@ pub struct Union<'a, T: 'a, S: 'a> {
|
||||
iter: Chain<Iter<'a, T>, Difference<'a, T, S>>
|
||||
}
|
||||
|
||||
// NOTE(stage0): remove impl after a snapshot
|
||||
#[cfg(stage0)]
|
||||
impl<'a, T, S, H> IntoIterator for &'a HashSet<T, S>
|
||||
where T: Eq + Hash<H>,
|
||||
S: HashState<Hasher=H>,
|
||||
@ -847,6 +849,22 @@ impl<'a, T, S, H> IntoIterator for &'a HashSet<T, S>
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
|
||||
impl<'a, T, S, H> IntoIterator for &'a HashSet<T, S>
|
||||
where T: Eq + Hash<H>,
|
||||
S: HashState<Hasher=H>,
|
||||
H: hash::Hasher<Output=u64>
|
||||
{
|
||||
type Item = &'a T;
|
||||
type IntoIter = Iter<'a, T>;
|
||||
|
||||
fn into_iter(self) -> Iter<'a, T> {
|
||||
self.iter()
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(stage0): remove impl after a snapshot
|
||||
#[cfg(stage0)]
|
||||
impl<T, S, H> IntoIterator for HashSet<T, S>
|
||||
where T: Eq + Hash<H>,
|
||||
S: HashState<Hasher=H>,
|
||||
@ -859,6 +877,20 @@ impl<T, S, H> IntoIterator for HashSet<T, S>
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
|
||||
impl<T, S, H> IntoIterator for HashSet<T, S>
|
||||
where T: Eq + Hash<H>,
|
||||
S: HashState<Hasher=H>,
|
||||
H: hash::Hasher<Output=u64>
|
||||
{
|
||||
type Item = T;
|
||||
type IntoIter = IntoIter<T>;
|
||||
|
||||
fn into_iter(self) -> IntoIter<T> {
|
||||
self.into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<'a, K> Iterator for Iter<'a, K> {
|
||||
type Item = &'a K;
|
||||
|
@ -112,10 +112,10 @@ impl File {
|
||||
OpenOptions::new().read(true).open(path)
|
||||
}
|
||||
|
||||
/// Creates a open a file in write-only mode.
|
||||
/// Open a file in write-only mode.
|
||||
///
|
||||
/// This method will attempt to open a new file, truncating it if it already
|
||||
/// exists.
|
||||
/// This function will create a file it it does not exist,
|
||||
/// and will truncate it if it does.
|
||||
///
|
||||
/// See the `OpenOptions::open` function for more details.
|
||||
pub fn create<P: AsPath + ?Sized>(path: &P) -> io::Result<File> {
|
||||
|
@ -132,7 +132,7 @@ pub fn env() -> Vec<(String,String)> {
|
||||
|
||||
/// Returns a vector of (variable, value) byte-vector pairs for all the
|
||||
/// environment variables of the current process.
|
||||
#[deprecated(since = "1.0.0", reason = "use env::vars instead")]
|
||||
#[deprecated(since = "1.0.0", reason = "use env::vars_os instead")]
|
||||
#[unstable(feature = "os")]
|
||||
pub fn env_as_bytes() -> Vec<(Vec<u8>, Vec<u8>)> {
|
||||
env::vars_os().map(|(k, v)| (byteify(k), byteify(v))).collect()
|
||||
@ -159,7 +159,7 @@ pub fn env_as_bytes() -> Vec<(Vec<u8>, Vec<u8>)> {
|
||||
/// None => println!("{} is not defined in the environment.", key)
|
||||
/// }
|
||||
/// ```
|
||||
#[deprecated(since = "1.0.0", reason = "use env::var or env::var_os instead")]
|
||||
#[deprecated(since = "1.0.0", reason = "use env::var instead")]
|
||||
#[unstable(feature = "os")]
|
||||
pub fn getenv(n: &str) -> Option<String> {
|
||||
env::var(n).ok()
|
||||
@ -171,7 +171,7 @@ pub fn getenv(n: &str) -> Option<String> {
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if `n` has any interior NULs.
|
||||
#[deprecated(since = "1.0.0", reason = "use env::var instead")]
|
||||
#[deprecated(since = "1.0.0", reason = "use env::var_os instead")]
|
||||
#[unstable(feature = "os")]
|
||||
pub fn getenv_as_bytes(n: &str) -> Option<Vec<u8>> {
|
||||
env::var_os(n).map(byteify)
|
||||
@ -732,7 +732,7 @@ pub fn args() -> Vec<String> {
|
||||
|
||||
/// Returns the arguments which this program was started with (normally passed
|
||||
/// via the command line) as byte vectors.
|
||||
#[deprecated(since = "1.0.0", reason = "use env::args_raw instead")]
|
||||
#[deprecated(since = "1.0.0", reason = "use env::args_os instead")]
|
||||
#[unstable(feature = "os")]
|
||||
pub fn args_as_bytes() -> Vec<Vec<u8>> {
|
||||
real_args_as_bytes()
|
||||
|
@ -292,7 +292,6 @@ pub mod eabi {
|
||||
|
||||
#[lang="eh_personality"]
|
||||
#[no_mangle] // referenced from rust_try.ll
|
||||
#[allow(private_no_mangle_fns)]
|
||||
pub extern "C" fn rust_eh_personality(
|
||||
version: c_int,
|
||||
actions: uw::_Unwind_Action,
|
||||
|
@ -364,7 +364,10 @@ mod tests {
|
||||
use os;
|
||||
use prelude::v1::*;
|
||||
|
||||
#[cfg_attr(target_os = "freebsd", ignore)] // hmm, maybe pipes have a tiny buffer
|
||||
#[cfg_attr(any(target_os = "freebsd",
|
||||
target_os = "openbsd"),
|
||||
ignore)]
|
||||
// under some system, pipe(2) will return a bidrectionnal pipe
|
||||
#[test]
|
||||
fn test_file_desc() {
|
||||
// Run this test with some pipes so we don't have to mess around with
|
||||
|
@ -50,7 +50,7 @@ fn main() {
|
||||
let mut term = Term::new();
|
||||
let cmd = os::args();
|
||||
|
||||
if cmd.len() < 1 {
|
||||
if cmd.len() <= 1 {
|
||||
help::usage()
|
||||
} else {
|
||||
match subcommand::parse_name(&cmd[1][]) {
|
||||
|
11
src/test/auxiliary/orphan_check_diagnostics.rs
Normal file
11
src/test/auxiliary/orphan_check_diagnostics.rs
Normal file
@ -0,0 +1,11 @@
|
||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
pub trait RemoteTrait {}
|
22
src/test/auxiliary/plugin_with_plugin_lib.rs
Normal file
22
src/test/auxiliary/plugin_with_plugin_lib.rs
Normal file
@ -0,0 +1,22 @@
|
||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// force-host
|
||||
|
||||
#![feature(plugin_registrar)]
|
||||
#![deny(plugin_as_library)] // should have no effect in a plugin crate
|
||||
|
||||
extern crate macro_crate_test;
|
||||
extern crate rustc;
|
||||
|
||||
use rustc::plugin::Registry;
|
||||
|
||||
#[plugin_registrar]
|
||||
pub fn plugin_registrar(_: &mut Registry) { }
|
@ -16,6 +16,6 @@
|
||||
|
||||
#![feature(plugin)]
|
||||
#![plugin(rlib_crate_test)]
|
||||
//~^ ERROR: plugin crate `rlib_crate_test` only found in rlib format, but must be available in dylib format
|
||||
//~^ ERROR: plugin `rlib_crate_test` only found in rlib format, but must be available in dylib format
|
||||
|
||||
fn main() {}
|
||||
|
22
src/test/compile-fail-fulldeps/plugin-as-extern-crate.rs
Normal file
22
src/test/compile-fail-fulldeps/plugin-as-extern-crate.rs
Normal file
@ -0,0 +1,22 @@
|
||||
// Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// aux-build:macro_crate_test.rs
|
||||
// ignore-stage1
|
||||
// ignore-cross-compile
|
||||
//
|
||||
// macro_crate_test will not compile on a cross-compiled target because
|
||||
// libsyntax is not compiled for it.
|
||||
|
||||
#![deny(plugin_as_library)]
|
||||
|
||||
extern crate macro_crate_test; //~ ERROR compiler plugin used as an ordinary library
|
||||
|
||||
fn main() { }
|
27
src/test/compile-fail-fulldeps/plugin-plus-extern-crate.rs
Normal file
27
src/test/compile-fail-fulldeps/plugin-plus-extern-crate.rs
Normal file
@ -0,0 +1,27 @@
|
||||
// Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// aux-build:macro_crate_test.rs
|
||||
// ignore-stage1
|
||||
// ignore-cross-compile
|
||||
//
|
||||
// macro_crate_test will not compile on a cross-compiled target because
|
||||
// libsyntax is not compiled for it.
|
||||
|
||||
#![deny(plugin_as_library)]
|
||||
#![feature(plugin)]
|
||||
#![plugin(macro_crate_test)]
|
||||
|
||||
extern crate macro_crate_test; //~ ERROR compiler plugin used as an ordinary library
|
||||
|
||||
fn main() {
|
||||
assert_eq!(1, make_a_1!());
|
||||
macro_crate_test::foo();
|
||||
}
|
@ -16,6 +16,6 @@ use lib::Remote1;
|
||||
pub struct BigInt;
|
||||
|
||||
impl<T> Remote1<BigInt> for T { }
|
||||
//~^ ERROR type parameter `T` is not constrained
|
||||
//~^ ERROR type parameter `T` must be used as the type parameter for some local type
|
||||
|
||||
fn main() { }
|
||||
|
@ -18,6 +18,6 @@ use lib::{Remote,Pair};
|
||||
pub struct Cover<T>(T);
|
||||
|
||||
impl<T,U> Remote for Pair<Cover<T>,U> { }
|
||||
//~^ ERROR type parameter `U` is not constrained by any local type
|
||||
//~^ ERROR type parameter `U` must be used as the type parameter for some local type
|
||||
|
||||
fn main() { }
|
||||
|
@ -16,7 +16,7 @@ extern crate trait_impl_conflict;
|
||||
use trait_impl_conflict::Foo;
|
||||
|
||||
impl<A> Foo for A {
|
||||
//~^ ERROR type parameter `A` is not constrained
|
||||
//~^ ERROR type parameter `A` must be used as the type parameter for some local type
|
||||
//~^^ ERROR E0119
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
extern crate "coherence-lib" as lib;
|
||||
use lib::Remote;
|
||||
|
||||
impl<T> Remote for T { } //~ ERROR type parameter `T` is not constrained
|
||||
impl<T> Remote for T { }
|
||||
//~^ ERROR type parameter `T` must be used as the type parameter for some local type
|
||||
|
||||
fn main() { }
|
||||
|
@ -16,6 +16,6 @@ use lib::Remote;
|
||||
struct Foo;
|
||||
|
||||
impl<T> Remote for lib::Pair<T,Foo> { }
|
||||
//~^ ERROR type parameter `T` is not constrained
|
||||
//~^ ERROR type parameter `T` must be used as the type parameter for some local type
|
||||
|
||||
fn main() { }
|
||||
|
@ -18,7 +18,7 @@ use lib::{Remote1, Pair};
|
||||
|
||||
pub struct Local<T>(T);
|
||||
|
||||
impl<T,U> Remote1<Pair<T,Local<U>>> for i32 { }
|
||||
//~^ ERROR type parameter `T` is not constrained
|
||||
impl<T, U> Remote1<Pair<T, Local<U>>> for i32 { }
|
||||
//~^ ERROR type parameter `T` must be used as the type parameter for some local type
|
||||
|
||||
fn main() { }
|
||||
|
@ -16,6 +16,6 @@ use lib::{Remote, Pair};
|
||||
struct Local<T>(T);
|
||||
|
||||
impl<T,U> Remote for Pair<T,Local<U>> { }
|
||||
//~^ ERROR type parameter `T` is not constrained
|
||||
//~^ ERROR type parameter `T` must be used as the type parameter for some local type
|
||||
|
||||
fn main() { }
|
||||
|
23
src/test/compile-fail/orphan-check-diagnostics.rs
Normal file
23
src/test/compile-fail/orphan-check-diagnostics.rs
Normal file
@ -0,0 +1,23 @@
|
||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// aux-build:orphan_check_diagnostics.rs
|
||||
// see #22388
|
||||
|
||||
extern crate orphan_check_diagnostics;
|
||||
|
||||
use orphan_check_diagnostics::RemoteTrait;
|
||||
|
||||
trait LocalTrait {}
|
||||
|
||||
impl<T> RemoteTrait for T where T: LocalTrait {}
|
||||
//~^ ERROR type parameter `T` must be used as the type parameter for some local type
|
||||
|
||||
fn main() {}
|
@ -13,6 +13,7 @@
|
||||
// gdb-pretty-struct-and-enums.rs
|
||||
|
||||
// ignore-windows failing on win32 bot
|
||||
// ignore-freebsd: gdb package too new
|
||||
// ignore-tidy-linelength
|
||||
// ignore-lldb
|
||||
// ignore-android: FIXME(#10381)
|
||||
|
@ -9,6 +9,7 @@
|
||||
// except according to those terms.
|
||||
|
||||
// ignore-windows failing on win32 bot
|
||||
// ignore-freebsd: output doesn't match
|
||||
// ignore-tidy-linelength
|
||||
// ignore-lldb
|
||||
// ignore-android: FIXME(#10381)
|
||||
|
@ -1,6 +1,6 @@
|
||||
-include ../tools.mk
|
||||
|
||||
ifneq ($(UNAME),OpenBSD)
|
||||
ifneq ($(findstring BSD,$(UNAME)),BSD)
|
||||
HOST := $(shell $(RUSTC) -vV | grep 'host:' | sed 's/host: //')
|
||||
ifeq ($(findstring i686,$(HOST)),i686)
|
||||
TARGET := $(subst i686,x86_64,$(HOST))
|
||||
@ -13,6 +13,6 @@ all:
|
||||
$(RUSTC) bar.rs -C extra-filename=-targ --target $(TARGET)
|
||||
$(RUSTC) baz.rs --extern a=$(TMPDIR)/liba-targ.rlib --target $(TARGET)
|
||||
else
|
||||
# OpenBSD support only x86_64 architecture for now
|
||||
# FreeBSD & OpenBSD support only x86_64 architecture for now
|
||||
all:
|
||||
endif
|
||||
|
26
src/test/run-pass-fulldeps/plugin-lib-ok-in-plugin.rs
Normal file
26
src/test/run-pass-fulldeps/plugin-lib-ok-in-plugin.rs
Normal file
@ -0,0 +1,26 @@
|
||||
// Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// aux-build:macro_crate_test.rs
|
||||
// aux-build:plugin_with_plugin_lib.rs
|
||||
// ignore-stage1
|
||||
// ignore-cross-compile
|
||||
//
|
||||
// macro_crate_test will not compile on a cross-compiled target because
|
||||
// libsyntax is not compiled for it.
|
||||
|
||||
#![deny(plugin_as_library)]
|
||||
#![feature(plugin)]
|
||||
#![plugin(macro_crate_test)]
|
||||
#![plugin(plugin_with_plugin_lib)]
|
||||
|
||||
fn main() {
|
||||
assert_eq!(1, make_a_1!());
|
||||
}
|
@ -15,6 +15,7 @@
|
||||
// macro_crate_test will not compile on a cross-compiled target because
|
||||
// libsyntax is not compiled for it.
|
||||
|
||||
#![allow(plugin_as_library)]
|
||||
#![feature(plugin)]
|
||||
#![plugin(macro_crate_test)]
|
||||
|
||||
|
17
src/test/run-pass/issue22346.rs
Normal file
17
src/test/run-pass/issue22346.rs
Normal file
@ -0,0 +1,17 @@
|
||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// This used to cause an ICE because the retslot for the "return" had the wrong type
|
||||
fn testcase<'a>() -> Box<Iterator<Item=usize> + 'a> {
|
||||
return Box::new(range(0, 3).map(|i| { return i; }));
|
||||
}
|
||||
|
||||
fn main() {
|
||||
}
|
Loading…
Reference in New Issue
Block a user