When looking through the `btree` code, I stumbled over a couple of `unwraps` that could be avoided.
formatted flowgraph for node)
.TP
\fB\-\-dep-info\fR [FILENAME]
-Output dependency info to <filename> after compiling, in o format suitable
+Output dependency info to <filename> after compiling, in a format suitable
for use by Makefiles.
.TP
\fB\-\-sysroot\fR PATH
ifeq ($$(OSTYPE_$(3)),apple-darwin)
LD_LIBRARY_PATH_ENV_NAME$(1)_T_$(2)_H_$(3) := DYLD_LIBRARY_PATH
else
-ifeq ($$(CFG_WINDOWSY_$(2)),1)
+ifeq ($$(CFG_WINDOWSY_$(3)),1)
LD_LIBRARY_PATH_ENV_NAME$(1)_T_$(2)_H_$(3) := PATH
else
LD_LIBRARY_PATH_ENV_NAME$(1)_T_$(2)_H_$(3) := LD_LIBRARY_PATH
optflag("h", "help", "show this message"));
assert!(!args.is_empty());
- let argv0 = (*args.get(0)).clone();
+ let argv0 = args[0].clone();
let args_ = args.tail();
- if args.get(1).as_slice() == "-h" || args.get(1).as_slice() == "--help" {
+ if args[1].as_slice() == "-h" || args[1].as_slice() == "--help" {
let message = format!("Usage: {} [OPTIONS] [TESTNAME...]", argv0);
println!("{}", getopts::usage(message.as_slice(), groups.as_slice()));
println!("");
}
let filter = if !matches.free.is_empty() {
- let s = matches.free.get(0).as_slice();
+ let s = matches.free[0].as_slice();
match regex::Regex::new(s) {
Ok(re) => Some(re),
Err(e) => {
let proc_res = print_source(config,
props,
testfile,
- (*srcs.get(round)).to_string(),
+ srcs[round].to_string(),
"normal");
if !proc_res.status.success() {
let s = File::open(&filepath).read_to_end().unwrap();
String::from_utf8(s).unwrap()
}
- None => { (*srcs.get(srcs.len() - 2u)).clone() }
+ None => { srcs[srcs.len() - 2u].clone() }
};
- let mut actual = (*srcs.get(srcs.len() - 1u)).clone();
+ let mut actual = srcs[srcs.len() - 1u].clone();
if props.pp_exact.is_some() {
// Now we have to care about line endings
if props.no_pretty_expanded { return }
// additionally, run `--pretty expanded` and try to build it.
- let proc_res = print_source(config, props, testfile, (*srcs.get(round)).clone(), "expanded");
+ let proc_res = print_source(config, props, testfile, srcs[round].clone(), "expanded");
if !proc_res.status.success() {
fatal_proc_rec("pretty-printing (expanded) failed", &proc_res);
}
let mut rest = line.trim();
let mut first = true;
let mut failed = false;
- for frag in check_fragments.get(i).iter() {
+ for frag in check_fragments[i].iter() {
let found = if first {
if rest.starts_with(frag.as_slice()) {
Some(0)
}
let mut next_err_idx = 0u;
- let mut next_err_pat = props.error_patterns.get(next_err_idx);
+ let mut next_err_pat = &props.error_patterns[next_err_idx];
let mut done = false;
let output_to_check = if props.check_stdout {
format!("{}{}", proc_res.stdout, proc_res.stderr)
};
for line in output_to_check.as_slice().lines() {
if line.contains(next_err_pat.as_slice()) {
- debug!("found error pattern {}", *next_err_pat);
+ debug!("found error pattern {}", next_err_pat);
next_err_idx += 1u;
if next_err_idx == props.error_patterns.len() {
debug!("found all error patterns");
done = true;
break;
}
- next_err_pat = props.error_patterns.get(next_err_idx);
+ next_err_pat = &props.error_patterns[next_err_idx];
}
}
if done { return; }
for line in proc_res.stderr.as_slice().lines() {
let mut was_expected = false;
for (i, ee) in expected_errors.iter().enumerate() {
- if !*found_flags.get(i) {
+ if !found_flags[i] {
debug!("prefix={} ee.kind={} ee.msg={} line={}",
- prefixes.get(i).as_slice(),
+ prefixes[i].as_slice(),
ee.kind,
ee.msg,
line);
- if prefix_matches(line, prefixes.get(i).as_slice()) &&
+ if prefix_matches(line, prefixes[i].as_slice()) &&
line.contains(ee.kind.as_slice()) &&
line.contains(ee.msg.as_slice()) {
*found_flags.get_mut(i) = true;
for (i, &flag) in found_flags.iter().enumerate() {
if !flag {
- let ee = expected_errors.get(i);
+ let ee = &expected_errors[i];
fatal_proc_rec(format!("expected {} on line {} not found: {}",
ee.kind, ee.line, ee.msg).as_slice(),
proc_res);
## Does it run on Windows?
-Yes. All development happens in lock-step on all 3 target platforms. Using MinGW, not Cygwin. Note that the windows implementation currently has some limitations: in particular 64-bit build is [not fully supported yet][win64], and all executables created by rustc [depends on libgcc DLL at runtime][libgcc].
+Yes. All development happens in lock-step on all 3 target platforms. Using MinGW, not Cygwin. Note that the windows implementation currently has some limitations: in particular 64-bit build is [not fully supported yet][win64], and all executables created by rustc [depend on libgcc DLL at runtime][libgcc].
[win64]: https://github.com/rust-lang/rust/issues/1237
[libgcc]: https://github.com/rust-lang/rust/issues/11782
## Why aren't modules type-parametric?
-We want to maintain the option to parametrize at runtime. We may make eventually change this limitation, but initially this is how type parameters were implemented.
+We want to maintain the option to parametrize at runtime. We may eventually change this limitation, but initially this is how type parameters were implemented.
## Why aren't values type-parametric? Why only items?
# let on_the_stack : Point = Point{x: 3.0, y: 4.0};
# let on_the_heap : Box<Point> = box Point{x: 7.0, y: 9.0};
# fn compute_distance(p1: &Point, p2: &Point) -> f64 { 0.0 }
-compute_distance(&on_the_stack, on_the_heap);
+compute_distance(&on_the_stack, &*on_the_heap);
~~~
Here, the `&` operator takes the address of the variable
`on_the_stack`, because we have created an alias: that is, another
name for the same data.
-In the case of `on_the_heap`, however, no explicit action is necessary.
-The compiler will automatically convert a box point to a reference like &point.
-This is another form of borrowing; in this case, the contents of the owned box
-are being lent out.
+Likewise, in the case of `owned_box`,
+the `&` operator is used in conjunction with the `*` operator
+to take a reference to the contents of the box.
Whenever a caller lends data to a callee, there are some limitations on what
the caller can do with the original. For example, if the contents of a
let origin = &Point { x: 0.0, y: 0.0 };
let p1 = box Point { x: 5.0, y: 3.0 };
- println!("{}", compute_distance(origin, p1));
+ println!("{}", compute_distance(origin, &*p1));
}
~~~
--- /dev/null
+% The Strings Guide
+
+# Strings
+
+Strings are an important concept to master in any programming language. If you
+come from a managed language background, you may be surprised at the complexity
+of string handling in a systems programming language. Efficient access and
+allocation of memory for a dynamically sized structure involves a lot of
+details. Luckily, Rust has lots of tools to help us here.
+
+A **string** is a sequence of unicode scalar values encoded as a stream of
+UTF-8 bytes. All strings are guaranteed to be validly-encoded UTF-8 sequences.
+Additionally, strings are not null-terminated and can contain null bytes.
+
+Rust has two main types of strings: `&str` and `String`.
+
+## &str
+
+The first kind is a `&str`. This is pronounced a 'string slice.' String literals
+are of the type `&str`:
+
+```{rust}
+let string = "Hello there.";
+```
+
+Like any Rust type, string slices have an associated lifetime. A string literal
+is a `&'static str`. A string slice can be written without an explicit
+lifetime in many cases, such as in function arguments. In these cases the
+lifetime will be inferred:
+
+```{rust}
+fn takes_slice(slice: &str) {
+ println!("Got: {}", slice);
+}
+```
+
+Like vector slices, string slices are simply a pointer plus a length. This
+means that they're a 'view' into an already-allocated string, such as a
+`&'static str` or a `String`.
+
+## String
+
+A `String` is a heap-allocated string. This string is growable, and is also
+guaranteed to be UTF-8.
+
+```{rust}
+let mut s = "Hello".to_string();
+println!("{}", s);
+
+s.push_str(", world.");
+println!("{}", s);
+```
+
+You can coerce a `String` into a `&str` with the `as_slice()` method:
+
+```{rust}
+fn takes_slice(slice: &str) {
+ println!("Got: {}", slice);
+}
+
+fn main() {
+ let s = "Hello".to_string();
+ takes_slice(s.as_slice());
+}
+```
+
+You can also get a `&str` from a stack-allocated array of bytes:
+
+```{rust}
+use std::str;
+
+let x: &[u8] = &[b'a', b'b'];
+let stack_str: &str = str::from_utf8(x).unwrap();
+```
+
+## Best Practices
+
+### `String` vs. `&str`
+
+In general, you should prefer `String` when you need ownership, and `&str` when
+you just need to borrow a string. This is very similar to using `Vec<T>` vs. `&[T]`,
+and `T` vs `&T` in general.
+
+This means starting off with this:
+
+```{rust,ignore}
+fn foo(s: &str) {
+```
+
+and only moving to this:
+
+```{rust,ignore}
+fn foo(s: String) {
+```
+
+If you have good reason. It's not polite to hold on to ownership you don't
+need, and it can make your lifetimes more complex. Furthermore, you can pass
+either kind of string into `foo` by using `.as_slice()` on any `String` you
+need to pass in, so the `&str` version is more flexible.
+
+### Comparisons
+
+To compare a String to a constant string, prefer `as_slice()`...
+
+```{rust}
+fn compare(string: String) {
+ if string.as_slice() == "Hello" {
+ println!("yes");
+ }
+}
+```
+
+... over `to_string()`:
+
+```{rust}
+fn compare(string: String) {
+ if string == "Hello".to_string() {
+ println!("yes");
+ }
+}
+```
+
+Converting a `String` to a `&str` is cheap, but converting the `&str` to a
+`String` involves an allocation.
+
+## Other Documentation
+
+* [the `&str` API documentation](/std/str/index.html)
+* [the `String` API documentation](std/string/index.html)
spawn(proc() {
let numbers = rx.recv();
- println!("{}", *numbers.get(0));
+ println!("{}", numbers[0]);
})
}
```
spawn(proc() {
let numbers = rx.recv();
- println!("{}", numbers.get(0));
+ println!("{}", numbers[0]);
});
// Try to print a number from the original task
- println!("{}", *numbers.get(0));
+ println!("{}", numbers[0]);
}
```
```text
concurrency.rs:12:20: 12:27 error: use of moved value: 'numbers'
-concurrency.rs:12 println!("{}", numbers.get(0));
+concurrency.rs:12 println!("{}", numbers[0]);
^~~~~~~
```
spawn(proc() {
let numbers = rx.recv();
- println!("{:d}", *numbers.get(num as uint));
+ println!("{:d}", numbers[num as uint]);
})
}
}
spawn(proc() {
let numbers = rx.recv();
- println!("{:d}", *numbers.get(num as uint));
+ println!("{:d}", (*numbers)[num as uint]);
})
}
}
// See: https://github.com/rust-lang/rust/issues/6515
*numbers.get_mut(num as uint) = *numbers.get_mut(num as uint) + 1;
- println!("{}", *numbers.get(num as uint));
+ println!("{}", (*numbers)[num as uint]);
// When `numbers` goes out of scope the lock is dropped
})
fn is_sorted(list: &List) -> bool {
match *list {
Nil | Cons(_, box Nil) => true,
- Cons(x, ref r @ box Cons(y, _)) => (x <= y) && is_sorted(*r)
+ Cons(x, ref r @ box Cons(y, _)) => (x <= y) && is_sorted(&**r)
}
}
# let on_the_stack : Point = Point { x: 3.0, y: 4.0 };
# let on_the_heap : Box<Point> = box Point { x: 7.0, y: 9.0 };
# fn compute_distance(p1: &Point, p2: &Point) -> f64 { 0.0 }
-compute_distance(&on_the_stack, on_the_heap);
+compute_distance(&on_the_stack, &*on_the_heap);
~~~
Here the `&` operator is used to take the address of the variable
`on_the_stack`, because we are creating an alias: that is, another
route to the same data.
-In the case of `owned_box`, however, no
-explicit action is necessary. The compiler will automatically convert
-a box `box point` to a reference like
-`&point`. This is another form of borrowing; in this case, the
-contents of the owned box are being lent out.
+Likewise, in the case of `owned_box`,
+the `&` operator is used in conjunction with the `*` operator
+to take a reference to the contents of the box.
Whenever a value is borrowed, there are some limitations on what you
can do with the original. For example, if the contents of a variable
fn print_all<T: Printable + Clone>(printable_things: Vec<T>) {
let mut i = 0;
while i < printable_things.len() {
- let copy_of_thing = printable_things.get(i).clone();
+ let copy_of_thing = printable_things[i].clone();
copy_of_thing.print();
i += 1;
}
impl<T:PartialOrd> PartialOrd for Box<T> {
#[inline]
fn partial_cmp(&self, other: &Box<T>) -> Option<Ordering> {
- (**self).partial_cmp(*other)
+ (**self).partial_cmp(&**other)
}
#[inline]
fn lt(&self, other: &Box<T>) -> bool { *(*self) < *(*other) }
}
impl<T: Ord> Ord for Box<T> {
#[inline]
- fn cmp(&self, other: &Box<T>) -> Ordering { (**self).cmp(*other) }
+ fn cmp(&self, other: &Box<T>) -> Ordering {
+ (**self).cmp(&**other)
+ }
}
impl<T: Eq> Eq for Box<T> {}
/// Extension methods for vector slices with cloneable elements
pub trait CloneableVector<T> {
- /// Copy `self` into a new owned vector
- fn to_owned(&self) -> Vec<T>;
+ /// Copy `self` into a new vector
+ fn to_vec(&self) -> Vec<T>;
+
+ /// Deprecated. Use `to_vec`
+ #[deprecated = "Replaced by `to_vec`"]
+ fn to_owned(&self) -> Vec<T> {
+ self.to_vec()
+ }
/// Convert `self` into an owned vector, not making a copy if possible.
- fn into_owned(self) -> Vec<T>;
+ fn into_vec(self) -> Vec<T>;
+
+ /// Deprecated. Use `into_vec`
+ #[deprecated = "Replaced by `into_vec`"]
+ fn into_owned(self) -> Vec<T> {
+ self.into_vec()
+ }
}
/// Extension methods for vector slices
impl<'a, T: Clone> CloneableVector<T> for &'a [T] {
/// Returns a copy of `v`.
#[inline]
- fn to_owned(&self) -> Vec<T> { Vec::from_slice(*self) }
+ fn to_vec(&self) -> Vec<T> { Vec::from_slice(*self) }
#[inline(always)]
- fn into_owned(self) -> Vec<T> { self.to_owned() }
+ fn into_vec(self) -> Vec<T> { self.to_vec() }
}
/// Extension methods for vectors containing `Clone` elements.
fn permutations(self) -> Permutations<T> {
Permutations{
swaps: ElementSwaps::new(self.len()),
- v: self.to_owned(),
+ v: self.to_vec(),
}
}
fn test_slice() {
// Test fixed length vector.
let vec_fixed = [1i, 2, 3, 4];
- let v_a = vec_fixed.slice(1u, vec_fixed.len()).to_owned();
+ let v_a = vec_fixed.slice(1u, vec_fixed.len()).to_vec();
assert_eq!(v_a.len(), 3u);
let v_a = v_a.as_slice();
assert_eq!(v_a[0], 2);
// Test on stack.
let vec_stack = &[1i, 2, 3];
- let v_b = vec_stack.slice(1u, 3u).to_owned();
+ let v_b = vec_stack.slice(1u, 3u).to_vec();
assert_eq!(v_b.len(), 2u);
let v_b = v_b.as_slice();
assert_eq!(v_b[0], 2);
// Test `Box<[T]>`
let vec_unique = vec![1i, 2, 3, 4, 5, 6];
- let v_d = vec_unique.slice(1u, 6u).to_owned();
+ let v_d = vec_unique.slice(1u, 6u).to_vec();
assert_eq!(v_d.len(), 5u);
let v_d = v_d.as_slice();
assert_eq!(v_d[0], 2);
let (min_size, max_opt) = it.size_hint();
assert_eq!(min_size, 1);
assert_eq!(max_opt.unwrap(), 1);
- assert_eq!(it.next(), Some(v.as_slice().to_owned()));
+ assert_eq!(it.next(), Some(v.as_slice().to_vec()));
assert_eq!(it.next(), None);
}
{
let (min_size, max_opt) = it.size_hint();
assert_eq!(min_size, 1);
assert_eq!(max_opt.unwrap(), 1);
- assert_eq!(it.next(), Some(v.as_slice().to_owned()));
+ assert_eq!(it.next(), Some(v.as_slice().to_vec()));
assert_eq!(it.next(), None);
}
{
# Representation
-Rust's string type, `str`, is a sequence of unicode codepoints encoded as a
-stream of UTF-8 bytes. All safely-created strings are guaranteed to be validly
-encoded UTF-8 sequences. Additionally, strings are not null-terminated
-and can contain null codepoints.
+Rust's string type, `str`, is a sequence of unicode scalar values encoded as a
+stream of UTF-8 bytes. All strings are guaranteed to be validly encoded UTF-8
+sequences. Additionally, strings are not null-terminated and can contain null
+bytes.
The actual representation of strings have direct mappings to vectors: `&str`
is the same as `&[u8]`.
//! An ordered map and set implemented as self-balancing binary search
//! trees. The only requirement for the types is that the key implements
//! `Ord`.
+//!
+//! ## Example
+//!
+//! ```{rust}
+//! use std::collections::TreeSet;
+//!
+//! let mut tree_set = TreeSet::new();
+//!
+//! tree_set.insert(2i);
+//! tree_set.insert(1i);
+//! tree_set.insert(3i);
+//!
+//! for i in tree_set.iter() {
+//! println!("{}", i) // prints 1, then 2, then 3
+//! }
+//! ```
use core::prelude::*;
fn deref<'a, K, V>(node: &'a Option<Box<TreeNode<K, V>>>) -> *const TreeNode<K, V> {
match *node {
Some(ref n) => {
- let n: &TreeNode<K, V> = *n;
+ let n: &TreeNode<K, V> = &**n;
n as *const TreeNode<K, V>
}
None => ptr::null()
/// A implementation of the `Set` trait on top of the `TreeMap` container. The
/// only requirement is that the type of the elements contained ascribes to the
/// `Ord` trait.
+///
+/// ## Example
+///
+/// ```{rust}
+/// use std::collections::TreeSet;
+///
+/// let mut tree_set = TreeSet::new();
+///
+/// tree_set.insert(2i);
+/// tree_set.insert(1i);
+/// tree_set.insert(3i);
+///
+/// for i in tree_set.iter() {
+/// println!("{}", i) // prints 1, then 2, then 3
+/// }
+/// ```
#[deriving(Clone)]
pub struct TreeSet<T> {
map: TreeMap<T, ()>
/// vec.push(2i);
///
/// assert_eq!(vec.len(), 2);
-/// assert_eq!(vec.get(0), &1);
+/// assert_eq!(vec[0], 1);
///
/// assert_eq!(vec.pop(), Some(2));
/// assert_eq!(vec.len(), 1);
}
}
+impl<T> Index<uint,T> for Vec<T> {
+ #[inline]
+ fn index<'a>(&'a self, index: &uint) -> &'a T {
+ self.get(*index)
+ }
+}
+
+// FIXME(#12825) Indexing will always try IndexMut first and that causes issues.
+/*impl<T> IndexMut<uint,T> for Vec<T> {
+ #[inline]
+ fn index_mut<'a>(&'a mut self, index: &uint) -> &'a mut T {
+ self.get_mut(*index)
+ }
+}*/
+
impl<T> FromIterator<T> for Vec<T> {
#[inline]
fn from_iter<I:Iterator<T>>(mut iterator: I) -> Vec<T> {
}
impl<T: Clone> CloneableVector<T> for Vec<T> {
- fn to_owned(&self) -> Vec<T> { self.clone() }
- fn into_owned(self) -> Vec<T> { self }
+ fn to_vec(&self) -> Vec<T> { self.clone() }
+ fn into_vec(self) -> Vec<T> { self }
}
// FIXME: #13996: need a way to mark the return value as `noalias`
/// # Example
///
/// ```rust
+ /// #![allow(deprecated)]
+ ///
/// let vec = vec!(1i, 2, 3);
/// assert!(vec.get(1) == &2);
/// ```
+ #[deprecated="prefer using indexing, e.g., vec[0]"]
#[inline]
pub fn get<'a>(&'a self, index: uint) -> &'a T {
&self.as_slice()[index]
v.truncate(0);
}
+ #[test]
+ fn test_index() {
+ let vec = vec!(1i, 2, 3);
+ assert!(vec[1] == 2);
+ }
+
+ #[test]
+ #[should_fail]
+ fn test_index_out_of_bounds() {
+ let vec = vec!(1i, 2, 3);
+ let _ = vec[3];
+ }
+
#[bench]
fn bench_new(b: &mut Bencher) {
b.iter(|| {
_offset: uint,
inner: *const TyDesc)
-> bool {
- match *self.var_stk.get(self.var_stk.len() - 1) {
+ match self.var_stk[self.var_stk.len() - 1] {
Matched => {
if i != 0 {
try!(self, self.writer.write(", ".as_bytes()));
_disr_val: Disr,
n_fields: uint,
_name: &str) -> bool {
- match *self.var_stk.get(self.var_stk.len() - 1) {
+ match self.var_stk[self.var_stk.len() - 1] {
Matched => {
if n_fields > 0 {
try!(self, self.writer.write([')' as u8]));
//! fn main() {
//! let args: Vec<String> = os::args();
//!
-//! let program = args.get(0).clone();
+//! let program = args[0].clone();
//!
//! let opts = [
//! optopt("o", "", "set output file name", "NAME"),
//! }
//! let output = matches.opt_str("o");
//! let input = if !matches.free.is_empty() {
-//! (*matches.free.get(0)).clone()
+//! matches.free[0].clone()
//! } else {
//! print_usage(program.as_slice(), opts);
//! return;
impl Matches {
fn opt_vals(&self, nm: &str) -> Vec<Optval> {
match find_opt(self.opts.as_slice(), Name::from_str(nm)) {
- Some(id) => (*self.vals.get(id)).clone(),
+ Some(id) => self.vals[id].clone(),
None => fail!("No option '{}' defined", nm)
}
}
if vals.is_empty() {
None
} else {
- Some((*vals.get(0)).clone())
+ Some(vals[0].clone())
}
}
for nm in names.iter() {
match find_opt(self.opts.as_slice(),
Name::from_str(nm.as_slice())) {
- Some(id) if !self.vals.get(id).is_empty() => return true,
+ Some(id) if !self.vals[id].is_empty() => return true,
_ => (),
};
}
if vals.is_empty() {
return None::<String>;
}
- match vals.get(0) {
- &Val(ref s) => Some((*s).clone()),
+ match vals[0] {
+ Val(ref s) => Some((*s).clone()),
_ => None
}
}
if vals.is_empty() {
return None;
}
- match vals.get(0) {
- &Val(ref s) => Some((*s).clone()),
+ match vals[0] {
+ Val(ref s) => Some((*s).clone()),
_ => Some(def.to_string())
}
}
names = vec!(Long(tail.to_string()));
} else {
names =
- vec!(Long((*tail_eq.get(0)).to_string()));
- i_arg = Some((*tail_eq.get(1)).to_string());
+ vec!(Long(tail_eq[0].to_string()));
+ i_arg = Some(tail_eq[1].to_string());
}
} else {
let mut j = 1;
None => {
let arg_follows =
last_valid_opt_id.is_some() &&
- match opts.get(last_valid_opt_id.unwrap())
+ match opts[last_valid_opt_id.unwrap()]
.hasarg {
Yes | Maybe => true,
Some(id) => id,
None => return Err(UnrecognizedOption(nm.to_string()))
};
- match opts.get(optid).hasarg {
+ match opts[optid].hasarg {
No => {
if !i_arg.is_none() {
return Err(UnexpectedArgument(nm.to_string()));
}
i = 0u;
while i < n_opts {
- let n = vals.get(i).len();
- let occ = opts.get(i).occur;
+ let n = vals[i].len();
+ let occ = opts[i].occur;
if occ == Req {
if n == 0 {
- return Err(OptionMissing(opts.get(i).name.to_string()));
+ return Err(OptionMissing(opts[i].name.to_string()));
}
}
if occ != Multi {
if n > 1 {
- return Err(OptionDuplicated(opts.get(i).name.to_string()));
+ return Err(OptionDuplicated(opts[i].name.to_string()));
}
}
i += 1;
if self.require_dir && !path.is_dir() { continue; }
return Some(path);
}
- let ref pattern = *self.dir_patterns.get(idx);
+ let ref pattern = self.dir_patterns[idx];
if pattern.matches_with(match path.filename_str() {
// this ugly match needs to go here to avoid a borrowck error
let mut i = 0;
while i < chars.len() {
- match *chars.get(i) {
+ match chars[i] {
'?' => {
tokens.push(AnyChar);
i += 1;
}
'*' => {
// *, **, ***, ****, ... are all equivalent
- while i < chars.len() && *chars.get(i) == '*' {
+ while i < chars.len() && chars[i] == '*' {
i += 1;
}
tokens.push(AnySequence);
}
'[' => {
- if i <= chars.len() - 4 && *chars.get(i + 1) == '!' {
+ if i <= chars.len() - 4 && chars[i + 1] == '!' {
match chars.slice_from(i + 3).position_elem(&']') {
None => (),
Some(j) => {
}
}
}
- else if i <= chars.len() - 3 && *chars.get(i + 1) != '!' {
+ else if i <= chars.len() - 3 && chars[i + 1] != '!' {
match chars.slice_from(i + 2).position_elem(&']') {
None => (),
Some(j) => {
// the current and parent directory respectively requires that
// the pattern has a leading dot, even if the `MatchOptions` field
// `require_literal_leading_dot` is not set.
- if pattern.tokens.len() > 0 && pattern.tokens.get(0) == &Char('.') {
+ if pattern.tokens.len() > 0 && pattern.tokens[0] == Char('.') {
for &special in [".", ".."].iter() {
if pattern.matches_with(special, options) {
add(todo, path.join(special));
dot::Id::new(format!("N{}", n))
}
fn node_label<'a>(&'a self, n: &Nd) -> dot::LabelText<'a> {
- dot::LabelStr(str::Slice(self.nodes.get(*n).as_slice()))
+ dot::LabelStr(str::Slice(self.nodes[*n].as_slice()))
}
fn edge_label<'a>(&'a self, _: &Ed) -> dot::LabelText<'a> {
dot::LabelStr(str::Slice("⊆"))
}
fn node_label<'a>(&'a self, n: &Nd<'a>) -> dot::LabelText<'a> {
let &(i, _) = n;
- dot::LabelStr(str::Slice(self.nodes.get(i).as_slice()))
+ dot::LabelStr(str::Slice(self.nodes[i].as_slice()))
}
fn edge_label<'a>(&'a self, _: &Ed<'a>) -> dot::LabelText<'a> {
dot::LabelStr(str::Slice("⊆"))
}
fn edges(&'a self) -> dot::Edges<'a,Ed<'a>> {
self.edges.iter()
- .map(|&(i,j)|((i, self.nodes.get(i).as_slice()),
- (j, self.nodes.get(j).as_slice())))
+ .map(|&(i,j)|((i, self.nodes[i].as_slice()),
+ (j, self.nodes[j].as_slice())))
.collect()
}
fn source(&self, e: &Ed<'a>) -> Nd<'a> { let &(s,_) = e; s }
impl<'a,T:Clone> CloneableVector<T> for MaybeOwnedVector<'a,T> {
/// Returns a copy of `self`.
- fn to_owned(&self) -> Vec<T> {
- self.as_slice().to_owned()
+ fn to_vec(&self) -> Vec<T> {
+ self.as_slice().to_vec()
}
/// Convert `self` into an owned slice, not making a copy if possible.
- fn into_owned(self) -> Vec<T> {
+ fn into_vec(self) -> Vec<T> {
match self {
- Growable(v) => v.as_slice().to_owned(),
- Borrowed(v) => v.to_owned(),
+ Growable(v) => v.as_slice().to_vec(),
+ Borrowed(v) => v.to_vec(),
}
}
}
impl<'a, T: Clone> Clone for MaybeOwnedVector<'a, T> {
fn clone(&self) -> MaybeOwnedVector<'a, T> {
match *self {
- Growable(ref v) => Growable(v.to_owned()),
+ Growable(ref v) => Growable(v.to_vec()),
Borrowed(v) => Borrowed(v)
}
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-/*!
-
-A Big integer (signed version: `BigInt`, unsigned version: `BigUint`).
-
-A `BigUint` is represented as an array of `BigDigit`s.
-A `BigInt` is a combination of `BigUint` and `Sign`.
-*/
+//! A Big integer (signed version: `BigInt`, unsigned version: `BigUint`).
+//!
+//! A `BigUint` is represented as an array of `BigDigit`s.
+//! A `BigInt` is a combination of `BigUint` and `Sign`.
+//!
+//! Common numerical operations are overloaded, so we can treat them
+//! the same way we treat other numbers.
+//!
+//! ## Example
+//!
+//! ```rust
+//! use num::bigint::BigUint;
+//! use std::num::{Zero, One};
+//! use std::mem::replace;
+//!
+//! // Calculate large fibonacci numbers.
+//! fn fib(n: uint) -> BigUint {
+//! let mut f0: BigUint = Zero::zero();
+//! let mut f1: BigUint = One::one();
+//! for _ in range(0, n) {
+//! let f2 = f0 + f1;
+//! // This is a low cost way of swapping f0 with f1 and f1 with f2.
+//! f0 = replace(&mut f1, f2);
+//! }
+//! f0
+//! }
+//!
+//! // This is a very large number.
+//! println!("fib(1000) = {}", fib(1000));
+//! ```
+//!
+//! It's easy to generate large random numbers:
+//!
+//! ```rust
+//! use num::bigint::{ToBigInt, RandBigInt};
+//! use std::rand;
+//!
+//! let mut rng = rand::task_rng();
+//! let a = rng.gen_bigint(1000u);
+//!
+//! let low = -10000i.to_bigint().unwrap();
+//! let high = 10000i.to_bigint().unwrap();
+//! let b = rng.gen_bigint_range(&low, &high);
+//!
+//! // Probably an even larger number.
+//! println!("{}", a * b);
+//! ```
use Integer;
use rand::Rng;
use std::string::String;
use std::{uint, i64, u64};
-/**
-A `BigDigit` is a `BigUint`'s composing element.
-*/
+/// A `BigDigit` is a `BigUint`'s composing element.
pub type BigDigit = u32;
-/**
-A `DoubleBigDigit` is the internal type used to do the computations. Its
-size is the double of the size of `BigDigit`.
-*/
+/// A `DoubleBigDigit` is the internal type used to do the computations. Its
+/// size is the double of the size of `BigDigit`.
pub type DoubleBigDigit = u64;
pub static ZERO_BIG_DIGIT: BigDigit = 0;
}
}
-/**
-A big unsigned integer type.
-
-A `BigUint`-typed value `BigUint { data: vec!(a, b, c) }` represents a number
-`(a + b * BigDigit::base + c * BigDigit::base^2)`.
-*/
+/// A big unsigned integer type.
+///
+/// A `BigUint`-typed value `BigUint { data: vec!(a, b, c) }` represents a number
+/// `(a + b * BigDigit::base + c * BigDigit::base^2)`.
#[deriving(Clone)]
pub struct BigUint {
data: Vec<BigDigit>
}
}
- /**
- * Calculates the Greatest Common Divisor (GCD) of the number and `other`
- *
- * The result is always positive
- */
+ /// Calculates the Greatest Common Divisor (GCD) of the number and `other`.
+ ///
+ /// The result is always positive.
#[inline]
fn gcd(&self, other: &BigUint) -> BigUint {
// Use Euclid's algorithm
return n;
}
- /**
- * Calculates the Lowest Common Multiple (LCM) of the number and `other`
- */
+ /// Calculates the Lowest Common Multiple (LCM) of the number and `other`.
#[inline]
fn lcm(&self, other: &BigUint) -> BigUint { ((*self * *other) / self.gcd(other)) }
- /// Returns `true` if the number can be divided by `other` without leaving a remainder
+ /// Returns `true` if the number can be divided by `other` without leaving a remainder.
#[inline]
fn divides(&self, other: &BigUint) -> bool { (*self % *other).is_zero() }
- /// Returns `true` if the number is divisible by `2`
+ /// Returns `true` if the number is divisible by `2`.
#[inline]
fn is_even(&self) -> bool {
// Considering only the last digit.
}
}
- /// Returns `true` if the number is not divisible by `2`
+ /// Returns `true` if the number is not divisible by `2`.
#[inline]
fn is_odd(&self) -> bool { !self.is_even() }
}
}
}
- /**
- * Calculates the Greatest Common Divisor (GCD) of the number and `other`
- *
- * The result is always positive
- */
+ /// Calculates the Greatest Common Divisor (GCD) of the number and `other`.
+ ///
+ /// The result is always positive.
#[inline]
fn gcd(&self, other: &BigInt) -> BigInt {
BigInt::from_biguint(Plus, self.data.gcd(&other.data))
}
- /**
- * Calculates the Lowest Common Multiple (LCM) of the number and `other`
- */
+ /// Calculates the Lowest Common Multiple (LCM) of the number and `other`.
#[inline]
fn lcm(&self, other: &BigInt) -> BigInt {
BigInt::from_biguint(Plus, self.data.lcm(&other.data))
}
- /// Returns `true` if the number can be divided by `other` without leaving a remainder
+ /// Returns `true` if the number can be divided by `other` without leaving a remainder.
#[inline]
fn divides(&self, other: &BigInt) -> bool { self.data.divides(&other.data) }
- /// Returns `true` if the number is divisible by `2`
+ /// Returns `true` if the number is divisible by `2`.
#[inline]
fn is_even(&self) -> bool { self.data.is_even() }
- /// Returns `true` if the number is not divisible by `2`
+ /// Returns `true` if the number is not divisible by `2`.
#[inline]
fn is_odd(&self) -> bool { self.data.is_odd() }
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-//! Integer trait and functions
+//! Integer trait and functions.
pub trait Integer: Num + PartialOrd
+ Div<Self, Self>
+ Rem<Self, Self> {
- /// Simultaneous truncated integer division and modulus
- #[inline]
- fn div_rem(&self, other: &Self) -> (Self, Self) {
- (*self / *other, *self % *other)
- }
-
- /// Floored integer division
+ /// Floored integer division.
///
/// # Examples
///
/// ~~~
fn mod_floor(&self, other: &Self) -> Self;
- /// Simultaneous floored integer division and modulus
- fn div_mod_floor(&self, other: &Self) -> (Self, Self) {
- (self.div_floor(other), self.mod_floor(other))
- }
-
- /// Greatest Common Divisor (GCD)
+ /// Greatest Common Divisor (GCD).
+ ///
+ /// # Examples
+ ///
+ /// ~~~
+ /// # use num::Integer;
+ /// assert_eq!(6i.gcd(&8), 2);
+ /// assert_eq!(7i.gcd(&3), 1);
+ /// ~~~
fn gcd(&self, other: &Self) -> Self;
- /// Lowest Common Multiple (LCM)
+ /// Lowest Common Multiple (LCM).
+ ///
+ /// # Examples
+ ///
+ /// ~~~
+ /// # use num::Integer;
+ /// assert_eq!(7i.lcm(&3), 21);
+ /// assert_eq!(2i.lcm(&4), 4);
+ /// ~~~
fn lcm(&self, other: &Self) -> Self;
- /// Returns `true` if `other` divides evenly into `self`
+ /// Returns `true` if `other` divides evenly into `self`.
+ ///
+ /// # Examples
+ ///
+ /// ~~~
+ /// # use num::Integer;
+ /// assert_eq!(9i.divides(&3), true);
+ /// assert_eq!(3i.divides(&9), false);
+ /// ~~~
fn divides(&self, other: &Self) -> bool;
- /// Returns `true` if the number is even
+ /// Returns `true` if the number is even.
+ ///
+ /// # Examples
+ ///
+ /// ~~~
+ /// # use num::Integer;
+ /// assert_eq!(3i.is_even(), false);
+ /// assert_eq!(4i.is_even(), true);
+ /// ~~~
fn is_even(&self) -> bool;
- /// Returns `true` if the number is odd
+ /// Returns `true` if the number is odd.
+ ///
+ /// # Examples
+ ///
+ /// ~~~
+ /// # use num::Integer;
+ /// assert_eq!(3i.is_odd(), true);
+ /// assert_eq!(4i.is_odd(), false);
+ /// ~~~
fn is_odd(&self) -> bool;
+
+ /// Simultaneous truncated integer division and modulus.
+ /// Returns `(quotient, remainder)`.
+ ///
+ /// # Examples
+ ///
+ /// ~~~
+ /// # use num::Integer;
+ /// assert_eq!(( 8i).div_rem( &3), ( 2, 2));
+ /// assert_eq!(( 8i).div_rem(&-3), (-2, 2));
+ /// assert_eq!((-8i).div_rem( &3), (-2, -2));
+ /// assert_eq!((-8i).div_rem(&-3), ( 2, -2));
+ ///
+ /// assert_eq!(( 1i).div_rem( &2), ( 0, 1));
+ /// assert_eq!(( 1i).div_rem(&-2), ( 0, 1));
+ /// assert_eq!((-1i).div_rem( &2), ( 0, -1));
+ /// assert_eq!((-1i).div_rem(&-2), ( 0, -1));
+ /// ~~~
+ #[inline]
+ fn div_rem(&self, other: &Self) -> (Self, Self) {
+ (*self / *other, *self % *other)
+ }
+
+ /// Simultaneous floored integer division and modulus.
+ /// Returns `(quotient, remainder)`.
+ ///
+ /// # Examples
+ ///
+ /// ~~~
+ /// # use num::Integer;
+ /// assert_eq!(( 8i).div_mod_floor( &3), ( 2, 2));
+ /// assert_eq!(( 8i).div_mod_floor(&-3), (-3, -1));
+ /// assert_eq!((-8i).div_mod_floor( &3), (-3, 1));
+ /// assert_eq!((-8i).div_mod_floor(&-3), ( 2, -2));
+ ///
+ /// assert_eq!(( 1i).div_mod_floor( &2), ( 0, 1));
+ /// assert_eq!(( 1i).div_mod_floor(&-2), (-1, -1));
+ /// assert_eq!((-1i).div_mod_floor( &2), (-1, 1));
+ /// assert_eq!((-1i).div_mod_floor(&-2), ( 0, -1));
+ /// ~~~
+ fn div_mod_floor(&self, other: &Self) -> (Self, Self) {
+ (self.div_floor(other), self.mod_floor(other))
+ }
}
/// Simultaneous integer division and modulus
// left paren, let's grab the old flags and see if we
// need a capture.
let (cap, cap_name, oldflags) = {
- let paren = self.stack.get(altfrom-1);
+ let paren = &self.stack[altfrom-1];
(paren.capture(), paren.capture_name(), paren.flags())
};
try!(self.alternate(altfrom));
Some(i) => i,
None => return None,
};
- if *self.chars.get(closer-1) != ':' {
+ if self.chars[closer-1] != ':' {
return None
}
if closer - self.chari <= 3 {
max = Some(min);
} else {
let pieces: Vec<&str> = inner.as_slice().splitn(',', 1).collect();
- let (smin, smax) = (*pieces.get(0), *pieces.get(1));
+ let (smin, smax) = (pieces[0], pieces[1]);
if smin.len() == 0 {
return self.err("Max repetitions cannot be specified \
without min repetitions.")
if self.chari + offset >= self.chars.len() {
return None
}
- Some(*self.chars.get(self.chari + offset))
+ Some(self.chars[self.chari + offset])
}
fn peek_is(&self, offset: uint, is: char) -> bool {
}
fn cur(&self) -> char {
- *self.chars.get(self.chari)
+ self.chars[self.chari]
}
fn slice(&self, start: uint, end: uint) -> String {
pub fn find(&self, text: &str) -> Option<(uint, uint)> {
let caps = exec(self, Location, text);
if has_match(&caps) {
- Some((caps.get(0).unwrap(), caps.get(1).unwrap()))
+ Some((caps[0].unwrap(), caps[1].unwrap()))
} else {
None
}
/// original string matched.
pub fn pos(&self, i: uint) -> Option<(uint, uint)> {
let (s, e) = (i * 2, i * 2 + 1);
- if e >= self.locs.len() || self.locs.get(s).is_none() {
+ if e >= self.locs.len() || self.locs[s].is_none() {
// VM guarantees that each pair of locations are both Some or None.
return None
}
- Some((self.locs.get(s).unwrap(), self.locs.get(e).unwrap()))
+ Some((self.locs[s].unwrap(), self.locs[e].unwrap()))
}
/// Returns the matched string for the capture group `i`.
if !has_match(&caps) {
return None
} else {
- (caps.get(0).unwrap(), caps.get(1).unwrap())
+ (caps[0].unwrap(), caps[1].unwrap())
};
// Don't accept empty matches immediately following a match.
if !has_match(&caps) {
return None
} else {
- (caps.get(0).unwrap(), caps.get(1).unwrap())
+ (caps[0].unwrap(), caps[1].unwrap())
};
// Don't accept empty matches immediately following a match.
#[inline]
fn has_match(caps: &CaptureLocs) -> bool {
- caps.len() >= 2 && caps.get(0).is_some() && caps.get(1).is_some()
+ caps.len() >= 2 && caps[0].is_some() && caps[1].is_some()
}
// Make sure multi-line mode isn't enabled for it, otherwise we can't
// drop the initial .*?
let prefix_anchor =
- match *self.prog.insts.get(1) {
+ match self.prog.insts[1] {
EmptyBegin(flags) if flags & FLAG_MULTI == 0 => true,
_ => false,
};
fn step(&self, groups: &mut [Option<uint>], nlist: &mut Threads,
caps: &mut [Option<uint>], pc: uint)
-> StepState {
- match *self.prog.insts.get(pc) {
+ match self.prog.insts[pc] {
Match => {
match self.which {
Exists => {
//
// We make a minor optimization by indicating that the state is "empty"
// so that its capture groups are not filled in.
- match *self.prog.insts.get(pc) {
+ match self.prog.insts[pc] {
EmptyBegin(flags) => {
let multi = flags & FLAG_MULTI > 0;
nlist.add(pc, groups, true);
#[inline]
fn contains(&self, pc: uint) -> bool {
- let s = *self.sparse.get(pc);
- s < self.size && self.queue.get(s).pc == pc
+ let s = self.sparse[pc];
+ s < self.size && self.queue[s].pc == pc
}
#[inline]
#[inline]
fn pc(&self, i: uint) -> uint {
- self.queue.get(i).pc
+ self.queue[i].pc
}
#[inline]
_ => {
cx.span_err(entry.span, format!(
"expected string literal but got `{}`",
- pprust::lit_to_string(lit)).as_slice());
+ pprust::lit_to_string(&*lit)).as_slice());
return None
}
}
_ => {
cx.span_err(entry.span, format!(
"expected string literal but got `{}`",
- pprust::expr_to_string(entry)).as_slice());
+ pprust::expr_to_string(&*entry)).as_slice());
return None
}
};
}
};
+ let code_model = match sess.opts.cg.code_model.as_slice() {
+ "default" => llvm::CodeModelDefault,
+ "small" => llvm::CodeModelSmall,
+ "kernel" => llvm::CodeModelKernel,
+ "medium" => llvm::CodeModelMedium,
+ "large" => llvm::CodeModelLarge,
+ _ => {
+ sess.err(format!("{} is not a valid code model",
+ sess.opts
+ .cg
+ .code_model).as_slice());
+ sess.abort_if_errors();
+ return;
+ }
+ };
+
let tm = sess.targ_cfg
.target_strs
.target_triple
target_feature(sess).with_c_str(|features| {
llvm::LLVMRustCreateTargetMachine(
t, cpu, features,
- llvm::CodeModelDefault,
+ code_model,
reloc_model,
opt_level,
true /* EnableSegstk */,
abi::OsMacos | abi::OsiOS => {
let morestack = lib_path.join("libmorestack.a");
- let mut v = "-Wl,-force_load,".as_bytes().to_owned();
+ let mut v = b"-Wl,-force_load,".to_vec();
v.push_all(morestack.as_vec());
cmd.arg(v.as_slice());
}
"prefer dynamic linking to static linking"),
no_integrated_as: bool = (false, parse_bool,
"use an external assembler rather than LLVM's integrated one"),
+ no_redzone: bool = (false, parse_bool,
+ "disable the use of the redzone"),
relocation_model: String = ("pic".to_string(), parse_string,
"choose the relocation model to use (llc -relocation-model for details)"),
+ code_model: String = ("default".to_string(), parse_string,
+ "choose the code model to use (llc -code-model for details)"),
metadata: Vec<String> = (Vec::new(), parse_list,
"metadata to mangle symbol names with"),
extra_filename: String = ("".to_string(), parse_string,
let ty_cx = &analysis.ty_cx;
let cfg = match code {
blocks::BlockCode(block) => cfg::CFG::new(ty_cx, &*block),
- blocks::FnLikeCode(fn_like) => cfg::CFG::new(ty_cx, fn_like.body()),
+ blocks::FnLikeCode(fn_like) => cfg::CFG::new(ty_cx, &*fn_like.body()),
};
debug!("cfg: {:?}", cfg);
pub fn main_args(args: &[String]) -> int {
- let owned_args = args.to_owned();
+ let owned_args = args.to_vec();
monitor(proc() run_compiler(owned_args.as_slice()));
0
}
}
fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
+ // if the expression was produced by a macro expansion,
+ if e.span.expn_info.is_some() { return }
+
let id = match e.node {
ast::ExprPath(..) | ast::ExprStruct(..) => {
match cx.tcx.def_map.borrow().find(&e.id) {
pub fn get_method_name_and_explicit_self(cstore: &cstore::CStore,
def: ast::DefId)
- -> (ast::Ident, ast::ExplicitSelf_)
+ -> (ast::Ident,
+ ty::ExplicitSelfCategory)
{
let cdata = cstore.get_crate_data(def.krate);
decoder::get_method_name_and_explicit_self(cstore.intr.clone(), &*cdata, def.node)
}).collect()
}
-fn get_explicit_self(item: ebml::Doc) -> ast::ExplicitSelf_ {
+fn get_explicit_self(item: ebml::Doc) -> ty::ExplicitSelfCategory {
fn get_mutability(ch: u8) -> ast::Mutability {
match ch as char {
'i' => ast::MutImmutable,
let explicit_self_kind = string.as_bytes()[0];
match explicit_self_kind as char {
- 's' => ast::SelfStatic,
- 'v' => ast::SelfValue(special_idents::self_),
- '~' => ast::SelfUniq(special_idents::self_),
+ 's' => ty::StaticExplicitSelfCategory,
+ 'v' => ty::ByValueExplicitSelfCategory,
+ '~' => ty::ByBoxExplicitSelfCategory,
// FIXME(#4846) expl. region
- '&' => ast::SelfRegion(None, get_mutability(string.as_bytes()[1]),
- special_idents::self_),
+ '&' => {
+ ty::ByReferenceExplicitSelfCategory(
+ ty::ReEmpty,
+ get_mutability(string.as_bytes()[1]))
+ }
_ => fail!("unknown self type code: `{}`", explicit_self_kind as char)
}
}
methods
}
-pub fn get_method_name_and_explicit_self(
- intr: Rc<IdentInterner>,
- cdata: Cmd,
- id: ast::NodeId) -> (ast::Ident, ast::ExplicitSelf_)
-{
+pub fn get_method_name_and_explicit_self(intr: Rc<IdentInterner>,
+ cdata: Cmd,
+ id: ast::NodeId)
+ -> (ast::Ident,
+ ty::ExplicitSelfCategory) {
let method_doc = lookup_item(id, cdata.data());
let name = item_name(&*intr, method_doc);
let explicit_self = get_explicit_self(method_doc);
for base_impl_did in implementations.borrow().iter() {
for &method_did in impl_methods.get(base_impl_did).iter() {
let m = ty::method(ecx.tcx, method_did);
- if m.explicit_self == ast::SelfStatic {
+ if m.explicit_self == ty::StaticExplicitSelfCategory {
encode_reexported_static_method(ebml_w, exp, m.def_id, m.ident);
}
}
match ecx.tcx.trait_methods_cache.borrow().find(&exp.def_id) {
Some(methods) => {
for m in methods.iter() {
- if m.explicit_self == ast::SelfStatic {
+ if m.explicit_self == ty::StaticExplicitSelfCategory {
encode_reexported_static_method(ebml_w, exp, m.def_id, m.ident);
}
}
ebml_w.end_tag();
}
-fn encode_explicit_self(ebml_w: &mut Encoder, explicit_self: ast::ExplicitSelf_) {
+fn encode_explicit_self(ebml_w: &mut Encoder,
+ explicit_self: &ty::ExplicitSelfCategory) {
ebml_w.start_tag(tag_item_trait_method_explicit_self);
// Encode the base self type.
- match explicit_self {
- SelfStatic => { ebml_w.writer.write(&[ 's' as u8 ]); }
- SelfValue(_) => { ebml_w.writer.write(&[ 'v' as u8 ]); }
- SelfUniq(_) => { ebml_w.writer.write(&[ '~' as u8 ]); }
- SelfRegion(_, m, _) => {
+ match *explicit_self {
+ ty::StaticExplicitSelfCategory => {
+ ebml_w.writer.write(&[ 's' as u8 ]);
+ }
+ ty::ByValueExplicitSelfCategory => {
+ ebml_w.writer.write(&[ 'v' as u8 ]);
+ }
+ ty::ByBoxExplicitSelfCategory => {
+ ebml_w.writer.write(&[ '~' as u8 ]);
+ }
+ ty::ByReferenceExplicitSelfCategory(_, m) => {
// FIXME(#4846) encode custom lifetime
ebml_w.writer.write(&['&' as u8]);
encode_mutability(ebml_w, m);
tag_item_method_tps);
encode_method_fty(ecx, ebml_w, &method_ty.fty);
encode_visibility(ebml_w, method_ty.vis);
- encode_explicit_self(ebml_w, method_ty.explicit_self);
+ encode_explicit_self(ebml_w, &method_ty.explicit_self);
let fn_style = method_ty.fty.fn_style;
match method_ty.explicit_self {
- ast::SelfStatic => {
+ ty::StaticExplicitSelfCategory => {
encode_family(ebml_w, fn_style_static_method_family(fn_style));
}
_ => encode_family(ebml_w, style_fn_family(fn_style))
encode_path(ebml_w, path.clone().chain(Some(elem).move_iter()));
match method_ty.explicit_self {
- SelfStatic => {
+ ty::StaticExplicitSelfCategory => {
encode_family(ebml_w,
fn_style_static_method_family(
method_ty.fty.fn_style));
encode_attributes(ebml_w, m.attrs.as_slice());
// If this is a static method, we've already encoded
// this.
- if method_ty.explicit_self != SelfStatic {
+ if method_ty.explicit_self != ty::StaticExplicitSelfCategory {
// FIXME: I feel like there is something funny going on.
let pty = ty::lookup_item_type(tcx, method_def_id);
encode_bounds_and_type(ebml_w, ecx, &pty);
encode_method_sort(ebml_w, 'p');
encode_inlined_item(ecx, ebml_w,
IIMethodRef(def_id, true, &*m));
- encode_method_argument_names(ebml_w, m.pe_fn_decl());
+ encode_method_argument_names(ebml_w, &*m.pe_fn_decl());
}
}
FileMatches => found = true,
FileDoesntMatch => ()
}
- visited_dirs.insert(path.as_vec().to_owned());
+ visited_dirs.insert(path.as_vec().to_vec());
}
debug!("filesearch: searching lib path");
}
}
- visited_dirs.insert(tlib_path.as_vec().to_owned());
+ visited_dirs.insert(tlib_path.as_vec().to_vec());
// Try RUST_PATH
if !found {
let rustpath = rust_path();
let tlib_path = make_rustpkg_lib_path(
self.sysroot, path, self.triple);
debug!("is {} in visited_dirs? {:?}", tlib_path.display(),
- visited_dirs.contains_equiv(&tlib_path.as_vec().to_owned()));
+ visited_dirs.contains_equiv(&tlib_path.as_vec().to_vec()));
if !visited_dirs.contains_equiv(&tlib_path.as_vec()) {
- visited_dirs.insert(tlib_path.as_vec().to_owned());
+ visited_dirs.insert(tlib_path.as_vec().to_vec());
// Don't keep searching the RUST_PATH if one match turns up --
// if we did, we'd get a "multiple matching crates" error
match f(&tlib_path) {
}
ty::ty_closure(ref f) => {
mywrite!(w, "f");
- enc_closure_ty(w, cx, *f);
+ enc_closure_ty(w, cx, &**f);
}
ty::ty_bare_fn(ref f) => {
mywrite!(w, "F");
return alist {eq_fn: eq_int, data: Vec::new()};
}
).unwrap();
- let item_in = e::IIItemRef(item);
+ let item_in = e::IIItemRef(&*item);
let item_out = simplify_ast(item_in);
let item_exp = ast::IIItem(quote_item!(cx,
fn new_int_alist<B>() -> alist<int, B> {
).unwrap());
match (item_out, item_exp) {
(ast::IIItem(item_out), ast::IIItem(item_exp)) => {
- assert!(pprust::item_to_string(item_out) == pprust::item_to_string(item_exp));
+ assert!(pprust::item_to_string(&*item_out) ==
+ pprust::item_to_string(&*item_exp));
}
_ => fail!()
}
let p = input.fn_parts;
- let dataflow_data = build_borrowck_dataflow_data(
- &mut bccx, &p.kind, p.decl, input.cfg, p.body, p.span, p.id);
+ let dataflow_data = build_borrowck_dataflow_data(&mut bccx,
+ &p.kind,
+ &*p.decl,
+ input.cfg,
+ &*p.body,
+ p.span,
+ p.id);
(bccx, dataflow_data)
}
let &Matrix(ref m) = self;
let pretty_printed_matrix: Vec<Vec<String>> = m.iter().map(|row| {
- row.iter().map(|&pat| pat_to_string(pat)).collect::<Vec<String>>()
+ row.iter()
+ .map(|&pat| pat_to_string(&*pat))
+ .collect::<Vec<String>>()
}).collect();
let column_count = m.iter().map(|row| row.len()).max().unwrap_or(0u);
let slice = match e {
Entry => on_entry,
Exit => {
- let mut t = on_entry.to_owned();
+ let mut t = on_entry.to_vec();
self.apply_gen_kill_frozen(cfgidx, t.as_mut_slice());
temp_bits = t;
temp_bits.as_slice()
cfg.graph.each_edge(|_edge_index, edge| {
let flow_exit = edge.source();
let (start, end) = self.compute_id_range(flow_exit);
- let mut orig_kills = self.kills.slice(start, end).to_owned();
+ let mut orig_kills = self.kills.slice(start, end).to_vec();
let mut changed = false;
for &node_id in edge.data.exiting_scopes.iter() {
visit::walk_trait_method(self, &*trait_method, ctxt);
}
ast_map::NodeMethod(method) => {
- visit::walk_block(self, method.pe_body(), ctxt);
+ visit::walk_block(self, &*method.pe_body(), ctxt);
}
ast_map::NodeForeignItem(foreign_item) => {
visit::walk_foreign_item(self, &*foreign_item, ctxt);
// Overwrite so that we don't warn the trait method itself.
fn visit_trait_method(&mut self, trait_method: &ast::TraitMethod, _: ()) {
match *trait_method {
- ast::Provided(ref method) => visit::walk_block(self, method.pe_body(), ()),
+ ast::Provided(ref method) => {
+ visit::walk_block(self, &*method.pe_body(), ())
+ }
ast::Required(_) => ()
}
}
// Keep going, nothing to get exported
}
ast::Provided(ref method) => {
- visit::walk_block(self, method.pe_body(), ())
+ visit::walk_block(self, &*method.pe_body(), ())
}
}
}
ast_map::NodeMethod(method) => {
let did = self.tcx.map.get_parent_did(search_item);
if method_might_be_inlined(self.tcx, &*method, did) {
- visit::walk_block(self, method.pe_body(), ())
+ visit::walk_block(self, &*method.pe_body(), ())
}
}
// Nothing to recurse on for these
self.sub_free_region(sub_fr, super_fr)
}
+ (ty::ReEarlyBound(param_id_a, param_space_a, index_a, _),
+ ty::ReEarlyBound(param_id_b, param_space_b, index_b, _)) => {
+ // This case is used only to make sure that explicitly-
+ // specified `Self` types match the real self type in
+ // implementations.
+ param_id_a == param_id_b &&
+ param_space_a == param_space_b &&
+ index_a == index_b
+ }
+
_ => {
false
}
#![allow(non_camel_case_types)]
use driver::session::Session;
+use lint;
use metadata::csearch;
use metadata::decoder::{DefLike, DlDef, DlField, DlImpl};
use middle::def::*;
use middle::lang_items::LanguageItems;
use middle::pat_util::pat_bindings;
use middle::subst::{ParamSpace, FnSpace, TypeSpace};
-use lint;
+use middle::ty::{ExplicitSelfCategory, StaticExplicitSelfCategory};
use util::nodemap::{NodeMap, DefIdSet, FnvHashMap};
use syntax::ast::*;
PrefixFound(Rc<Module>, uint)
}
+#[deriving(Clone, Eq, PartialEq)]
+enum MethodIsStaticFlag {
+ MethodIsNotStatic,
+ MethodIsStatic,
+}
+
+impl MethodIsStaticFlag {
+ fn from_explicit_self_category(explicit_self_category:
+ ExplicitSelfCategory)
+ -> MethodIsStaticFlag {
+ if explicit_self_category == StaticExplicitSelfCategory {
+ MethodIsStatic
+ } else {
+ MethodIsNotStatic
+ }
+ }
+}
+
#[deriving(PartialEq)]
enum NameSearchType {
/// We're doing a name search in order to resolve a `use` directive.
graph_root: NameBindings,
- method_map: RefCell<FnvHashMap<(Name, DefId), ast::ExplicitSelf_>>,
+ method_map: RefCell<FnvHashMap<(Name, DefId), MethodIsStaticFlag>>,
+
structs: FnvHashMap<DefId, Vec<Name>>,
// The number of imports that are currently unresolved.
let ident = ty_m.ident;
// Add it as a name in the trait module.
- let def = match ty_m.explicit_self.node {
+ let (def, static_flag) = match ty_m.explicit_self.node {
SelfStatic => {
// Static methods become `def_static_method`s.
- DefStaticMethod(local_def(ty_m.id),
+ (DefStaticMethod(local_def(ty_m.id),
FromTrait(local_def(item.id)),
- ty_m.fn_style)
+ ty_m.fn_style),
+ MethodIsStatic)
}
_ => {
// Non-static methods become `def_method`s.
- DefMethod(local_def(ty_m.id),
- Some(local_def(item.id)))
+ (DefMethod(local_def(ty_m.id),
+ Some(local_def(item.id))),
+ MethodIsNotStatic)
}
};
ty_m.span);
method_name_bindings.define_value(def, ty_m.span, true);
- self.method_map.borrow_mut().insert((ident.name, def_id),
- ty_m.explicit_self.node);
+ self.method_map
+ .borrow_mut()
+ .insert((ident.name, def_id), static_flag);
}
name_bindings.define_type(DefTrait(def_id), sp, is_public);
trait method '{}'",
token::get_ident(method_name));
- self.method_map.borrow_mut().insert((method_name.name, def_id), explicit_self);
+ self.method_map
+ .borrow_mut()
+ .insert((method_name.name, def_id),
+ MethodIsStaticFlag::from_explicit_self_category(
+ explicit_self));
if is_exported {
self.external_exports.insert(method_def_id);
this.resolve_type(&*argument.ty);
}
+ match ty_m.explicit_self.node {
+ SelfExplicit(ref typ, _) => {
+ this.resolve_type(&**typ)
+ }
+ _ => {}
+ }
+
this.resolve_type(&*ty_m.decl.output);
});
}
method.id,
rib_kind);
- self.resolve_function(rib_kind, Some(method.pe_fn_decl()), type_parameters,
+ match method.pe_explicit_self().node {
+ SelfExplicit(ref typ, _) => self.resolve_type(&**typ),
+ _ => {}
+ }
+
+ self.resolve_function(rib_kind,
+ Some(method.pe_fn_decl()),
+ type_parameters,
method.pe_body());
}
match containing_module.def_id.get() {
Some(def_id) => {
match self.method_map.borrow().find(&(ident.name, def_id)) {
- Some(x) if *x == SelfStatic => (),
+ Some(&MethodIsStatic) => (),
None => (),
_ => {
debug!("containing module was a trait or impl \
let path_str = self.path_idents_to_string(&trait_ref.path);
match method_map.find(&(name, did)) {
- Some(&SelfStatic) => return StaticTraitMethod(path_str),
+ Some(&MethodIsStatic) => return StaticTraitMethod(path_str),
Some(_) => return TraitMethod,
None => {}
}
for arg in method.pe_fn_decl().inputs.iter() {
self.visit_ty(&*arg.ty, e);
}
- self.visit_ty(method.pe_fn_decl().output, e);
+ self.visit_ty(&*method.pe_fn_decl().output, e);
// walk the fn body
- self.visit_block(method.pe_body(), DxrVisitorEnv::new_nested(method.id));
+ self.visit_block(&*method.pe_body(),
+ DxrVisitorEnv::new_nested(method.id));
self.process_generic_params(method.pe_generics(),
method.span,
}
},
ast::ViewItemExternCrate(ident, ref s, id) => {
- let name = get_ident(ident).get().to_owned();
+ let name = get_ident(ident);
+ let name = name.get();
let s = match *s {
- Some((ref s, _)) => s.get().to_owned(),
- None => name.to_owned(),
+ Some((ref s, _)) => s.get().to_string(),
+ None => name.to_string(),
};
let sub_span = self.span.sub_span_after_keyword(i.span, keywords::Crate);
let cnum = match self.sess.cstore.find_extern_mod_stmt_cnum(id) {
sub_span,
id,
cnum,
- name.as_slice(),
+ name,
s.as_slice(),
e.cur_scope);
},
// process collected paths
for &(id, ref p, ref immut, ref_kind) in self.collected_paths.iter() {
let value = if *immut {
- self.span.snippet(p.span).into_owned()
+ self.span.snippet(p.span).into_string()
} else {
- "<mutable>".to_owned()
+ "<mutable>".to_string()
};
let sub_span = self.span.span_for_first_ident(p.span);
let def_map = self.analysis.ty_cx.def_map.borrow();
let value = self.span.snippet(l.span);
for &(id, ref p, ref immut, _) in self.collected_paths.iter() {
- let value = if *immut { value.to_owned() } else { "<mutable>".to_owned() };
+ let value = if *immut { value.to_string() } else { "<mutable>".to_string() };
let types = self.analysis.ty_cx.node_types.borrow();
let typ = ppaux::ty_to_string(&self.analysis.ty_cx, *types.get(&(id as uint)));
// Get the span only for the name of the variable (I hope the path
String::from_str(v)
}
)));
- Some(strs.fold(String::new(), |s, ss| s.append(ss.as_slice()))).map(|s| s.into_owned())
+ Some(strs.fold(String::new(), |s, ss| s.append(ss.as_slice())))
}
pub fn record_without_span(&mut self,
};
let (dcn, dck) = match declid {
Some(declid) => (s!(declid.node), s!(declid.krate)),
- None => ("".to_owned(), "".to_owned())
+ None => ("".to_string(), "".to_string())
};
self.check_and_record(MethodCall,
span,
// Collect all of the matches that can match against anything.
enter_match(bcx, dm, m, col, val, |pats| {
- if pat_is_binding_or_wild(dm, pats[col]) {
+ if pat_is_binding_or_wild(dm, &*pats[col]) {
Some(Vec::from_slice(pats.slice_to(col)).append(pats.slice_from(col + 1)))
} else {
None
let _indenter = indenter();
let ctor = match opt {
- &lit(x) => check_match::ConstantValue(const_eval::eval_const_expr(
- bcx.tcx(), lit_to_expr(bcx.tcx(), &x))),
+ &lit(x) => {
+ check_match::ConstantValue(const_eval::eval_const_expr(
+ bcx.tcx(), &*lit_to_expr(bcx.tcx(), &x)))
+ }
&range(ref lo, ref hi) => check_match::ConstantRange(
const_eval::eval_const_expr(bcx.tcx(), &**lo),
const_eval::eval_const_expr(bcx.tcx(), &**hi)
_ => {}
}
+ if ccx.tcx.sess.opts.cg.no_redzone {
+ unsafe {
+ llvm::LLVMAddFunctionAttribute(llfn,
+ llvm::FunctionIndex as c_uint,
+ llvm::NoRedZoneAttribute as uint64_t)
+ }
+ }
+
llvm::SetFunctionCallConv(llfn, cc);
// Function addresses in Rust are never significant, allowing functions to be merged.
llvm::SetUnnamedAddr(llfn, true);
var_item).as_slice())
};
- let filename = span_start(cx, span).file.name.clone();
- let file_metadata = file_metadata(cx, filename.as_slice());
+ let (file_metadata, line_number) = if span != codemap::DUMMY_SP {
+ let loc = span_start(cx, span);
+ (file_metadata(cx, loc.file.name.as_slice()), loc.line as c_uint)
+ } else {
+ (UNKNOWN_FILE_METADATA, UNKNOWN_LINE_NUMBER)
+ };
let is_local_to_unit = is_node_local_to_unit(cx, node_id);
- let loc = span_start(cx, span);
-
let variable_type = ty::node_id_to_type(cx.tcx(), node_id);
let type_metadata = type_metadata(cx, variable_type, span);
-
let namespace_node = namespace_for_item(cx, ast_util::local_def(node_id));
let var_name = token::get_ident(ident).get().to_string();
let linkage_name =
var_name,
linkage_name,
file_metadata,
- loc.line as c_uint,
+ line_number,
type_metadata,
is_local_to_unit,
global,
for method in methods.iter() {
if method.pe_generics().ty_params.len() == 0u {
let llfn = get_item_val(ccx, method.id);
- trans_fn(ccx, method.pe_fn_decl(), method.pe_body(),
- llfn, ¶m_substs::empty(), method.id, []);
+ trans_fn(ccx,
+ &*method.pe_fn_decl(),
+ &*method.pe_body(),
+ llfn,
+ ¶m_substs::empty(),
+ method.id,
+ []);
} else {
let mut v = TransItemVisitor{ ccx: ccx };
visit::walk_method_helper(&mut v, &**method, ());
ExprId(0),
substs.clone(),
vtables.clone());
- match m.explicit_self {
- ast::SelfValue(_) => {
- fn_ref = trans_unboxing_shim(bcx,
- fn_ref,
- &*m,
- m_id,
- substs.clone());
- },
- _ => {}
+ if m.explicit_self == ty::ByValueExplicitSelfCategory {
+ fn_ref = trans_unboxing_shim(bcx,
+ fn_ref,
+ &*m,
+ m_id,
+ substs.clone());
}
fn_ref
}
pub ident: ast::Ident,
pub generics: ty::Generics,
pub fty: BareFnTy,
- pub explicit_self: ast::ExplicitSelf_,
+ pub explicit_self: ExplicitSelfCategory,
pub vis: ast::Visibility,
pub def_id: ast::DefId,
pub container: MethodContainer,
pub fn new(ident: ast::Ident,
generics: ty::Generics,
fty: BareFnTy,
- explicit_self: ast::ExplicitSelf_,
+ explicit_self: ExplicitSelfCategory,
vis: ast::Visibility,
def_id: ast::DefId,
container: MethodContainer,
/// (inferred) variance.
pub item_variance_map: RefCell<DefIdMap<Rc<ItemVariances>>>,
+ /// True if the variance has been computed yet; false otherwise.
+ pub variance_computed: Cell<bool>,
+
/// A mapping from the def ID of an enum or struct type to the def ID
/// of the method that implements its destructor. If the type is not
/// present in this map, it does not have a destructor. This map is
ctxt {
named_region_map: named_region_map,
item_variance_map: RefCell::new(DefIdMap::new()),
+ variance_computed: Cell::new(false),
interner: RefCell::new(FnvHashMap::new()),
next_id: Cell::new(primitives::LAST_PRIMITIVE_ID),
sess: s,
}
ty_closure(ref c) => {
- closure_contents(cx, *c)
+ closure_contents(cx, &**c)
}
ty_box(typ) => {
self.upvar_borrow_map.borrow().get_copy(&upvar_id)
}
}
+
+/// The category of explicit self.
+#[deriving(Clone, Eq, PartialEq)]
+pub enum ExplicitSelfCategory {
+ StaticExplicitSelfCategory,
+ ByValueExplicitSelfCategory,
+ ByReferenceExplicitSelfCategory(Region, ast::Mutability),
+ ByBoxExplicitSelfCategory,
+}
+
use middle::const_eval;
use middle::def;
use middle::lang_items::FnMutTraitLangItem;
-use rl = middle::resolve_lifetime;
use middle::subst::{FnSpace, TypeSpace, SelfSpace, Subst, Substs};
use middle::ty;
-use middle::typeck::TypeAndSubsts;
-use middle::typeck::lookup_def_tcx;
+use middle::ty_fold::TypeFolder;
use middle::typeck::rscope::RegionScope;
-use middle::typeck::rscope;
+use middle::typeck::{TypeAndSubsts, infer, lookup_def_tcx, rscope};
+use middle::typeck;
+use rl = middle::resolve_lifetime;
use util::ppaux::Repr;
use std::rc::Rc;
}
}
-struct SelfInfo {
+struct SelfInfo<'a> {
untransformed_self_ty: ty::t,
- explicit_self: ast::ExplicitSelf
+ explicit_self: ast::ExplicitSelf,
}
pub fn ty_of_method<AC:AstConv>(
- this: &AC,
- id: ast::NodeId,
- fn_style: ast::FnStyle,
- untransformed_self_ty: ty::t,
- explicit_self: ast::ExplicitSelf,
- decl: &ast::FnDecl)
- -> ty::BareFnTy
-{
- ty_of_method_or_bare_fn(this, id, fn_style, abi::Rust, Some(SelfInfo {
+ this: &AC,
+ id: ast::NodeId,
+ fn_style: ast::FnStyle,
+ untransformed_self_ty: ty::t,
+ explicit_self: ast::ExplicitSelf,
+ decl: &ast::FnDecl)
+ -> (ty::BareFnTy, ty::ExplicitSelfCategory) {
+ let self_info = Some(SelfInfo {
untransformed_self_ty: untransformed_self_ty,
- explicit_self: explicit_self
- }), decl)
+ explicit_self: explicit_self,
+ });
+ let (bare_fn_ty, optional_explicit_self_category) =
+ ty_of_method_or_bare_fn(this,
+ id,
+ fn_style,
+ abi::Rust,
+ self_info,
+ decl);
+ (bare_fn_ty, optional_explicit_self_category.unwrap())
}
pub fn ty_of_bare_fn<AC:AstConv>(this: &AC, id: ast::NodeId,
fn_style: ast::FnStyle, abi: abi::Abi,
decl: &ast::FnDecl) -> ty::BareFnTy {
- ty_of_method_or_bare_fn(this, id, fn_style, abi, None, decl)
+ let (bare_fn_ty, _) =
+ ty_of_method_or_bare_fn(this, id, fn_style, abi, None, decl);
+ bare_fn_ty
}
-fn ty_of_method_or_bare_fn<AC:AstConv>(this: &AC, id: ast::NodeId,
- fn_style: ast::FnStyle, abi: abi::Abi,
- opt_self_info: Option<SelfInfo>,
- decl: &ast::FnDecl) -> ty::BareFnTy {
+fn ty_of_method_or_bare_fn<AC:AstConv>(
+ this: &AC,
+ id: ast::NodeId,
+ fn_style: ast::FnStyle,
+ abi: abi::Abi,
+ opt_self_info: Option<SelfInfo>,
+ decl: &ast::FnDecl)
+ -> (ty::BareFnTy,
+ Option<ty::ExplicitSelfCategory>) {
debug!("ty_of_method_or_bare_fn");
// new region names that appear inside of the fn decl are bound to
// that function type
let rb = rscope::BindingRscope::new(id);
+ let mut explicit_self_category_result = None;
let self_ty = opt_self_info.and_then(|self_info| {
- match self_info.explicit_self.node {
- ast::SelfStatic => None,
- ast::SelfValue(_) => {
+ // Figure out and record the explicit self category.
+ let explicit_self_category =
+ determine_explicit_self_category(this, &rb, &self_info);
+ explicit_self_category_result = Some(explicit_self_category);
+ match explicit_self_category {
+ ty::StaticExplicitSelfCategory => None,
+ ty::ByValueExplicitSelfCategory => {
Some(self_info.untransformed_self_ty)
}
- ast::SelfRegion(ref lifetime, mutability, _) => {
- let region =
- opt_ast_region_to_region(this, &rb,
- self_info.explicit_self.span,
- lifetime);
+ ty::ByReferenceExplicitSelfCategory(region, mutability) => {
Some(ty::mk_rptr(this.tcx(), region,
ty::mt {ty: self_info.untransformed_self_ty,
mutbl: mutability}))
}
- ast::SelfUniq(_) => {
+ ty::ByBoxExplicitSelfCategory => {
Some(ty::mk_uniq(this.tcx(), self_info.untransformed_self_ty))
}
}
_ => ast_ty_to_ty(this, &rb, &*decl.output)
};
- return ty::BareFnTy {
+ (ty::BareFnTy {
fn_style: fn_style,
abi: abi,
sig: ty::FnSig {
output: output_ty,
variadic: decl.variadic
}
- };
+ }, explicit_self_category_result)
+}
+
+fn determine_explicit_self_category<AC:AstConv,
+ RS:RegionScope>(
+ this: &AC,
+ rscope: &RS,
+ self_info: &SelfInfo)
+ -> ty::ExplicitSelfCategory {
+ match self_info.explicit_self.node {
+ ast::SelfStatic => ty::StaticExplicitSelfCategory,
+ ast::SelfValue(_) => ty::ByValueExplicitSelfCategory,
+ ast::SelfRegion(ref lifetime, mutability, _) => {
+ let region =
+ opt_ast_region_to_region(this,
+ rscope,
+ self_info.explicit_self.span,
+ lifetime);
+ ty::ByReferenceExplicitSelfCategory(region, mutability)
+ }
+ ast::SelfUniq(_) => ty::ByBoxExplicitSelfCategory,
+ ast::SelfExplicit(ast_type, _) => {
+ let explicit_type = ast_ty_to_ty(this, rscope, &*ast_type);
+
+ {
+ let inference_context = infer::new_infer_ctxt(this.tcx());
+ let expected_self = self_info.untransformed_self_ty;
+ let actual_self = explicit_type;
+ let result = infer::mk_eqty(
+ &inference_context,
+ false,
+ infer::Misc(self_info.explicit_self.span),
+ expected_self,
+ actual_self);
+ match result {
+ Ok(_) => {
+ inference_context.resolve_regions_and_report_errors();
+ return ty::ByValueExplicitSelfCategory
+ }
+ Err(_) => {}
+ }
+ }
+
+ match ty::get(explicit_type).sty {
+ ty::ty_rptr(region, tm) => {
+ typeck::require_same_types(
+ this.tcx(),
+ None,
+ false,
+ self_info.explicit_self.span,
+ self_info.untransformed_self_ty,
+ tm.ty,
+ || "not a valid type for `self`".to_owned());
+ return ty::ByReferenceExplicitSelfCategory(region,
+ tm.mutbl)
+ }
+ ty::ty_uniq(typ) => {
+ typeck::require_same_types(
+ this.tcx(),
+ None,
+ false,
+ self_info.explicit_self.span,
+ self_info.untransformed_self_ty,
+ typ,
+ || "not a valid type for `self`".to_owned());
+ return ty::ByBoxExplicitSelfCategory
+ }
+ _ => {
+ this.tcx()
+ .sess
+ .span_err(self_info.explicit_self.span,
+ "not a valid type for `self`");
+ return ty::ByValueExplicitSelfCategory
+ }
+ }
+ }
+ }
}
pub fn ty_of_closure<AC:AstConv>(
(&None, ty::UniqTraitStore) => ty::empty_builtin_bounds(),
}
}
+
use std::collections::HashSet;
use std::rc::Rc;
-use syntax::ast::{DefId, SelfValue, SelfRegion};
-use syntax::ast::{SelfUniq, SelfStatic};
-use syntax::ast::{MutMutable, MutImmutable};
+use syntax::ast::{DefId, MutImmutable, MutMutable};
use syntax::ast;
use syntax::codemap::Span;
use syntax::parse::token;
obj_substs.types.pop(subst::SelfSpace).unwrap();
match method_ty.explicit_self {
- ast::SelfStatic => {
+ StaticExplicitSelfCategory => {
tcx.sess.span_bug(span, "static method for object type receiver");
}
- ast::SelfValue(_) => {
+ ByValueExplicitSelfCategory => {
let tr = ty::mk_trait(tcx, trait_def_id, obj_substs,
ty::empty_builtin_bounds());
ty::mk_uniq(tcx, tr)
}
- ast::SelfRegion(..) | ast::SelfUniq(..) => {
+ ByReferenceExplicitSelfCategory(..) | ByBoxExplicitSelfCategory => {
let transformed_self_ty = *method_ty.fty.sig.inputs.get(0);
match ty::get(transformed_self_ty).sty {
ty::ty_rptr(r, mt) => { // must be SelfRegion
let trait_methods = ty::trait_methods(tcx, bound_trait_ref.def_id);
match trait_methods.iter().position(|m| {
- m.explicit_self != ast::SelfStatic &&
+ m.explicit_self != ty::StaticExplicitSelfCategory &&
m.ident.name == self.m_name }) {
Some(pos) => {
let method = trait_methods.get(pos).clone();
if self.report_statics == ReportStaticMethods {
// lookup should only be called with ReportStaticMethods if a regular lookup failed
- assert!(relevant_candidates.iter().all(|c| c.method_ty.explicit_self == SelfStatic));
+ assert!(relevant_candidates.iter()
+ .all(|c| {
+ c.method_ty.explicit_self == ty::StaticExplicitSelfCategory
+ }));
self.tcx().sess.fileline_note(self.span,
"found defined static methods, maybe a `self` is missing?");
self.enforce_drop_trait_limitations(candidate);
// static methods should never have gotten this far:
- assert!(candidate.method_ty.explicit_self != SelfStatic);
+ assert!(candidate.method_ty.explicit_self !=
+ ty::StaticExplicitSelfCategory);
// Determine the values for the generic parameters of the method.
// If they were not explicitly supplied, just construct fresh
}
match candidate.method_ty.explicit_self {
- ast::SelfStatic => { // reason (a) above
- span_err!(self.tcx().sess, self.span, E0037,
- "cannot call a method without a receiver through an object");
+ ty::StaticExplicitSelfCategory => { // reason (a) above
+ self.tcx().sess.span_err(
+ self.span,
+ "cannot call a method without a receiver \
+ through an object");
}
- ast::SelfValue(_) | ast::SelfRegion(..) | ast::SelfUniq(_) => {}
+ ty::ByValueExplicitSelfCategory |
+ ty::ByReferenceExplicitSelfCategory(..) |
+ ty::ByBoxExplicitSelfCategory => {}
}
// reason (a) above
self.ty_to_string(rcvr_ty), candidate.repr(self.tcx()));
return match candidate.method_ty.explicit_self {
- SelfStatic => {
+ StaticExplicitSelfCategory => {
debug!("(is relevant?) explicit self is static");
self.report_statics == ReportStaticMethods
}
- SelfValue(_) => {
+ ByValueExplicitSelfCategory => {
debug!("(is relevant?) explicit self is by-value");
match ty::get(rcvr_ty).sty {
ty::ty_uniq(typ) => {
}
}
- SelfRegion(_, m, _) => {
+ ByReferenceExplicitSelfCategory(_, m) => {
debug!("(is relevant?) explicit self is a region");
match ty::get(rcvr_ty).sty {
ty::ty_rptr(_, mt) => {
}
}
- SelfUniq(_) => {
+ ByBoxExplicitSelfCategory => {
debug!("(is relevant?) explicit self is a unique pointer");
match ty::get(rcvr_ty).sty {
ty::ty_uniq(typ) => {
}
}
}
+
+
+
let fty = ty::node_id_to_type(ccx.tcx, method.id);
- check_bare_fn(ccx, method.pe_fn_decl(), method.pe_body(), method.id, fty, param_env);
+ check_bare_fn(ccx,
+ &*method.pe_fn_decl(),
+ &*method.pe_body(),
+ method.id,
+ fty,
+ param_env);
}
fn check_impl_methods_against_trait(ccx: &CrateCtxt,
// inscrutable, particularly for cases where one method has no
// self.
match (&trait_m.explicit_self, &impl_m.explicit_self) {
- (&ast::SelfStatic, &ast::SelfStatic) => {}
- (&ast::SelfStatic, _) => {
- span_err!(tcx.sess, impl_m_span, E0047,
- "method `{}` has a `{}` declaration in the impl, but not in the trait",
- token::get_ident(trait_m.ident),
- pprust::explicit_self_to_string(impl_m.explicit_self));
+ (&ty::StaticExplicitSelfCategory,
+ &ty::StaticExplicitSelfCategory) => {}
+ (&ty::StaticExplicitSelfCategory, _) => {
+ tcx.sess.span_err(
+ impl_m_span,
+ format!("method `{}` has a `{}` declaration in the impl, \
+ but not in the trait",
+ token::get_ident(trait_m.ident),
+ ppaux::explicit_self_category_to_str(
+ &impl_m.explicit_self)).as_slice());
return;
}
- (_, &ast::SelfStatic) => {
- span_err!(tcx.sess, impl_m_span, E0048,
- "method `{}` has a `{}` declaration in the trait, but not in the impl",
- token::get_ident(trait_m.ident),
- pprust::explicit_self_to_string(trait_m.explicit_self));
+ (_, &ty::StaticExplicitSelfCategory) => {
+ tcx.sess.span_err(
+ impl_m_span,
+ format!("method `{}` has a `{}` declaration in the trait, \
+ but not in the impl",
+ token::get_ident(trait_m.ident),
+ ppaux::explicit_self_category_to_str(
+ &trait_m.explicit_self)).as_slice());
return;
}
_ => {
if ty::type_is_integral(lhs_t) && ast_util::is_shift_binop(op) {
// Shift is a special case: rhs must be uint, no matter what lhs is
- check_expr_has_type(fcx, rhs, ty::mk_uint());
+ check_expr_has_type(fcx, &*rhs, ty::mk_uint());
fcx.write_ty(expr.id, lhs_t);
return;
}
}
ast::ExprLit(lit) => {
- let typ = check_lit(fcx, lit, expected);
+ let typ = check_lit(fcx, &*lit, expected);
fcx.write_ty(id, typ);
}
ast::ExprBinary(op, ref lhs, ref rhs) => {
fcx.write_bot(id);
}
ast::ExprParen(a) => {
- check_expr_with_expectation_and_lvalue_pref(fcx, a, expected, lvalue_pref);
- fcx.write_ty(id, fcx.expr_ty(a));
+ check_expr_with_expectation_and_lvalue_pref(fcx,
+ &*a,
+ expected,
+ lvalue_pref);
+ fcx.write_ty(id, fcx.expr_ty(&*a));
}
ast::ExprAssign(ref lhs, ref rhs) => {
check_expr_with_lvalue_pref(fcx, &**lhs, PreferMutLvalue);
Some(ref fs) if i < fs.len() => ExpectHasType(*fs.get(i)),
_ => NoExpectation
};
- check_expr_with_expectation(fcx, *e, opt_hint);
- let t = fcx.expr_ty(*e);
+ check_expr_with_expectation(fcx, &**e, opt_hint);
+ let t = fcx.expr_ty(&**e);
err_field = err_field || ty::type_is_error(t);
bot_field = bot_field || ty::type_is_bot(t);
t
e.span,
"unreachable expression".to_string());
}
- check_expr_with_expectation(fcx, e, expected);
- let ety = fcx.expr_ty(e);
+ check_expr_with_expectation(fcx, &*e, expected);
+ let ety = fcx.expr_ty(&*e);
fcx.write_ty(blk.id, ety);
if any_err {
fcx.write_error(blk.id);
});
}
}
+
use middle::ty::{ImplContainer, MethodContainer, TraitContainer};
use middle::ty::{Polytype};
use middle::ty;
+use middle::ty_fold::TypeFolder;
use middle::typeck::astconv::{AstConv, ty_of_arg};
use middle::typeck::astconv::{ast_ty_to_ty};
use middle::typeck::astconv;
+use middle::typeck::infer;
use middle::typeck::rscope::*;
use middle::typeck::{CrateCtxt, lookup_def_tcx, no_params, write_ty_to_tcx};
+use middle::typeck;
use util::ppaux;
use util::ppaux::Repr;
&ast::Provided(ref m) => {
ty_method_of_trait_method(
- ccx, trait_id, &trait_def.generics,
- &m.id, &m.pe_ident(), m.pe_explicit_self(),
- m.pe_generics(), &m.pe_fn_style(), m.pe_fn_decl())
+ ccx,
+ trait_id,
+ &trait_def.generics,
+ &m.id,
+ &m.pe_ident(),
+ m.pe_explicit_self(),
+ m.pe_generics(),
+ &m.pe_fn_style(),
+ &*m.pe_fn_decl())
}
});
- if ty_method.explicit_self == ast::SelfStatic {
+ if ty_method.explicit_self ==
+ ty::StaticExplicitSelfCategory {
make_static_method_ty(ccx, &*ty_method);
}
m_fn_style: &ast::FnStyle,
m_decl: &ast::FnDecl) -> ty::Method
{
- let trait_self_ty = ty::mk_self_type(this.tcx, local_def(trait_id));
- let fty = astconv::ty_of_method(this, *m_id, *m_fn_style, trait_self_ty,
- *m_explicit_self, m_decl);
- let ty_generics =
- ty_generics_for_fn_or_method(this,
- m_generics,
- (*trait_generics).clone());
+ let trait_self_ty = ty::mk_param(this.tcx,
+ subst::SelfSpace,
+ 0,
+ local_def(trait_id));
+ let ty_generics = ty_generics_for_fn_or_method(
+ this,
+ m_generics,
+ (*trait_generics).clone());
+ let (fty, explicit_self_category) =
+ astconv::ty_of_method(this,
+ *m_id,
+ *m_fn_style,
+ trait_self_ty,
+ *m_explicit_self,
+ m_decl);
ty::Method::new(
*m_ident,
ty_generics,
fty,
- m_explicit_self.node,
+ explicit_self_category,
// assume public, because this is only invoked on trait methods
ast::Public,
local_def(*m_id),
rcvr_visibility: ast::Visibility)
-> ty::Method
{
- let fty = astconv::ty_of_method(ccx, m.id, m.pe_fn_style(),
- untransformed_rcvr_ty,
- *m.pe_explicit_self(), m.pe_fn_decl());
+ let (fty, explicit_self_category) =
+ astconv::ty_of_method(ccx,
+ m.id,
+ m.pe_fn_style(),
+ untransformed_rcvr_ty,
+ *m.pe_explicit_self(),
+ &*m.pe_fn_decl());
// if the method specifies a visibility, use that, otherwise
// inherit the visibility from the impl (so `foo` in `pub impl
ty::Method::new(m.pe_ident(),
m_ty_generics,
fty,
- m.pe_explicit_self().node,
+ explicit_self_category,
method_vis,
local_def(m.id),
container,
it.vis
};
+ for method in ms.iter() {
+ check_method_self_type(ccx,
+ &BindingRscope::new(method.id),
+ selfty,
+ method.pe_explicit_self())
+ }
+
convert_methods(ccx,
ImplContainer(local_def(it.id)),
ms.as_slice(),
ast::ItemTrait(_, _, _, ref trait_methods) => {
let trait_def = trait_def_of_item(ccx, it);
+ for trait_method in trait_methods.iter() {
+ let self_type = ty::mk_param(ccx.tcx,
+ subst::SelfSpace,
+ 0,
+ local_def(it.id));
+ match *trait_method {
+ ast::Required(ref type_method) => {
+ let rscope = BindingRscope::new(type_method.id);
+ check_method_self_type(ccx,
+ &rscope,
+ self_type,
+ &type_method.explicit_self)
+ }
+ ast::Provided(ref method) => {
+ check_method_self_type(ccx,
+ &BindingRscope::new(method.id),
+ self_type,
+ method.pe_explicit_self())
+ }
+ }
+ }
+
// Run convert_methods on the provided methods.
let (_, provided_methods) =
split_trait_methods(trait_methods.as_slice());
subst::Substs::new(types, regions)
}
+
+/// Verifies that the explicit self type of a method matches the impl or
+/// trait.
+fn check_method_self_type<RS:RegionScope>(
+ crate_context: &CrateCtxt,
+ rs: &RS,
+ required_type: ty::t,
+ explicit_self: &ast::ExplicitSelf) {
+ match explicit_self.node {
+ ast::SelfExplicit(ref ast_type, _) => {
+ let typ = crate_context.to_ty(rs, &**ast_type);
+ let base_type = match ty::get(typ).sty {
+ ty::ty_rptr(_, tm) => tm.ty,
+ ty::ty_uniq(typ) => typ,
+ _ => typ,
+ };
+ let infcx = infer::new_infer_ctxt(crate_context.tcx);
+ drop(typeck::require_same_types(crate_context.tcx,
+ Some(&infcx),
+ false,
+ explicit_self.span,
+ base_type,
+ required_type,
+ || {
+ format!("mismatched self type: expected `{}`",
+ ppaux::ty_to_string(crate_context.tcx, required_type))
+ }));
+ infcx.resolve_regions_and_report_errors();
+ }
+ _ => {}
+ }
+}
+
use util::ppaux::Repr;
use syntax::abi;
-use syntax::ast::MutImmutable;
use syntax::ast;
// Note: Coerce is not actually a combiner, in that it does not
let r_borrow = self.get_ref().infcx.next_region_var(coercion);
let inner_ty = match *sty_a {
- ty::ty_box(typ) | ty::ty_uniq(typ) => {
- if mt_b.mutbl == ast::MutMutable {
- return Err(ty::terr_mutability)
- }
- typ
- }
+ ty::ty_box(_) | ty::ty_uniq(_) => return Err(ty::terr_mismatch),
ty::ty_rptr(_, mt_a) => mt_a.ty,
_ => {
return self.subtype(a, b);
b.repr(self.get_ref().infcx.tcx));
match *sty_a {
- ty::ty_uniq(t) => match ty::get(t).sty {
- ty::ty_str => {}
- _ => return self.subtype(a, b),
- },
- _ => {
- return self.subtype(a, b);
- }
- };
-
- let coercion = Coercion(self.get_ref().trace.clone());
- let r_a = self.get_ref().infcx.next_region_var(coercion);
- let a_borrowed = ty::mk_str_slice(self.get_ref().infcx.tcx, r_a, ast::MutImmutable);
- if_ok!(self.subtype(a_borrowed, b));
- Ok(Some(AutoDerefRef(AutoDerefRef {
- autoderefs: 0,
- autoref: Some(AutoBorrowVec(r_a, MutImmutable))
- })))
+ ty::ty_uniq(_) => return Err(ty::terr_mismatch),
+ _ => return self.subtype(a, b),
+ }
}
pub fn coerce_borrowed_vector(&self,
let coercion = Coercion(self.get_ref().trace.clone());
let r_borrow = self.get_ref().infcx.next_region_var(coercion);
let ty_inner = match *sty_a {
- ty::ty_uniq(t) | ty::ty_ptr(ty::mt{ty: t, ..}) |
+ ty::ty_uniq(_) => return Err(ty::terr_mismatch),
+ ty::ty_ptr(ty::mt{ty: t, ..}) |
ty::ty_rptr(_, ty::mt{ty: t, ..}) => match ty::get(t).sty {
ty::ty_vec(mt, None) => mt.ty,
_ => {
b_subst: &subst::Substs)
-> cres<subst::Substs>
{
- let variances = ty::item_variances(self.infcx().tcx, item_def_id);
+ let variances = if self.infcx().tcx.variance_computed.get() {
+ Some(ty::item_variances(self.infcx().tcx, item_def_id))
+ } else {
+ None
+ };
let mut substs = subst::Substs::empty();
for &space in subst::ParamSpace::all().iter() {
let a_regions = a_subst.regions().get_slice(space);
let b_regions = b_subst.regions().get_slice(space);
- let r_variances = variances.regions.get_slice(space);
+
+ let mut invariance = Vec::new();
+ let r_variances = match variances {
+ Some(ref variances) => variances.regions.get_slice(space),
+ None => {
+ for _ in a_regions.iter() {
+ invariance.push(ty::Invariant);
+ }
+ invariance.as_slice()
+ }
+ };
+
let regions = if_ok!(relate_region_params(self,
item_def_id,
r_variances,
}
(&ty::ty_closure(ref a_fty), &ty::ty_closure(ref b_fty)) => {
- this.closure_tys(*a_fty, *b_fty).and_then(|fty| {
+ this.closure_tys(&**a_fty, &**b_fty).and_then(|fty| {
Ok(ty::mk_closure(tcx, fty))
})
}
use middle::typeck::check::regionmanip::replace_late_bound_regions_in_fn_sig;
use middle::typeck::infer::coercion::Coerce;
use middle::typeck::infer::combine::{Combine, CombineFields, eq_tys};
-use middle::typeck::infer::region_inference::{RegionVarBindings,
- RegionSnapshot};
+use middle::typeck::infer::region_inference::{RegionSnapshot};
+use middle::typeck::infer::region_inference::{RegionVarBindings};
use middle::typeck::infer::resolve::{resolver};
use middle::typeck::infer::sub::Sub;
use middle::typeck::infer::lub::Lub;
use middle::ty;
use middle::ty::{BoundRegion, FreeRegion, Region, RegionVid};
-use middle::ty::{ReEmpty, ReStatic, ReInfer, ReFree, ReEarlyBound,
- ReLateBound};
-use middle::ty::{ReScope, ReVar, ReSkolemized, BrFresh};
+use middle::ty::{ReEmpty, ReStatic, ReInfer, ReFree, ReEarlyBound};
+use middle::ty::{ReLateBound, ReScope, ReVar, ReSkolemized, BrFresh};
use middle::typeck::infer::cres;
use middle::typeck::infer::{RegionVariableOrigin, SubregionOrigin, TypeTrace};
use middle::typeck::infer;
use middle::graph;
use middle::graph::{Direction, NodeIndex};
use util::common::indenter;
-use util::ppaux::{Repr};
+use util::ppaux::Repr;
use std::cell::{Cell, RefCell};
use std::uint;
origin.repr(self.tcx));
match (sub, sup) {
+ (ReEarlyBound(..), ReEarlyBound(..)) => {
+ // This case is used only to make sure that explicitly-specified
+ // `Self` types match the real self type in implementations.
+ self.add_constraint(ConstrainRegSubReg(sub, sup), origin);
+ }
(ReEarlyBound(..), _) |
(ReLateBound(..), _) |
(_, ReEarlyBound(..)) |
}
fn errors(msgs: &[&str]) -> (Box<Emitter+Send>, uint) {
- let v = Vec::from_fn(msgs.len(), |i| msgs[i].to_owned());
+ let v = msgs.iter().map(|m| m.to_string()).collect();
(box ExpectErrorEmitter { messages: v } as Box<Emitter+Send>, msgs.len())
}
let sess = session::build_session_(options, None, span_diagnostic_handler);
let krate_config = Vec::new();
- let input = driver::StrInput(source_string.to_owned());
+ let input = driver::StrInput(source_string.to_string());
let krate = driver::phase_1_parse_input(&sess, krate_config, &input);
let (krate, ast_map) =
driver::phase_2_configure_and_expand(&sess, krate, "test")
assert!(idx < names.len());
for item in m.items.iter() {
if item.ident.user_string(this.tcx) == names[idx] {
- return search(this, *item, idx+1, names);
+ return search(this, &**item, idx+1, names);
}
}
return None;
let terms_cx = determine_parameters_to_be_inferred(tcx, &mut arena, krate);
let constraints_cx = add_constraints_from_crate(terms_cx, krate);
solve_constraints(constraints_cx);
+ tcx.variance_computed.set(true);
}
/**************************************************************************
use middle::subst::{VecPerParamSpace,Subst};
use middle::ty::{ReSkolemized, ReVar};
use middle::ty::{BoundRegion, BrAnon, BrNamed};
-use middle::ty::{BrFresh, ctxt};
+use middle::ty::{ReEarlyBound, BrFresh, ctxt};
use middle::ty::{mt, t, ParamTy};
use middle::ty::{ReFree, ReScope, ReInfer, ReStatic, Region, ReEmpty};
use middle::ty::{ty_bool, ty_char, ty_bot, ty_box, ty_struct, ty_enum};
ReEmpty => { ("the empty lifetime".to_string(), None) }
+ ReEarlyBound(_, _, _, name) => {
+ (format!("{}", token::get_name(name)), None)
+ }
+
// I believe these cases should not occur (except when debugging,
// perhaps)
- ty::ReInfer(_) | ty::ReEarlyBound(..) | ty::ReLateBound(..) => {
+ ty::ReInfer(_) | ty::ReLateBound(..) => {
(format!("lifetime {:?}", region), None)
}
};
format!("({})", strs.connect(","))
}
ty_closure(ref f) => {
- closure_to_string(cx, *f)
+ closure_to_string(cx, &**f)
}
ty_bare_fn(ref f) => {
bare_fn_to_string(cx, f.fn_style, f.abi, None, &f.sig)
}
}
+pub fn explicit_self_category_to_str(category: &ty::ExplicitSelfCategory)
+ -> &'static str {
+ match *category {
+ ty::StaticExplicitSelfCategory => "static",
+ ty::ByValueExplicitSelfCategory => "self",
+ ty::ByReferenceExplicitSelfCategory(_, ast::MutMutable) => {
+ "&mut self"
+ }
+ ty::ByReferenceExplicitSelfCategory(_, ast::MutImmutable) => "&self",
+ ty::ByBoxExplicitSelfCategory => "Box<self>",
+ }
+}
+
pub fn parameterized(cx: &ctxt,
base: &str,
substs: &subst::Substs,
}
}
}
+
+impl Repr for ty::ExplicitSelfCategory {
+ fn repr(&self, _: &ctxt) -> String {
+ explicit_self_category_to_str(self).to_string()
+ }
+}
+
}
}
-#[deriving(Clone, Encodable, Decodable)]
+#[deriving(Clone, Encodable, Decodable, PartialEq)]
pub enum Attribute {
Word(String),
List(String, Vec<Attribute> ),
fn meta_item_list<'a>(&'a self) -> Option<&'a [Gc<ast::MetaItem>]> { None }
}
-#[deriving(Clone, Encodable, Decodable)]
+#[deriving(Clone, Encodable, Decodable, PartialEq)]
pub struct TyParam {
pub name: String,
pub did: ast::DefId,
}
}
-#[deriving(Clone, Encodable, Decodable)]
+#[deriving(Clone, Encodable, Decodable, PartialEq)]
pub enum TyParamBound {
RegionBound,
TraitBound(Type)
}
// maybe use a Generic enum and use ~[Generic]?
-#[deriving(Clone, Encodable, Decodable)]
+#[deriving(Clone, Encodable, Decodable, PartialEq)]
pub struct Generics {
pub lifetimes: Vec<Lifetime>,
pub type_params: Vec<TyParam>,
SelfValue,
SelfBorrowed(Option<Lifetime>, Mutability),
SelfOwned,
+ SelfExplicit(Type),
}
impl Clean<SelfTy> for ast::ExplicitSelf_ {
ast::SelfStatic => SelfStatic,
ast::SelfValue(_) => SelfValue,
ast::SelfUniq(_) => SelfOwned,
- ast::SelfRegion(lt, mt, _) => SelfBorrowed(lt.clean(), mt.clean()),
+ ast::SelfRegion(lt, mt, _) => {
+ SelfBorrowed(lt.clean(), mt.clean())
+ }
+ ast::SelfExplicit(typ, _) => SelfExplicit(typ.clean()),
}
}
}
}
}
-#[deriving(Clone, Encodable, Decodable)]
+#[deriving(Clone, Encodable, Decodable, PartialEq)]
pub struct ClosureDecl {
pub lifetimes: Vec<Lifetime>,
pub decl: FnDecl,
}
}
-#[deriving(Clone, Encodable, Decodable)]
+#[deriving(Clone, Encodable, Decodable, PartialEq)]
pub struct FnDecl {
pub inputs: Arguments,
pub output: Type,
pub attrs: Vec<Attribute>,
}
-#[deriving(Clone, Encodable, Decodable)]
+#[deriving(Clone, Encodable, Decodable, PartialEq)]
pub struct Arguments {
pub values: Vec<Argument>,
}
}
}
-#[deriving(Clone, Encodable, Decodable)]
+#[deriving(Clone, Encodable, Decodable, PartialEq)]
pub struct Argument {
pub type_: Type,
pub name: String,
}
}
-#[deriving(Clone, Encodable, Decodable)]
+#[deriving(Clone, Encodable, Decodable, PartialEq)]
pub enum RetStyle {
NoReturn,
Return
fn clean(&self) -> Item {
let cx = get_cx();
let (self_, sig) = match self.explicit_self {
- ast::SelfStatic => (ast::SelfStatic.clean(), self.fty.sig.clone()),
+ ty::StaticExplicitSelfCategory => (ast::SelfStatic.clean(), self.fty.sig.clone()),
s => {
let sig = ty::FnSig {
inputs: Vec::from_slice(self.fty.sig.inputs.slice_from(1)),
..self.fty.sig.clone()
};
let s = match s {
- ast::SelfRegion(..) => {
- match ty::get(*self.fty.sig.inputs.get(0)).sty {
+ ty::ByReferenceExplicitSelfCategory(..) => {
+ match ty::get(self.fty.sig.inputs[0]).sty {
ty::ty_rptr(r, mt) => {
SelfBorrowed(r.clean(), mt.mutbl.clean())
}
- _ => s.clean(),
+ _ => {
+ // FIXME(pcwalton): This is wrong.
+ SelfStatic
+ }
}
}
- s => s.clean(),
+ _ => {
+ // FIXME(pcwalton): This is wrong.
+ SelfStatic
+ }
};
(s, sig)
}
/// A representation of a Type suitable for hyperlinking purposes. Ideally one can get the original
/// type out of the AST/ty::ctxt given one of these, if more information is needed. Most importantly
/// it does not preserve mutability or boxes.
-#[deriving(Clone, Encodable, Decodable)]
+#[deriving(Clone, Encodable, Decodable, PartialEq)]
pub enum Type {
/// structs/enums/traits (anything that'd be an ast::TyPath)
ResolvedPath {
}
}
-#[deriving(Clone, Encodable, Decodable)]
+#[deriving(Clone, Encodable, Decodable, PartialEq)]
pub struct Path {
pub global: bool,
pub segments: Vec<PathSegment>,
}
}
-#[deriving(Clone, Encodable, Decodable)]
+#[deriving(Clone, Encodable, Decodable, PartialEq)]
pub struct PathSegment {
pub name: String,
pub lifetimes: Vec<Lifetime>,
}
}
-#[deriving(Clone, Encodable, Decodable)]
+#[deriving(Clone, Encodable, Decodable, PartialEq)]
pub struct BareFunctionDecl {
pub fn_style: ast::FnStyle,
pub generics: Generics,
let loc = current_location_key.get().unwrap();
let cache = cache_key.get().unwrap();
let abs_root = root(&**cache, loc.as_slice());
- let rel_root = match path.segments.get(0).name.as_slice() {
+ let rel_root = match path.segments[0].name.as_slice() {
"self" => Some("./".to_string()),
_ => None,
};
args.push_str(format!("&{}self",
MutableSpace(mtbl)).as_slice());
}
+ clean::SelfExplicit(ref typ) => {
+ args.push_str(format!("self: {}", *typ).as_slice());
+ }
}
for (i, input) in d.inputs.values.iter().enumerate() {
if i > 0 || args.len() > 0 { args.push_str(", "); }
}
mydst.push(format!("{}.{}.js",
remote_item_type.to_static_str(),
- *remote_path.get(remote_path.len() - 1)));
+ remote_path[remote_path.len() - 1]));
let all_implementors = try!(collect(&mydst, krate.name.as_slice(),
"implementors"));
println!("only one input file may be specified");
return 1;
}
- let input = matches.free.get(0).as_slice();
+ let input = matches.free[0].as_slice();
let libs = matches.opt_strs("L").iter().map(|s| Path::new(s.as_slice())).collect();
"invalid markdown file: expecting initial line with `% ...TITLE...`");
return 5;
}
- let title = metadata.get(0).as_slice();
+ let title = metadata[0].as_slice();
reset_headers();
});
if lines.len() >= 1 {
- let mut unindented = vec![ lines.get(0).trim().to_string() ];
+ let mut unindented = vec![ lines[0].trim().to_string() ];
unindented.push_all(lines.tail().iter().map(|&line| {
if line.is_whitespace() {
line.to_string()
c_ = Some(c.clone());
c.clone();
// force a copy, reading the memory
- c.as_bytes().to_owned();
+ c.as_bytes().to_vec();
});
let c_ = c_.unwrap();
// force a copy, reading the memory
- c_.as_bytes().to_owned();
+ c_.as_bytes().to_vec();
}
#[test]
## Using Autoserialization
-Create a struct called TestStruct1 and serialize and deserialize it to and from JSON
-using the serialization API, using the derived serialization code.
+Create a struct called `TestStruct` and serialize and deserialize it to and from JSON using the
+serialization API, using the derived serialization code.
```rust
extern crate serialize;
use serialize::json;
-#[deriving(Decodable, Encodable)] //generate Decodable, Encodable impl.
-pub struct TestStruct1 {
+// Automatically generate `Decodable` and `Encodable` trait implementations
+#[deriving(Decodable, Encodable)]
+pub struct TestStruct {
data_int: u8,
data_str: String,
data_vector: Vec<u8>,
}
fn main() {
- let object = TestStruct1
- {data_int: 1, data_str:"toto".to_string(), data_vector:vec![2,3,4,5]};
+ let object = TestStruct {
+ data_int: 1,
+ data_str: "toto".to_string(),
+ data_vector: vec![2,3,4,5],
+ };
// Serialize using `json::encode`
let encoded = json::encode(&object);
// Deserialize using `json::decode`
- let decoded: TestStruct1 = json::decode(encoded.as_slice()).unwrap();
+ let decoded: TestStruct = json::decode(encoded.as_slice()).unwrap();
}
```
-## Using `ToJson`
+## Using the `ToJson` trait
+
+The examples above use the `ToJson` trait to generate the JSON string, which required
+for custom mappings.
+
+### Simple example of `ToJson` usage
+
+```rust
+extern crate serialize;
+use serialize::json::ToJson;
+use serialize::json;
+
+// A custom data structure
+struct ComplexNum {
+ a: f64,
+ b: f64,
+}
+
+// JSON value representation
+impl ToJson for ComplexNum {
+ fn to_json(&self) -> json::Json {
+ json::String(format!("{}+{}i", self.a, self.b))
+ }
+}
-This example uses the `ToJson` trait to generate the JSON string.
+// Only generate `Encodable` trait implementation
+#[deriving(Encodable)]
+pub struct ComplexNumRecord {
+ uid: u8,
+ dsc: String,
+ val: json::Json,
+}
+
+fn main() {
+ let num = ComplexNum { a: 0.0001, b: 12.539 };
+ let data: String = json::encode(&ComplexNumRecord{
+ uid: 1,
+ dsc: "test".to_string(),
+ val: num.to_json(),
+ });
+ println!("data: {}", data);
+ // data: {"uid":1,"dsc":"test","val":"0.0001+12.539j"};
+}
+```
+
+### Verbose example of `ToJson` usage
```rust
+extern crate serialize;
use std::collections::TreeMap;
use serialize::json::ToJson;
use serialize::json;
+// Only generate `Decodable` trait implementation
#[deriving(Decodable)]
-pub struct TestStruct1 {
+pub struct TestStruct {
data_int: u8,
data_str: String,
data_vector: Vec<u8>,
}
-impl ToJson for TestStruct1 {
- fn to_json( &self ) -> json::Json {
+// Specify encoding method manually
+impl ToJson for TestStruct {
+ fn to_json(&self) -> json::Json {
let mut d = TreeMap::new();
+ // All standard types implement `to_json()`, so use it
d.insert("data_int".to_string(), self.data_int.to_json());
d.insert("data_str".to_string(), self.data_str.to_json());
d.insert("data_vector".to_string(), self.data_vector.to_json());
fn main() {
// Serialize using `ToJson`
- let test2 = TestStruct1 {data_int: 1, data_str:"toto".to_string(), data_vector:vec![2,3,4,5]};
- let tjson: json::Json = test2.to_json();
- let json_str: String = tjson.to_string();
+ let input_data = TestStruct {
+ data_int: 1,
+ data_str: "toto".to_string(),
+ data_vector: vec![2,3,4,5],
+ };
+ let json_obj: json::Json = input_data.to_json();
+ let json_str: String = json_obj.to_string();
// Deserialize like before
- let decoded: TestStruct1 = json::decode(json_str.as_slice()).unwrap();
+ let decoded: TestStruct = json::decode(json_str.as_slice()).unwrap();
}
```
/// lower indices are at the bottom of the stack while higher indices are
/// at the top.
pub fn get<'l>(&'l self, idx: uint) -> StackElement<'l> {
- match *self.stack.get(idx) {
+ match self.stack[idx] {
InternalIndex(i) => { Index(i) }
InternalKey(start, size) => {
Key(str::from_utf8(
let mask = self.mask;
let mut pos = self.enqueue_pos.load(Relaxed);
loop {
- let node = self.buffer.get(pos & mask);
+ let node = &self.buffer[pos & mask];
let seq = unsafe { (*node.get()).sequence.load(Acquire) };
let diff: int = seq as int - pos as int;
let mask = self.mask;
let mut pos = self.dequeue_pos.load(Relaxed);
loop {
- let node = self.buffer.get(pos & mask);
+ let node = &self.buffer[pos & mask];
let seq = unsafe { (*node.get()).sequence.load(Acquire) };
let diff: int = seq as int - (pos + 1) as int;
if diff == 0 {
}
// Create waiter nobe, and enqueue ourself to
// be woken up by a signaller.
- wait_end = Some(state.blocked.get(condvar_id).wait_end());
+ wait_end = Some(state.blocked[condvar_id].wait_end());
} else {
out_of_bounds = Some(state.blocked.len());
}
let mut result = false;
self.sem.with(|state| {
if condvar_id < state.blocked.len() {
- result = state.blocked.get(condvar_id).signal();
+ result = state.blocked[condvar_id].signal();
} else {
out_of_bounds = Some(state.blocked.len());
}
pub enum ExplicitSelf_ {
/// No self
SelfStatic,
- /// `self
+ /// `self`
SelfValue(Ident),
/// `&'lt self`, `&'lt mut self`
SelfRegion(Option<Lifetime>, Mutability, Ident),
/// `~self`
- SelfUniq(Ident)
+ SelfUniq(Ident),
+ /// `self: TYPE`
+ SelfExplicit(P<Ty>, Ident),
}
pub type ExplicitSelf = Spanned<ExplicitSelf_>;
// expressions for referencing every field of every
// Self arg, assuming all are instances of VariantK.
// Build up code associated with such a case.
- let substructure = EnumMatching(index, variant, field_tuples);
+ let substructure = EnumMatching(index,
+ &*variant,
+ field_tuples);
let arm_expr = self.call_substructure_method(
cx, trait_, type_ident, self_args, nonself_args,
&substructure);
/// The types of pointers
pub enum PtrTy<'a> {
- /// ~
- Send,
/// &'lifetime mut
Borrowed(Option<&'a str>, ast::Mutability),
}
Ptr(ref ty, ref ptr) => {
let raw_ty = ty.to_ty(cx, span, self_ty, self_generics);
match *ptr {
- Send => {
- cx.ty_uniq(span, raw_ty)
- }
Borrowed(ref lt, mutbl) => {
let lt = mk_lifetime(cx, span, lt);
cx.ty_rptr(span, raw_ty, lt, mutbl)
let self_ty = respan(
span,
match *ptr {
- Send => ast::SelfUniq(special_idents::self_),
Borrowed(ref lt, mutbl) => {
let lt = lt.map(|s| cx.lifetime(span, cx.ident_of(s).name));
ast::SelfRegion(lt, mutbl, special_idents::self_)
ast::ExprFnBlock(fn_decl, block) => {
let (rewritten_fn_decl, rewritten_block)
- = expand_and_rename_fn_decl_and_block(fn_decl, block, fld);
+ = expand_and_rename_fn_decl_and_block(&*fn_decl, block, fld);
let new_node = ast::ExprFnBlock(rewritten_fn_decl, rewritten_block);
box(GC) ast::Expr{id:e.id, node: new_node, span: fld.new_span(e.span)}
}
ast::ExprProc(fn_decl, block) => {
let (rewritten_fn_decl, rewritten_block)
- = expand_and_rename_fn_decl_and_block(fn_decl, block, fld);
+ = expand_and_rename_fn_decl_and_block(&*fn_decl, block, fld);
let new_node = ast::ExprProc(rewritten_fn_decl, rewritten_block);
box(GC) ast::Expr{id:e.id, node: new_node, span: fld.new_span(e.span)}
}
match *item {
ast::ItemFn(decl, fn_style, abi, ref generics, body) => {
let (rewritten_fn_decl, rewritten_body)
- = expand_and_rename_fn_decl_and_block(decl,body,fld);
+ = expand_and_rename_fn_decl_and_block(&*decl, body, fld);
let expanded_generics = fold::fold_generics(generics,fld);
ast::ItemFn(rewritten_fn_decl, fn_style, abi, expanded_generics, rewritten_body)
}
};
let expanded_stmt = match expand_mac_invoc(mac,&s.span,
|r|{r.make_stmt()},
- |sts,mrk|{mark_stmt(sts,mrk)},
+ |sts,mrk| {
+ mark_stmt(&*sts,mrk)
+ },
fld) {
Some(stmt) => stmt,
None => {
// names, as well... but that should be okay, as long as
// the new names are gensyms for the old ones.
// generate fresh names, push them to a new pending list
- let idents = pattern_bindings(expanded_pat);
+ let idents = pattern_bindings(&*expanded_pat);
let mut new_pending_renames =
idents.iter().map(|ident| (*ident, fresh_name(ident))).collect();
// rewrite the pattern using the new names (the old
// all of the pats must have the same set of bindings, so use the
// first one to extract them and generate new names:
let first_pat = expanded_pats.get(0);
- let idents = pattern_bindings(*first_pat);
+ let idents = pattern_bindings(&**first_pat);
let new_renames =
idents.iter().map(|id| (*id,fresh_name(id))).collect();
// apply the renaming, but only to the PatIdents:
fn fn_decl_arg_bindings(fn_decl: &ast::FnDecl) -> Vec<ast::Ident> {
let mut pat_idents = PatIdentFinder{ident_accumulator:Vec::new()};
for arg in fn_decl.inputs.iter() {
- pat_idents.visit_pat(arg.pat,());
+ pat_idents.visit_pat(&*arg.pat, ());
}
pat_idents.ident_accumulator
}
match m.node {
ast::MethDecl(ident, ref generics, ref explicit_self, fn_style, decl, body, vis) => {
let (rewritten_fn_decl, rewritten_body)
- = expand_and_rename_fn_decl_and_block(decl,body,fld);
+ = expand_and_rename_fn_decl_and_block(&*decl,body,fld);
SmallVector::one(box(GC) ast::Method {
attrs: m.attrs.iter().map(|a| fld.fold_attribute(*a)).collect(),
id: id,
fld: &mut MacroExpander)
-> (Gc<ast::FnDecl>, Gc<ast::Block>) {
let expanded_decl = fld.fold_fn_decl(fn_decl);
- let idents = fn_decl_arg_bindings(expanded_decl);
+ let idents = fn_decl_arg_bindings(&*expanded_decl);
let renames =
idents.iter().map(|id : &ast::Ident| (*id,fresh_name(id))).collect();
// first, a renamer for the PatIdents, for the fn_decl:
let mut rename_pat_fld = PatIdentRenamer{renames: &renames};
- let rewritten_fn_decl = rename_pat_fld.fold_fn_decl(expanded_decl);
+ let rewritten_fn_decl = rename_pat_fld.fold_fn_decl(&*expanded_decl);
// now, a renamer for *all* idents, for the body:
let mut rename_fld = IdentRenamer{renames: &renames};
let rewritten_body = fld.fold_block(rename_fld.fold_block(block));
}
fn fold_method(&mut self, method: Gc<ast::Method>) -> SmallVector<Gc<ast::Method>> {
- expand_method(method, self)
+ expand_method(&*method, self)
}
fn new_span(&mut self, span: Span) -> Span {
fn run_renaming_test(t: &RenamingTest, test_idx: uint) {
let invalid_name = token::special_idents::invalid.name;
let (teststr, bound_connections, bound_ident_check) = match *t {
- (ref str,ref conns, bic) => (str.to_owned(), conns.clone(), bic)
+ (ref str,ref conns, bic) => (str.to_string(), conns.clone(), bic)
};
let cr = expand_crate_str(teststr.to_string());
let bindings = crate_bindings(&cr);
fn pat_idents(){
let pat = string_to_pat(
"(a,Foo{x:c @ (b,9),y:Bar(4,d)})".to_string());
- let idents = pattern_bindings(pat);
+ let idents = pattern_bindings(&*pat);
assert_eq!(idents, strs_to_idents(vec!("a","c","b","d")));
}
SelfRegion(ref lifetime, m, id) => {
SelfRegion(fold_opt_lifetime(lifetime, self), m, id)
}
+ SelfExplicit(ref typ, id) => SelfExplicit(self.fold_ty(*typ), id),
}
}
.expect_one("expected fold to produce exactly one item")),
token::NtBlock(block) => token::NtBlock(fld.fold_block(block)),
token::NtStmt(stmt) =>
- token::NtStmt(fld.fold_stmt(stmt)
+ token::NtStmt(fld.fold_stmt(&*stmt)
// this is probably okay, because the only folds likely
// to peek inside interpolated nodes will be renamings/markings,
// which map single items to single items
token::NtIdent(ref id, is_mod_name) =>
token::NtIdent(box fld.fold_ident(**id),is_mod_name),
token::NtMeta(meta_item) => token::NtMeta(fold_meta_item_(meta_item,fld)),
- token::NtPath(ref path) => token::NtPath(box fld.fold_path(*path)),
- token::NtTT(tt) => token::NtTT(box (GC) fold_tt(tt,fld)),
+ token::NtPath(ref path) => token::NtPath(box fld.fold_path(&**path)),
+ token::NtTT(tt) => token::NtTT(box (GC) fold_tt(&*tt,fld)),
// it looks to me like we can leave out the matchers: token::NtMatchers(matchers)
_ => (*nt).clone()
}
),
ObsoleteManagedExpr => (
"`@` notation for a managed pointer allocation",
- "use the `box(GC)` oeprator instead of `@`"
+ "use the `box(GC)` operator instead of `@`"
),
};
use ast::{StmtExpr, StmtSemi, StmtMac, StructDef, StructField};
use ast::{StructVariantKind, BiSub};
use ast::StrStyle;
-use ast::{SelfRegion, SelfStatic, SelfUniq, SelfValue};
+use ast::{SelfExplicit, SelfRegion, SelfStatic, SelfUniq, SelfValue};
use ast::{TokenTree, TraitMethod, TraitRef, TTDelim, TTSeq, TTTok};
use ast::{TTNonterminal, TupleVariantKind, Ty, Ty_, TyBot, TyBox};
use ast::{TypeField, TyFixedLengthVec, TyClosure, TyProc, TyBareFn};
inedible: &[token::Token]) {
debug!("commit_stmt {:?}", s);
let _s = s; // unused, but future checks might want to inspect `s`.
- if self.last_token.as_ref().map_or(false, |t| is_ident_or_path(*t)) {
+ if self.last_token
+ .as_ref()
+ .map_or(false, |t| is_ident_or_path(&**t)) {
let expected = edible.iter().map(|x| (*x).clone()).collect::<Vec<_>>()
.append(inedible.as_slice());
self.check_for_erroneous_unit_struct_expecting(
}
}
token::IDENT(..) if self.is_self_ident() => {
- SelfValue(self.expect_self_ident())
+ let self_ident = self.expect_self_ident();
+
+ // Determine whether this is the fully explicit form, `self:
+ // TYPE`.
+ if self.eat(&token::COLON) {
+ SelfExplicit(self.parse_ty(false), self_ident)
+ } else {
+ SelfValue(self_ident)
+ }
}
token::BINOP(token::STAR) => {
// Possibly "*self" or "*mut self" -- not supported. Try to avoid
self.bump();
let _mutability = if Parser::token_is_mutability(&self.token) {
self.parse_mutability()
- } else { MutImmutable };
+ } else {
+ MutImmutable
+ };
if self.is_self_ident() {
let span = self.span;
self.span_err(span, "cannot pass self by unsafe pointer");
_ if Parser::token_is_mutability(&self.token) &&
self.look_ahead(1, |t| token::is_keyword(keywords::Self, t)) => {
mutbl_self = self.parse_mutability();
- SelfValue(self.expect_self_ident())
+ let self_ident = self.expect_self_ident();
+
+ // Determine whether this is the fully explicit form, `self:
+ // TYPE`.
+ if self.eat(&token::COLON) {
+ SelfExplicit(self.parse_ty(false), self_ident)
+ } else {
+ SelfValue(self_ident)
+ }
}
_ if Parser::token_is_mutability(&self.token) &&
self.look_ahead(1, |t| *t == token::TILDE) &&
}
SelfValue(id) => parse_remaining_arguments!(id),
SelfRegion(_,_,id) => parse_remaining_arguments!(id),
- SelfUniq(id) => parse_remaining_arguments!(id)
-
+ SelfUniq(id) => parse_remaining_arguments!(id),
+ SelfExplicit(_,id) => parse_remaining_arguments!(id),
};
try!(self.print_mutability(m));
try!(word(&mut self.s, "self"));
}
+ ast::SelfExplicit(ref typ, _) => {
+ try!(word(&mut self.s, "self"));
+ try!(self.word_space(":"));
+ try!(self.print_type(&**typ));
+ }
}
return Ok(true);
}
SelfRegion(ref lifetime, _, _) => {
visitor.visit_opt_lifetime_ref(explicit_self.span, lifetime, env)
}
+ SelfExplicit(ref typ, _) => visitor.visit_ty(&**typ, env.clone()),
}
}
MethDecl(ident, ref generics, _, _, decl, body, _) => {
visitor.visit_ident(method.span, ident, env.clone());
visitor.visit_fn(&FkMethod(ident, generics, method),
- decl,
- body,
+ &*decl,
+ &*body,
method.span,
method.id,
env.clone());
assert!(!s.is_empty(), "string conversion produced empty result");
match op {
FormatDigit => {
- if flags.space && !(*s.get(0) == '-' as u8 ||
- *s.get(0) == '+' as u8) {
+ if flags.space && !(s[0] == '-' as u8 ||
+ s[0] == '+' as u8) {
s.unshift(' ' as u8);
}
}
FormatOctal => {
- if flags.alternate && *s.get(0) != '0' as u8 {
+ if flags.alternate && s[0] != '0' as u8 {
s.unshift('0' as u8);
}
}
pub fn open(term: &str) -> Result<File, String> {
match get_dbpath_for_term(term) {
Some(x) => {
- match File::open(x) {
+ match File::open(&*x) {
Ok(file) => Ok(file),
Err(e) => Err(format!("error opening file: {}", e)),
}
if matches.opt_present("h") { usage(args[0].as_slice()); return None; }
let filter = if matches.free.len() > 0 {
- let s = matches.free.get(0).as_slice();
+ let s = matches.free[0].as_slice();
match Regex::new(s) {
Ok(re) => Some(re),
Err(e) => return Some(Err(format!("could not parse /{}/: {}", s, e)))
// This inner loop applies `hi`/`lo` summation to each
// partial so that the list of partial sums remains exact.
for i in range(0, partials.len()) {
- let mut y = *partials.get(i);
+ let mut y = partials[i];
if num::abs(x) < num::abs(y) {
mem::swap(&mut x, &mut y);
}
match group_lens.len() {
// Single group, no hyphens
1 => {
- if *group_lens.get(0) != 32 {
- return Err(ErrorInvalidLength(*group_lens.get(0)));
+ if group_lens[0] != 32 {
+ return Err(ErrorInvalidLength(group_lens[0]));
}
},
// Five groups, hyphens in between each
#![crate_id="lint_stability#0.1"]
#![crate_type = "lib"]
+#![feature(macro_rules)]
+#![macro_escape]
+
#[deprecated]
pub fn deprecated() {}
#[deprecated="text"]
pub struct FrozenTupleStruct(pub int);
#[locked]
pub struct LockedTupleStruct(pub int);
+
+#[macro_export]
+macro_rules! macro_test(
+ () => (deprecated());
+)
// given a map, search for the frequency of a pattern
fn find(mm: &HashMap<Vec<u8> , uint>, key: String) -> uint {
- let key = key.to_owned().into_ascii().as_slice().to_lower().into_string();
+ let key = key.into_ascii().as_slice().to_lower().into_string();
match mm.find_equiv(&key.as_bytes()) {
option::None => { return 0u; }
option::Some(&num) => { return num; }
let mut proc_mode = false;
for line in rdr.lines() {
- let line = line.unwrap().as_slice().trim().to_owned();
+ let line = line.unwrap().as_slice().trim().to_string();
if line.len() == 0u { continue; }
let (mut variant_strs, mut counts) = (vec!(), vec!());
for variant in variants.move_iter() {
let seq_arc_copy = seq_arc.clone();
- variant_strs.push(variant.to_string().to_owned());
+ variant_strs.push(variant.to_string());
counts.push(Future::spawn(proc() {
count_matches(seq_arc_copy.as_slice(), &variant)
}));
// evaluated, but it gets freed when evaluating the second
// argument!
add(
- a,
+ &*a,
rewrite(&mut a)); //~ ERROR cannot borrow
}
// evaluated, but it gets moved when evaluating the second
// argument!
add(
- a,
+ &*a,
a); //~ ERROR cannot move
}
let test = |foo: &Foo| {
ptr = box Foo { x: ptr.x + 1 };
};
- test(ptr); //~ ERROR cannot borrow `*ptr`
+ test(&*ptr); //~ ERROR cannot borrow `*ptr`
}
let mut x = &mut v;
**x += 1;
loop {
- borrow(v); //~ ERROR cannot borrow
+ borrow(&*v); //~ ERROR cannot borrow
}
}
let mut v = box 3;
let mut x = &mut v;
for _ in range(0i, 3) {
- borrow(v); //~ ERROR cannot borrow
+ borrow(&*v); //~ ERROR cannot borrow
}
*x = box 5;
}
let mut x = &mut w;
while cond {
**x += 1;
- borrow(v); //~ ERROR cannot borrow
+ borrow(&*v); //~ ERROR cannot borrow
if cond2 {
x = &mut v; //~ ERROR cannot borrow
}
fn box_imm() {
let mut v = box 3;
- borrow(v,
+ borrow(&*v,
|w| { //~ ERROR cannot borrow `v` as mutable
v = box 4;
assert_eq!(*v, 3);
pub fn main() {
let mut x = box(GC) F {f: box 3};
- borrow(x.f, |b_x| {
+ borrow(&*x.f, |b_x| {
//~^ ERROR cannot borrow `x` as mutable because `*x.f` is also borrowed as immutable
assert_eq!(*b_x, 3);
assert_eq!(&(*x.f) as *const int, &(*b_x) as *const int);
pub fn main() {
let mut x = box box(GC) F{f: box 3};
- borrow(x.f, |b_x| {
+ borrow(&*x.f, |b_x| {
//~^ ERROR cannot borrow `x` as mutable because `*x.f` is also borrowed as immutable
assert_eq!(*b_x, 3);
assert_eq!(&(*x.f) as *const int, &(*b_x) as *const int);
pub fn main() {
let mut x = box(GC) 3;
- borrow(x, |b_x| {
+ borrow(&*x, |b_x| {
//~^ ERROR cannot borrow `x` as mutable because `*x` is also borrowed as immutable
assert_eq!(*b_x, 3);
assert_eq!(&(*x) as *const int, &(*b_x) as *const int);
pub fn main() {
let mut x = box(GC) F {f: box 3};
- borrow((*x).f, |b_x| {
+ borrow(&*(*x).f, |b_x| {
//~^ ERROR cannot borrow `x` as mutable because `*x.f` is also borrowed as immutable
assert_eq!(*b_x, 3);
assert_eq!(&(*x.f) as *const int, &(*b_x) as *const int);
fn local() {
let mut v = box 3i;
- borrow(v);
+ borrow(&*v);
}
fn local_rec() {
struct F { f: Box<int> }
let mut v = F {f: box 3};
- borrow(v.f);
+ borrow(&*v.f);
}
fn local_recs() {
struct G { g: H }
struct H { h: Box<int> }
let mut v = F {f: G {g: H {h: box 3}}};
- borrow(v.f.g.h);
+ borrow(&*v.f.g.h);
}
fn aliased_imm() {
let mut v = box 3i;
let _w = &v;
- borrow(v);
+ borrow(&*v);
}
fn aliased_mut() {
let mut v = box 3i;
let _w = &mut v;
- borrow(v); //~ ERROR cannot borrow `*v`
+ borrow(&*v); //~ ERROR cannot borrow `*v`
}
fn aliased_other() {
let mut v = box 3i;
let mut w = box 4i;
let _x = &mut w;
- borrow(v);
+ borrow(&*v);
}
fn aliased_other_reassign() {
let mut w = box 4i;
let mut _x = &mut w;
_x = &mut v;
- borrow(v); //~ ERROR cannot borrow `*v`
+ borrow(&*v); //~ ERROR cannot borrow `*v`
}
fn main() {
--- /dev/null
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+struct Foo<'a,'b> {
+ x: &'a int,
+ y: &'b int,
+}
+
+impl<'a,'b> Foo<'a,'b> {
+ // The number of errors is related to the way invariance works.
+ fn bar(self: Foo<'b,'a>) {}
+ //~^ ERROR mismatched types: expected `Foo<'a,'b>` but found `Foo<'b,'a>`
+ //~^^ ERROR mismatched types: expected `Foo<'a,'b>` but found `Foo<'b,'a>`
+ //~^^^ ERROR mismatched types: expected `Foo<'b,'a>` but found `Foo<'a,'b>`
+ //~^^^^ ERROR mismatched types: expected `Foo<'b,'a>` but found `Foo<'a,'b>`
+}
+
+fn main() {}
+
ptr = box Foo { x: ptr.x + 1 };
println!("access {}", foo.x);
};
- test(ptr);
+ test(&*ptr);
//~^ ERROR: cannot borrow `*ptr` as immutable
}
// error-pattern: type `&Foo` does not implement any method in scope named `foo`
trait Foo {
- fn foo(~self);
+ fn foo(self: Box<Self>);
}
impl Foo for int {
- fn foo(~self) { }
+ fn foo(self: Box<int>) { }
}
fn main() {
fn make_make_a() -> A {
let b: Box<B> = box B {i:1};
- let bb: &B = b; //~ ERROR does not live long enough
+ let bb: &B = &*b; //~ ERROR does not live long enough
make_a(bb)
}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <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.
-
-#![deny(unnecessary_allocation)]
-
-fn f(_: &int) {}
-
-fn main() {
- f(box 1); //~ ERROR unnecessary allocation, use & instead
-}
// aux-build:lint_stability.rs
// aux-build:inherited_stability.rs
-#![feature(globs)]
+#![feature(globs, phase)]
#![deny(unstable)]
#![deny(deprecated)]
#![deny(experimental)]
#![allow(dead_code)]
mod cross_crate {
+ #[phase(plugin, link)]
extern crate lint_stability;
use self::lint_stability::*;
foo.method_locked_text();
foo.trait_locked_text();
-
let _ = DeprecatedStruct { i: 0 }; //~ ERROR use of deprecated item
let _ = ExperimentalStruct { i: 0 }; //~ ERROR use of experimental item
let _ = UnstableStruct { i: 0 }; //~ ERROR use of unstable item
let _ = StableTupleStruct (1);
let _ = FrozenTupleStruct (1);
let _ = LockedTupleStruct (1);
+
+ // At the moment, the following just checks that the stability
+ // level of expanded code does not trigger the
+ // lint. Eventually, we will want to lint the contents of the
+ // macro in the module *defining* it. Also, stability levels
+ // on macros themselves are not yet linted.
+ macro_test!();
}
fn test_method_param<F: Trait>(foo: F) {
struct Foo;
impl Foo {
fn foo(mut self) {} //~ ERROR: variable does not need to be mutable
- fn bar(mut ~self) {} //~ ERROR: variable does not need to be mutable
+ fn bar(mut self: Box<Foo>) {} //~ ERROR: variable does not need to be mutable
}
fn main() {}
fn borrowed(&self);
fn borrowed_mut(&mut self);
- fn owned(~self);
+ fn owned(self: Box<Self>);
}
fn borrowed_receiver(x: &Foo) {
}
fn foo(p: Gc<point>) -> &int {
- let xc = x_coord(p); //~ ERROR `*p` does not live long enough
+ let xc = x_coord(&*p); //~ ERROR `*p` does not live long enough
assert_eq!(*xc, 3);
return xc;
}
// Here we complain because the resulting region
// of this borrow is the fn body as a whole.
- y = borrow(x); //~ ERROR `*x` does not live long enough
+ y = borrow(&*x); //~ ERROR `*x` does not live long enough
assert_eq!(*x, *y);
if cond() { break; }
let b: Box<B> = box B {
i: 1,
};
- let bb: &B = b; //~ ERROR `*b` does not live long enough
+ let bb: &B = &*b; //~ ERROR `*b` does not live long enough
make_a(bb)
}
+// ignore-test
+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
}
pub fn main() {
- let f = Foo { x: box(GC) 3 }; //~ ERROR borrowed value does not live long enough
+ let f = Foo { x: &*(box(GC) 3) }; //~ ERROR borrowed value does not live long enough
assert_eq!(*f.x, 3);
}
--- /dev/null
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::owned::Box;
+
+struct Foo {
+ f: int,
+}
+
+impl Foo {
+ fn foo(self: int, x: int) -> int { //~ ERROR mismatched self type
+//~^ ERROR not a valid type for `self`
+ self.f + x
+ }
+}
+
+struct Bar<T> {
+ f: T,
+}
+
+impl<T> Bar<T> {
+ fn foo(self: Bar<int>, x: int) -> int { //~ ERROR mismatched self type
+//~^ ERROR not a valid type for `self`
+ x
+ }
+ fn bar(self: &Bar<uint>, x: int) -> int { //~ ERROR mismatched self type
+//~^ ERROR not a valid type for `self`
+ x
+ }
+}
+
+fn main() {
+ let foo = box Foo {
+ f: 1,
+ };
+ println!("{}", foo.foo(2));
+ let bar = box Bar {
+ f: 1,
+ };
+ println!("{} {}", bar.foo(2), bar.bar(2));
+}
+
fn main() {
let bool_box: Gc<bool> = box(GC) true;
- let bool_ref: &bool = bool_box;
+ let bool_ref: &bool = &*bool_box;
let int_box: Gc<int> = box(GC) -1;
- let int_ref: &int = int_box;
+ let int_ref: &int = &*int_box;
let char_box: Gc<char> = box(GC) 'a';
- let char_ref: &char = char_box;
+ let char_ref: &char = &*char_box;
let i8_box: Gc<i8> = box(GC) 68;
- let i8_ref: &i8 = i8_box;
+ let i8_ref: &i8 = &*i8_box;
let i16_box: Gc<i16> = box(GC) -16;
- let i16_ref: &i16 = i16_box;
+ let i16_ref: &i16 = &*i16_box;
let i32_box: Gc<i32> = box(GC) -32;
- let i32_ref: &i32 = i32_box;
+ let i32_ref: &i32 = &*i32_box;
let i64_box: Gc<i64> = box(GC) -64;
- let i64_ref: &i64 = i64_box;
+ let i64_ref: &i64 = &*i64_box;
let uint_box: Gc<uint> = box(GC) 1;
- let uint_ref: &uint = uint_box;
+ let uint_ref: &uint = &*uint_box;
let u8_box: Gc<u8> = box(GC) 100;
- let u8_ref: &u8 = u8_box;
+ let u8_ref: &u8 = &*u8_box;
let u16_box: Gc<u16> = box(GC) 16;
- let u16_ref: &u16 = u16_box;
+ let u16_ref: &u16 = &*u16_box;
let u32_box: Gc<u32> = box(GC) 32;
- let u32_ref: &u32 = u32_box;
+ let u32_ref: &u32 = &*u32_box;
let u64_box: Gc<u64> = box(GC) 64;
- let u64_ref: &u64 = u64_box;
+ let u64_ref: &u64 = &*u64_box;
let f32_box: Gc<f32> = box(GC) 2.5;
- let f32_ref: &f32 = f32_box;
+ let f32_ref: &f32 = &*f32_box;
let f64_box: Gc<f64> = box(GC) 3.5;
- let f64_ref: &f64 = f64_box;
+ let f64_ref: &f64 = &*f64_box;
zzz(); // #break
}
let ref_to_unnamed: &SomeStruct = &SomeStruct { x: 11, y: 24.5 };
let managed_val = box(GC) SomeStruct { x: 12, y: 25.5 };
- let managed_val_ref: &SomeStruct = managed_val;
+ let managed_val_ref: &SomeStruct = &*managed_val;
let managed_val_interior_ref_1: &int = &managed_val.x;
let managed_val_interior_ref_2: &f64 = &managed_val.y;
let unique_val = box SomeStruct { x: 13, y: 26.5 };
- let unique_val_ref: &SomeStruct = unique_val;
+ let unique_val_ref: &SomeStruct = &*unique_val;
let unique_val_interior_ref_1: &int = &unique_val.x;
let unique_val_interior_ref_2: &f64 = &unique_val.y;
let ref_to_unnamed: &(i16, f32) = &(-15, -20f32);
let managed_val: Gc<(i16, f32)> = box(GC) (-16, -21f32);
- let managed_val_ref: &(i16, f32) = managed_val;
+ let managed_val_ref: &(i16, f32) = &*managed_val;
let unique_val: Box<(i16, f32)> = box() (-17, -22f32);
- let unique_val_ref: &(i16, f32) = unique_val;
+ let unique_val_ref: &(i16, f32) = &*unique_val;
zzz(); // #break
}
fn main() {
let bool_box: Box<bool> = box true;
- let bool_ref: &bool = bool_box;
+ let bool_ref: &bool = &*bool_box;
let int_box: Box<int> = box -1;
- let int_ref: &int = int_box;
+ let int_ref: &int = &*int_box;
let char_box: Box<char> = box 'a';
- let char_ref: &char = char_box;
+ let char_ref: &char = &*char_box;
let i8_box: Box<i8> = box 68;
- let i8_ref: &i8 = i8_box;
+ let i8_ref: &i8 = &*i8_box;
let i16_box: Box<i16> = box -16;
- let i16_ref: &i16 = i16_box;
+ let i16_ref: &i16 = &*i16_box;
let i32_box: Box<i32> = box -32;
- let i32_ref: &i32 = i32_box;
+ let i32_ref: &i32 = &*i32_box;
let i64_box: Box<i64> = box -64;
- let i64_ref: &i64 = i64_box;
+ let i64_ref: &i64 = &*i64_box;
let uint_box: Box<uint> = box 1;
- let uint_ref: &uint = uint_box;
+ let uint_ref: &uint = &*uint_box;
let u8_box: Box<u8> = box 100;
- let u8_ref: &u8 = u8_box;
+ let u8_ref: &u8 = &*u8_box;
let u16_box: Box<u16> = box 16;
- let u16_ref: &u16 = u16_box;
+ let u16_ref: &u16 = &*u16_box;
let u32_box: Box<u32> = box 32;
- let u32_ref: &u32 = u32_box;
+ let u32_ref: &u32 = &*u32_box;
let u64_box: Box<u64> = box 64;
- let u64_ref: &u64 = u64_box;
+ let u64_ref: &u64 = &*u64_box;
let f32_box: Box<f32> = box 2.5;
- let f32_ref: &f32 = f32_box;
+ let f32_ref: &f32 = &*f32_box;
let f64_box: Box<f64> = box 3.5;
- let f64_ref: &f64 = f64_box;
+ let f64_ref: &f64 = &*f64_box;
zzz(); // #break
}
arg1
}
- fn self_owned<T2>(~self, arg1: int, arg2: T2) -> int {
+ fn self_owned<T2>(self: Box<Struct<T1>>, arg1: int, arg2: T2) -> int {
zzz(); // #break
arg1
}
arg1 + arg2
}
- fn self_owned(~self, arg1: int, arg2: int) -> int {
+ fn self_owned(self: Box<Enum>, arg1: int, arg2: int) -> int {
zzz(); // #break
arg1 + arg2
}
arg1 + arg2
}
- fn self_owned(~self, arg1: int, arg2: int) -> int {
+ fn self_owned(self: Box<Struct<T>>, arg1: int, arg2: int) -> int {
zzz(); // #break
arg1 + arg2
}
self.x + arg1 + arg2
}
- fn self_owned(~self, arg1: int, arg2: int) -> int {
+ fn self_owned(self: Box<Struct>, arg1: int, arg2: int) -> int {
zzz(); // #break
self.x + arg1 + arg2
}
trait Trait {
fn self_by_ref(&self, arg1: int, arg2: int) -> int;
fn self_by_val(self, arg1: int, arg2: int) -> int;
- fn self_owned(~self, arg1: int, arg2: int) -> int;
+ fn self_owned(self: Box<Self>, arg1: int, arg2: int) -> int;
}
impl Trait for Struct {
self.x + arg1 + arg2
}
- fn self_owned(~self, arg1: int, arg2: int) -> int {
+ fn self_owned(self: Box<Struct>, arg1: int, arg2: int) -> int {
zzz(); // #break
self.x + arg1 + arg2
}
arg1 + arg2
}
- fn self_owned(~self, arg1: int, arg2: int) -> int {
+ fn self_owned(self: Box<TupleStruct>, arg1: int, arg2: int) -> int {
zzz(); // #break
arg1 + arg2
}
arg1 + arg2
}
- fn self_owned(~self, arg1: int, arg2: int) -> int {
+ fn self_owned(self: Box<Self>, arg1: int, arg2: int) -> int {
zzz(); // #break
arg1 + arg2
}
arg1
}
- fn self_owned<T>(~self, arg1: int, arg2: T) -> int {
+ fn self_owned<T>(self: Box<Self>, arg1: int, arg2: T) -> int {
zzz(); // #break
arg1
}
let closure: proc() = proc() {
zzz(); // #break
- do_something(&constant, &a_struct.a, owned);
+ do_something(&constant, &a_struct.a, &*owned);
};
closure();
trait double {
- fn double(~self) -> uint;
+ fn double(self: Box<Self>) -> uint;
}
impl double for uint {
- fn double(~self) -> uint { *self * 2u }
+ fn double(self: Box<uint>) -> uint { *self * 2u }
}
pub fn main() {
trait double {
- fn double(~self) -> uint;
+ fn double(self: Box<Self>) -> uint;
}
impl double for Box<uint> {
- fn double(~self) -> uint { **self * 2u }
+ fn double(self: Box<Box<uint>>) -> uint { **self * 2u }
}
pub fn main() {
// except according to those terms.
trait double {
- fn double(~self) -> uint;
+ fn double(self: Box<Self>) -> uint;
}
impl double for uint {
- fn double(~self) -> uint { *self * 2u }
+ fn double(self: Box<uint>) -> uint { *self * 2u }
}
pub fn main() {
// except according to those terms.
trait double {
- fn double(~self) -> uint;
+ fn double(self: Box<Self>) -> uint;
}
impl double for uint {
- fn double(~self) -> uint { *self * 2u }
+ fn double(self: Box<uint>) -> uint { *self * 2u }
}
pub fn main() {
fn bitv_test() {
let mut v1 = box Bitv::with_capacity(31, false);
let v2 = box Bitv::with_capacity(31, true);
- v1.union(v2);
+ v1.union(&*v2);
}
pub fn main() {
fn borrow(_v: &int) {}
fn borrow_from_arg_imm_ref(v: Box<int>) {
- borrow(v);
+ borrow(&*v);
}
fn borrow_from_arg_mut_ref(v: &mut Box<int>) {
- borrow(*v);
+ borrow(&**v);
}
fn borrow_from_arg_copy(v: Box<int>) {
- borrow(v);
+ borrow(&*v);
}
pub fn main() {
add_int(&mut *ints, 22);
add_int(&mut *ints, 44);
- iter_ints(ints, |i| {
+ iter_ints(&*ints, |i| {
println!("int = {}", *i);
true
});
pub fn main() {
let rec = box(GC) Rec {f: box(GC) 22};
- while *borrow(rec.f) == 23 {}
+ while *borrow(&*rec.f) == 23 {}
}
fn borrow(_v: &int) {}
fn box_mut(v: &mut Box<int>) {
- borrow(*v); // OK: &mut -> &imm
+ borrow(&**v); // OK: &mut -> &imm
}
fn box_mut_rec(v: &mut Rec) {
- borrow(v.f); // OK: &mut -> &imm
+ borrow(&*v.f); // OK: &mut -> &imm
}
fn box_mut_recs(v: &mut Outer) {
- borrow(v.f.g.h); // OK: &mut -> &imm
+ borrow(&*v.f.g.h); // OK: &mut -> &imm
}
fn box_imm(v: &Box<int>) {
- borrow(*v); // OK
+ borrow(&**v); // OK
}
fn box_imm_rec(v: &Rec) {
- borrow(v.f); // OK
+ borrow(&*v.f); // OK
}
fn box_imm_recs(v: &Outer) {
- borrow(v.f.g.h); // OK
+ borrow(&*v.f.g.h); // OK
}
pub fn main() {
pub fn main() {
let p = box(GC) 22u;
- let r = foo(p);
+ let r = foo(&*p);
println!("r={}", r);
assert_eq!(r, 22u);
}
trait Foo {
- fn f(~self);
+ fn f(self: Box<Self>);
}
struct S {
}
impl Foo for S {
- fn f(~self) {
+ fn f(self: Box<S>) {
assert_eq!(self.x, 3);
}
}
}
impl thing {
- pub fn bar(~self) -> int { self.x.a }
+ pub fn bar(self: Box<thing>) -> int { self.x.a }
pub fn quux(&self) -> int { self.x.a }
pub fn baz<'a>(&'a self) -> &'a A { &self.x }
pub fn spam(self) -> int { self.x.a }
pub fn main() {
let mut m = HashMap::new();
- m.insert("foo".as_bytes().to_owned(), "bar".as_bytes().to_owned());
+ m.insert(b"foo".to_vec(), b"bar".to_vec());
println!("{:?}", m);
}
pub fn main() {
let s: Box<S> = box S { s: 5 };
- print_s(s);
+ print_s(&*s);
let t: Box<T> = s as Box<T>;
print_t(t);
-
}
}
priv fn chop(s: String) -> String {
- s.slice(0, s.len() - 1).to_owned()
+ s.slice(0, s.len() - 1).to_string()
}
priv fn parse_bulk(io: @io::Reader) -> Result {
}
fn check(a: Gc<Foo>) {
- let _ic = Bar{ b: a, a: box None };
+ let _ic = Bar{ b: &*a, a: box None };
}
pub fn main(){}
trait Foo {
- fn foo(~self) { bar(self as Box<Foo>); }
+ fn foo(self: Box<Self>) { bar(self as Box<Foo>); }
}
fn bar(_b: Box<Foo>) { }
fn f() {
let a = box 1;
- let b: &int = a;
+ let b: &int = &*a;
println!("{}", b);
}
fn f(x: Box<int>) {
- let y: &int = x;
+ let y: &int = &*x;
println!("{}", *x);
println!("{}", *y);
}
trait FooTrait {
- fn foo(~self) -> uint;
+ fn foo(self: Box<Self>) -> uint;
}
struct BarStruct {
}
impl FooTrait for BarStruct {
- fn foo(~self) -> uint {
+ fn foo(self: Box<BarStruct>) -> uint {
self.x
}
}
pub fn main() {
let p = box(GC) 22u;
- let r = foo(p);
+ let r = foo(&*p);
println!("r={}", r);
assert_eq!(r, 22u);
}
pub fn main() {
let p = box 3u;
- let r = foo(p);
+ let r = foo(&*p);
assert_eq!(r, 3u);
}
pub fn main() {
let p = box(GC) 3u;
- assert_eq!(bar(foo(p)), 3);
+ assert_eq!(bar(foo(&*p)), 3);
}
pub fn main() {
let x = box(GC) 3i;
loop {
- let y = borrow(x);
+ let y = borrow(&*x);
assert_eq!(*x, *y);
break;
}
pub fn main() {
let p = box(GC) Point {x: 3, y: 4};
- let xc = x_coord(p);
+ let xc = x_coord(&*p);
assert_eq!(*xc, 3);
}
self
}
- fn change_again(mut ~self) -> Box<Self> {
+ fn change_again(mut self: Box<Self>) -> Box<Self> {
self.set_to(45);
self
}
--- /dev/null
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::owned::Box;
+
+struct Foo {
+ f: int,
+}
+
+impl Foo {
+ fn foo(self: Foo, x: int) -> int {
+ self.f + x
+ }
+ fn bar(self: &Foo, x: int) -> int {
+ self.f + x
+ }
+ fn baz(self: Box<Foo>, x: int) -> int {
+ self.f + x
+ }
+}
+
+struct Bar<T> {
+ f: T,
+}
+
+impl<T> Bar<T> {
+ fn foo(self: Bar<T>, x: int) -> int {
+ x
+ }
+ fn bar<'a>(self: &'a Bar<T>, x: int) -> int {
+ x
+ }
+ fn baz(self: Bar<T>, x: int) -> int {
+ x
+ }
+}
+
+fn main() {
+ let foo = box Foo {
+ f: 1,
+ };
+ println!("{} {} {}", foo.foo(2), foo.bar(2), foo.baz(2));
+ let bar = box Bar {
+ f: 1,
+ };
+ println!("{} {} {}", bar.foo(2), bar.bar(2), bar.baz(2));
+ let bar: Box<Bar<int>> = bar;
+ println!("{} {} {}", bar.foo(2), bar.bar(2), bar.baz(2));
+}
+
}
trait Changer {
- fn change(mut ~self) -> Box<Self>;
+ fn change(mut self: Box<Self>) -> Box<Self>;
}
impl Changer for X {
- fn change(mut ~self) -> Box<X> {
+ fn change(mut self: Box<X>) -> Box<X> {
self.a = 55;
self
}