]>
Commit | Line | Data |
---|---|---|
f035d41b | 1 | extern crate rustc_ast; |
e74abb32 | 2 | extern crate rustc_data_structures; |
f035d41b | 3 | extern crate rustc_span; |
e74abb32 | 4 | extern crate rustc_target; |
e74abb32 XL |
5 | |
6 | use std::mem; | |
7 | ||
f035d41b XL |
8 | use rustc_ast::ast::{ |
9 | AngleBracketedArg, AngleBracketedArgs, AnonConst, Arm, AssocItemKind, AssocTyConstraint, | |
10 | AssocTyConstraintKind, Async, AttrId, AttrItem, AttrKind, AttrStyle, Attribute, BareFnTy, | |
11 | BinOpKind, BindingMode, Block, BlockCheckMode, BorrowKind, CaptureBy, Const, Crate, CrateSugar, | |
12 | Defaultness, EnumDef, Expr, ExprKind, Extern, Field, FieldPat, FloatTy, FnDecl, FnHeader, | |
13 | FnRetTy, FnSig, ForeignItemKind, ForeignMod, GenericArg, GenericArgs, GenericBound, | |
14 | GenericParam, GenericParamKind, Generics, GlobalAsm, ImplPolarity, InlineAsm, InlineAsmOperand, | |
15 | InlineAsmOptions, InlineAsmRegOrRegClass, InlineAsmTemplatePiece, IntTy, IsAuto, Item, | |
16 | ItemKind, Label, Lifetime, Lit, LitFloatType, LitIntType, LitKind, LlvmAsmDialect, | |
1b1a35ee XL |
17 | LlvmInlineAsm, LlvmInlineAsmOutput, Local, MacArgs, MacCall, MacCallStmt, MacDelimiter, |
18 | MacStmtStyle, MacroDef, Mod, Movability, MutTy, Mutability, NodeId, Param, ParenthesizedArgs, | |
19 | Pat, PatKind, Path, PathSegment, PolyTraitRef, QSelf, RangeEnd, RangeLimits, RangeSyntax, Stmt, | |
20 | StmtKind, StrLit, StrStyle, StructField, TraitBoundModifier, TraitObjectSyntax, TraitRef, Ty, | |
21 | TyKind, UintTy, UnOp, Unsafe, UnsafeSource, UseTree, UseTreeKind, Variant, VariantData, | |
22 | VisibilityKind, WhereBoundPredicate, WhereClause, WhereEqPredicate, WherePredicate, | |
23 | WhereRegionPredicate, | |
e74abb32 | 24 | }; |
f035d41b | 25 | use rustc_ast::ptr::P; |
1b1a35ee | 26 | use rustc_ast::token::{self, CommentKind, DelimToken, Token, TokenKind}; |
f035d41b | 27 | use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree}; |
f035d41b XL |
28 | use rustc_data_structures::sync::Lrc; |
29 | use rustc_data_structures::thin_vec::ThinVec; | |
30 | use rustc_span::source_map::Spanned; | |
31 | use rustc_span::symbol::Ident; | |
1b1a35ee | 32 | use rustc_span::{Span, Symbol, SyntaxContext}; |
e74abb32 XL |
33 | |
34 | pub trait SpanlessEq { | |
35 | fn eq(&self, other: &Self) -> bool; | |
36 | } | |
37 | ||
38 | impl<T: SpanlessEq> SpanlessEq for P<T> { | |
39 | fn eq(&self, other: &Self) -> bool { | |
40 | SpanlessEq::eq(&**self, &**other) | |
41 | } | |
42 | } | |
43 | ||
44 | impl<T: SpanlessEq> SpanlessEq for Lrc<T> { | |
45 | fn eq(&self, other: &Self) -> bool { | |
46 | SpanlessEq::eq(&**self, &**other) | |
47 | } | |
48 | } | |
49 | ||
50 | impl<T: SpanlessEq> SpanlessEq for Option<T> { | |
51 | fn eq(&self, other: &Self) -> bool { | |
52 | match (self, other) { | |
53 | (None, None) => true, | |
54 | (Some(this), Some(other)) => SpanlessEq::eq(this, other), | |
55 | _ => false, | |
56 | } | |
57 | } | |
58 | } | |
59 | ||
60 | impl<T: SpanlessEq> SpanlessEq for Vec<T> { | |
61 | fn eq(&self, other: &Self) -> bool { | |
62 | self.len() == other.len() && self.iter().zip(other).all(|(a, b)| SpanlessEq::eq(a, b)) | |
63 | } | |
64 | } | |
65 | ||
66 | impl<T: SpanlessEq> SpanlessEq for ThinVec<T> { | |
67 | fn eq(&self, other: &Self) -> bool { | |
68 | self.len() == other.len() | |
69 | && self | |
70 | .iter() | |
71 | .zip(other.iter()) | |
72 | .all(|(a, b)| SpanlessEq::eq(a, b)) | |
73 | } | |
74 | } | |
75 | ||
76 | impl<T: SpanlessEq> SpanlessEq for Spanned<T> { | |
77 | fn eq(&self, other: &Self) -> bool { | |
78 | SpanlessEq::eq(&self.node, &other.node) | |
79 | } | |
80 | } | |
81 | ||
82 | impl<A: SpanlessEq, B: SpanlessEq> SpanlessEq for (A, B) { | |
83 | fn eq(&self, other: &Self) -> bool { | |
84 | SpanlessEq::eq(&self.0, &other.0) && SpanlessEq::eq(&self.1, &other.1) | |
85 | } | |
86 | } | |
87 | ||
e74abb32 XL |
88 | macro_rules! spanless_eq_true { |
89 | ($name:ident) => { | |
90 | impl SpanlessEq for $name { | |
91 | fn eq(&self, _other: &Self) -> bool { | |
92 | true | |
93 | } | |
94 | } | |
95 | }; | |
96 | } | |
97 | ||
98 | spanless_eq_true!(Span); | |
99 | spanless_eq_true!(DelimSpan); | |
100 | spanless_eq_true!(AttrId); | |
101 | spanless_eq_true!(NodeId); | |
102 | spanless_eq_true!(SyntaxContext); | |
103 | ||
104 | macro_rules! spanless_eq_partial_eq { | |
105 | ($name:ident) => { | |
106 | impl SpanlessEq for $name { | |
107 | fn eq(&self, other: &Self) -> bool { | |
108 | PartialEq::eq(self, other) | |
109 | } | |
110 | } | |
111 | }; | |
112 | } | |
113 | ||
114 | spanless_eq_partial_eq!(bool); | |
115 | spanless_eq_partial_eq!(u8); | |
116 | spanless_eq_partial_eq!(u16); | |
117 | spanless_eq_partial_eq!(u128); | |
118 | spanless_eq_partial_eq!(usize); | |
119 | spanless_eq_partial_eq!(char); | |
f035d41b | 120 | spanless_eq_partial_eq!(String); |
e74abb32 | 121 | spanless_eq_partial_eq!(Symbol); |
1b1a35ee | 122 | spanless_eq_partial_eq!(CommentKind); |
e74abb32 | 123 | spanless_eq_partial_eq!(DelimToken); |
f035d41b | 124 | spanless_eq_partial_eq!(InlineAsmOptions); |
e74abb32 XL |
125 | |
126 | macro_rules! spanless_eq_struct { | |
127 | { | |
f035d41b | 128 | $name:ident $(<$param:ident>)?; |
e74abb32 XL |
129 | $([$field:ident $other:ident])* |
130 | $(![$ignore:ident])* | |
131 | } => { | |
f035d41b | 132 | impl $(<$param: SpanlessEq>)* SpanlessEq for $name $(<$param>)* { |
e74abb32 XL |
133 | fn eq(&self, other: &Self) -> bool { |
134 | let $name { $($field,)* $($ignore: _,)* } = self; | |
135 | let $name { $($field: $other,)* $($ignore: _,)* } = other; | |
136 | $(SpanlessEq::eq($field, $other))&&* | |
137 | } | |
138 | } | |
139 | }; | |
140 | ||
141 | { | |
f035d41b | 142 | $name:ident $(<$param:ident>)?; |
e74abb32 XL |
143 | $([$field:ident $other:ident])* |
144 | $next:ident | |
145 | $($rest:ident)* | |
146 | $(!$ignore:ident)* | |
147 | } => { | |
148 | spanless_eq_struct! { | |
f035d41b | 149 | $name $(<$param>)*; |
e74abb32 XL |
150 | $([$field $other])* |
151 | [$next other] | |
152 | $($rest)* | |
153 | $(!$ignore)* | |
154 | } | |
155 | }; | |
156 | ||
157 | { | |
f035d41b | 158 | $name:ident $(<$param:ident>)?; |
e74abb32 XL |
159 | $([$field:ident $other:ident])* |
160 | $(![$ignore:ident])* | |
161 | !$next:ident | |
162 | $(!$rest:ident)* | |
163 | } => { | |
164 | spanless_eq_struct! { | |
f035d41b | 165 | $name $(<$param>)*; |
e74abb32 XL |
166 | $([$field $other])* |
167 | $(![$ignore])* | |
168 | ![$next] | |
169 | $(!$rest)* | |
170 | } | |
171 | }; | |
172 | } | |
173 | ||
174 | macro_rules! spanless_eq_enum { | |
175 | { | |
176 | $name:ident; | |
177 | $([$variant:ident $([$field:tt $this:ident $other:ident])*])* | |
178 | } => { | |
179 | impl SpanlessEq for $name { | |
180 | fn eq(&self, other: &Self) -> bool { | |
181 | match self { | |
182 | $( | |
183 | $name::$variant { .. } => {} | |
184 | )* | |
185 | } | |
186 | #[allow(unreachable_patterns)] | |
187 | match (self, other) { | |
188 | $( | |
189 | ( | |
190 | $name::$variant { $($field: $this),* }, | |
191 | $name::$variant { $($field: $other),* }, | |
192 | ) => { | |
193 | true $(&& SpanlessEq::eq($this, $other))* | |
194 | } | |
195 | )* | |
196 | _ => false, | |
197 | } | |
198 | } | |
199 | } | |
200 | }; | |
201 | ||
202 | { | |
203 | $name:ident; | |
204 | $([$variant:ident $($fields:tt)*])* | |
205 | $next:ident [$($named:tt)*] ( $i:tt $($field:tt)* ) | |
206 | $($rest:tt)* | |
207 | } => { | |
208 | spanless_eq_enum! { | |
209 | $name; | |
210 | $([$variant $($fields)*])* | |
211 | $next [$($named)* [$i this other]] ( $($field)* ) | |
212 | $($rest)* | |
213 | } | |
214 | }; | |
215 | ||
216 | { | |
217 | $name:ident; | |
218 | $([$variant:ident $($fields:tt)*])* | |
219 | $next:ident [$($named:tt)*] () | |
220 | $($rest:tt)* | |
221 | } => { | |
222 | spanless_eq_enum! { | |
223 | $name; | |
224 | $([$variant $($fields)*])* | |
225 | [$next $($named)*] | |
226 | $($rest)* | |
227 | } | |
228 | }; | |
229 | ||
230 | { | |
231 | $name:ident; | |
232 | $([$variant:ident $($fields:tt)*])* | |
233 | $next:ident ( $($field:tt)* ) | |
234 | $($rest:tt)* | |
235 | } => { | |
236 | spanless_eq_enum! { | |
237 | $name; | |
238 | $([$variant $($fields)*])* | |
239 | $next [] ( $($field)* ) | |
240 | $($rest)* | |
241 | } | |
242 | }; | |
243 | ||
244 | { | |
245 | $name:ident; | |
246 | $([$variant:ident $($fields:tt)*])* | |
247 | $next:ident | |
248 | $($rest:tt)* | |
249 | } => { | |
250 | spanless_eq_enum! { | |
251 | $name; | |
252 | $([$variant $($fields)*])* | |
253 | [$next] | |
254 | $($rest)* | |
255 | } | |
256 | }; | |
257 | } | |
258 | ||
f035d41b | 259 | spanless_eq_struct!(AngleBracketedArgs; span args); |
e74abb32 | 260 | spanless_eq_struct!(AnonConst; id value); |
60c5eb7d | 261 | spanless_eq_struct!(Arm; attrs pat guard body span id is_placeholder); |
e74abb32 | 262 | spanless_eq_struct!(AssocTyConstraint; id ident kind span); |
f035d41b | 263 | spanless_eq_struct!(AttrItem; path args); |
60c5eb7d XL |
264 | spanless_eq_struct!(Attribute; kind id style span); |
265 | spanless_eq_struct!(BareFnTy; unsafety ext generic_params decl); | |
e74abb32 | 266 | spanless_eq_struct!(Block; stmts id rules span); |
f035d41b | 267 | spanless_eq_struct!(Crate; module attrs span proc_macros); |
e74abb32 | 268 | spanless_eq_struct!(EnumDef; variants); |
f035d41b | 269 | spanless_eq_struct!(Expr; id kind span attrs !tokens); |
60c5eb7d XL |
270 | spanless_eq_struct!(Field; attrs id span ident expr is_shorthand is_placeholder); |
271 | spanless_eq_struct!(FieldPat; ident pat is_shorthand attrs id span is_placeholder); | |
272 | spanless_eq_struct!(FnDecl; inputs output); | |
273 | spanless_eq_struct!(FnHeader; constness asyncness unsafety ext); | |
1b1a35ee | 274 | spanless_eq_struct!(FnSig; header decl span); |
e74abb32 | 275 | spanless_eq_struct!(ForeignMod; abi items); |
60c5eb7d | 276 | spanless_eq_struct!(GenericParam; id ident attrs bounds is_placeholder kind); |
e74abb32 XL |
277 | spanless_eq_struct!(Generics; params where_clause span); |
278 | spanless_eq_struct!(GlobalAsm; asm); | |
f035d41b XL |
279 | spanless_eq_struct!(InlineAsm; template operands options line_spans); |
280 | spanless_eq_struct!(Item<K>; attrs id span vis ident kind !tokens); | |
e74abb32 XL |
281 | spanless_eq_struct!(Label; ident); |
282 | spanless_eq_struct!(Lifetime; id ident); | |
60c5eb7d | 283 | spanless_eq_struct!(Lit; token kind span); |
f035d41b XL |
284 | spanless_eq_struct!(LlvmInlineAsm; asm asm_str_style outputs inputs clobbers volatile alignstack dialect); |
285 | spanless_eq_struct!(LlvmInlineAsmOutput; constraint expr is_rw is_indirect); | |
e74abb32 | 286 | spanless_eq_struct!(Local; pat ty init id span attrs); |
f035d41b | 287 | spanless_eq_struct!(MacCall; path args prior_type_ascription); |
1b1a35ee | 288 | spanless_eq_struct!(MacCallStmt; mac style attrs); |
f035d41b | 289 | spanless_eq_struct!(MacroDef; body macro_rules); |
e74abb32 XL |
290 | spanless_eq_struct!(Mod; inner items inline); |
291 | spanless_eq_struct!(MutTy; ty mutbl); | |
60c5eb7d | 292 | spanless_eq_struct!(Param; attrs ty pat id span is_placeholder); |
e74abb32 | 293 | spanless_eq_struct!(ParenthesizedArgs; span inputs output); |
1b1a35ee | 294 | spanless_eq_struct!(Pat; id kind span tokens); |
e74abb32 XL |
295 | spanless_eq_struct!(Path; span segments); |
296 | spanless_eq_struct!(PathSegment; ident id args); | |
297 | spanless_eq_struct!(PolyTraitRef; bound_generic_params trait_ref span); | |
298 | spanless_eq_struct!(QSelf; ty path_span position); | |
60c5eb7d XL |
299 | spanless_eq_struct!(Stmt; id kind span); |
300 | spanless_eq_struct!(StrLit; style symbol suffix span symbol_unescaped); | |
301 | spanless_eq_struct!(StructField; attrs id span vis ident ty is_placeholder); | |
e74abb32 | 302 | spanless_eq_struct!(Token; kind span); |
e74abb32 | 303 | spanless_eq_struct!(TraitRef; path ref_id); |
60c5eb7d | 304 | spanless_eq_struct!(Ty; id kind span); |
e74abb32 | 305 | spanless_eq_struct!(UseTree; prefix kind span); |
60c5eb7d | 306 | spanless_eq_struct!(Variant; attrs id span vis ident data disr_expr is_placeholder); |
e74abb32 | 307 | spanless_eq_struct!(WhereBoundPredicate; span bound_generic_params bounded_ty bounds); |
f035d41b | 308 | spanless_eq_struct!(WhereClause; has_where_token predicates span); |
e74abb32 XL |
309 | spanless_eq_struct!(WhereEqPredicate; id span lhs_ty rhs_ty); |
310 | spanless_eq_struct!(WhereRegionPredicate; span lifetime bounds); | |
f035d41b XL |
311 | spanless_eq_enum!(AngleBracketedArg; Arg(0) Constraint(0)); |
312 | spanless_eq_enum!(AssocItemKind; Const(0 1 2) Fn(0 1 2 3) TyAlias(0 1 2 3) MacCall(0)); | |
e74abb32 | 313 | spanless_eq_enum!(AssocTyConstraintKind; Equality(ty) Bound(bounds)); |
f035d41b | 314 | spanless_eq_enum!(Async; Yes(span closure_id return_impl_trait_id) No); |
1b1a35ee | 315 | spanless_eq_enum!(AttrKind; Normal(0) DocComment(0 1)); |
e74abb32 XL |
316 | spanless_eq_enum!(AttrStyle; Outer Inner); |
317 | spanless_eq_enum!(BinOpKind; Add Sub Mul Div Rem And Or BitXor BitAnd BitOr Shl Shr Eq Lt Le Ne Ge Gt); | |
318 | spanless_eq_enum!(BindingMode; ByRef(0) ByValue(0)); | |
319 | spanless_eq_enum!(BlockCheckMode; Default Unsafe(0)); | |
60c5eb7d | 320 | spanless_eq_enum!(BorrowKind; Ref Raw); |
e74abb32 | 321 | spanless_eq_enum!(CaptureBy; Value Ref); |
f035d41b | 322 | spanless_eq_enum!(Const; Yes(0) No); |
e74abb32 | 323 | spanless_eq_enum!(CrateSugar; PubCrate JustCrate); |
f035d41b | 324 | spanless_eq_enum!(Defaultness; Default(0) Final); |
60c5eb7d | 325 | spanless_eq_enum!(Extern; None Implicit Explicit(0)); |
e74abb32 | 326 | spanless_eq_enum!(FloatTy; F32 F64); |
f035d41b XL |
327 | spanless_eq_enum!(FnRetTy; Default(0) Ty(0)); |
328 | spanless_eq_enum!(ForeignItemKind; Static(0 1 2) Fn(0 1 2 3) TyAlias(0 1 2 3) MacCall(0)); | |
e74abb32 XL |
329 | spanless_eq_enum!(GenericArg; Lifetime(0) Type(0) Const(0)); |
330 | spanless_eq_enum!(GenericArgs; AngleBracketed(0) Parenthesized(0)); | |
331 | spanless_eq_enum!(GenericBound; Trait(0 1) Outlives(0)); | |
3dfed10e | 332 | spanless_eq_enum!(GenericParamKind; Lifetime Type(default) Const(ty kw_span)); |
f035d41b XL |
333 | spanless_eq_enum!(ImplPolarity; Positive Negative(0)); |
334 | spanless_eq_enum!(InlineAsmRegOrRegClass; Reg(0) RegClass(0)); | |
335 | spanless_eq_enum!(InlineAsmTemplatePiece; String(0) Placeholder(operand_idx modifier span)); | |
e74abb32 | 336 | spanless_eq_enum!(IntTy; Isize I8 I16 I32 I64 I128); |
e74abb32 | 337 | spanless_eq_enum!(IsAuto; Yes No); |
60c5eb7d | 338 | spanless_eq_enum!(LitFloatType; Suffixed(0) Unsuffixed); |
e74abb32 | 339 | spanless_eq_enum!(LitIntType; Signed(0) Unsigned(0) Unsuffixed); |
f035d41b XL |
340 | spanless_eq_enum!(LlvmAsmDialect; Att Intel); |
341 | spanless_eq_enum!(MacArgs; Empty Delimited(0 1 2) Eq(0 1)); | |
e74abb32 XL |
342 | spanless_eq_enum!(MacDelimiter; Parenthesis Bracket Brace); |
343 | spanless_eq_enum!(MacStmtStyle; Semicolon Braces NoBraces); | |
344 | spanless_eq_enum!(Movability; Static Movable); | |
f035d41b | 345 | spanless_eq_enum!(Mutability; Mut Not); |
e74abb32 XL |
346 | spanless_eq_enum!(RangeEnd; Included(0) Excluded); |
347 | spanless_eq_enum!(RangeLimits; HalfOpen Closed); | |
f035d41b | 348 | spanless_eq_enum!(StmtKind; Local(0) Item(0) Expr(0) Semi(0) Empty MacCall(0)); |
e74abb32 XL |
349 | spanless_eq_enum!(StrStyle; Cooked Raw(0)); |
350 | spanless_eq_enum!(TokenTree; Token(0) Delimited(0 1 2)); | |
f035d41b | 351 | spanless_eq_enum!(TraitBoundModifier; None Maybe MaybeConst MaybeConstMaybe); |
e74abb32 XL |
352 | spanless_eq_enum!(TraitObjectSyntax; Dyn None); |
353 | spanless_eq_enum!(UintTy; Usize U8 U16 U32 U64 U128); | |
354 | spanless_eq_enum!(UnOp; Deref Not Neg); | |
f035d41b | 355 | spanless_eq_enum!(Unsafe; Yes(0) No); |
e74abb32 | 356 | spanless_eq_enum!(UnsafeSource; CompilerGenerated UserProvided); |
e74abb32 XL |
357 | spanless_eq_enum!(UseTreeKind; Simple(0 1 2) Nested(0) Glob); |
358 | spanless_eq_enum!(VariantData; Struct(0 1) Tuple(0 1) Unit(0)); | |
359 | spanless_eq_enum!(VisibilityKind; Public Crate(0) Restricted(path id) Inherited); | |
360 | spanless_eq_enum!(WherePredicate; BoundPredicate(0) RegionPredicate(0) EqPredicate(0)); | |
f035d41b | 361 | spanless_eq_enum!(ExprKind; Box(0) Array(0) Call(0 1) MethodCall(0 1 2) Tup(0) |
e74abb32 XL |
362 | Binary(0 1 2) Unary(0 1) Lit(0) Cast(0 1) Type(0 1) Let(0 1) If(0 1 2) |
363 | While(0 1 2) ForLoop(0 1 2 3) Loop(0 1) Match(0 1) Closure(0 1 2 3 4 5) | |
f035d41b | 364 | Block(0 1) Async(0 1 2) Await(0) TryBlock(0) Assign(0 1 2) AssignOp(0 1 2) |
60c5eb7d | 365 | Field(0 1) Index(0 1) Range(0 1 2) Path(0 1) AddrOf(0 1 2) Break(0 1) |
f035d41b XL |
366 | Continue(0) Ret(0) InlineAsm(0) LlvmInlineAsm(0) MacCall(0) Struct(0 1 2) |
367 | Repeat(0 1) Paren(0) Try(0) Yield(0) Err); | |
368 | spanless_eq_enum!(InlineAsmOperand; In(reg expr) Out(reg late expr) | |
369 | InOut(reg late expr) SplitInOut(reg late in_expr out_expr) Const(expr) | |
370 | Sym(expr)); | |
371 | spanless_eq_enum!(ItemKind; ExternCrate(0) Use(0) Static(0 1 2) Const(0 1 2) | |
372 | Fn(0 1 2 3) Mod(0) ForeignMod(0) GlobalAsm(0) TyAlias(0 1 2 3) Enum(0 1) | |
373 | Struct(0 1) Union(0 1) Trait(0 1 2 3 4) TraitAlias(0 1) | |
374 | Impl(unsafety polarity defaultness constness generics of_trait self_ty items) | |
375 | MacCall(0) MacroDef(0)); | |
e74abb32 | 376 | spanless_eq_enum!(LitKind; Str(0 1) ByteStr(0) Byte(0) Char(0) Int(0 1) |
60c5eb7d | 377 | Float(0 1) Bool(0) Err(0)); |
e74abb32 XL |
378 | spanless_eq_enum!(PatKind; Wild Ident(0 1 2) Struct(0 1 2) TupleStruct(0 1) |
379 | Or(0) Path(0 1) Tuple(0) Box(0) Ref(0 1) Lit(0) Range(0 1 2) Slice(0) Rest | |
f035d41b | 380 | Paren(0) MacCall(0)); |
e74abb32 XL |
381 | spanless_eq_enum!(TyKind; Slice(0) Array(0 1) Ptr(0) Rptr(0 1) BareFn(0) Never |
382 | Tup(0) Path(0 1) TraitObject(0 1) ImplTrait(0 1) Paren(0) Typeof(0) Infer | |
f035d41b | 383 | ImplicitSelf MacCall(0) Err CVarArgs); |
e74abb32 XL |
384 | |
385 | impl SpanlessEq for Ident { | |
386 | fn eq(&self, other: &Self) -> bool { | |
387 | self.as_str() == other.as_str() | |
388 | } | |
389 | } | |
390 | ||
391 | // Give up on comparing literals inside of macros because there are so many | |
392 | // equivalent representations of the same literal; they are tested elsewhere | |
393 | impl SpanlessEq for token::Lit { | |
394 | fn eq(&self, other: &Self) -> bool { | |
395 | mem::discriminant(self) == mem::discriminant(other) | |
396 | } | |
397 | } | |
398 | ||
399 | impl SpanlessEq for RangeSyntax { | |
400 | fn eq(&self, _other: &Self) -> bool { | |
401 | match self { | |
402 | RangeSyntax::DotDotDot | RangeSyntax::DotDotEq => true, | |
403 | } | |
404 | } | |
405 | } | |
406 | ||
407 | impl SpanlessEq for TokenKind { | |
408 | fn eq(&self, other: &Self) -> bool { | |
409 | match (self, other) { | |
410 | (TokenKind::Literal(this), TokenKind::Literal(other)) => SpanlessEq::eq(this, other), | |
411 | (TokenKind::DotDotEq, _) | (TokenKind::DotDotDot, _) => match other { | |
412 | TokenKind::DotDotEq | TokenKind::DotDotDot => true, | |
413 | _ => false, | |
414 | }, | |
415 | _ => self == other, | |
416 | } | |
417 | } | |
418 | } | |
419 | ||
420 | impl SpanlessEq for TokenStream { | |
421 | fn eq(&self, other: &Self) -> bool { | |
1b1a35ee XL |
422 | let mut this = self.clone().into_trees(); |
423 | let mut other = other.clone().into_trees(); | |
424 | loop { | |
425 | let this = match this.next() { | |
426 | None => return other.next().is_none(), | |
427 | Some(val) => val, | |
428 | }; | |
429 | let other = match other.next() { | |
430 | None => return false, | |
431 | Some(val) => val, | |
432 | }; | |
433 | if !SpanlessEq::eq(&this, &other) { | |
434 | return false; | |
e74abb32 | 435 | } |
e74abb32 | 436 | } |
e74abb32 | 437 | } |
e74abb32 | 438 | } |