|  | 
| 2 | 2 | 
 | 
| 3 | 3 | use rustc_ast as ast; | 
| 4 | 4 | use rustc_ast::ptr::P; | 
| 5 |  | -use rustc_ast::{GenericArg, Impl, ItemKind, MetaItem}; | 
|  | 5 | +use rustc_ast::{GenericArg, MetaItem}; | 
| 6 | 6 | use rustc_expand::base::{Annotatable, ExpandResult, ExtCtxt, MultiItemModifier}; | 
| 7 |  | -use rustc_span::symbol::{sym, Ident, Symbol}; | 
|  | 7 | +use rustc_span::symbol::{sym, Symbol}; | 
| 8 | 8 | use rustc_span::Span; | 
| 9 | 9 | use thin_vec::{thin_vec, ThinVec}; | 
| 10 | 10 | 
 | 
| @@ -116,100 +116,6 @@ fn call_unreachable(cx: &ExtCtxt<'_>, span: Span) -> P<ast::Expr> { | 
| 116 | 116 |     })) | 
| 117 | 117 | } | 
| 118 | 118 | 
 | 
| 119 |  | -// Injects `impl<...> Structural for ItemType<...> { }`. In particular, | 
| 120 |  | -// does *not* add `where T: Structural` for parameters `T` in `...`. | 
| 121 |  | -// (That's the main reason we cannot use TraitDef here.) | 
| 122 |  | -fn inject_impl_of_structural_trait( | 
| 123 |  | -    cx: &mut ExtCtxt<'_>, | 
| 124 |  | -    span: Span, | 
| 125 |  | -    item: &Annotatable, | 
| 126 |  | -    structural_path: generic::ty::Path, | 
| 127 |  | -    push: &mut dyn FnMut(Annotatable), | 
| 128 |  | -) { | 
| 129 |  | -    let Annotatable::Item(item) = item else { | 
| 130 |  | -        unreachable!(); | 
| 131 |  | -    }; | 
| 132 |  | - | 
| 133 |  | -    let generics = match &item.kind { | 
| 134 |  | -        ItemKind::Struct(_, generics) | ItemKind::Enum(_, generics) => generics, | 
| 135 |  | -        // Do not inject `impl Structural for Union`. (`PartialEq` does not | 
| 136 |  | -        // support unions, so we will see error downstream.) | 
| 137 |  | -        ItemKind::Union(..) => return, | 
| 138 |  | -        _ => unreachable!(), | 
| 139 |  | -    }; | 
| 140 |  | - | 
| 141 |  | -    // Create generics param list for where clauses and impl headers | 
| 142 |  | -    let mut generics = generics.clone(); | 
| 143 |  | - | 
| 144 |  | -    let ctxt = span.ctxt(); | 
| 145 |  | - | 
| 146 |  | -    // Create the type of `self`. | 
| 147 |  | -    // | 
| 148 |  | -    // in addition, remove defaults from generic params (impls cannot have them). | 
| 149 |  | -    let self_params: Vec<_> = generics | 
| 150 |  | -        .params | 
| 151 |  | -        .iter_mut() | 
| 152 |  | -        .map(|param| match &mut param.kind { | 
| 153 |  | -            ast::GenericParamKind::Lifetime => ast::GenericArg::Lifetime( | 
| 154 |  | -                cx.lifetime(param.ident.span.with_ctxt(ctxt), param.ident), | 
| 155 |  | -            ), | 
| 156 |  | -            ast::GenericParamKind::Type { default } => { | 
| 157 |  | -                *default = None; | 
| 158 |  | -                ast::GenericArg::Type(cx.ty_ident(param.ident.span.with_ctxt(ctxt), param.ident)) | 
| 159 |  | -            } | 
| 160 |  | -            ast::GenericParamKind::Const { ty: _, kw_span: _, default } => { | 
| 161 |  | -                *default = None; | 
| 162 |  | -                ast::GenericArg::Const( | 
| 163 |  | -                    cx.const_ident(param.ident.span.with_ctxt(ctxt), param.ident), | 
| 164 |  | -                ) | 
| 165 |  | -            } | 
| 166 |  | -        }) | 
| 167 |  | -        .collect(); | 
| 168 |  | - | 
| 169 |  | -    let type_ident = item.ident; | 
| 170 |  | - | 
| 171 |  | -    let trait_ref = cx.trait_ref(structural_path.to_path(cx, span, type_ident, &generics)); | 
| 172 |  | -    let self_type = cx.ty_path(cx.path_all(span, false, vec![type_ident], self_params)); | 
| 173 |  | - | 
| 174 |  | -    // It would be nice to also encode constraint `where Self: Eq` (by adding it | 
| 175 |  | -    // onto `generics` cloned above). Unfortunately, that strategy runs afoul of | 
| 176 |  | -    // rust-lang/rust#48214. So we perform that additional check in the compiler | 
| 177 |  | -    // itself, instead of encoding it here. | 
| 178 |  | - | 
| 179 |  | -    // Keep the lint and stability attributes of the original item, to control | 
| 180 |  | -    // how the generated implementation is linted. | 
| 181 |  | -    let mut attrs = ast::AttrVec::new(); | 
| 182 |  | -    attrs.extend( | 
| 183 |  | -        item.attrs | 
| 184 |  | -            .iter() | 
| 185 |  | -            .filter(|a| { | 
| 186 |  | -                [sym::allow, sym::warn, sym::deny, sym::forbid, sym::stable, sym::unstable] | 
| 187 |  | -                    .contains(&a.name_or_empty()) | 
| 188 |  | -            }) | 
| 189 |  | -            .cloned(), | 
| 190 |  | -    ); | 
| 191 |  | -    // Mark as `automatically_derived` to avoid some silly lints. | 
| 192 |  | -    attrs.push(cx.attr_word(sym::automatically_derived, span)); | 
| 193 |  | - | 
| 194 |  | -    let newitem = cx.item( | 
| 195 |  | -        span, | 
| 196 |  | -        Ident::empty(), | 
| 197 |  | -        attrs, | 
| 198 |  | -        ItemKind::Impl(Box::new(Impl { | 
| 199 |  | -            unsafety: ast::Unsafe::No, | 
| 200 |  | -            polarity: ast::ImplPolarity::Positive, | 
| 201 |  | -            defaultness: ast::Defaultness::Final, | 
| 202 |  | -            constness: ast::Const::No, | 
| 203 |  | -            generics, | 
| 204 |  | -            of_trait: Some(trait_ref), | 
| 205 |  | -            self_ty: self_type, | 
| 206 |  | -            items: ThinVec::new(), | 
| 207 |  | -        })), | 
| 208 |  | -    ); | 
| 209 |  | - | 
| 210 |  | -    push(Annotatable::Item(newitem)); | 
| 211 |  | -} | 
| 212 |  | - | 
| 213 | 119 | fn assert_ty_bounds( | 
| 214 | 120 |     cx: &mut ExtCtxt<'_>, | 
| 215 | 121 |     stmts: &mut ThinVec<ast::Stmt>, | 
|  | 
0 commit comments