A trait is a language feature that tells the Rust compiler about
functionality a type must provide.
-Do you remember the `impl` keyword, used to call a function with [method
-syntax][methodsyntax]?
+Recall the `impl` keyword, used to call a function with [method
+syntax][methodsyntax]:
```rust
struct Circle {
[methodsyntax]: method-syntax.html
-Traits are similar, except that we define a trait with just the method
-signature, then implement the trait for that struct. Like this:
+Traits are similar, except that we first define a trait with a method
+signature, then implement the trait for a type. In this example, we implement the trait `HasArea` for `Circle`:
```rust
struct Circle {
```
This shows off the additional feature of `where` clauses: they allow bounds
-where the left-hand side is an arbitrary type (`i32` in this case), not just a
-plain type parameter (like `T`). In this example, `i32` must implement
+on the left-hand side not only of type parameters `T`, but also of types (`i32` in this case). In this example, `i32` must implement
`ConvertTo<T>`. Rather than defining what `i32` is (since that's obvious), the
-`where` clause here is a constraint on `T`.
+`where` clause here constrains `T`.
# Default methods
-If you already know how a typical implementor will define a method, you can
-let your trait supply a default:
+A default method can be added to a trait definition if it is already known how a typical implementor will define a method. For example, `is_invalid()` is defined as the opposite of `is_valid()`:
```rust
trait Foo {
}
```
-Implementors of the `Foo` trait need to implement `is_valid()`, but they don’t
-need to implement `is_invalid()`. They’ll get this default behavior. They can
-override the default if they so choose:
+Implementors of the `Foo` trait need to implement `is_valid()` but not `is_invalid()` due to the added default behavior. This default behavior can still be overridden as in:
```rust
# trait Foo {
fn is_invalid(&self) -> bool {
println!("Called OverrideDefault.is_invalid!");
- true // this implementation is a self-contradiction!
+ true // overrides the expected value of is_invalid()
}
}
# Deriving
-Implementing traits like `Debug` and `Default` over and over again can become
+Implementing traits like `Debug` and `Default` repeatedly can become
quite tedious. For that reason, Rust provides an [attribute][attributes] that
allows you to let Rust automatically implement traits for you:
# fn main() {}
```
+Additionally keyword `super` may be repeated several times after the first
+`super` or `self` to refer to ancestor modules.
+
+```rust
+mod a {
+ fn foo() {}
+
+ mod b {
+ mod c {
+ fn foo() {
+ super::super::foo(); // call a's foo function
+ self::super::super::foo(); // call a's foo function
+ }
+ }
+ }
+}
+# fn main() {}
+```
+
# Syntax extensions
A number of minor features of Rust are not central enough to have their own
}
}
- /// Appends all elements in a slice to the `Vec`.
- ///
- /// Iterates over the slice `other`, clones each element, and then appends
- /// it to this `Vec`. The `other` vector is traversed in-order.
- ///
- /// # Examples
- ///
- /// ```
- /// #![feature(vec_push_all)]
- /// #![allow(deprecated)]
- ///
- /// let mut vec = vec![1];
- /// vec.push_all(&[2, 3, 4]);
- /// assert_eq!(vec, [1, 2, 3, 4]);
- /// ```
+ #[allow(missing_docs)]
#[inline]
#[unstable(feature = "vec_push_all",
reason = "likely to be replaced by a more optimized extend",
.map(|(_, x)| x)
}
- /// Returns the element that gives the maximum value from the
- /// specified function.
- ///
- /// Returns the rightmost element if the comparison determines two elements
- /// to be equally maximum.
- ///
- /// # Examples
- ///
- /// ```
- /// #![feature(iter_cmp)]
- /// #![allow(deprecated)]
- ///
- /// let a = [-3_i32, 0, 1, 5, -10];
- /// assert_eq!(*a.iter().max_by(|x| x.abs()).unwrap(), -10);
- /// ```
+ #[allow(missing_docs)]
#[inline]
#[unstable(feature = "iter_cmp",
reason = "may want to produce an Ordering directly; see #15311",
.map(|(_, x)| x)
}
- /// Returns the element that gives the minimum value from the
- /// specified function.
- ///
- /// Returns the latest element if the comparison determines two elements
- /// to be equally minimum.
- ///
- /// # Examples
- ///
- /// ```
- /// #![feature(iter_cmp)]
- /// #![allow(deprecated)]
- ///
- /// let a = [-3_i32, 0, 1, 5, -10];
- /// assert_eq!(*a.iter().min_by(|x| x.abs()).unwrap(), 0);
- /// ```
#[inline]
+ #[allow(missing_docs)]
#[unstable(feature = "iter_cmp",
reason = "may want to produce an Ordering directly; see #15311",
issue = "27724")]
You cannot directly use a dereference operation whilst initializing a constant
or a static. To fix this error, restructure your code to avoid this dereference,
-perharps moving it inline:
+perhaps moving it inline:
```
use std::ops::Deref;
```
"##,
+E0452: r##"
+An invalid lint attribute has been given. Erroneous code example:
+
+```
+#![allow(foo = "")] // error: malformed lint attribute
+```
+
+Lint attributes only accept a list of identifiers (where each identifier is a
+lint name). Ensure the attribute is of this form:
+
+```
+#![allow(foo)] // ok!
+// or:
+#![allow(foo, foo2)] // ok!
+```
+"##,
+
E0492: r##"
A borrow of a constant containing interior mutability was attempted. Erroneous
code example:
E0314, // closure outlives stack frame
E0315, // cannot invoke closure outside of its lifetime
E0316, // nested quantification of lifetimes
- E0452, // malformed lint attribute
E0453, // overruled by outer forbid
E0471, // constant evaluation error: ..
E0472, // asm! is unsupported on this target
#[stable(feature = "rust1", since = "1.0.0")]
Other,
- /// An error returned when an operation could not be completed because an
- /// "end of file" was reached prematurely.
- ///
- /// This typically means that an operation could only succeed if it read a
- /// particular number of bytes but only a smaller number of bytes could be
- /// read.
+ #[allow(missing_docs)]
#[unstable(feature = "read_exact_old", reason = "recently added",
issue = "0")]
#[rustc_deprecated(since = "1.6.0", reason = "renamed to UnexpectedEof")]
/// will continue.
///
/// If this function encounters an "end of file" before completely filling
- /// the buffer, it returns an error of the kind `ErrorKind::UnexpectedEOF`.
+ /// the buffer, it returns an error of the kind `ErrorKind::UnexpectedEof`.
/// The contents of `buf` are unspecified in this case.
///
/// If any other read error is encountered then this function immediately
--- /dev/null
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// error-pattern:thread '<main>' panicked at 'shift operation overflowed'
+// compile-flags: -C debug-assertions
+
+#![warn(exceeding_bitshifts)]
+
+fn main() {
+ let _n = 1i64 >> [64][0];
+}
--- /dev/null
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// error-pattern:thread '<main>' panicked at 'shift operation overflowed'
+// compile-flags: -C debug-assertions
+
+#![warn(exceeding_bitshifts)]
+#![feature(const_indexing)]
+
+fn main() {
+ let _n = 1i64 >> [64][0];
+}