1 extern crate rustc_ast
;
2 extern crate rustc_data_structures
;
3 extern crate rustc_span
;
6 AngleBracketedArg
, AngleBracketedArgs
, AnonConst
, Arm
, AssocItemKind
, AssocTyConstraint
,
7 AssocTyConstraintKind
, Async
, AttrId
, AttrItem
, AttrKind
, AttrStyle
, Attribute
, BareFnTy
,
8 BinOpKind
, BindingMode
, Block
, BlockCheckMode
, BorrowKind
, CaptureBy
, Const
, Crate
, CrateSugar
,
9 Defaultness
, EnumDef
, Expr
, ExprField
, ExprKind
, Extern
, FieldDef
, FloatTy
, FnDecl
, FnHeader
,
10 FnKind
, FnRetTy
, FnSig
, ForeignItemKind
, ForeignMod
, GenericArg
, GenericArgs
, GenericBound
,
11 GenericParam
, GenericParamKind
, Generics
, ImplKind
, ImplPolarity
, Inline
, InlineAsm
,
12 InlineAsmOperand
, InlineAsmOptions
, InlineAsmRegOrRegClass
, InlineAsmTemplatePiece
, IntTy
,
13 IsAuto
, Item
, ItemKind
, Label
, Lifetime
, Lit
, LitFloatType
, LitIntType
, LitKind
,
14 LlvmAsmDialect
, LlvmInlineAsm
, LlvmInlineAsmOutput
, Local
, LocalKind
, MacArgs
, MacCall
,
15 MacCallStmt
, MacDelimiter
, MacStmtStyle
, MacroDef
, ModKind
, Movability
, MutTy
, Mutability
,
16 NodeId
, Param
, ParenthesizedArgs
, Pat
, PatField
, PatKind
, Path
, PathSegment
, PolyTraitRef
,
17 QSelf
, RangeEnd
, RangeLimits
, RangeSyntax
, Stmt
, StmtKind
, StrLit
, StrStyle
, StructExpr
,
18 StructRest
, TraitBoundModifier
, TraitKind
, TraitObjectSyntax
, TraitRef
, Ty
, TyAliasKind
,
19 TyKind
, UintTy
, UnOp
, Unsafe
, UnsafeSource
, UseTree
, UseTreeKind
, Variant
, VariantData
,
20 Visibility
, VisibilityKind
, WhereBoundPredicate
, WhereClause
, WhereEqPredicate
, WherePredicate
,
23 use rustc_ast
::ptr
::P
;
24 use rustc_ast
::token
::{self, CommentKind, DelimToken, Nonterminal, Token, TokenKind}
;
25 use rustc_ast
::tokenstream
::{
26 AttrAnnotatedTokenStream
, AttrAnnotatedTokenTree
, AttributesData
, DelimSpan
, LazyTokenStream
,
27 Spacing
, TokenStream
, TokenTree
,
29 use rustc_data_structures
::sync
::Lrc
;
30 use rustc_data_structures
::thin_vec
::ThinVec
;
31 use rustc_span
::source_map
::Spanned
;
32 use rustc_span
::symbol
::{sym, Ident}
;
33 use rustc_span
::{Span, Symbol, SyntaxContext, DUMMY_SP}
;
35 pub trait SpanlessEq
{
36 fn eq(&self, other
: &Self) -> bool
;
39 impl<T
: ?Sized
+ SpanlessEq
> SpanlessEq
for Box
<T
> {
40 fn eq(&self, other
: &Self) -> bool
{
41 SpanlessEq
::eq(&**self, &**other
)
45 impl<T
: SpanlessEq
> SpanlessEq
for P
<T
> {
46 fn eq(&self, other
: &Self) -> bool
{
47 SpanlessEq
::eq(&**self, &**other
)
51 impl<T
: ?Sized
+ SpanlessEq
> SpanlessEq
for Lrc
<T
> {
52 fn eq(&self, other
: &Self) -> bool
{
53 SpanlessEq
::eq(&**self, &**other
)
57 impl<T
: SpanlessEq
> SpanlessEq
for Option
<T
> {
58 fn eq(&self, other
: &Self) -> bool
{
61 (Some(this
), Some(other
)) => SpanlessEq
::eq(this
, other
),
67 impl<T
: SpanlessEq
> SpanlessEq
for [T
] {
68 fn eq(&self, other
: &Self) -> bool
{
69 self.len() == other
.len() && self.iter().zip(other
).all(|(a
, b
)| SpanlessEq
::eq(a
, b
))
73 impl<T
: SpanlessEq
> SpanlessEq
for Vec
<T
> {
74 fn eq(&self, other
: &Self) -> bool
{
75 <[T
] as SpanlessEq
>::eq(self, other
)
79 impl<T
: SpanlessEq
> SpanlessEq
for ThinVec
<T
> {
80 fn eq(&self, other
: &Self) -> bool
{
81 self.len() == other
.len()
85 .all(|(a
, b
)| SpanlessEq
::eq(a
, b
))
89 impl<T
: SpanlessEq
> SpanlessEq
for Spanned
<T
> {
90 fn eq(&self, other
: &Self) -> bool
{
91 SpanlessEq
::eq(&self.node
, &other
.node
)
95 impl<A
: SpanlessEq
, B
: SpanlessEq
> SpanlessEq
for (A
, B
) {
96 fn eq(&self, other
: &Self) -> bool
{
97 SpanlessEq
::eq(&self.0, &other
.0) && SpanlessEq
::eq(&self.1, &other
.1)
101 impl<A
: SpanlessEq
, B
: SpanlessEq
, C
: SpanlessEq
> SpanlessEq
for (A
, B
, C
) {
102 fn eq(&self, other
: &Self) -> bool
{
103 SpanlessEq
::eq(&self.0, &other
.0)
104 && SpanlessEq
::eq(&self.1, &other
.1)
105 && SpanlessEq
::eq(&self.2, &other
.2)
109 macro_rules
! spanless_eq_true
{
111 impl SpanlessEq
for $name
{
112 fn eq(&self, _other
: &Self) -> bool
{
119 spanless_eq_true
!(Span
);
120 spanless_eq_true
!(DelimSpan
);
121 spanless_eq_true
!(AttrId
);
122 spanless_eq_true
!(NodeId
);
123 spanless_eq_true
!(SyntaxContext
);
124 spanless_eq_true
!(Spacing
);
126 macro_rules
! spanless_eq_partial_eq
{
128 impl SpanlessEq
for $name
{
129 fn eq(&self, other
: &Self) -> bool
{
130 PartialEq
::eq(self, other
)
136 spanless_eq_partial_eq
!(bool
);
137 spanless_eq_partial_eq
!(u8);
138 spanless_eq_partial_eq
!(u16);
139 spanless_eq_partial_eq
!(u128
);
140 spanless_eq_partial_eq
!(usize);
141 spanless_eq_partial_eq
!(char);
142 spanless_eq_partial_eq
!(String
);
143 spanless_eq_partial_eq
!(Symbol
);
144 spanless_eq_partial_eq
!(CommentKind
);
145 spanless_eq_partial_eq
!(DelimToken
);
146 spanless_eq_partial_eq
!(InlineAsmOptions
);
147 spanless_eq_partial_eq
!(token
::LitKind
);
149 macro_rules
! spanless_eq_struct
{
151 $
($name
:ident
)::+ $
(<$param
:ident
>)?
152 $
([$field
:tt $this
:ident $other
:ident
])*
155 impl $
(<$param
: SpanlessEq
>)* SpanlessEq
for $
($name
)::+ $
(<$param
>)* {
156 fn eq(&self, other
: &Self) -> bool
{
157 let $
($name
)::+ { $($field: $this,)* $($ignore: _,)* }
= self;
158 let $
($name
)::+ { $($field: $other,)* $($ignore: _,)* }
= other
;
159 true $
(&& SpanlessEq
::eq($this
, $other
))*
165 $
($name
:ident
)::+ $
(<$param
:ident
>)?
166 $
([$field
:tt $this
:ident $other
:ident
])*
171 spanless_eq_struct
! {
172 $
($name
)::+ $
(<$param
>)*
173 $
([$field $this $other
])*
181 $
($name
:ident
)::+ $
(<$param
:ident
>)?
182 $
([$field
:tt $this
:ident $other
:ident
])*
187 spanless_eq_struct
! {
188 $
($name
)::+ $
(<$param
>)*
189 $
([$field $this $other
])*
197 macro_rules
! spanless_eq_enum
{
200 $
([$
($variant
:ident
)::+; $
([$field
:tt $this
:ident $other
:ident
])* $
(![$ignore
:tt
])*])*
202 impl SpanlessEq
for $
($name
)::+ {
203 fn eq(&self, other
: &Self) -> bool
{
206 $
($variant
)::+ { .. }
=> {}
209 #[allow(unreachable_patterns)]
210 match (self, other
) {
213 $
($variant
)::+ { $($field: $this,)* $($ignore: _,)* }
,
214 $
($variant
)::+ { $($field: $other,)* $($ignore: _,)* }
,
216 true $
(&& SpanlessEq
::eq($this
, $other
))*
227 $
([$
($variant
:ident
)::+; $
($fields
:tt
)*])*
228 $next
:ident
[$
([$
($named
:tt
)*])* $
(![$ignore
:tt
])*] (!$i
:tt $
($field
:tt
)*)
233 $
([$
($variant
)::+; $
($fields
)*])*
234 $next
[$
([$
($named
)*])* $
(![$ignore
])* ![$i
]] ($
($field
)*)
241 $
([$
($variant
:ident
)::+; $
($fields
:tt
)*])*
242 $next
:ident
[$
([$
($named
:tt
)*])* $
(![$ignore
:tt
])*] ($i
:tt $
($field
:tt
)*)
247 $
([$
($variant
)::+; $
($fields
)*])*
248 $next
[$
([$
($named
)*])* [$i this other
] $
(![$ignore
])*] ($
($field
)*)
255 $
([$
($variant
:ident
)::+; $
($fields
:tt
)*])*
256 $next
:ident
[$
($named
:tt
)*] ()
261 $
([$
($variant
)::+; $
($fields
)*])*
262 [$
($name
)::+::$next
; $
($named
)*]
269 $
([$
($variant
:ident
)::+; $
($fields
:tt
)*])*
270 $next
:ident ($
($field
:tt
)*)
275 $
([$
($variant
)::+; $
($fields
)*])*
276 $next
[] ($
($field
)*)
283 $
([$
($variant
:ident
)::+; $
($fields
:tt
)*])*
289 $
([$
($variant
)::+; $
($fields
)*])*
290 [$
($name
)::+::$next
;]
296 spanless_eq_struct
!(AngleBracketedArgs
; span args
);
297 spanless_eq_struct
!(AnonConst
; id value
);
298 spanless_eq_struct
!(Arm
; attrs pat guard body span id is_placeholder
);
299 spanless_eq_struct
!(AssocTyConstraint
; id ident gen_args kind span
);
300 spanless_eq_struct
!(AttrAnnotatedTokenStream
; 0);
301 spanless_eq_struct
!(AttrItem
; path args tokens
);
302 spanless_eq_struct
!(Attribute
; kind id style span
);
303 spanless_eq_struct
!(AttributesData
; attrs tokens
);
304 spanless_eq_struct
!(BareFnTy
; unsafety ext generic_params decl
);
305 spanless_eq_struct
!(Block
; stmts id rules span tokens could_be_bare_literal
);
306 spanless_eq_struct
!(Crate
; attrs items span
);
307 spanless_eq_struct
!(EnumDef
; variants
);
308 spanless_eq_struct
!(Expr
; id kind span attrs
!tokens
);
309 spanless_eq_struct
!(ExprField
; attrs id span ident expr is_shorthand is_placeholder
);
310 spanless_eq_struct
!(FieldDef
; attrs id span vis ident ty is_placeholder
);
311 spanless_eq_struct
!(FnDecl
; inputs output
);
312 spanless_eq_struct
!(FnHeader
; constness asyncness unsafety ext
);
313 spanless_eq_struct
!(FnKind
; 0 1 2 3);
314 spanless_eq_struct
!(FnSig
; header decl span
);
315 spanless_eq_struct
!(ForeignMod
; unsafety abi items
);
316 spanless_eq_struct
!(GenericParam
; id ident attrs bounds is_placeholder kind
);
317 spanless_eq_struct
!(Generics
; params where_clause span
);
318 spanless_eq_struct
!(ImplKind
; unsafety polarity defaultness constness generics of_trait self_ty items
);
319 spanless_eq_struct
!(InlineAsm
; template template_strs operands clobber_abi options line_spans
);
320 spanless_eq_struct
!(Item
<K
>; attrs id span vis ident kind
!tokens
);
321 spanless_eq_struct
!(Label
; ident
);
322 spanless_eq_struct
!(Lifetime
; id ident
);
323 spanless_eq_struct
!(Lit
; token kind span
);
324 spanless_eq_struct
!(LlvmInlineAsm
; asm asm_str_style outputs inputs clobbers volatile alignstack dialect
);
325 spanless_eq_struct
!(LlvmInlineAsmOutput
; constraint expr is_rw is_indirect
);
326 spanless_eq_struct
!(Local
; pat ty kind id span attrs
!tokens
);
327 spanless_eq_struct
!(MacCall
; path args prior_type_ascription
);
328 spanless_eq_struct
!(MacCallStmt
; mac style attrs tokens
);
329 spanless_eq_struct
!(MacroDef
; body macro_rules
);
330 spanless_eq_struct
!(MutTy
; ty mutbl
);
331 spanless_eq_struct
!(ParenthesizedArgs
; span inputs inputs_span output
);
332 spanless_eq_struct
!(Pat
; id kind span tokens
);
333 spanless_eq_struct
!(PatField
; ident pat is_shorthand attrs id span is_placeholder
);
334 spanless_eq_struct
!(Path
; span segments tokens
);
335 spanless_eq_struct
!(PathSegment
; ident id args
);
336 spanless_eq_struct
!(PolyTraitRef
; bound_generic_params trait_ref span
);
337 spanless_eq_struct
!(QSelf
; ty path_span position
);
338 spanless_eq_struct
!(Stmt
; id kind span
);
339 spanless_eq_struct
!(StrLit
; style symbol suffix span symbol_unescaped
);
340 spanless_eq_struct
!(StructExpr
; qself path fields rest
);
341 spanless_eq_struct
!(Token
; kind span
);
342 spanless_eq_struct
!(TraitKind
; 0 1 2 3 4);
343 spanless_eq_struct
!(TraitRef
; path ref_id
);
344 spanless_eq_struct
!(Ty
; id kind span tokens
);
345 spanless_eq_struct
!(TyAliasKind
; 0 1 2 3);
346 spanless_eq_struct
!(UseTree
; prefix kind span
);
347 spanless_eq_struct
!(Variant
; attrs id span
!vis ident data disr_expr is_placeholder
);
348 spanless_eq_struct
!(Visibility
; kind span tokens
);
349 spanless_eq_struct
!(WhereBoundPredicate
; span bound_generic_params bounded_ty bounds
);
350 spanless_eq_struct
!(WhereClause
; has_where_token predicates span
);
351 spanless_eq_struct
!(WhereEqPredicate
; id span lhs_ty rhs_ty
);
352 spanless_eq_struct
!(WhereRegionPredicate
; span lifetime bounds
);
353 spanless_eq_struct
!(token
::Lit
; kind symbol suffix
);
354 spanless_eq_enum
!(AngleBracketedArg
; Arg(0) Constraint(0));
355 spanless_eq_enum
!(AssocItemKind
; Const(0 1 2) Fn(0) TyAlias(0) MacCall(0));
356 spanless_eq_enum
!(AssocTyConstraintKind
; Equality(ty
) Bound(bounds
));
357 spanless_eq_enum
!(Async
; Yes(span closure_id return_impl_trait_id
) No
);
358 spanless_eq_enum
!(AttrAnnotatedTokenTree
; Token(0) Delimited(0 1 2) Attributes(0));
359 spanless_eq_enum
!(AttrStyle
; Outer Inner
);
360 spanless_eq_enum
!(BinOpKind
; Add Sub Mul Div Rem And Or BitXor BitAnd BitOr Shl Shr Eq Lt Le Ne Ge Gt
);
361 spanless_eq_enum
!(BindingMode
; ByRef(0) ByValue(0));
362 spanless_eq_enum
!(BlockCheckMode
; Default
Unsafe(0));
363 spanless_eq_enum
!(BorrowKind
; Ref Raw
);
364 spanless_eq_enum
!(CaptureBy
; Value Ref
);
365 spanless_eq_enum
!(Const
; Yes(0) No
);
366 spanless_eq_enum
!(CrateSugar
; PubCrate JustCrate
);
367 spanless_eq_enum
!(Defaultness
; Default(0) Final
);
368 spanless_eq_enum
!(Extern
; None Implicit
Explicit(0));
369 spanless_eq_enum
!(FloatTy
; F32 F64
);
370 spanless_eq_enum
!(FnRetTy
; Default(0) Ty(0));
371 spanless_eq_enum
!(ForeignItemKind
; Static(0 1 2) Fn(0) TyAlias(0) MacCall(0));
372 spanless_eq_enum
!(GenericArg
; Lifetime(0) Type(0) Const(0));
373 spanless_eq_enum
!(GenericArgs
; AngleBracketed(0) Parenthesized(0));
374 spanless_eq_enum
!(GenericBound
; Trait(0 1) Outlives(0));
375 spanless_eq_enum
!(GenericParamKind
; Lifetime
Type(default) Const(ty kw_span
default));
376 spanless_eq_enum
!(ImplPolarity
; Positive
Negative(0));
377 spanless_eq_enum
!(Inline
; Yes No
);
378 spanless_eq_enum
!(InlineAsmRegOrRegClass
; Reg(0) RegClass(0));
379 spanless_eq_enum
!(InlineAsmTemplatePiece
; String(0) Placeholder(operand_idx modifier span
));
380 spanless_eq_enum
!(IntTy
; Isize I8 I16 I32 I64 I128
);
381 spanless_eq_enum
!(IsAuto
; Yes No
);
382 spanless_eq_enum
!(LitFloatType
; Suffixed(0) Unsuffixed
);
383 spanless_eq_enum
!(LitIntType
; Signed(0) Unsigned(0) Unsuffixed
);
384 spanless_eq_enum
!(LlvmAsmDialect
; Att Intel
);
385 spanless_eq_enum
!(LocalKind
; Decl
Init(0) InitElse(0 1));
386 spanless_eq_enum
!(MacArgs
; Empty
Delimited(0 1 2) Eq(0 1));
387 spanless_eq_enum
!(MacDelimiter
; Parenthesis Bracket Brace
);
388 spanless_eq_enum
!(MacStmtStyle
; Semicolon Braces NoBraces
);
389 spanless_eq_enum
!(ModKind
; Loaded(0 1 2) Unloaded
);
390 spanless_eq_enum
!(Movability
; Static Movable
);
391 spanless_eq_enum
!(Mutability
; Mut Not
);
392 spanless_eq_enum
!(RangeEnd
; Included(0) Excluded
);
393 spanless_eq_enum
!(RangeLimits
; HalfOpen Closed
);
394 spanless_eq_enum
!(StmtKind
; Local(0) Item(0) Expr(0) Semi(0) Empty
MacCall(0));
395 spanless_eq_enum
!(StrStyle
; Cooked
Raw(0));
396 spanless_eq_enum
!(StructRest
; Base(0) Rest(0) None
);
397 spanless_eq_enum
!(TokenTree
; Token(0) Delimited(0 1 2));
398 spanless_eq_enum
!(TraitBoundModifier
; None Maybe MaybeConst MaybeConstMaybe
);
399 spanless_eq_enum
!(TraitObjectSyntax
; Dyn None
);
400 spanless_eq_enum
!(UintTy
; Usize U8 U16 U32 U64 U128
);
401 spanless_eq_enum
!(UnOp
; Deref Not Neg
);
402 spanless_eq_enum
!(Unsafe
; Yes(0) No
);
403 spanless_eq_enum
!(UnsafeSource
; CompilerGenerated UserProvided
);
404 spanless_eq_enum
!(UseTreeKind
; Simple(0 1 2) Nested(0) Glob
);
405 spanless_eq_enum
!(VariantData
; Struct(0 1) Tuple(0 1) Unit(0));
406 spanless_eq_enum
!(VisibilityKind
; Public
Crate(0) Restricted(path id
) Inherited
);
407 spanless_eq_enum
!(WherePredicate
; BoundPredicate(0) RegionPredicate(0) EqPredicate(0));
408 spanless_eq_enum
!(ExprKind
; Box(0) Array(0) ConstBlock(0) Call(0 1)
409 MethodCall(0 1 2) Tup(0) Binary(0 1 2) Unary(0 1) Lit(0) Cast(0 1) Type(0 1)
410 Let(0 1 2) If(0 1 2) While(0 1 2) ForLoop(0 1 2 3) Loop(0 1) Match(0 1)
411 Closure(0 1 2 3 4 5) Block(0 1) Async(0 1 2) Await(0) TryBlock(0)
412 Assign(0 1 2) AssignOp(0 1 2) Field(0 1) Index(0 1) Underscore
Range(0 1 2)
413 Path(0 1) AddrOf(0 1 2) Break(0 1) Continue(0) Ret(0) InlineAsm(0)
414 LlvmInlineAsm(0) MacCall(0) Struct(0) Repeat(0 1) Paren(0) Try(0) Yield(0)
416 spanless_eq_enum
!(InlineAsmOperand
; In(reg expr
) Out(reg late expr
)
417 InOut(reg late expr
) SplitInOut(reg late in_expr out_expr
) Const(anon_const
)
419 spanless_eq_enum
!(ItemKind
; ExternCrate(0) Use(0) Static(0 1 2) Const(0 1 2)
420 Fn(0) Mod(0 1) ForeignMod(0) GlobalAsm(0) TyAlias(0) Enum(0 1) Struct(0 1)
421 Union(0 1) Trait(0) TraitAlias(0 1) Impl(0) MacCall(0) MacroDef(0));
422 spanless_eq_enum
!(LitKind
; Str(0 1) ByteStr(0) Byte(0) Char(0) Int(0 1)
423 Float(0 1) Bool(0) Err(0));
424 spanless_eq_enum
!(PatKind
; Wild
Ident(0 1 2) Struct(0 1 2 3) TupleStruct(0 1 2)
425 Or(0) Path(0 1) Tuple(0) Box(0) Ref(0 1) Lit(0) Range(0 1 2) Slice(0) Rest
426 Paren(0) MacCall(0));
427 spanless_eq_enum
!(TyKind
; Slice(0) Array(0 1) Ptr(0) Rptr(0 1) BareFn(0) Never
428 Tup(0) Path(0 1) TraitObject(0 1) ImplTrait(0 1) Paren(0) Typeof(0) Infer
429 ImplicitSelf
MacCall(0) Err CVarArgs
);
431 impl SpanlessEq
for Ident
{
432 fn eq(&self, other
: &Self) -> bool
{
433 self.as_str() == other
.as_str()
437 impl SpanlessEq
for RangeSyntax
{
438 fn eq(&self, _other
: &Self) -> bool
{
440 RangeSyntax
::DotDotDot
| RangeSyntax
::DotDotEq
=> true,
445 impl SpanlessEq
for Param
{
446 fn eq(&self, other
: &Self) -> bool
{
461 is_placeholder
: is_placeholder2
,
463 SpanlessEq
::eq(id
, id2
)
464 && SpanlessEq
::eq(is_placeholder
, is_placeholder2
)
465 && (matches
!(ty
.kind
, TyKind
::Err
)
466 || matches
!(ty2
.kind
, TyKind
::Err
)
467 || SpanlessEq
::eq(attrs
, attrs2
)
468 && SpanlessEq
::eq(ty
, ty2
)
469 && SpanlessEq
::eq(pat
, pat2
))
473 impl SpanlessEq
for TokenKind
{
474 fn eq(&self, other
: &Self) -> bool
{
475 match (self, other
) {
476 (TokenKind
::Literal(this
), TokenKind
::Literal(other
)) => SpanlessEq
::eq(this
, other
),
477 (TokenKind
::DotDotEq
, _
) | (TokenKind
::DotDotDot
, _
) => match other
{
478 TokenKind
::DotDotEq
| TokenKind
::DotDotDot
=> true,
481 (TokenKind
::Interpolated(this
), TokenKind
::Interpolated(other
)) => {
482 match (this
.as_ref(), other
.as_ref()) {
483 (Nonterminal
::NtExpr(this
), Nonterminal
::NtExpr(other
)) => {
484 SpanlessEq
::eq(this
, other
)
494 impl SpanlessEq
for TokenStream
{
495 fn eq(&self, other
: &Self) -> bool
{
496 let mut this_trees
= self.trees();
497 let mut other_trees
= other
.trees();
499 let this
= match this_trees
.next() {
500 None
=> return other_trees
.next().is_none(),
503 let other
= match other_trees
.next() {
504 None
=> return false,
507 if SpanlessEq
::eq(&this
, &other
) {
510 if let (TokenTree
::Token(this
), TokenTree
::Token(other
)) = (this
, other
) {
511 if match (&this
.kind
, &other
.kind
) {
512 (TokenKind
::Literal(this
), TokenKind
::Literal(other
)) => {
513 SpanlessEq
::eq(this
, other
)
515 (TokenKind
::DocComment(_kind
, style
, symbol
), TokenKind
::Pound
) => {
516 doc_comment(*style
, *symbol
, &mut other_trees
)
518 (TokenKind
::Pound
, TokenKind
::DocComment(_kind
, style
, symbol
)) => {
519 doc_comment(*style
, *symbol
, &mut this_trees
)
534 trees
: &mut impl Iterator
<Item
= TokenTree
>,
537 AttrStyle
::Outer
=> false,
538 AttrStyle
::Inner
=> true,
541 Some(TokenTree
::Token(Token
{
542 kind
: TokenKind
::Not
,
548 let stream
= match trees
.next() {
549 Some(TokenTree
::Delimited(_span
, DelimToken
::Bracket
, stream
)) => stream
,
552 let mut trees
= stream
.trees();
554 Some(TokenTree
::Token(Token
{
555 kind
: TokenKind
::Ident(symbol
, false),
557 })) if symbol
== sym
::doc
=> {}
561 Some(TokenTree
::Token(Token
{
568 Some(TokenTree
::Token(token
)) => {
569 is_escaped_literal(&token
, unescaped
) && trees
.next().is_none()
575 fn is_escaped_literal(token
: &Token
, unescaped
: Symbol
) -> bool
{
578 kind
: TokenKind
::Literal(lit
),
580 } => Lit
::from_lit_token(*lit
, DUMMY_SP
),
582 kind
: TokenKind
::Interpolated(nonterminal
),
584 } => match nonterminal
.as_ref() {
585 Nonterminal
::NtExpr(expr
) => match &expr
.kind
{
586 ExprKind
::Lit(lit
) => Ok(lit
.clone()),
596 kind
: token
::LitKind
::Str
,
600 kind
: LitKind
::Str(symbol
, StrStyle
::Cooked
),
602 }) => symbol
.as_str().replace('
\r'
, "") == unescaped
.as_str().replace('
\r'
, ""),
607 impl SpanlessEq
for LazyTokenStream
{
608 fn eq(&self, other
: &Self) -> bool
{
609 let this
= self.create_token_stream();
610 let other
= other
.create_token_stream();
611 SpanlessEq
::eq(&this
, &other
)
615 impl SpanlessEq
for AttrKind
{
616 fn eq(&self, other
: &Self) -> bool
{
617 match (self, other
) {
618 (AttrKind
::Normal(item
, tokens
), AttrKind
::Normal(item2
, tokens2
)) => {
619 SpanlessEq
::eq(item
, item2
) && SpanlessEq
::eq(tokens
, tokens2
)
621 (AttrKind
::DocComment(kind
, symbol
), AttrKind
::DocComment(kind2
, symbol2
)) => {
622 SpanlessEq
::eq(kind
, kind2
) && SpanlessEq
::eq(symbol
, symbol2
)
624 (AttrKind
::DocComment(kind
, unescaped
), AttrKind
::Normal(item2
, _tokens
)) => {
626 CommentKind
::Line
| CommentKind
::Block
=> {}
628 let path
= Path
::from_ident(Ident
::with_dummy_span(sym
::doc
));
629 SpanlessEq
::eq(&path
, &item2
.path
)
630 && match &item2
.args
{
631 MacArgs
::Empty
| MacArgs
::Delimited(..) => false,
632 MacArgs
::Eq(_span
, token
) => is_escaped_literal(token
, *unescaped
),
635 (AttrKind
::Normal(..), AttrKind
::DocComment(..)) => SpanlessEq
::eq(other
, self),