diff --git a/src/doc/book/borrow-and-asref.md b/src/doc/book/borrow-and-asref.md index 1cfeb2620bd08..c30b2e68665f1 100644 --- a/src/doc/book/borrow-and-asref.md +++ b/src/doc/book/borrow-and-asref.md @@ -8,7 +8,7 @@ different. Here’s a quick refresher on what these two traits mean. # Borrow -The `Borrow` trait is used when you’re writing a datastructure, and you want to +The `Borrow` trait is used when you’re writing a data structure, and you want to use either an owned or borrowed type as synonymous for some purpose. For example, [`HashMap`][hashmap] has a [`get` method][get] which uses `Borrow`: @@ -86,7 +86,7 @@ We can see how they’re kind of the same: they both deal with owned and borrowe versions of some type. However, they’re a bit different. Choose `Borrow` when you want to abstract over different kinds of borrowing, or -when you’re building a datastructure that treats owned and borrowed values in +when you’re building a data structure that treats owned and borrowed values in equivalent ways, such as hashing and comparison. Choose `AsRef` when you want to convert something to a reference directly, and diff --git a/src/doc/book/closures.md b/src/doc/book/closures.md index d332cac7d8d16..3ed85c1a90b69 100644 --- a/src/doc/book/closures.md +++ b/src/doc/book/closures.md @@ -340,7 +340,7 @@ fn call_with_ref<'a, F>(some_closure:F) -> i32 where F: Fn(&'a i32) -> i32 { ``` -However this presents a problem with in our case. When you specify the explicit +However this presents a problem in our case. When you specify the explicit lifetime on a function it binds that lifetime to the *entire* scope of the function instead of just the invocation scope of our closure. This means that the borrow checker will see a mutable reference in the same lifetime as our immutable reference and fail diff --git a/src/libcore/iter/range.rs b/src/libcore/iter/range.rs index 079dfe2a81f80..f8b3c84be5aa7 100644 --- a/src/libcore/iter/range.rs +++ b/src/libcore/iter/range.rs @@ -267,14 +267,11 @@ impl ops::RangeFrom { /// # Examples /// /// ``` - /// # #![feature(step_by)] + /// #![feature(step_by)] /// - /// for i in (0u8..).step_by(2).take(10) { - /// println!("{}", i); - /// } + /// let result: Vec<_> = (0..).step_by(2).take(5).collect(); + /// assert_eq!(result, vec![0, 2, 4, 6, 8]); /// ``` - /// - /// This prints the first ten even natural integers (0 to 18). #[unstable(feature = "step_by", reason = "recent addition", issue = "27741")] pub fn step_by(self, by: A) -> StepBy { @@ -319,20 +316,8 @@ impl ops::RangeInclusive { /// ``` /// #![feature(step_by, inclusive_range_syntax)] /// - /// for i in (0...10).step_by(2) { - /// println!("{}", i); - /// } - /// ``` - /// - /// This prints: - /// - /// ```text - /// 0 - /// 2 - /// 4 - /// 6 - /// 8 - /// 10 + /// let result: Vec<_> = (0...10).step_by(2).collect(); + /// assert_eq!(result, vec![0, 2, 4, 6, 8, 10]); /// ``` #[unstable(feature = "step_by", reason = "recent addition", issue = "27741")] diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index 4ac1b8394f450..2ad7864d71d65 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -67,8 +67,7 @@ //! } //! ``` //! -//! See the documentation for each trait for a minimum implementation that -//! prints something to the screen. +//! See the documentation for each trait for an example implementation. #![stable(feature = "rust1", since = "1.0.0")] @@ -107,6 +106,13 @@ pub trait Drop { /// /// After this function is over, the memory of `self` will be deallocated. /// + /// This function cannot be called explicitly. This is compiler error + /// [0040]. However, the [`std::mem::drop`] function in the prelude can be + /// used to call the argument's `Drop` implementation. + /// + /// [0040]: https://doc.rust-lang.org/error-index.html#E0040 + /// [`std::mem::drop`]: https://doc.rust-lang.org/std/mem/fn.drop.html + /// /// # Panics /// /// Given that a `panic!` will call `drop()` as it unwinds, any `panic!` in @@ -171,27 +177,46 @@ macro_rules! forward_ref_binop { /// /// # Examples /// -/// A trivial implementation of `Add`. When `Foo + Foo` happens, it ends up -/// calling `add`, and therefore, `main` prints `Adding!`. +/// This example creates a `Point` struct that implements the `Add` trait, and +/// then demonstrates adding two `Point`s. /// /// ``` /// use std::ops::Add; /// -/// struct Foo; +/// #[derive(Debug)] +/// struct Point { +/// x: i32, +/// y: i32, +/// } /// -/// impl Add for Foo { -/// type Output = Foo; +/// impl Add for Point { +/// type Output = Point; /// -/// fn add(self, _rhs: Foo) -> Foo { -/// println!("Adding!"); -/// self +/// fn add(self, other: Point) -> Point { +/// Point { +/// x: self.x + other.x, +/// y: self.y + other.y, +/// } +/// } +/// } +/// +/// impl PartialEq for Point { +/// fn eq(&self, other: &Self) -> bool { +/// self.x == other.x && self.y == other.y /// } /// } /// /// fn main() { -/// Foo + Foo; +/// assert_eq!(Point { x: 1, y: 0 } + Point { x: 2, y: 3 }, +/// Point { x: 3, y: 3 }); /// } /// ``` +/// +/// Note that `RHS = Self` by default, but this is not mandatory. For example, +/// [std::time::SystemTime] implements `Add`, which permits +/// operations of the form `SystemTime = SystemTime + Duration`. +/// +/// [std::time::SystemTime]: ../../time/struct.SystemTime.html #[lang = "add"] #[stable(feature = "rust1", since = "1.0.0")] pub trait Add { @@ -246,6 +271,12 @@ add_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 } /// Foo - Foo; /// } /// ``` +/// +/// Note that `RHS = Self` by default, but this is not mandatory. For example, +/// [std::time::SystemTime] implements `Sub`, which permits +/// operations of the form `SystemTime = SystemTime - Duration`. +/// +/// [std::time::SystemTime]: ../../time/struct.SystemTime.html #[lang = "sub"] #[stable(feature = "rust1", since = "1.0.0")] pub trait Sub { @@ -899,25 +930,36 @@ shr_impl_all! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize } /// /// # Examples /// -/// A trivial implementation of `AddAssign`. When `Foo += Foo` happens, it ends up -/// calling `add_assign`, and therefore, `main` prints `Adding!`. +/// This example creates a `Point` struct that implements the `AddAssign` +/// trait, and then demonstrates add-assigning to a mutable `Point`. /// /// ``` /// use std::ops::AddAssign; /// -/// struct Foo; +/// #[derive(Debug)] +/// struct Point { +/// x: i32, +/// y: i32, +/// } /// -/// impl AddAssign for Foo { -/// fn add_assign(&mut self, _rhs: Foo) { -/// println!("Adding!"); +/// impl AddAssign for Point { +/// fn add_assign(&mut self, other: Point) { +/// *self = Point { +/// x: self.x + other.x, +/// y: self.y + other.y, +/// }; /// } /// } /// -/// # #[allow(unused_assignments)] -/// fn main() { -/// let mut foo = Foo; -/// foo += Foo; +/// impl PartialEq for Point { +/// fn eq(&self, other: &Self) -> bool { +/// self.x == other.x && self.y == other.y +/// } /// } +/// +/// let mut point = Point { x: 1, y: 0 }; +/// point += Point { x: 2, y: 3 }; +/// assert_eq!(point, Point { x: 3, y: 3 }); /// ``` #[lang = "add_assign"] #[stable(feature = "op_assign_traits", since = "1.8.0")] diff --git a/src/librustc/middle/effect.rs b/src/librustc/middle/effect.rs index 3ca6cf0399797..250ad80f5af6c 100644 --- a/src/librustc/middle/effect.rs +++ b/src/librustc/middle/effect.rs @@ -66,7 +66,7 @@ impl<'a, 'tcx> EffectCheckVisitor<'a, 'tcx> { struct_span_err!( self.tcx.sess, span, E0133, "{} requires unsafe function or block", description) - .span_label(span, &format!("unsafe call requires unsafe function or block")) + .span_label(span, &description) .emit(); } UnsafeBlock(block_id) => { diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 1de67922b1b3a..bcdc0d2ea3f9d 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -493,9 +493,13 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { if let ty::TyRawPtr(_) = base_ty.sty { this.add(Qualif::NOT_CONST); if this.mode != Mode::Fn { - span_err!(this.tcx.sess, this.span, E0396, - "raw pointers cannot be dereferenced in {}s", - this.mode); + struct_span_err!(this.tcx.sess, + this.span, E0396, + "raw pointers cannot be dereferenced in {}s", + this.mode) + .span_label(this.span, + &format!("dereference of raw pointer in constant")) + .emit(); } } } @@ -681,9 +685,14 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { self.add(Qualif::NOT_CONST); if self.mode != Mode::Fn { - span_err!(self.tcx.sess, self.span, E0395, - "raw pointers cannot be compared in {}s", - self.mode); + struct_span_err!( + self.tcx.sess, self.span, E0395, + "raw pointers cannot be compared in {}s", + self.mode) + .span_label( + self.span, + &format!("comparing raw pointers in static")) + .emit(); } } } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index ff0b86aa59540..6eeb2c4099805 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -903,9 +903,12 @@ fn check_on_unimplemented<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, } } } else { - span_err!(ccx.tcx.sess, attr.span, E0232, - "this attribute must have a value, \ - eg `#[rustc_on_unimplemented = \"foo\"]`") + struct_span_err!( + ccx.tcx.sess, attr.span, E0232, + "this attribute must have a value") + .span_label(attr.span, &format!("attribute requires a value")) + .note(&format!("eg `#[rustc_on_unimplemented = \"foo\"]`")) + .emit(); } } } @@ -1245,8 +1248,11 @@ pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, let hint = *ccx.tcx.lookup_repr_hints(def_id).get(0).unwrap_or(&attr::ReprAny); if hint != attr::ReprAny && vs.is_empty() { - span_err!(ccx.tcx.sess, sp, E0084, - "unsupported representation for zero-variant enum"); + struct_span_err!( + ccx.tcx.sess, sp, E0084, + "unsupported representation for zero-variant enum") + .span_label(sp, &format!("unsupported enum representation")) + .emit(); } let repr_type_ty = ccx.tcx.enum_repr_type(Some(&hint)).to_ty(ccx.tcx); diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs index 0d29e62485abb..3d23a9a2383ff 100644 --- a/src/libstd/ffi/os_str.rs +++ b/src/libstd/ffi/os_str.rs @@ -251,6 +251,14 @@ impl Hash for OsString { impl OsStr { /// Coerces into an `OsStr` slice. + /// + /// # Examples + /// + /// ``` + /// use std::ffi::OsStr; + /// + /// let os_str = OsStr::new("foo"); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn new + ?Sized>(s: &S) -> &OsStr { s.as_ref() @@ -283,6 +291,18 @@ impl OsStr { } /// Checks whether the `OsStr` is empty. + /// + /// # Examples + /// + /// ``` + /// use std::ffi::OsStr; + /// + /// let os_str = OsStr::new(""); + /// assert!(os_str.is_empty()); + /// + /// let os_str = OsStr::new("foo"); + /// assert!(!os_str.is_empty()); + /// ``` #[stable(feature = "osstring_simple_functions", since = "1.9.0")] pub fn is_empty(&self) -> bool { self.inner.inner.is_empty() @@ -296,6 +316,18 @@ impl OsStr { /// other methods like `OsString::with_capacity` to avoid reallocations. /// /// See `OsStr` introduction for more information about encoding. + /// + /// # Examples + /// + /// ``` + /// use std::ffi::OsStr; + /// + /// let os_str = OsStr::new(""); + /// assert_eq!(os_str.len(), 0); + /// + /// let os_str = OsStr::new("foo"); + /// assert_eq!(os_str.len(), 3); + /// ``` #[stable(feature = "osstring_simple_functions", since = "1.9.0")] pub fn len(&self) -> usize { self.inner.inner.len() diff --git a/src/test/compile-fail/E0084.rs b/src/test/compile-fail/E0084.rs index c579101325f5d..c7c5662f1feda 100644 --- a/src/test/compile-fail/E0084.rs +++ b/src/test/compile-fail/E0084.rs @@ -9,7 +9,9 @@ // except according to those terms. #[repr(i32)] -enum Foo {} //~ ERROR E0084 +enum Foo {} +//~^ ERROR E0084 +//~| unsupported enum representation fn main() { } diff --git a/src/test/compile-fail/E0133.rs b/src/test/compile-fail/E0133.rs index b8a4476fc5967..f60d9a5083f6f 100644 --- a/src/test/compile-fail/E0133.rs +++ b/src/test/compile-fail/E0133.rs @@ -13,5 +13,5 @@ unsafe fn f() { return; } fn main() { f(); //~^ ERROR E0133 - //~| NOTE unsafe call requires unsafe function or block + //~| NOTE call to unsafe function } diff --git a/src/test/compile-fail/E0232.rs b/src/test/compile-fail/E0232.rs index efeb869d71fa5..ce4f4638dac59 100644 --- a/src/test/compile-fail/E0232.rs +++ b/src/test/compile-fail/E0232.rs @@ -10,7 +10,10 @@ #![feature(on_unimplemented)] -#[rustc_on_unimplemented] //~ ERROR E0232 +#[rustc_on_unimplemented] +//~^ ERROR E0232 +//~| NOTE attribute requires a value +//~| NOTE eg `#[rustc_on_unimplemented = "foo"]` trait Bar {} fn main() { diff --git a/src/test/compile-fail/E0395.rs b/src/test/compile-fail/E0395.rs index 6ab66313a0472..98f08cd68c22d 100644 --- a/src/test/compile-fail/E0395.rs +++ b/src/test/compile-fail/E0395.rs @@ -12,6 +12,6 @@ static FOO: i32 = 42; static BAR: i32 = 42; static BAZ: bool = { (&FOO as *const i32) == (&BAR as *const i32) }; //~ ERROR E0395 - + //~| NOTE comparing raw pointers in static fn main() { } diff --git a/src/test/compile-fail/E0396.rs b/src/test/compile-fail/E0396.rs index 7f34acdfb9007..47080fb6e9ef7 100644 --- a/src/test/compile-fail/E0396.rs +++ b/src/test/compile-fail/E0396.rs @@ -11,6 +11,7 @@ const REG_ADDR: *const u8 = 0x5f3759df as *const u8; const VALUE: u8 = unsafe { *REG_ADDR }; //~ ERROR E0396 + //~| NOTE dereference of raw pointer in constant fn main() { } diff --git a/src/test/compile-fail/const-deref-ptr.rs b/src/test/compile-fail/const-deref-ptr.rs index fa15f3e87c694..c626801d48c03 100644 --- a/src/test/compile-fail/const-deref-ptr.rs +++ b/src/test/compile-fail/const-deref-ptr.rs @@ -12,5 +12,6 @@ fn main() { static C: u64 = unsafe {*(0xdeadbeef as *const u64)}; //~ ERROR E0396 + //~| NOTE dereference of raw pointer in constant println!("{}", C); } diff --git a/src/test/compile-fail/issue-25826.rs b/src/test/compile-fail/issue-25826.rs index 00e1279d58a0e..468282fa7cca9 100644 --- a/src/test/compile-fail/issue-25826.rs +++ b/src/test/compile-fail/issue-25826.rs @@ -12,5 +12,6 @@ fn id(t: T) -> T { t } fn main() { const A: bool = id:: as *const () < id:: as *const (); //~^ ERROR raw pointers cannot be compared in constants [E0395] + //~^^ NOTE comparing raw pointers in static println!("{}", A); } diff --git a/src/test/compile-fail/issue-28776.rs b/src/test/compile-fail/issue-28776.rs index 52b0eba96cbdf..4a36bc88fa7d9 100644 --- a/src/test/compile-fail/issue-28776.rs +++ b/src/test/compile-fail/issue-28776.rs @@ -13,5 +13,5 @@ use std::ptr; fn main() { (&ptr::write)(1 as *mut _, 42); //~^ ERROR E0133 - //~| NOTE unsafe call requires unsafe function or block + //~| NOTE call to unsafe function } diff --git a/src/test/compile-fail/trait-safety-fn-body.rs b/src/test/compile-fail/trait-safety-fn-body.rs index 0df7ee8cabed2..65732a8ff69e5 100644 --- a/src/test/compile-fail/trait-safety-fn-body.rs +++ b/src/test/compile-fail/trait-safety-fn-body.rs @@ -20,7 +20,7 @@ unsafe impl UnsafeTrait for *mut isize { // Unsafe actions are not made legal by taking place in an unsafe trait: *self += 1; //~^ ERROR E0133 - //~| NOTE unsafe call requires unsafe function or block + //~| NOTE dereference of raw pointer } } diff --git a/src/test/compile-fail/unsafe-const-fn.rs b/src/test/compile-fail/unsafe-const-fn.rs index 174939b09009c..91e16592be472 100644 --- a/src/test/compile-fail/unsafe-const-fn.rs +++ b/src/test/compile-fail/unsafe-const-fn.rs @@ -18,7 +18,7 @@ const unsafe fn dummy(v: u32) -> u32 { const VAL: u32 = dummy(0xFFFF); //~^ ERROR E0133 -//~| NOTE unsafe call requires unsafe function or block +//~| NOTE call to unsafe function fn main() { assert_eq!(VAL, 0xFFFF0000);