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
, MacArgs
, MacCall
, MacCallStmt
,
15 MacDelimiter
, MacStmtStyle
, MacroDef
, ModKind
, Movability
, MutTy
, Mutability
, NodeId
, Param
,
16 ParenthesizedArgs
, Pat
, PatField
, PatKind
, Path
, PathSegment
, PolyTraitRef
, QSelf
, RangeEnd
,
17 RangeLimits
, RangeSyntax
, Stmt
, StmtKind
, StrLit
, StrStyle
, StructExpr
, StructRest
,
18 TraitBoundModifier
, TraitKind
, TraitObjectSyntax
, TraitRef
, Ty
, TyAliasKind
, TyKind
, UintTy
,
19 UnOp
, Unsafe
, UnsafeSource
, UseTree
, UseTreeKind
, Variant
, VariantData
, Visibility
,
20 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
: 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 macro_rules
! spanless_eq_true
{
103 impl SpanlessEq
for $name
{
104 fn eq(&self, _other
: &Self) -> bool
{
111 spanless_eq_true
!(Span
);
112 spanless_eq_true
!(DelimSpan
);
113 spanless_eq_true
!(AttrId
);
114 spanless_eq_true
!(NodeId
);
115 spanless_eq_true
!(SyntaxContext
);
116 spanless_eq_true
!(Spacing
);
118 macro_rules
! spanless_eq_partial_eq
{
120 impl SpanlessEq
for $name
{
121 fn eq(&self, other
: &Self) -> bool
{
122 PartialEq
::eq(self, other
)
128 spanless_eq_partial_eq
!(bool
);
129 spanless_eq_partial_eq
!(u8);
130 spanless_eq_partial_eq
!(u16);
131 spanless_eq_partial_eq
!(u128
);
132 spanless_eq_partial_eq
!(usize);
133 spanless_eq_partial_eq
!(char);
134 spanless_eq_partial_eq
!(String
);
135 spanless_eq_partial_eq
!(Symbol
);
136 spanless_eq_partial_eq
!(CommentKind
);
137 spanless_eq_partial_eq
!(DelimToken
);
138 spanless_eq_partial_eq
!(InlineAsmOptions
);
139 spanless_eq_partial_eq
!(token
::LitKind
);
141 macro_rules
! spanless_eq_struct
{
143 $
($name
:ident
)::+ $
(<$param
:ident
>)?
144 $
([$field
:tt $this
:ident $other
:ident
])*
147 impl $
(<$param
: SpanlessEq
>)* SpanlessEq
for $
($name
)::+ $
(<$param
>)* {
148 fn eq(&self, other
: &Self) -> bool
{
149 let $
($name
)::+ { $($field: $this,)* $($ignore: _,)* }
= self;
150 let $
($name
)::+ { $($field: $other,)* $($ignore: _,)* }
= other
;
151 true $
(&& SpanlessEq
::eq($this
, $other
))*
157 $
($name
:ident
)::+ $
(<$param
:ident
>)?
158 $
([$field
:tt $this
:ident $other
:ident
])*
163 spanless_eq_struct
! {
164 $
($name
)::+ $
(<$param
>)*
165 $
([$field $this $other
])*
173 $
($name
:ident
)::+ $
(<$param
:ident
>)?
174 $
([$field
:tt $this
:ident $other
:ident
])*
179 spanless_eq_struct
! {
180 $
($name
)::+ $
(<$param
>)*
181 $
([$field $this $other
])*
189 macro_rules
! spanless_eq_enum
{
192 $
([$
($variant
:ident
)::+; $
([$field
:tt $this
:ident $other
:ident
])* $
(![$ignore
:tt
])*])*
194 impl SpanlessEq
for $
($name
)::+ {
195 fn eq(&self, other
: &Self) -> bool
{
198 $
($variant
)::+ { .. }
=> {}
201 #[allow(unreachable_patterns)]
202 match (self, other
) {
205 $
($variant
)::+ { $($field: $this,)* $($ignore: _,)* }
,
206 $
($variant
)::+ { $($field: $other,)* $($ignore: _,)* }
,
208 true $
(&& SpanlessEq
::eq($this
, $other
))*
219 $
([$
($variant
:ident
)::+; $
($fields
:tt
)*])*
220 $next
:ident
[$
([$
($named
:tt
)*])* $
(![$ignore
:tt
])*] (!$i
:tt $
($field
:tt
)*)
225 $
([$
($variant
)::+; $
($fields
)*])*
226 $next
[$
([$
($named
)*])* $
(![$ignore
])* ![$i
]] ($
($field
)*)
233 $
([$
($variant
:ident
)::+; $
($fields
:tt
)*])*
234 $next
:ident
[$
([$
($named
:tt
)*])* $
(![$ignore
:tt
])*] ($i
:tt $
($field
:tt
)*)
239 $
([$
($variant
)::+; $
($fields
)*])*
240 $next
[$
([$
($named
)*])* [$i this other
] $
(![$ignore
])*] ($
($field
)*)
247 $
([$
($variant
:ident
)::+; $
($fields
:tt
)*])*
248 $next
:ident
[$
($named
:tt
)*] ()
253 $
([$
($variant
)::+; $
($fields
)*])*
254 [$
($name
)::+::$next
; $
($named
)*]
261 $
([$
($variant
:ident
)::+; $
($fields
:tt
)*])*
262 $next
:ident ($
($field
:tt
)*)
267 $
([$
($variant
)::+; $
($fields
)*])*
268 $next
[] ($
($field
)*)
275 $
([$
($variant
:ident
)::+; $
($fields
:tt
)*])*
281 $
([$
($variant
)::+; $
($fields
)*])*
282 [$
($name
)::+::$next
;]
288 spanless_eq_struct
!(AngleBracketedArgs
; span args
);
289 spanless_eq_struct
!(AnonConst
; id value
);
290 spanless_eq_struct
!(Arm
; attrs pat guard body span id is_placeholder
);
291 spanless_eq_struct
!(AssocTyConstraint
; id ident gen_args kind span
);
292 spanless_eq_struct
!(AttrAnnotatedTokenStream
; 0);
293 spanless_eq_struct
!(AttrItem
; path args tokens
);
294 spanless_eq_struct
!(Attribute
; kind id style span
);
295 spanless_eq_struct
!(AttributesData
; attrs tokens
);
296 spanless_eq_struct
!(BareFnTy
; unsafety ext generic_params decl
);
297 spanless_eq_struct
!(Block
; stmts id rules span tokens
);
298 spanless_eq_struct
!(Crate
; attrs items span proc_macros
);
299 spanless_eq_struct
!(EnumDef
; variants
);
300 spanless_eq_struct
!(Expr
; id kind span attrs
!tokens
);
301 spanless_eq_struct
!(ExprField
; attrs id span ident expr is_shorthand is_placeholder
);
302 spanless_eq_struct
!(FieldDef
; attrs id span vis ident ty is_placeholder
);
303 spanless_eq_struct
!(FnDecl
; inputs output
);
304 spanless_eq_struct
!(FnHeader
; constness asyncness unsafety ext
);
305 spanless_eq_struct
!(FnKind
; 0 1 2 3);
306 spanless_eq_struct
!(FnSig
; header decl span
);
307 spanless_eq_struct
!(ForeignMod
; unsafety abi items
);
308 spanless_eq_struct
!(GenericParam
; id ident attrs bounds is_placeholder kind
);
309 spanless_eq_struct
!(Generics
; params where_clause span
);
310 spanless_eq_struct
!(ImplKind
; unsafety polarity defaultness constness generics of_trait self_ty items
);
311 spanless_eq_struct
!(InlineAsm
; template operands options line_spans
);
312 spanless_eq_struct
!(Item
<K
>; attrs id span vis ident kind
!tokens
);
313 spanless_eq_struct
!(Label
; ident
);
314 spanless_eq_struct
!(Lifetime
; id ident
);
315 spanless_eq_struct
!(Lit
; token kind span
);
316 spanless_eq_struct
!(LlvmInlineAsm
; asm asm_str_style outputs inputs clobbers volatile alignstack dialect
);
317 spanless_eq_struct
!(LlvmInlineAsmOutput
; constraint expr is_rw is_indirect
);
318 spanless_eq_struct
!(Local
; pat ty init id span attrs
!tokens
);
319 spanless_eq_struct
!(MacCall
; path args prior_type_ascription
);
320 spanless_eq_struct
!(MacCallStmt
; mac style attrs tokens
);
321 spanless_eq_struct
!(MacroDef
; body macro_rules
);
322 spanless_eq_struct
!(MutTy
; ty mutbl
);
323 spanless_eq_struct
!(ParenthesizedArgs
; span inputs inputs_span output
);
324 spanless_eq_struct
!(Pat
; id kind span tokens
);
325 spanless_eq_struct
!(PatField
; ident pat is_shorthand attrs id span is_placeholder
);
326 spanless_eq_struct
!(Path
; span segments tokens
);
327 spanless_eq_struct
!(PathSegment
; ident id args
);
328 spanless_eq_struct
!(PolyTraitRef
; bound_generic_params trait_ref span
);
329 spanless_eq_struct
!(QSelf
; ty path_span position
);
330 spanless_eq_struct
!(Stmt
; id kind span
);
331 spanless_eq_struct
!(StrLit
; style symbol suffix span symbol_unescaped
);
332 spanless_eq_struct
!(StructExpr
; qself path fields rest
);
333 spanless_eq_struct
!(Token
; kind span
);
334 spanless_eq_struct
!(TraitKind
; 0 1 2 3 4);
335 spanless_eq_struct
!(TraitRef
; path ref_id
);
336 spanless_eq_struct
!(Ty
; id kind span tokens
);
337 spanless_eq_struct
!(TyAliasKind
; 0 1 2 3);
338 spanless_eq_struct
!(UseTree
; prefix kind span
);
339 spanless_eq_struct
!(Variant
; attrs id span
!vis ident data disr_expr is_placeholder
);
340 spanless_eq_struct
!(Visibility
; kind span tokens
);
341 spanless_eq_struct
!(WhereBoundPredicate
; span bound_generic_params bounded_ty bounds
);
342 spanless_eq_struct
!(WhereClause
; has_where_token predicates span
);
343 spanless_eq_struct
!(WhereEqPredicate
; id span lhs_ty rhs_ty
);
344 spanless_eq_struct
!(WhereRegionPredicate
; span lifetime bounds
);
345 spanless_eq_struct
!(token
::Lit
; kind symbol suffix
);
346 spanless_eq_enum
!(AngleBracketedArg
; Arg(0) Constraint(0));
347 spanless_eq_enum
!(AssocItemKind
; Const(0 1 2) Fn(0) TyAlias(0) MacCall(0));
348 spanless_eq_enum
!(AssocTyConstraintKind
; Equality(ty
) Bound(bounds
));
349 spanless_eq_enum
!(Async
; Yes(span closure_id return_impl_trait_id
) No
);
350 spanless_eq_enum
!(AttrAnnotatedTokenTree
; Token(0) Delimited(0 1 2) Attributes(0));
351 spanless_eq_enum
!(AttrStyle
; Outer Inner
);
352 spanless_eq_enum
!(BinOpKind
; Add Sub Mul Div Rem And Or BitXor BitAnd BitOr Shl Shr Eq Lt Le Ne Ge Gt
);
353 spanless_eq_enum
!(BindingMode
; ByRef(0) ByValue(0));
354 spanless_eq_enum
!(BlockCheckMode
; Default
Unsafe(0));
355 spanless_eq_enum
!(BorrowKind
; Ref Raw
);
356 spanless_eq_enum
!(CaptureBy
; Value Ref
);
357 spanless_eq_enum
!(Const
; Yes(0) No
);
358 spanless_eq_enum
!(CrateSugar
; PubCrate JustCrate
);
359 spanless_eq_enum
!(Defaultness
; Default(0) Final
);
360 spanless_eq_enum
!(Extern
; None Implicit
Explicit(0));
361 spanless_eq_enum
!(FloatTy
; F32 F64
);
362 spanless_eq_enum
!(FnRetTy
; Default(0) Ty(0));
363 spanless_eq_enum
!(ForeignItemKind
; Static(0 1 2) Fn(0) TyAlias(0) MacCall(0));
364 spanless_eq_enum
!(GenericArg
; Lifetime(0) Type(0) Const(0));
365 spanless_eq_enum
!(GenericArgs
; AngleBracketed(0) Parenthesized(0));
366 spanless_eq_enum
!(GenericBound
; Trait(0 1) Outlives(0));
367 spanless_eq_enum
!(GenericParamKind
; Lifetime
Type(default) Const(ty kw_span
default));
368 spanless_eq_enum
!(ImplPolarity
; Positive
Negative(0));
369 spanless_eq_enum
!(Inline
; Yes No
);
370 spanless_eq_enum
!(InlineAsmRegOrRegClass
; Reg(0) RegClass(0));
371 spanless_eq_enum
!(InlineAsmTemplatePiece
; String(0) Placeholder(operand_idx modifier span
));
372 spanless_eq_enum
!(IntTy
; Isize I8 I16 I32 I64 I128
);
373 spanless_eq_enum
!(IsAuto
; Yes No
);
374 spanless_eq_enum
!(LitFloatType
; Suffixed(0) Unsuffixed
);
375 spanless_eq_enum
!(LitIntType
; Signed(0) Unsigned(0) Unsuffixed
);
376 spanless_eq_enum
!(LlvmAsmDialect
; Att Intel
);
377 spanless_eq_enum
!(MacArgs
; Empty
Delimited(0 1 2) Eq(0 1));
378 spanless_eq_enum
!(MacDelimiter
; Parenthesis Bracket Brace
);
379 spanless_eq_enum
!(MacStmtStyle
; Semicolon Braces NoBraces
);
380 spanless_eq_enum
!(ModKind
; Loaded(0 1 2) Unloaded
);
381 spanless_eq_enum
!(Movability
; Static Movable
);
382 spanless_eq_enum
!(Mutability
; Mut Not
);
383 spanless_eq_enum
!(RangeEnd
; Included(0) Excluded
);
384 spanless_eq_enum
!(RangeLimits
; HalfOpen Closed
);
385 spanless_eq_enum
!(StmtKind
; Local(0) Item(0) Expr(0) Semi(0) Empty
MacCall(0));
386 spanless_eq_enum
!(StrStyle
; Cooked
Raw(0));
387 spanless_eq_enum
!(StructRest
; Base(0) Rest(0) None
);
388 spanless_eq_enum
!(TokenTree
; Token(0) Delimited(0 1 2));
389 spanless_eq_enum
!(TraitBoundModifier
; None Maybe MaybeConst MaybeConstMaybe
);
390 spanless_eq_enum
!(TraitObjectSyntax
; Dyn None
);
391 spanless_eq_enum
!(UintTy
; Usize U8 U16 U32 U64 U128
);
392 spanless_eq_enum
!(UnOp
; Deref Not Neg
);
393 spanless_eq_enum
!(Unsafe
; Yes(0) No
);
394 spanless_eq_enum
!(UnsafeSource
; CompilerGenerated UserProvided
);
395 spanless_eq_enum
!(UseTreeKind
; Simple(0 1 2) Nested(0) Glob
);
396 spanless_eq_enum
!(VariantData
; Struct(0 1) Tuple(0 1) Unit(0));
397 spanless_eq_enum
!(VisibilityKind
; Public
Crate(0) Restricted(path id
) Inherited
);
398 spanless_eq_enum
!(WherePredicate
; BoundPredicate(0) RegionPredicate(0) EqPredicate(0));
399 spanless_eq_enum
!(ExprKind
; Box(0) Array(0) ConstBlock(0) Call(0 1)
400 MethodCall(0 1 2) Tup(0) Binary(0 1 2) Unary(0 1) Lit(0) Cast(0 1) Type(0 1)
401 Let(0 1) If(0 1 2) While(0 1 2) ForLoop(0 1 2 3) Loop(0 1) Match(0 1)
402 Closure(0 1 2 3 4 5) Block(0 1) Async(0 1 2) Await(0) TryBlock(0)
403 Assign(0 1 2) AssignOp(0 1 2) Field(0 1) Index(0 1) Underscore
Range(0 1 2)
404 Path(0 1) AddrOf(0 1 2) Break(0 1) Continue(0) Ret(0) InlineAsm(0)
405 LlvmInlineAsm(0) MacCall(0) Struct(0) Repeat(0 1) Paren(0) Try(0) Yield(0)
407 spanless_eq_enum
!(InlineAsmOperand
; In(reg expr
) Out(reg late expr
)
408 InOut(reg late expr
) SplitInOut(reg late in_expr out_expr
) Const(anon_const
)
410 spanless_eq_enum
!(ItemKind
; ExternCrate(0) Use(0) Static(0 1 2) Const(0 1 2)
411 Fn(0) Mod(0 1) ForeignMod(0) GlobalAsm(0) TyAlias(0) Enum(0 1) Struct(0 1)
412 Union(0 1) Trait(0) TraitAlias(0 1) Impl(0) MacCall(0) MacroDef(0));
413 spanless_eq_enum
!(LitKind
; Str(0 1) ByteStr(0) Byte(0) Char(0) Int(0 1)
414 Float(0 1) Bool(0) Err(0));
415 spanless_eq_enum
!(PatKind
; Wild
Ident(0 1 2) Struct(0 1 2 3) TupleStruct(0 1 2)
416 Or(0) Path(0 1) Tuple(0) Box(0) Ref(0 1) Lit(0) Range(0 1 2) Slice(0) Rest
417 Paren(0) MacCall(0));
418 spanless_eq_enum
!(TyKind
; Slice(0) Array(0 1) Ptr(0) Rptr(0 1) BareFn(0) Never
419 Tup(0) AnonymousStruct(0 1) AnonymousUnion(0 1) Path(0 1) TraitObject(0 1)
420 ImplTrait(0 1) Paren(0) Typeof(0) Infer ImplicitSelf
MacCall(0) Err
423 impl SpanlessEq
for Ident
{
424 fn eq(&self, other
: &Self) -> bool
{
425 self.as_str() == other
.as_str()
429 impl SpanlessEq
for RangeSyntax
{
430 fn eq(&self, _other
: &Self) -> bool
{
432 RangeSyntax
::DotDotDot
| RangeSyntax
::DotDotEq
=> true,
437 impl SpanlessEq
for Param
{
438 fn eq(&self, other
: &Self) -> bool
{
453 is_placeholder
: is_placeholder2
,
455 SpanlessEq
::eq(id
, id2
)
456 && SpanlessEq
::eq(is_placeholder
, is_placeholder2
)
457 && (matches
!(ty
.kind
, TyKind
::Err
)
458 || matches
!(ty2
.kind
, TyKind
::Err
)
459 || SpanlessEq
::eq(attrs
, attrs2
)
460 && SpanlessEq
::eq(ty
, ty2
)
461 && SpanlessEq
::eq(pat
, pat2
))
465 impl SpanlessEq
for TokenKind
{
466 fn eq(&self, other
: &Self) -> bool
{
467 match (self, other
) {
468 (TokenKind
::Literal(this
), TokenKind
::Literal(other
)) => SpanlessEq
::eq(this
, other
),
469 (TokenKind
::DotDotEq
, _
) | (TokenKind
::DotDotDot
, _
) => match other
{
470 TokenKind
::DotDotEq
| TokenKind
::DotDotDot
=> true,
473 (TokenKind
::Interpolated(this
), TokenKind
::Interpolated(other
)) => {
474 match (this
.as_ref(), other
.as_ref()) {
475 (Nonterminal
::NtExpr(this
), Nonterminal
::NtExpr(other
)) => {
476 SpanlessEq
::eq(this
, other
)
486 impl SpanlessEq
for TokenStream
{
487 fn eq(&self, other
: &Self) -> bool
{
488 let mut this_trees
= self.trees();
489 let mut other_trees
= other
.trees();
491 let this
= match this_trees
.next() {
492 None
=> return other_trees
.next().is_none(),
495 let other
= match other_trees
.next() {
496 None
=> return false,
499 if SpanlessEq
::eq(&this
, &other
) {
502 if let (TokenTree
::Token(this
), TokenTree
::Token(other
)) = (this
, other
) {
503 if match (&this
.kind
, &other
.kind
) {
504 (TokenKind
::Literal(this
), TokenKind
::Literal(other
)) => {
505 SpanlessEq
::eq(this
, other
)
507 (TokenKind
::DocComment(_kind
, style
, symbol
), TokenKind
::Pound
) => {
508 doc_comment(*style
, *symbol
, &mut other_trees
)
510 (TokenKind
::Pound
, TokenKind
::DocComment(_kind
, style
, symbol
)) => {
511 doc_comment(*style
, *symbol
, &mut this_trees
)
526 trees
: &mut impl Iterator
<Item
= TokenTree
>,
529 AttrStyle
::Outer
=> false,
530 AttrStyle
::Inner
=> true,
533 Some(TokenTree
::Token(Token
{
534 kind
: TokenKind
::Not
,
540 let stream
= match trees
.next() {
541 Some(TokenTree
::Delimited(_span
, DelimToken
::Bracket
, stream
)) => stream
,
544 let mut trees
= stream
.trees();
546 Some(TokenTree
::Token(Token
{
547 kind
: TokenKind
::Ident(symbol
, false),
549 })) if symbol
== sym
::doc
=> {}
553 Some(TokenTree
::Token(Token
{
560 Some(TokenTree
::Token(token
)) => {
561 is_escaped_literal(&token
, unescaped
) && trees
.next().is_none()
567 fn is_escaped_literal(token
: &Token
, unescaped
: Symbol
) -> bool
{
570 kind
: TokenKind
::Literal(lit
),
572 } => Lit
::from_lit_token(*lit
, DUMMY_SP
),
574 kind
: TokenKind
::Interpolated(nonterminal
),
576 } => match nonterminal
.as_ref() {
577 Nonterminal
::NtExpr(expr
) => match &expr
.kind
{
578 ExprKind
::Lit(lit
) => Ok(lit
.clone()),
588 kind
: token
::LitKind
::Str
,
592 kind
: LitKind
::Str(symbol
, StrStyle
::Cooked
),
594 }) => symbol
.as_str().replace('
\r'
, "") == unescaped
.as_str().replace('
\r'
, ""),
599 impl SpanlessEq
for LazyTokenStream
{
600 fn eq(&self, other
: &Self) -> bool
{
601 let this
= self.create_token_stream();
602 let other
= other
.create_token_stream();
603 SpanlessEq
::eq(&this
, &other
)
607 impl SpanlessEq
for AttrKind
{
608 fn eq(&self, other
: &Self) -> bool
{
609 match (self, other
) {
610 (AttrKind
::Normal(item
, tokens
), AttrKind
::Normal(item2
, tokens2
)) => {
611 SpanlessEq
::eq(item
, item2
) && SpanlessEq
::eq(tokens
, tokens2
)
613 (AttrKind
::DocComment(kind
, symbol
), AttrKind
::DocComment(kind2
, symbol2
)) => {
614 SpanlessEq
::eq(kind
, kind2
) && SpanlessEq
::eq(symbol
, symbol2
)
616 (AttrKind
::DocComment(kind
, unescaped
), AttrKind
::Normal(item2
, _tokens
)) => {
618 CommentKind
::Line
| CommentKind
::Block
=> {}
620 let path
= Path
::from_ident(Ident
::with_dummy_span(sym
::doc
));
621 SpanlessEq
::eq(&path
, &item2
.path
)
622 && match &item2
.args
{
623 MacArgs
::Empty
| MacArgs
::Delimited(..) => false,
624 MacArgs
::Eq(_span
, token
) => is_escaped_literal(token
, *unescaped
),
627 (AttrKind
::Normal(..), AttrKind
::DocComment(..)) => SpanlessEq
::eq(other
, self),