blob: c794fc6eba494dfd0f3c89b12f25d487c139e452 [file] [log] [blame]
David Tolnayecd024d2018-07-21 09:07:56 -07001extern crate rustc_data_structures;
2extern crate rustc_target;
3extern crate syntax;
4extern crate syntax_pos;
5
6use std::mem;
7
8use self::rustc_data_structures::sync::Lrc;
David Tolnayc8659922018-08-14 22:40:50 -07009use self::rustc_data_structures::thin_vec::ThinVec;
David Tolnayecd024d2018-07-21 09:07:56 -070010use self::rustc_target::abi::FloatTy;
11use self::rustc_target::spec::abi::Abi;
12use self::syntax::ast::{
David Tolnayae019182019-04-24 03:16:48 -070013 AngleBracketedArgs, AnonConst, Arg, ArgSource, Arm, AsmDialect, AsyncArgument, AttrId,
David Tolnay0db515d2019-05-08 17:58:12 -070014 AttrStyle, Attribute, AwaitOrigin, BareFnTy, BinOpKind, BindingMode, Block, BlockCheckMode,
15 CaptureBy, Constness, Crate, CrateSugar, Defaultness, EnumDef, Expr, ExprKind, Field, FieldPat,
16 FnDecl, FnHeader, ForeignItem, ForeignItemKind, ForeignMod, FunctionRetTy, GenericArg,
17 GenericArgs, GenericBound, GenericParam, GenericParamKind, Generics, GlobalAsm, Guard, Ident,
18 ImplItem, ImplItemKind, ImplPolarity, InlineAsm, InlineAsmOutput, IntTy, IsAsync, IsAuto, Item,
19 ItemKind, Label, Lifetime, LitIntType, LitKind, Local, LocalSource, MacDelimiter, MacStmtStyle,
20 Mac_, MacroDef, MethodSig, Mod, Movability, MutTy, Mutability, NodeId, ParenthesizedArgs, Pat,
David Tolnayae019182019-04-24 03:16:48 -070021 PatKind, Path, PathSegment, PolyTraitRef, QSelf, RangeEnd, RangeLimits, RangeSyntax, Stmt,
22 StmtKind, StrStyle, StructField, TraitBoundModifier, TraitItem, TraitItemKind,
23 TraitObjectSyntax, TraitRef, Ty, TyKind, TypeBinding, UintTy, UnOp, UnsafeSource, Unsafety,
24 UseTree, UseTreeKind, VariantData, Variant_, VisibilityKind, WhereBoundPredicate, WhereClause,
25 WhereEqPredicate, WherePredicate, WhereRegionPredicate,
David Tolnayecd024d2018-07-21 09:07:56 -070026};
David Tolnayecd024d2018-07-21 09:07:56 -070027use self::syntax::parse::lexer::comments;
28use self::syntax::parse::token::{DelimToken, Lit, Token};
29use self::syntax::ptr::P;
David Tolnayd1c31cc2018-08-24 14:47:15 -040030use self::syntax::source_map::Spanned;
David Tolnayecd024d2018-07-21 09:07:56 -070031use self::syntax::symbol::Symbol;
David Tolnay29bfbf32019-01-19 20:59:37 -080032use self::syntax::tokenstream::{DelimSpan, TokenStream, TokenTree};
David Tolnayecd024d2018-07-21 09:07:56 -070033use self::syntax_pos::{Span, SyntaxContext, DUMMY_SP};
34
35pub trait SpanlessEq {
36 fn eq(&self, other: &Self) -> bool;
37}
38
39impl<T: SpanlessEq> SpanlessEq for P<T> {
40 fn eq(&self, other: &Self) -> bool {
41 SpanlessEq::eq(&**self, &**other)
42 }
43}
44
45impl<T: SpanlessEq> SpanlessEq for Lrc<T> {
46 fn eq(&self, other: &Self) -> bool {
47 SpanlessEq::eq(&**self, &**other)
48 }
49}
50
51impl<T: SpanlessEq> SpanlessEq for Option<T> {
52 fn eq(&self, other: &Self) -> bool {
53 match (self, other) {
54 (None, None) => true,
55 (Some(this), Some(other)) => SpanlessEq::eq(this, other),
56 _ => false,
57 }
58 }
59}
60
61impl<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))
64 }
65}
66
67impl<T: SpanlessEq> SpanlessEq for ThinVec<T> {
68 fn eq(&self, other: &Self) -> bool {
David Tolnaye614f282018-10-27 22:50:12 -070069 self.len() == other.len()
70 && self
71 .iter()
72 .zip(other.iter())
73 .all(|(a, b)| SpanlessEq::eq(a, b))
David Tolnayecd024d2018-07-21 09:07:56 -070074 }
75}
76
77impl<T: SpanlessEq> SpanlessEq for Spanned<T> {
78 fn eq(&self, other: &Self) -> bool {
79 SpanlessEq::eq(&self.node, &other.node)
80 }
81}
82
83impl<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)
86 }
87}
88
89impl<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)
94 }
95}
96
97macro_rules! spanless_eq_true {
98 ($name:ident) => {
99 impl SpanlessEq for $name {
100 fn eq(&self, _other: &Self) -> bool {
101 true
102 }
103 }
104 };
105}
106
107spanless_eq_true!(Span);
David Tolnay2b940f62018-09-09 22:16:07 -0700108spanless_eq_true!(DelimSpan);
David Tolnayecd024d2018-07-21 09:07:56 -0700109spanless_eq_true!(AttrId);
110spanless_eq_true!(NodeId);
111spanless_eq_true!(SyntaxContext);
112
113macro_rules! spanless_eq_partial_eq {
114 ($name:ident) => {
115 impl SpanlessEq for $name {
116 fn eq(&self, other: &Self) -> bool {
117 PartialEq::eq(self, other)
118 }
119 }
120 };
121}
122
123spanless_eq_partial_eq!(bool);
124spanless_eq_partial_eq!(u8);
125spanless_eq_partial_eq!(u16);
126spanless_eq_partial_eq!(u128);
127spanless_eq_partial_eq!(usize);
128spanless_eq_partial_eq!(char);
129spanless_eq_partial_eq!(Symbol);
130spanless_eq_partial_eq!(Abi);
131spanless_eq_partial_eq!(DelimToken);
132
133macro_rules! spanless_eq_struct {
134 {
135 $name:ident;
136 $([$field:ident $other:ident])*
137 $(![$ignore:ident])*
138 } => {
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))&&*
144 }
145 }
146 };
147
148 {
149 $name:ident;
150 $([$field:ident $other:ident])*
151 $next:ident
152 $($rest:ident)*
153 $(!$ignore:ident)*
154 } => {
155 spanless_eq_struct! {
156 $name;
157 $([$field $other])*
158 [$next other]
159 $($rest)*
160 $(!$ignore)*
161 }
162 };
163
164 {
165 $name:ident;
166 $([$field:ident $other:ident])*
167 $(![$ignore:ident])*
168 !$next:ident
169 $(!$rest:ident)*
170 } => {
171 spanless_eq_struct! {
172 $name;
173 $([$field $other])*
174 $(![$ignore])*
175 ![$next]
176 $(!$rest)*
177 }
178 };
179}
180
181macro_rules! spanless_eq_enum {
182 {
183 $name:ident;
184 $([$variant:ident $([$field:tt $this:ident $other:ident])*])*
185 } => {
186 impl SpanlessEq for $name {
187 fn eq(&self, other: &Self) -> bool {
188 match self {
189 $(
190 $name::$variant { .. } => {}
191 )*
192 }
David Tolnay83c89012018-09-01 18:15:53 -0700193 #[allow(unreachable_patterns)]
David Tolnayecd024d2018-07-21 09:07:56 -0700194 match (self, other) {
195 $(
196 (
197 $name::$variant { $($field: $this),* },
198 $name::$variant { $($field: $other),* },
199 ) => {
200 true $(&& SpanlessEq::eq($this, $other))*
201 }
202 )*
203 _ => false,
204 }
205 }
206 }
207 };
208
209 {
210 $name:ident;
211 $([$variant:ident $($fields:tt)*])*
212 $next:ident [$($named:tt)*] ( $i:tt $($field:tt)* )
213 $($rest:tt)*
214 } => {
215 spanless_eq_enum! {
216 $name;
217 $([$variant $($fields)*])*
218 $next [$($named)* [$i this other]] ( $($field)* )
219 $($rest)*
220 }
221 };
222
223 {
224 $name:ident;
225 $([$variant:ident $($fields:tt)*])*
226 $next:ident [$($named:tt)*] ()
227 $($rest:tt)*
228 } => {
229 spanless_eq_enum! {
230 $name;
231 $([$variant $($fields)*])*
232 [$next $($named)*]
233 $($rest)*
234 }
235 };
236
237 {
238 $name:ident;
239 $([$variant:ident $($fields:tt)*])*
240 $next:ident ( $($field:tt)* )
241 $($rest:tt)*
242 } => {
243 spanless_eq_enum! {
244 $name;
245 $([$variant $($fields)*])*
246 $next [] ( $($field)* )
247 $($rest)*
248 }
249 };
250
251 {
252 $name:ident;
253 $([$variant:ident $($fields:tt)*])*
254 $next:ident
255 $($rest:tt)*
256 } => {
257 spanless_eq_enum! {
258 $name;
259 $([$variant $($fields)*])*
260 [$next]
261 $($rest)*
262 }
263 };
264}
265
266spanless_eq_struct!(AngleBracketedArgs; span args bindings);
267spanless_eq_struct!(AnonConst; id value);
David Tolnayae019182019-04-24 03:16:48 -0700268spanless_eq_struct!(Arg; ty pat id source);
David Tolnayecd024d2018-07-21 09:07:56 -0700269spanless_eq_struct!(Arm; attrs pats guard body);
David Tolnayb25e1132019-05-02 22:49:12 -0700270spanless_eq_struct!(AsyncArgument; ident arg move_stmt pat_stmt);
David Tolnayecd024d2018-07-21 09:07:56 -0700271spanless_eq_struct!(Attribute; id style path tokens span !is_sugared_doc);
272spanless_eq_struct!(BareFnTy; unsafety abi generic_params decl);
David Tolnay5f5d76a2018-12-29 00:20:35 -0500273spanless_eq_struct!(Block; stmts id rules span);
David Tolnayecd024d2018-07-21 09:07:56 -0700274spanless_eq_struct!(Crate; module attrs span);
David Tolnayecd024d2018-07-21 09:07:56 -0700275spanless_eq_struct!(EnumDef; variants);
276spanless_eq_struct!(Expr; id node span attrs);
277spanless_eq_struct!(Field; ident expr span is_shorthand attrs);
278spanless_eq_struct!(FieldPat; ident pat is_shorthand attrs);
Dan Robertsonb7aa8072019-02-08 18:38:27 +0000279spanless_eq_struct!(FnDecl; inputs output c_variadic);
David Tolnayecd024d2018-07-21 09:07:56 -0700280spanless_eq_struct!(FnHeader; unsafety asyncness constness abi);
281spanless_eq_struct!(ForeignItem; ident attrs node id span vis);
282spanless_eq_struct!(ForeignMod; abi items);
283spanless_eq_struct!(GenericParam; id ident attrs bounds kind);
284spanless_eq_struct!(Generics; params where_clause span);
285spanless_eq_struct!(GlobalAsm; asm ctxt);
286spanless_eq_struct!(ImplItem; id ident vis defaultness attrs generics node span !tokens);
287spanless_eq_struct!(InlineAsm; asm asm_str_style outputs inputs clobbers volatile alignstack dialect ctxt);
288spanless_eq_struct!(InlineAsmOutput; constraint expr is_rw is_indirect);
289spanless_eq_struct!(Item; ident attrs id node vis span !tokens);
290spanless_eq_struct!(Label; ident);
291spanless_eq_struct!(Lifetime; id ident);
David Tolnayae019182019-04-24 03:16:48 -0700292spanless_eq_struct!(Local; pat ty init id span attrs source);
David Tolnayecd024d2018-07-21 09:07:56 -0700293spanless_eq_struct!(Mac_; path delim tts);
294spanless_eq_struct!(MacroDef; tokens legacy);
295spanless_eq_struct!(MethodSig; header decl);
David Tolnay35cb3402018-09-27 22:38:19 -0700296spanless_eq_struct!(Mod; inner items inline);
David Tolnayecd024d2018-07-21 09:07:56 -0700297spanless_eq_struct!(MutTy; ty mutbl);
David Tolnayd54cc9b2019-01-22 21:53:44 -0800298spanless_eq_struct!(ParenthesizedArgs; span inputs output);
David Tolnayecd024d2018-07-21 09:07:56 -0700299spanless_eq_struct!(Pat; id node span);
300spanless_eq_struct!(Path; span segments);
David Tolnay41280d82018-10-27 21:22:02 -0700301spanless_eq_struct!(PathSegment; ident id args);
David Tolnayecd024d2018-07-21 09:07:56 -0700302spanless_eq_struct!(PolyTraitRef; bound_generic_params trait_ref span);
303spanless_eq_struct!(QSelf; ty path_span position);
304spanless_eq_struct!(Stmt; id node span);
305spanless_eq_struct!(StructField; span ident vis id ty attrs);
306spanless_eq_struct!(TraitItem; id ident attrs generics node span !tokens);
307spanless_eq_struct!(TraitRef; path ref_id);
308spanless_eq_struct!(Ty; id node span);
309spanless_eq_struct!(TypeBinding; id ident ty span);
310spanless_eq_struct!(UseTree; prefix kind span);
David Tolnay162a5042019-03-26 08:57:26 -0300311spanless_eq_struct!(Variant_; ident attrs id data disr_expr);
David Tolnayecd024d2018-07-21 09:07:56 -0700312spanless_eq_struct!(WhereBoundPredicate; span bound_generic_params bounded_ty bounds);
313spanless_eq_struct!(WhereClause; id predicates span);
314spanless_eq_struct!(WhereEqPredicate; id span lhs_ty rhs_ty);
315spanless_eq_struct!(WhereRegionPredicate; span lifetime bounds);
David Tolnayae019182019-04-24 03:16:48 -0700316spanless_eq_enum!(ArgSource; Normal AsyncFn(0));
David Tolnayecd024d2018-07-21 09:07:56 -0700317spanless_eq_enum!(AsmDialect; Att Intel);
318spanless_eq_enum!(AttrStyle; Outer Inner);
David Tolnay0db515d2019-05-08 17:58:12 -0700319spanless_eq_enum!(AwaitOrigin; FieldLike MacroLike);
David Tolnayecd024d2018-07-21 09:07:56 -0700320spanless_eq_enum!(BinOpKind; Add Sub Mul Div Rem And Or BitXor BitAnd BitOr Shl Shr Eq Lt Le Ne Ge Gt);
321spanless_eq_enum!(BindingMode; ByRef(0) ByValue(0));
322spanless_eq_enum!(BlockCheckMode; Default Unsafe(0));
323spanless_eq_enum!(CaptureBy; Value Ref);
324spanless_eq_enum!(Constness; Const NotConst);
325spanless_eq_enum!(CrateSugar; PubCrate JustCrate);
326spanless_eq_enum!(Defaultness; Default Final);
327spanless_eq_enum!(FloatTy; F32 F64);
328spanless_eq_enum!(ForeignItemKind; Fn(0 1) Static(0 1) Ty Macro(0));
329spanless_eq_enum!(FunctionRetTy; Default(0) Ty(0));
David Tolnay9f788452019-02-09 16:00:37 +0100330spanless_eq_enum!(GenericArg; Lifetime(0) Type(0) Const(0));
David Tolnayecd024d2018-07-21 09:07:56 -0700331spanless_eq_enum!(GenericArgs; AngleBracketed(0) Parenthesized(0));
332spanless_eq_enum!(GenericBound; Trait(0 1) Outlives(0));
David Tolnay9f788452019-02-09 16:00:37 +0100333spanless_eq_enum!(GenericParamKind; Lifetime Type(default) Const(ty));
David Tolnay83c89012018-09-01 18:15:53 -0700334spanless_eq_enum!(Guard; If(0));
David Tolnay72972e72018-07-21 18:35:24 -0700335spanless_eq_enum!(ImplItemKind; Const(0 1) Method(0 1) Type(0) Existential(0) Macro(0));
David Tolnayecd024d2018-07-21 09:07:56 -0700336spanless_eq_enum!(ImplPolarity; Positive Negative);
337spanless_eq_enum!(IntTy; Isize I8 I16 I32 I64 I128);
David Tolnayae019182019-04-24 03:16:48 -0700338spanless_eq_enum!(IsAsync; Async(closure_id return_impl_trait_id arguments) NotAsync);
David Tolnayecd024d2018-07-21 09:07:56 -0700339spanless_eq_enum!(IsAuto; Yes No);
340spanless_eq_enum!(LitIntType; Signed(0) Unsigned(0) Unsuffixed);
David Tolnayae019182019-04-24 03:16:48 -0700341spanless_eq_enum!(LocalSource; Normal AsyncFn);
David Tolnayecd024d2018-07-21 09:07:56 -0700342spanless_eq_enum!(MacDelimiter; Parenthesis Bracket Brace);
343spanless_eq_enum!(MacStmtStyle; Semicolon Braces NoBraces);
344spanless_eq_enum!(Movability; Static Movable);
345spanless_eq_enum!(Mutability; Mutable Immutable);
346spanless_eq_enum!(RangeEnd; Included(0) Excluded);
347spanless_eq_enum!(RangeLimits; HalfOpen Closed);
David Tolnayecd024d2018-07-21 09:07:56 -0700348spanless_eq_enum!(StmtKind; Local(0) Item(0) Expr(0) Semi(0) Mac(0));
349spanless_eq_enum!(StrStyle; Cooked Raw(0));
David Tolnaya69aa512018-12-14 23:42:26 -0800350spanless_eq_enum!(TokenTree; Token(0 1) Delimited(0 1 2));
David Tolnayecd024d2018-07-21 09:07:56 -0700351spanless_eq_enum!(TraitBoundModifier; None Maybe);
352spanless_eq_enum!(TraitItemKind; Const(0 1) Method(0 1) Type(0 1) Macro(0));
353spanless_eq_enum!(TraitObjectSyntax; Dyn None);
354spanless_eq_enum!(UintTy; Usize U8 U16 U32 U64 U128);
355spanless_eq_enum!(UnOp; Deref Not Neg);
356spanless_eq_enum!(UnsafeSource; CompilerGenerated UserProvided);
357spanless_eq_enum!(Unsafety; Unsafe Normal);
358spanless_eq_enum!(UseTreeKind; Simple(0 1 2) Nested(0) Glob);
David Tolnay162a5042019-03-26 08:57:26 -0300359spanless_eq_enum!(VariantData; Struct(0 1) Tuple(0 1) Unit(0));
David Tolnayecd024d2018-07-21 09:07:56 -0700360spanless_eq_enum!(VisibilityKind; Public Crate(0) Restricted(path id) Inherited);
361spanless_eq_enum!(WherePredicate; BoundPredicate(0) RegionPredicate(0) EqPredicate(0));
362spanless_eq_enum!(ExprKind; Box(0) ObsoleteInPlace(0 1) Array(0) Call(0 1)
363 MethodCall(0 1) Tup(0) Binary(0 1 2) Unary(0 1) Lit(0) Cast(0 1) Type(0 1)
364 If(0 1 2) IfLet(0 1 2 3) While(0 1 2) WhileLet(0 1 2 3) ForLoop(0 1 2 3)
David Tolnay0db515d2019-05-08 17:58:12 -0700365 Loop(0 1) Match(0 1) Closure(0 1 2 3 4 5) Block(0 1) Async(0 1 2) Await(0 1)
366 TryBlock(0) Assign(0 1) AssignOp(0 1 2) Field(0 1) Index(0 1) Range(0 1 2)
367 Path(0 1) AddrOf(0 1) Break(0 1) Continue(0) Ret(0) InlineAsm(0) Mac(0)
368 Struct(0 1 2) Repeat(0 1) Paren(0) Try(0) Yield(0) Err);
David Tolnayecd024d2018-07-21 09:07:56 -0700369spanless_eq_enum!(ItemKind; ExternCrate(0) Use(0) Static(0 1 2) Const(0 1)
David Tolnay72972e72018-07-21 18:35:24 -0700370 Fn(0 1 2 3) Mod(0) ForeignMod(0) GlobalAsm(0) Ty(0 1) Existential(0 1)
371 Enum(0 1) Struct(0 1) Union(0 1) Trait(0 1 2 3 4) TraitAlias(0 1)
372 Impl(0 1 2 3 4 5 6) Mac(0) MacroDef(0));
David Tolnayecd024d2018-07-21 09:07:56 -0700373spanless_eq_enum!(LitKind; Str(0 1) ByteStr(0) Byte(0) Char(0) Int(0 1)
David Tolnay30ccfe32019-01-20 20:41:20 -0800374 Float(0 1) FloatUnsuffixed(0) Bool(0) Err(0));
David Tolnayecd024d2018-07-21 09:07:56 -0700375spanless_eq_enum!(PatKind; Wild Ident(0 1 2) Struct(0 1 2) TupleStruct(0 1 2)
376 Path(0 1) Tuple(0 1) Box(0) Ref(0 1) Lit(0) Range(0 1 2) Slice(0 1 2)
377 Paren(0) Mac(0));
378spanless_eq_enum!(TyKind; Slice(0) Array(0 1) Ptr(0) Rptr(0 1) BareFn(0) Never
379 Tup(0) Path(0 1) TraitObject(0 1) ImplTrait(0 1) Paren(0) Typeof(0) Infer
Dan Robertsonb7aa8072019-02-08 18:38:27 +0000380 ImplicitSelf Mac(0) Err CVarArgs);
David Tolnayecd024d2018-07-21 09:07:56 -0700381
382impl SpanlessEq for Ident {
383 fn eq(&self, other: &Self) -> bool {
384 self.as_str() == other.as_str()
385 }
386}
387
388// Give up on comparing literals inside of macros because there are so many
389// equivalent representations of the same literal; they are tested elsewhere
390impl SpanlessEq for Lit {
391 fn eq(&self, other: &Self) -> bool {
392 mem::discriminant(self) == mem::discriminant(other)
393 }
394}
395
David Tolnayc6b5e812018-07-21 14:04:28 -0700396impl SpanlessEq for RangeSyntax {
397 fn eq(&self, _other: &Self) -> bool {
398 match self {
399 RangeSyntax::DotDotDot | RangeSyntax::DotDotEq => true,
400 }
401 }
402}
403
David Tolnayecd024d2018-07-21 09:07:56 -0700404impl SpanlessEq for Token {
405 fn eq(&self, other: &Self) -> bool {
406 match (self, other) {
407 (Token::Literal(this, _), Token::Literal(other, _)) => SpanlessEq::eq(this, other),
David Tolnayc6b5e812018-07-21 14:04:28 -0700408 (Token::DotDotEq, _) | (Token::DotDotDot, _) => match other {
409 Token::DotDotEq | Token::DotDotDot => true,
410 _ => false,
David Tolnay72972e72018-07-21 18:35:24 -0700411 },
David Tolnayecd024d2018-07-21 09:07:56 -0700412 _ => self == other,
413 }
414 }
415}
416
417impl SpanlessEq for TokenStream {
418 fn eq(&self, other: &Self) -> bool {
419 SpanlessEq::eq(&expand_tts(self), &expand_tts(other))
420 }
421}
422
David Tolnayecd024d2018-07-21 09:07:56 -0700423fn expand_tts(tts: &TokenStream) -> Vec<TokenTree> {
424 let mut tokens = Vec::new();
425 for tt in tts.clone().into_trees() {
426 let c = match tt {
427 TokenTree::Token(_, Token::DocComment(c)) => c,
428 _ => {
429 tokens.push(tt);
430 continue;
431 }
432 };
433 let contents = comments::strip_doc_comment_decoration(&c.as_str());
434 let style = comments::doc_comment_style(&c.as_str());
435 tokens.push(TokenTree::Token(DUMMY_SP, Token::Pound));
436 if style == AttrStyle::Inner {
437 tokens.push(TokenTree::Token(DUMMY_SP, Token::Not));
438 }
439 let lit = Lit::Str_(Symbol::intern(&contents));
David Tolnay44b831c2019-04-24 03:17:50 -0700440 let tts = vec![
David Tolnayecd024d2018-07-21 09:07:56 -0700441 TokenTree::Token(DUMMY_SP, Token::Ident(Ident::from_str("doc"), false)),
442 TokenTree::Token(DUMMY_SP, Token::Eq),
443 TokenTree::Token(DUMMY_SP, Token::Literal(lit, None)),
444 ];
445 tokens.push(TokenTree::Delimited(
David Tolnay2b940f62018-09-09 22:16:07 -0700446 DelimSpan::dummy(),
David Tolnaya69aa512018-12-14 23:42:26 -0800447 DelimToken::Bracket,
448 tts.into_iter().collect::<TokenStream>().into(),
David Tolnayecd024d2018-07-21 09:07:56 -0700449 ));
450 }
451 tokens
452}