1 extern crate rustc_data_structures
;
2 extern crate rustc_target
;
4 extern crate syntax_pos
;
8 use self::rustc_data_structures
::sync
::Lrc
;
9 use self::rustc_data_structures
::thin_vec
::ThinVec
;
10 use self::rustc_target
::abi
::FloatTy
;
11 use self::rustc_target
::spec
::abi
::Abi
;
12 use self::syntax
::ast
::{
13 AngleBracketedArgs
, AnonConst
, Arg
, Arm
, AsmDialect
, AssocTyConstraint
, AssocTyConstraintKind
,
14 AttrId
, AttrStyle
, Attribute
, AwaitOrigin
, BareFnTy
, BinOpKind
, BindingMode
, Block
,
15 BlockCheckMode
, CaptureBy
, Constness
, Crate
, CrateSugar
, Defaultness
, EnumDef
, Expr
, ExprKind
,
16 Field
, FieldPat
, FnDecl
, FnHeader
, ForeignItem
, ForeignItemKind
, ForeignMod
, FunctionRetTy
,
17 GenericArg
, GenericArgs
, GenericBound
, GenericParam
, GenericParamKind
, Generics
, GlobalAsm
,
18 Ident
, ImplItem
, ImplItemKind
, ImplPolarity
, InlineAsm
, InlineAsmOutput
, IntTy
, IsAsync
,
19 IsAuto
, Item
, ItemKind
, Label
, Lifetime
, Lit
, LitIntType
, LitKind
, Local
, MacDelimiter
,
20 MacStmtStyle
, Mac_
, MacroDef
, MethodSig
, Mod
, Movability
, MutTy
, Mutability
, NodeId
,
21 ParenthesizedArgs
, Pat
, PatKind
, Path
, PathSegment
, PolyTraitRef
, QSelf
, RangeEnd
, RangeLimits
,
22 RangeSyntax
, Stmt
, StmtKind
, StrStyle
, StructField
, TraitBoundModifier
, TraitItem
,
23 TraitItemKind
, TraitObjectSyntax
, TraitRef
, Ty
, TyKind
, UintTy
, UnOp
, UnsafeSource
, Unsafety
,
24 UseTree
, UseTreeKind
, VariantData
, Variant_
, VisibilityKind
, WhereBoundPredicate
, WhereClause
,
25 WhereEqPredicate
, WherePredicate
, WhereRegionPredicate
,
27 use self::syntax
::parse
::lexer
::comments
;
28 use self::syntax
::parse
::token
::{self, DelimToken, Token, TokenKind}
;
29 use self::syntax
::ptr
::P
;
30 use self::syntax
::source_map
::Spanned
;
31 use self::syntax
::symbol
::{sym, Symbol}
;
32 use self::syntax
::tokenstream
::{DelimSpan, TokenStream, TokenTree}
;
33 use self::syntax_pos
::{Span, SyntaxContext, DUMMY_SP}
;
35 pub trait SpanlessEq
{
36 fn eq(&self, other
: &Self) -> bool
;
39 impl<T
: SpanlessEq
> SpanlessEq
for P
<T
> {
40 fn eq(&self, other
: &Self) -> bool
{
41 SpanlessEq
::eq(&**self, &**other
)
45 impl<T
: SpanlessEq
> SpanlessEq
for Lrc
<T
> {
46 fn eq(&self, other
: &Self) -> bool
{
47 SpanlessEq
::eq(&**self, &**other
)
51 impl<T
: SpanlessEq
> SpanlessEq
for Option
<T
> {
52 fn eq(&self, other
: &Self) -> bool
{
55 (Some(this
), Some(other
)) => SpanlessEq
::eq(this
, other
),
61 impl<T
: SpanlessEq
> SpanlessEq
for Vec
<T
> {
62 fn eq(&self, other
: &Self) -> bool
{
63 self.len() == other
.len() && self.iter().zip(other
).all(|(a
, b
)| SpanlessEq
::eq(a
, b
))
67 impl<T
: SpanlessEq
> SpanlessEq
for ThinVec
<T
> {
68 fn eq(&self, other
: &Self) -> bool
{
69 self.len() == other
.len()
73 .all(|(a
, b
)| SpanlessEq
::eq(a
, b
))
77 impl<T
: SpanlessEq
> SpanlessEq
for Spanned
<T
> {
78 fn eq(&self, other
: &Self) -> bool
{
79 SpanlessEq
::eq(&self.node
, &other
.node
)
83 impl<A
: SpanlessEq
, B
: SpanlessEq
> SpanlessEq
for (A
, B
) {
84 fn eq(&self, other
: &Self) -> bool
{
85 SpanlessEq
::eq(&self.0, &other
.0) && SpanlessEq
::eq(&self.1, &other
.1)
89 impl<A
: SpanlessEq
, B
: SpanlessEq
, C
: SpanlessEq
> SpanlessEq
for (A
, B
, C
) {
90 fn eq(&self, other
: &Self) -> bool
{
91 SpanlessEq
::eq(&self.0, &other
.0)
92 && SpanlessEq
::eq(&self.1, &other
.1)
93 && SpanlessEq
::eq(&self.2, &other
.2)
97 macro_rules
! spanless_eq_true
{
99 impl SpanlessEq
for $name
{
100 fn eq(&self, _other
: &Self) -> bool
{
107 spanless_eq_true
!(Span
);
108 spanless_eq_true
!(DelimSpan
);
109 spanless_eq_true
!(AttrId
);
110 spanless_eq_true
!(NodeId
);
111 spanless_eq_true
!(SyntaxContext
);
113 macro_rules
! spanless_eq_partial_eq
{
115 impl SpanlessEq
for $name
{
116 fn eq(&self, other
: &Self) -> bool
{
117 PartialEq
::eq(self, other
)
123 spanless_eq_partial_eq
!(bool
);
124 spanless_eq_partial_eq
!(u8);
125 spanless_eq_partial_eq
!(u16);
126 spanless_eq_partial_eq
!(u128
);
127 spanless_eq_partial_eq
!(usize);
128 spanless_eq_partial_eq
!(char);
129 spanless_eq_partial_eq
!(Symbol
);
130 spanless_eq_partial_eq
!(Abi
);
131 spanless_eq_partial_eq
!(DelimToken
);
133 macro_rules
! spanless_eq_struct
{
136 $
([$field
:ident $other
:ident
])*
139 impl SpanlessEq
for $name
{
140 fn eq(&self, other
: &Self) -> bool
{
141 let $name { $($field,)* $($ignore: _,)* }
= self;
142 let $name { $($field: $other,)* $($ignore: _,)* }
= other
;
143 $
(SpanlessEq
::eq($field
, $other
))&&*
150 $
([$field
:ident $other
:ident
])*
155 spanless_eq_struct
! {
166 $
([$field
:ident $other
:ident
])*
171 spanless_eq_struct
! {
181 macro_rules
! spanless_eq_enum
{
184 $
([$variant
:ident $
([$field
:tt $this
:ident $other
:ident
])*])*
186 impl SpanlessEq
for $name
{
187 fn eq(&self, other
: &Self) -> bool
{
190 $name
::$variant { .. }
=> {}
193 #[allow(unreachable_patterns)]
194 match (self, other
) {
197 $name
::$variant { $($field: $this),* }
,
198 $name
::$variant { $($field: $other),* }
,
200 true $
(&& SpanlessEq
::eq($this
, $other
))*
211 $
([$variant
:ident $
($fields
:tt
)*])*
212 $next
:ident
[$
($named
:tt
)*] ( $i
:tt $
($field
:tt
)* )
217 $
([$variant $
($fields
)*])*
218 $next
[$
($named
)* [$i this other
]] ( $
($field
)* )
225 $
([$variant
:ident $
($fields
:tt
)*])*
226 $next
:ident
[$
($named
:tt
)*] ()
231 $
([$variant $
($fields
)*])*
239 $
([$variant
:ident $
($fields
:tt
)*])*
240 $next
:ident ( $
($field
:tt
)* )
245 $
([$variant $
($fields
)*])*
246 $next
[] ( $
($field
)* )
253 $
([$variant
:ident $
($fields
:tt
)*])*
259 $
([$variant $
($fields
)*])*
266 spanless_eq_struct
!(AngleBracketedArgs
; span args constraints
);
267 spanless_eq_struct
!(AnonConst
; id value
);
268 spanless_eq_struct
!(Arg
; attrs ty pat id
);
269 spanless_eq_struct
!(Arm
; attrs pats guard body span
);
270 spanless_eq_struct
!(AssocTyConstraint
; id ident kind span
);
271 spanless_eq_struct
!(Attribute
; id style path tokens span
!is_sugared_doc
);
272 spanless_eq_struct
!(BareFnTy
; unsafety abi generic_params decl
);
273 spanless_eq_struct
!(Block
; stmts id rules span
);
274 spanless_eq_struct
!(Crate
; module attrs span
);
275 spanless_eq_struct
!(EnumDef
; variants
);
276 spanless_eq_struct
!(Expr
; id node span attrs
);
277 spanless_eq_struct
!(Field
; ident expr span is_shorthand attrs
);
278 spanless_eq_struct
!(FieldPat
; ident pat is_shorthand attrs
);
279 spanless_eq_struct
!(FnDecl
; inputs output c_variadic
);
280 spanless_eq_struct
!(FnHeader
; constness asyncness unsafety abi
);
281 spanless_eq_struct
!(ForeignItem
; ident attrs node id span vis
);
282 spanless_eq_struct
!(ForeignMod
; abi items
);
283 spanless_eq_struct
!(GenericParam
; id ident attrs bounds kind
);
284 spanless_eq_struct
!(Generics
; params where_clause span
);
285 spanless_eq_struct
!(GlobalAsm
; asm ctxt
);
286 spanless_eq_struct
!(ImplItem
; id ident vis defaultness attrs generics node span
!tokens
);
287 spanless_eq_struct
!(InlineAsm
; asm asm_str_style outputs inputs clobbers volatile alignstack dialect ctxt
);
288 spanless_eq_struct
!(InlineAsmOutput
; constraint expr is_rw is_indirect
);
289 spanless_eq_struct
!(Item
; ident attrs id node vis span
!tokens
);
290 spanless_eq_struct
!(Label
; ident
);
291 spanless_eq_struct
!(Lifetime
; id ident
);
292 spanless_eq_struct
!(Lit
; token node span
);
293 spanless_eq_struct
!(Local
; pat ty init id span attrs
);
294 spanless_eq_struct
!(Mac_
; path delim tts
);
295 spanless_eq_struct
!(MacroDef
; tokens legacy
);
296 spanless_eq_struct
!(MethodSig
; header decl
);
297 spanless_eq_struct
!(Mod
; inner items inline
);
298 spanless_eq_struct
!(MutTy
; ty mutbl
);
299 spanless_eq_struct
!(ParenthesizedArgs
; span inputs output
);
300 spanless_eq_struct
!(Pat
; id node span
);
301 spanless_eq_struct
!(Path
; span segments
);
302 spanless_eq_struct
!(PathSegment
; ident id args
);
303 spanless_eq_struct
!(PolyTraitRef
; bound_generic_params trait_ref span
);
304 spanless_eq_struct
!(QSelf
; ty path_span position
);
305 spanless_eq_struct
!(Stmt
; id node span
);
306 spanless_eq_struct
!(StructField
; span ident vis id ty attrs
);
307 spanless_eq_struct
!(Token
; kind span
);
308 spanless_eq_struct
!(TraitItem
; id ident attrs generics node span
!tokens
);
309 spanless_eq_struct
!(TraitRef
; path ref_id
);
310 spanless_eq_struct
!(Ty
; id node span
);
311 spanless_eq_struct
!(UseTree
; prefix kind span
);
312 spanless_eq_struct
!(Variant_
; ident attrs id data disr_expr
);
313 spanless_eq_struct
!(WhereBoundPredicate
; span bound_generic_params bounded_ty bounds
);
314 spanless_eq_struct
!(WhereClause
; predicates span
);
315 spanless_eq_struct
!(WhereEqPredicate
; id span lhs_ty rhs_ty
);
316 spanless_eq_struct
!(WhereRegionPredicate
; span lifetime bounds
);
317 spanless_eq_enum
!(AsmDialect
; Att Intel
);
318 spanless_eq_enum
!(AssocTyConstraintKind
; Equality(ty
) Bound(bounds
));
319 spanless_eq_enum
!(AttrStyle
; Outer Inner
);
320 spanless_eq_enum
!(AwaitOrigin
; FieldLike MacroLike
);
321 spanless_eq_enum
!(BinOpKind
; Add Sub Mul Div Rem And Or BitXor BitAnd BitOr Shl Shr Eq Lt Le Ne Ge Gt
);
322 spanless_eq_enum
!(BindingMode
; ByRef(0) ByValue(0));
323 spanless_eq_enum
!(BlockCheckMode
; Default
Unsafe(0));
324 spanless_eq_enum
!(CaptureBy
; Value Ref
);
325 spanless_eq_enum
!(Constness
; Const NotConst
);
326 spanless_eq_enum
!(CrateSugar
; PubCrate JustCrate
);
327 spanless_eq_enum
!(Defaultness
; Default Final
);
328 spanless_eq_enum
!(FloatTy
; F32 F64
);
329 spanless_eq_enum
!(ForeignItemKind
; Fn(0 1) Static(0 1) Ty
Macro(0));
330 spanless_eq_enum
!(FunctionRetTy
; Default(0) Ty(0));
331 spanless_eq_enum
!(GenericArg
; Lifetime(0) Type(0) Const(0));
332 spanless_eq_enum
!(GenericArgs
; AngleBracketed(0) Parenthesized(0));
333 spanless_eq_enum
!(GenericBound
; Trait(0 1) Outlives(0));
334 spanless_eq_enum
!(GenericParamKind
; Lifetime
Type(default) Const(ty
));
335 spanless_eq_enum
!(ImplItemKind
; Const(0 1) Method(0 1) Type(0) Existential(0) Macro(0));
336 spanless_eq_enum
!(ImplPolarity
; Positive Negative
);
337 spanless_eq_enum
!(IntTy
; Isize I8 I16 I32 I64 I128
);
338 spanless_eq_enum
!(IsAsync
; Async(closure_id return_impl_trait_id
) NotAsync
);
339 spanless_eq_enum
!(IsAuto
; Yes No
);
340 spanless_eq_enum
!(LitIntType
; Signed(0) Unsigned(0) Unsuffixed
);
341 spanless_eq_enum
!(MacDelimiter
; Parenthesis Bracket Brace
);
342 spanless_eq_enum
!(MacStmtStyle
; Semicolon Braces NoBraces
);
343 spanless_eq_enum
!(Movability
; Static Movable
);
344 spanless_eq_enum
!(Mutability
; Mutable Immutable
);
345 spanless_eq_enum
!(RangeEnd
; Included(0) Excluded
);
346 spanless_eq_enum
!(RangeLimits
; HalfOpen Closed
);
347 spanless_eq_enum
!(StmtKind
; Local(0) Item(0) Expr(0) Semi(0) Mac(0));
348 spanless_eq_enum
!(StrStyle
; Cooked
Raw(0));
349 spanless_eq_enum
!(TokenTree
; Token(0) Delimited(0 1 2));
350 spanless_eq_enum
!(TraitBoundModifier
; None Maybe
);
351 spanless_eq_enum
!(TraitItemKind
; Const(0 1) Method(0 1) Type(0 1) Macro(0));
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
);
355 spanless_eq_enum
!(UnsafeSource
; CompilerGenerated UserProvided
);
356 spanless_eq_enum
!(Unsafety
; Unsafe Normal
);
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));
361 spanless_eq_enum
!(ExprKind
; Box(0) Array(0) Call(0 1) MethodCall(0 1) Tup(0)
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)
364 Block(0 1) Async(0 1 2) Await(0 1) TryBlock(0) Assign(0 1) AssignOp(0 1 2)
365 Field(0 1) Index(0 1) Range(0 1 2) Path(0 1) AddrOf(0 1) Break(0 1)
366 Continue(0) Ret(0) InlineAsm(0) Mac(0) Struct(0 1 2) Repeat(0 1) Paren(0)
367 Try(0) Yield(0) Err
);
368 spanless_eq_enum
!(ItemKind
; ExternCrate(0) Use(0) Static(0 1 2) Const(0 1)
369 Fn(0 1 2 3) Mod(0) ForeignMod(0) GlobalAsm(0) Ty(0 1) Existential(0 1)
370 Enum(0 1) Struct(0 1) Union(0 1) Trait(0 1 2 3 4) TraitAlias(0 1)
371 Impl(0 1 2 3 4 5 6) Mac(0) MacroDef(0));
372 spanless_eq_enum
!(LitKind
; Str(0 1) ByteStr(0) Byte(0) Char(0) Int(0 1)
373 Float(0 1) FloatUnsuffixed(0) Bool(0) Err(0));
374 spanless_eq_enum
!(PatKind
; Wild
Ident(0 1 2) Struct(0 1 2) TupleStruct(0 1 2)
375 Path(0 1) Tuple(0 1) Box(0) Ref(0 1) Lit(0) Range(0 1 2) Slice(0 1 2)
377 spanless_eq_enum
!(TyKind
; Slice(0) Array(0 1) Ptr(0) Rptr(0 1) BareFn(0) Never
378 Tup(0) Path(0 1) TraitObject(0 1) ImplTrait(0 1) Paren(0) Typeof(0) Infer
379 ImplicitSelf
Mac(0) Err CVarArgs
);
381 impl SpanlessEq
for Ident
{
382 fn eq(&self, other
: &Self) -> bool
{
383 self.as_str() == other
.as_str()
387 // Give up on comparing literals inside of macros because there are so many
388 // equivalent representations of the same literal; they are tested elsewhere
389 impl SpanlessEq
for token
::Lit
{
390 fn eq(&self, other
: &Self) -> bool
{
391 mem
::discriminant(self) == mem
::discriminant(other
)
395 impl SpanlessEq
for RangeSyntax
{
396 fn eq(&self, _other
: &Self) -> bool
{
398 RangeSyntax
::DotDotDot
| RangeSyntax
::DotDotEq
=> true,
403 impl SpanlessEq
for TokenKind
{
404 fn eq(&self, other
: &Self) -> bool
{
405 match (self, other
) {
406 (TokenKind
::Literal(this
), TokenKind
::Literal(other
)) => SpanlessEq
::eq(this
, other
),
407 (TokenKind
::DotDotEq
, _
) | (TokenKind
::DotDotDot
, _
) => match other
{
408 TokenKind
::DotDotEq
| TokenKind
::DotDotDot
=> true,
416 impl SpanlessEq
for TokenStream
{
417 fn eq(&self, other
: &Self) -> bool
{
418 SpanlessEq
::eq(&expand_tts(self), &expand_tts(other
))
422 fn expand_tts(tts
: &TokenStream
) -> Vec
<TokenTree
> {
423 let mut tokens
= Vec
::new();
424 for tt
in tts
.clone().into_trees() {
426 TokenTree
::Token(Token
{
427 kind
: TokenKind
::DocComment(c
),
435 let contents
= comments
::strip_doc_comment_decoration(&c
.as_str());
436 let style
= comments
::doc_comment_style(&c
.as_str());
437 tokens
.push(TokenTree
::token(TokenKind
::Pound
, DUMMY_SP
));
438 if style
== AttrStyle
::Inner
{
439 tokens
.push(TokenTree
::token(TokenKind
::Not
, DUMMY_SP
));
441 let lit
= token
::Lit
{
442 kind
: token
::LitKind
::Str
,
443 symbol
: Symbol
::intern(&contents
),
447 TokenTree
::token(TokenKind
::Ident(sym
::doc
, false), DUMMY_SP
),
448 TokenTree
::token(TokenKind
::Eq
, DUMMY_SP
),
449 TokenTree
::token(TokenKind
::Literal(lit
), DUMMY_SP
),
451 tokens
.push(TokenTree
::Delimited(
454 tts
.into_iter().collect
::<TokenStream
>().into(),