diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index 72e951a7c347c..62aa57bbbbf05 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -1645,7 +1645,7 @@ rem_assign_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 } #[lang = "bitand_assign"] #[stable(feature = "op_assign_traits", since = "1.8.0")] pub trait BitAndAssign { - /// The method for the `&` operator + /// The method for the `&=` operator #[stable(feature = "op_assign_traits", since = "1.8.0")] fn bitand_assign(&mut self, Rhs); } @@ -1879,10 +1879,18 @@ shr_assign_impl_all! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize } /// The `Index` trait is used to specify the functionality of indexing operations /// like `container[index]` when used in an immutable context. /// +/// `container[index]` is actually syntactic sugar for `*container.index(index)`, +/// but only when used as an immutable value. If a mutable value is requested, +/// [`IndexMut`] is used instead. This allows nice things such as +/// `let value = v[index]` if `value` implements [`Copy`]. +/// +/// [`IndexMut`]: ../../std/ops/trait.IndexMut.html +/// [`Copy`]: ../../std/marker/trait.Copy.html +/// /// # Examples /// -/// This example implements `Index` on a read-only `NucleotideCount` container, -/// enabling individual counts to be retrieved with index syntax. +/// The following example implements `Index` on a read-only `NucleotideCount` +/// container, enabling individual counts to be retrieved with index syntax. /// /// ``` /// use std::ops::Index; @@ -1934,37 +1942,78 @@ pub trait Index { } /// The `IndexMut` trait is used to specify the functionality of indexing -/// operations like `container[index]`, when used in a mutable context. +/// operations like `container[index]` when used in a mutable context. +/// +/// `container[index]` is actually syntactic sugar for +/// `*container.index_mut(index)`, but only when used as a mutable value. If +/// an immutable value is requested, the [`Index`] trait is used instead. This +/// allows nice things such as `v[index] = value` if `value` implements [`Copy`]. +/// +/// [`Index`]: ../../std/ops/trait.Index.html +/// [`Copy`]: ../../std/marker/trait.Copy.html /// /// # Examples /// -/// A trivial implementation of `IndexMut` for a type `Foo`. When `&mut Foo[2]` -/// happens, it ends up calling `index_mut`, and therefore, `main` prints -/// `Mutable indexing with 2!`. +/// A very simple implementation of a `Balance` struct that has two sides, where +/// each can be indexed mutably and immutably. /// /// ``` -/// use std::ops::{Index, IndexMut}; +/// use std::ops::{Index,IndexMut}; /// -/// #[derive(Copy, Clone)] -/// struct Foo; +/// #[derive(Debug)] +/// enum Side { +/// Left, +/// Right, +/// } /// -/// impl Index for Foo { -/// type Output = Foo; +/// #[derive(Debug, PartialEq)] +/// enum Weight { +/// Kilogram(f32), +/// Pound(f32), +/// } +/// +/// struct Balance { +/// pub left: Weight, +/// pub right:Weight, +/// } /// -/// fn index(&self, _index: usize) -> &Foo { -/// self +/// impl Index for Balance { +/// type Output = Weight; +/// +/// fn index<'a>(&'a self, index: Side) -> &'a Weight { +/// println!("Accessing {:?}-side of balance immutably", index); +/// match index { +/// Side::Left => &self.left, +/// Side::Right => &self.right, +/// } /// } /// } /// -/// impl IndexMut for Foo { -/// fn index_mut(&mut self, index: usize) -> &mut Foo { -/// println!("Mutable indexing with {}!", index); -/// self +/// impl IndexMut for Balance { +/// fn index_mut<'a>(&'a mut self, index: Side) -> &'a mut Weight { +/// println!("Accessing {:?}-side of balance mutably", index); +/// match index { +/// Side::Left => &mut self.left, +/// Side::Right => &mut self.right, +/// } /// } /// } /// /// fn main() { -/// &mut Foo[2]; +/// let mut balance = Balance { +/// right: Weight::Kilogram(2.5), +/// left: Weight::Pound(1.5), +/// }; +/// +/// // In this case balance[Side::Right] is sugar for +/// // *balance.index(Side::Right), since we are only reading +/// // balance[Side::Right], not writing it. +/// assert_eq!(balance[Side::Right],Weight::Kilogram(2.5)); +/// +/// // However in this case balance[Side::Left] is sugar for +/// // *balance.index_mut(Side::Left), since we are writing +/// // balance[Side::Left]. +/// balance[Side::Left] = Weight::Kilogram(3.0); /// } /// ``` #[lang = "index_mut"] diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 4ffe2fe38566e..77b3e76fc541f 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -859,9 +859,6 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> // expression/block context can't possibly contain exported things. // (Making them no-ops stops us from traversing the whole AST without // having to be super careful about our `walk_...` calls above.) - // FIXME(#29524): Unfortunately this ^^^ is not true, blocks can contain - // exported items (e.g. impls) and actual code in rustc itself breaks - // if we don't traverse blocks in `EmbargoVisitor` fn visit_block(&mut self, _: &hir::Block) {} fn visit_expr(&mut self, _: &hir::Expr) {} } diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index 1fb5db05dd508..5eb269030a004 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -1461,6 +1461,47 @@ match r { ``` "##, +E0532: r##" +Pattern arm did not match expected kind. + +Erroneous code example: + +```compile_fail,E0532 +enum State { + Succeeded, + Failed(String), +} + +fn print_on_failure(state: &State) { + match *state { + // error: expected unit struct/variant or constant, found tuple + // variant `State::Failed` + State::Failed => println!("Failed"), + _ => () + } +} +``` + +To fix this error, ensure the match arm kind is the same as the expression +matched. + +Fixed example: + +``` +enum State { + Succeeded, + Failed(String), +} + +fn print_on_failure(state: &State) { + match *state { + State::Failed(ref msg) => println!("Failed with {}", msg), + _ => () + } +} +``` +"##, + } register_diagnostics! { @@ -1480,6 +1521,5 @@ register_diagnostics! { // E0421, merged into 531 // E0422, merged into 531/532 E0531, // unresolved pattern path kind `name` - E0532, // expected pattern path kind, found another pattern path kind // E0427, merged into 530 } diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs index 687f8c902f259..e6b63be3efc0d 100644 --- a/src/libsyntax_ext/deriving/generic/mod.rs +++ b/src/libsyntax_ext/deriving/generic/mod.rs @@ -1546,7 +1546,7 @@ impl<'a> TraitDef<'a> { cx.span_bug(sp, "a braced struct with unnamed fields in `derive`"); } codemap::Spanned { - span: pat.span, + span: Span { expn_id: self.span.expn_id, ..pat.span }, node: ast::FieldPat { ident: ident.unwrap(), pat: pat, @@ -1577,7 +1577,8 @@ impl<'a> TraitDef<'a> { mutbl: ast::Mutability) -> (P, Vec<(Span, Option, P, &'a [ast::Attribute])>) { let variant_ident = variant.node.name; - let variant_path = cx.path(variant.span, vec![enum_ident, variant_ident]); + let sp = Span { expn_id: self.span.expn_id, ..variant.span }; + let variant_path = cx.path(sp, vec![enum_ident, variant_ident]); self.create_struct_pattern(cx, variant_path, &variant.node.data, prefix, mutbl) } }