3737//! following snippet
3838//!
3939//! ```rust
40- //! # #![allow(dead_code)]
41- //! struct A { x : i32 }
40+ //! struct A {
41+ //! x: i32,
42+ //! }
4243//!
4344//! struct B(i32);
4445//!
7475//! trait PartialEq {
7576//! fn eq(&self, other: &Self) -> bool;
7677//! }
78+ //!
7779//! impl PartialEq for i32 {
7880//! fn eq(&self, other: &i32) -> bool {
7981//! *self == *other
9092//!
9193//! ```text
9294//! Struct(vec![FieldInfo {
93- //! span: <span of x>
94- //! name: Some(<ident of x>),
95- //! self_: <expr for &self.x>,
96- //! other: vec![<expr for &other.x]
97- //! }])
95+ //! span: <span of x>,
96+ //! name: Some(<ident of x>),
97+ //! self_: <expr for &self.x>,
98+ //! other: vec![<expr for &other.x>],
99+ //! }])
98100//! ```
99101//!
100102//! For the `B` impl, called with `B(a)` and `B(b)`,
101103//!
102104//! ```text
103105//! Struct(vec![FieldInfo {
104- //! span: <span of ` i32` >,
105- //! name: None,
106- //! self_: <expr for &a>
107- //! other: vec![<expr for &b>]
108- //! }])
106+ //! span: <span of i32>,
107+ //! name: None,
108+ //! self_: <expr for &a>,
109+ //! other: vec![<expr for &b>],
110+ //! }])
109111//! ```
110112//!
111113//! ## Enums
114116//! == C0(b)`, the SubstructureFields is
115117//!
116118//! ```text
117- //! EnumMatching(0, <ast::Variant for C0>,
118- //! vec![FieldInfo {
119- //! span: <span of i32>
120- //! name: None,
121- //! self_: <expr for &a>,
122- //! other: vec![<expr for &b>]
123- //! }])
119+ //! EnumMatching(
120+ //! 0,
121+ //! <ast::Variant for C0>,
122+ //! vec![FieldInfo {
123+ //! span: <span of i32>,
124+ //! name: None,
125+ //! self_: <expr for &a>,
126+ //! other: vec![<expr for &b>],
127+ //! }],
128+ //! )
124129//! ```
125130//!
126131//! For `C1 {x}` and `C1 {x}`,
127132//!
128133//! ```text
129- //! EnumMatching(1, <ast::Variant for C1>,
130- //! vec![FieldInfo {
131- //! span: <span of x>
132- //! name: Some(<ident of x>),
133- //! self_: <expr for &self.x>,
134- //! other: vec![<expr for &other.x>]
135- //! }])
134+ //! EnumMatching(
135+ //! 1,
136+ //! <ast::Variant for C1>,
137+ //! vec![FieldInfo {
138+ //! span: <span of x>,
139+ //! name: Some(<ident of x>),
140+ //! self_: <expr for &self.x>,
141+ //! other: vec![<expr for &other.x>],
142+ //! }],
143+ //! )
136144//! ```
137145//!
138146//! For the tags,
139147//!
140148//! ```text
141149//! EnumTag(
142- //! &[<ident of self tag>, <ident of other tag>], <expr to combine with>)
150+ //! &[<ident of self tag>, <ident of other tag>],
151+ //! <expr to combine with>,
152+ //! )
143153//! ```
154+ //!
144155//! Note that this setup doesn't allow for the brute-force "match every variant
145156//! against every other variant" approach, which is bad because it produces a
146157//! quadratic amount of code (see #15375).
154165//!
155166//! StaticStruct(<ast::VariantData of B>, Unnamed(vec![<span of x>]))
156167//!
157- //! StaticEnum(<ast::EnumDef of C>,
158- //! vec![(<ident of C0>, <span of C0>, Unnamed(vec![<span of i32>])),
159- //! (<ident of C1>, <span of C1>, Named(vec![(<ident of x>, <span of x>)]))])
168+ //! StaticEnum(
169+ //! <ast::EnumDef of C>,
170+ //! vec![
171+ //! (<ident of C0>, <span of C0>, Unnamed(vec![<span of i32>])),
172+ //! (<ident of C1>, <span of C1>, Named(vec![(<ident of x>, <span of x>)])),
173+ //! ],
174+ //! )
160175//! ```
161176
162177pub use StaticFields :: * ;
@@ -522,7 +537,10 @@ impl<'a> TraitDef<'a> {
522537 /// Given that we are deriving a trait `DerivedTrait` for a type like:
523538 ///
524539 /// ```ignore (only-for-syntax-highlight)
525- /// struct Struct<'a, ..., 'z, A, B: DeclaredTrait, C, ..., Z> where C: WhereTrait {
540+ /// struct Struct<'a, ..., 'z, A, B: DeclaredTrait, C, ..., Z>
541+ /// where
542+ /// C: WhereTrait,
543+ /// {
526544 /// a: A,
527545 /// b: B::Item,
528546 /// b1: <B as DeclaredTrait>::Item,
@@ -535,12 +553,13 @@ impl<'a> TraitDef<'a> {
535553 /// create an impl like:
536554 ///
537555 /// ```ignore (only-for-syntax-highlight)
538- /// impl<'a, ..., 'z, A, B: DeclaredTrait, C, ... Z> where
539- /// C: WhereTrait,
556+ /// impl<'a, ..., 'z, A, B: DeclaredTrait, C, ..., Z>
557+ /// where
558+ /// C: WhereTrait,
540559 /// A: DerivedTrait + B1 + ... + BN,
541560 /// B: DerivedTrait + B1 + ... + BN,
542561 /// C: DerivedTrait + B1 + ... + BN,
543- /// B::Item: DerivedTrait + B1 + ... + BN,
562+ /// B::Item: DerivedTrait + B1 + ... + BN,
544563 /// <C as WhereTrait>::Item: DerivedTrait + B1 + ... + BN,
545564 /// ...
546565 /// {
@@ -676,65 +695,61 @@ impl<'a> TraitDef<'a> {
676695 }
677696 } ) ) ;
678697
679- {
680- // Extra scope required here so ty_params goes out of scope before params is moved
681-
682- let mut ty_params = params
683- . iter ( )
684- . filter ( |param| matches ! ( param. kind, ast:: GenericParamKind :: Type { .. } ) )
685- . peekable ( ) ;
686-
687- if ty_params. peek ( ) . is_some ( ) {
688- let ty_param_names: Vec < Symbol > =
689- ty_params. map ( |ty_param| ty_param. ident . name ) . collect ( ) ;
690-
691- for field_ty in field_tys {
692- let field_ty_params = find_type_parameters ( & field_ty, & ty_param_names, cx) ;
693-
694- for field_ty_param in field_ty_params {
695- // if we have already handled this type, skip it
696- if let ast:: TyKind :: Path ( _, p) = & field_ty_param. ty . kind
697- && let [ sole_segment] = & * p. segments
698- && ty_param_names. contains ( & sole_segment. ident . name )
699- {
700- continue ;
701- }
702- let mut bounds: Vec < _ > = self
703- . additional_bounds
704- . iter ( )
705- . map ( |p| {
706- cx. trait_bound (
707- p. to_path ( cx, self . span , type_ident, generics) ,
708- self . is_const ,
709- )
710- } )
711- . collect ( ) ;
712-
713- // Require the current trait.
714- if !self . skip_path_as_bound {
715- bounds. push ( cx. trait_bound ( trait_path. clone ( ) , self . is_const ) ) ;
716- }
717-
718- // Add a `Copy` bound if required.
719- if is_packed && self . needs_copy_as_bound_if_packed {
720- let p = deriving:: path_std!( marker:: Copy ) ;
721- bounds. push ( cx. trait_bound (
698+ let mut ty_params = params
699+ . iter ( )
700+ . filter ( |param| matches ! ( param. kind, ast:: GenericParamKind :: Type { .. } ) )
701+ . peekable ( ) ;
702+
703+ if ty_params. peek ( ) . is_some ( ) {
704+ let ty_param_names: Vec < Symbol > =
705+ ty_params. map ( |ty_param| ty_param. ident . name ) . collect ( ) ;
706+
707+ for field_ty in field_tys {
708+ let field_ty_params = find_type_parameters ( & field_ty, & ty_param_names, cx) ;
709+
710+ for field_ty_param in field_ty_params {
711+ // if we have already handled this type, skip it
712+ if let ast:: TyKind :: Path ( _, p) = & field_ty_param. ty . kind
713+ && let [ sole_segment] = & * p. segments
714+ && ty_param_names. contains ( & sole_segment. ident . name )
715+ {
716+ continue ;
717+ }
718+ let mut bounds: Vec < _ > = self
719+ . additional_bounds
720+ . iter ( )
721+ . map ( |p| {
722+ cx. trait_bound (
722723 p. to_path ( cx, self . span , type_ident, generics) ,
723724 self . is_const ,
724- ) ) ;
725- }
725+ )
726+ } )
727+ . collect ( ) ;
726728
727- if !bounds. is_empty ( ) {
728- let predicate = ast:: WhereBoundPredicate {
729- span : self . span ,
730- bound_generic_params : field_ty_param. bound_generic_params ,
731- bounded_ty : field_ty_param. ty ,
732- bounds,
733- } ;
729+ // Require the current trait.
730+ if !self . skip_path_as_bound {
731+ bounds. push ( cx. trait_bound ( trait_path. clone ( ) , self . is_const ) ) ;
732+ }
734733
735- let predicate = ast:: WherePredicate :: BoundPredicate ( predicate) ;
736- where_clause. predicates . push ( predicate) ;
737- }
734+ // Add a `Copy` bound if required.
735+ if is_packed && self . needs_copy_as_bound_if_packed {
736+ let p = deriving:: path_std!( marker:: Copy ) ;
737+ bounds. push ( cx. trait_bound (
738+ p. to_path ( cx, self . span , type_ident, generics) ,
739+ self . is_const ,
740+ ) ) ;
741+ }
742+
743+ if !bounds. is_empty ( ) {
744+ let predicate = ast:: WhereBoundPredicate {
745+ span : self . span ,
746+ bound_generic_params : field_ty_param. bound_generic_params ,
747+ bounded_ty : field_ty_param. ty ,
748+ bounds,
749+ } ;
750+
751+ let predicate = ast:: WherePredicate :: BoundPredicate ( predicate) ;
752+ where_clause. predicates . push ( predicate) ;
738753 }
739754 }
740755 }
@@ -1026,6 +1041,7 @@ impl<'a> MethodDef<'a> {
10261041 }
10271042
10281043 /// The normal case uses field access.
1044+ ///
10291045 /// ```
10301046 /// #[derive(PartialEq)]
10311047 /// # struct Dummy;
@@ -1038,10 +1054,12 @@ impl<'a> MethodDef<'a> {
10381054 /// }
10391055 /// }
10401056 /// ```
1057+ ///
10411058 /// But if the struct is `repr(packed)`, we can't use something like
10421059 /// `&self.x` because that might cause an unaligned ref. So for any trait
10431060 /// method that takes a reference, we use a local block to force a copy.
10441061 /// This requires that the field impl `Copy`.
1062+ ///
10451063 /// ```rust,ignore (example)
10461064 /// # struct A { x: u8, y: u8 }
10471065 /// impl PartialEq for A {
@@ -1053,7 +1071,7 @@ impl<'a> MethodDef<'a> {
10531071 /// impl Hash for A {
10541072 /// fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {
10551073 /// ::core::hash::Hash::hash(&{ self.x }, state);
1056- /// ::core::hash::Hash::hash(&{ self.y }, state)
1074+ /// ::core::hash::Hash::hash(&{ self.y }, state);
10571075 /// }
10581076 /// }
10591077 /// ```
@@ -1107,7 +1125,9 @@ impl<'a> MethodDef<'a> {
11071125 /// A2(i32)
11081126 /// }
11091127 /// ```
1128+ ///
11101129 /// is equivalent to:
1130+ ///
11111131 /// ```
11121132 /// #![feature(core_intrinsics)]
11131133 /// enum A {
@@ -1119,15 +1139,15 @@ impl<'a> MethodDef<'a> {
11191139 /// fn eq(&self, other: &A) -> bool {
11201140 /// let __self_tag = ::core::intrinsics::discriminant_value(self);
11211141 /// let __arg1_tag = ::core::intrinsics::discriminant_value(other);
1122- /// __self_tag == __arg1_tag &&
1123- /// match (self, other) {
1124- /// (A::A2(__self_0), A::A2(__arg1_0)) =>
1125- /// *__self_0 == *__arg1_0,
1142+ /// __self_tag == __arg1_tag
1143+ /// && match (self, other) {
1144+ /// (A::A2(__self_0), A::A2(__arg1_0)) => *__self_0 == *__arg1_0,
11261145 /// _ => true,
11271146 /// }
11281147 /// }
11291148 /// }
11301149 /// ```
1150+ ///
11311151 /// Creates a tag check combined with a match for a tuple of all
11321152 /// `selflike_args`, with an arm for each variant with fields, possibly an
11331153 /// arm for each fieldless variant (if `unify_fieldless_variants` is not
@@ -1349,7 +1369,7 @@ impl<'a> MethodDef<'a> {
13491369 // (Variant1, Variant1, ...) => Body1
13501370 // (Variant2, Variant2, ...) => Body2,
13511371 // ...
1352- // _ => ::core::intrinsics::unreachable()
1372+ // _ => ::core::intrinsics::unreachable(),
13531373 // }
13541374 let get_match_expr = |mut selflike_args : ThinVec < P < Expr > > | {
13551375 let match_arg = if selflike_args. len ( ) == 1 {
0 commit comments