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,59 @@ 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- }
698+ let ty_param_names: Vec < Symbol > = params
699+ . iter ( )
700+ . filter ( |param| matches ! ( param. kind, ast:: GenericParamKind :: Type { .. } ) )
701+ . map ( |ty_param| ty_param. ident . name )
702+ . collect ( ) ;
717703
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 (
704+ if !ty_param_names. is_empty ( ) {
705+ for field_ty in field_tys {
706+ let field_ty_params = find_type_parameters ( & field_ty, & ty_param_names, cx) ;
707+
708+ for field_ty_param in field_ty_params {
709+ // if we have already handled this type, skip it
710+ if let ast:: TyKind :: Path ( _, p) = & field_ty_param. ty . kind
711+ && let [ sole_segment] = & * p. segments
712+ && ty_param_names. contains ( & sole_segment. ident . name )
713+ {
714+ continue ;
715+ }
716+ let mut bounds: Vec < _ > = self
717+ . additional_bounds
718+ . iter ( )
719+ . map ( |p| {
720+ cx. trait_bound (
722721 p. to_path ( cx, self . span , type_ident, generics) ,
723722 self . is_const ,
724- ) ) ;
725- }
723+ )
724+ } )
725+ . collect ( ) ;
726726
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- } ;
727+ // Require the current trait.
728+ if !self . skip_path_as_bound {
729+ bounds. push ( cx. trait_bound ( trait_path. clone ( ) , self . is_const ) ) ;
730+ }
734731
735- let predicate = ast:: WherePredicate :: BoundPredicate ( predicate) ;
736- where_clause. predicates . push ( predicate) ;
737- }
732+ // Add a `Copy` bound if required.
733+ if is_packed && self . needs_copy_as_bound_if_packed {
734+ let p = deriving:: path_std!( marker:: Copy ) ;
735+ bounds. push ( cx. trait_bound (
736+ p. to_path ( cx, self . span , type_ident, generics) ,
737+ self . is_const ,
738+ ) ) ;
739+ }
740+
741+ if !bounds. is_empty ( ) {
742+ let predicate = ast:: WhereBoundPredicate {
743+ span : self . span ,
744+ bound_generic_params : field_ty_param. bound_generic_params ,
745+ bounded_ty : field_ty_param. ty ,
746+ bounds,
747+ } ;
748+
749+ let predicate = ast:: WherePredicate :: BoundPredicate ( predicate) ;
750+ where_clause. predicates . push ( predicate) ;
738751 }
739752 }
740753 }
@@ -1026,6 +1039,7 @@ impl<'a> MethodDef<'a> {
10261039 }
10271040
10281041 /// The normal case uses field access.
1042+ ///
10291043 /// ```
10301044 /// #[derive(PartialEq)]
10311045 /// # struct Dummy;
@@ -1038,10 +1052,12 @@ impl<'a> MethodDef<'a> {
10381052 /// }
10391053 /// }
10401054 /// ```
1055+ ///
10411056 /// But if the struct is `repr(packed)`, we can't use something like
10421057 /// `&self.x` because that might cause an unaligned ref. So for any trait
10431058 /// method that takes a reference, we use a local block to force a copy.
10441059 /// This requires that the field impl `Copy`.
1060+ ///
10451061 /// ```rust,ignore (example)
10461062 /// # struct A { x: u8, y: u8 }
10471063 /// impl PartialEq for A {
@@ -1053,7 +1069,7 @@ impl<'a> MethodDef<'a> {
10531069 /// impl Hash for A {
10541070 /// fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {
10551071 /// ::core::hash::Hash::hash(&{ self.x }, state);
1056- /// ::core::hash::Hash::hash(&{ self.y }, state)
1072+ /// ::core::hash::Hash::hash(&{ self.y }, state);
10571073 /// }
10581074 /// }
10591075 /// ```
@@ -1107,7 +1123,9 @@ impl<'a> MethodDef<'a> {
11071123 /// A2(i32)
11081124 /// }
11091125 /// ```
1126+ ///
11101127 /// is equivalent to:
1128+ ///
11111129 /// ```
11121130 /// #![feature(core_intrinsics)]
11131131 /// enum A {
@@ -1119,15 +1137,15 @@ impl<'a> MethodDef<'a> {
11191137 /// fn eq(&self, other: &A) -> bool {
11201138 /// let __self_tag = ::core::intrinsics::discriminant_value(self);
11211139 /// 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,
1140+ /// __self_tag == __arg1_tag
1141+ /// && match (self, other) {
1142+ /// (A::A2(__self_0), A::A2(__arg1_0)) => *__self_0 == *__arg1_0,
11261143 /// _ => true,
11271144 /// }
11281145 /// }
11291146 /// }
11301147 /// ```
1148+ ///
11311149 /// Creates a tag check combined with a match for a tuple of all
11321150 /// `selflike_args`, with an arm for each variant with fields, possibly an
11331151 /// arm for each fieldless variant (if `unify_fieldless_variants` is not
@@ -1349,7 +1367,7 @@ impl<'a> MethodDef<'a> {
13491367 // (Variant1, Variant1, ...) => Body1
13501368 // (Variant2, Variant2, ...) => Body2,
13511369 // ...
1352- // _ => ::core::intrinsics::unreachable()
1370+ // _ => ::core::intrinsics::unreachable(),
13531371 // }
13541372 let get_match_expr = |mut selflike_args : ThinVec < P < Expr > > | {
13551373 let match_arg = if selflike_args. len ( ) == 1 {
0 commit comments