blob: 1292edf5e3b3e441b037770ffe70a23dd2779f25 [file] [log] [blame]
Alex Crichtona914a612018-04-04 07:48:44 -07001#![cfg_attr(not(procmacro2_semver_exempt), allow(dead_code))]
Alex Crichtonaf5bad42018-03-27 14:45:10 -07002
Alex Crichtoncbec8ec2017-06-02 13:19:33 -07003use std::fmt;
4use std::iter;
Alex Crichton30a4e9e2018-04-27 17:02:19 -07005use std::panic;
David Tolnay3d9d6ad2018-05-18 10:51:55 -07006use std::str::FromStr;
Alex Crichtoncbec8ec2017-06-02 13:19:33 -07007
8use proc_macro;
Alex Crichton30a4e9e2018-04-27 17:02:19 -07009use stable;
Alex Crichtoncbec8ec2017-06-02 13:19:33 -070010
Alex Crichtonf3888432018-05-16 09:11:05 -070011use {Delimiter, Group, Punct, Spacing, TokenTree};
Alex Crichtoncbec8ec2017-06-02 13:19:33 -070012
13#[derive(Clone)]
Alex Crichton30a4e9e2018-04-27 17:02:19 -070014pub enum TokenStream {
15 Nightly(proc_macro::TokenStream),
16 Stable(stable::TokenStream),
17}
Alex Crichtoncbec8ec2017-06-02 13:19:33 -070018
Alex Crichton30a4e9e2018-04-27 17:02:19 -070019pub enum LexError {
20 Nightly(proc_macro::LexError),
21 Stable(stable::LexError),
22}
23
24fn nightly_works() -> bool {
25 use std::sync::atomic::*;
26 static WORKS: AtomicUsize = ATOMIC_USIZE_INIT;
27
28 match WORKS.load(Ordering::SeqCst) {
29 1 => return false,
30 2 => return true,
31 _ => {}
32 }
33 let works = panic::catch_unwind(|| proc_macro::Span::call_site()).is_ok();
34 WORKS.store(works as usize + 1, Ordering::SeqCst);
35 works
36}
37
38fn mismatch() -> ! {
39 panic!("stable/nightly mismatch")
40}
Alex Crichtoncbec8ec2017-06-02 13:19:33 -070041
42impl TokenStream {
David Tolnayc3bb4592018-05-28 20:09:44 -070043 pub fn new() -> TokenStream {
Alex Crichton30a4e9e2018-04-27 17:02:19 -070044 if nightly_works() {
David Tolnayc3bb4592018-05-28 20:09:44 -070045 TokenStream::Nightly(proc_macro::TokenStream::new())
Alex Crichton30a4e9e2018-04-27 17:02:19 -070046 } else {
David Tolnayc3bb4592018-05-28 20:09:44 -070047 TokenStream::Stable(stable::TokenStream::new())
Alex Crichton30a4e9e2018-04-27 17:02:19 -070048 }
Alex Crichtoncbec8ec2017-06-02 13:19:33 -070049 }
50
51 pub fn is_empty(&self) -> bool {
Alex Crichton30a4e9e2018-04-27 17:02:19 -070052 match self {
53 TokenStream::Nightly(tts) => tts.is_empty(),
54 TokenStream::Stable(tts) => tts.is_empty(),
55 }
56 }
57
58 fn unwrap_nightly(self) -> proc_macro::TokenStream {
59 match self {
60 TokenStream::Nightly(s) => s,
61 TokenStream::Stable(_) => mismatch(),
62 }
Alex Crichtoncbec8ec2017-06-02 13:19:33 -070063 }
64}
65
66impl FromStr for TokenStream {
67 type Err = LexError;
68
69 fn from_str(src: &str) -> Result<TokenStream, LexError> {
Alex Crichton30a4e9e2018-04-27 17:02:19 -070070 if nightly_works() {
71 Ok(TokenStream::Nightly(src.parse()?))
72 } else {
73 Ok(TokenStream::Stable(src.parse()?))
74 }
Alex Crichtoncbec8ec2017-06-02 13:19:33 -070075 }
76}
77
78impl fmt::Display for TokenStream {
79 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Alex Crichton30a4e9e2018-04-27 17:02:19 -070080 match self {
81 TokenStream::Nightly(tts) => tts.fmt(f),
82 TokenStream::Stable(tts) => tts.fmt(f),
83 }
Alex Crichtoncbec8ec2017-06-02 13:19:33 -070084 }
85}
86
87impl From<proc_macro::TokenStream> for TokenStream {
88 fn from(inner: proc_macro::TokenStream) -> TokenStream {
Alex Crichton30a4e9e2018-04-27 17:02:19 -070089 TokenStream::Nightly(inner)
Alex Crichtoncbec8ec2017-06-02 13:19:33 -070090 }
91}
92
93impl From<TokenStream> for proc_macro::TokenStream {
94 fn from(inner: TokenStream) -> proc_macro::TokenStream {
Alex Crichton30a4e9e2018-04-27 17:02:19 -070095 match inner {
96 TokenStream::Nightly(inner) => inner,
97 TokenStream::Stable(inner) => inner.to_string().parse().unwrap(),
98 }
99 }
100}
101
102impl From<stable::TokenStream> for TokenStream {
103 fn from(inner: stable::TokenStream) -> TokenStream {
104 TokenStream::Stable(inner)
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700105 }
106}
107
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700108impl From<TokenTree> for TokenStream {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700109 fn from(token: TokenTree) -> TokenStream {
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700110 if !nightly_works() {
David Tolnay3d9d6ad2018-05-18 10:51:55 -0700111 return TokenStream::Stable(token.into());
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700112 }
Alex Crichton9cd80a62018-04-05 17:46:58 -0700113 let tt: proc_macro::TokenTree = match token {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700114 TokenTree::Group(tt) => {
115 let delim = match tt.delimiter() {
116 Delimiter::Parenthesis => proc_macro::Delimiter::Parenthesis,
117 Delimiter::Bracket => proc_macro::Delimiter::Bracket,
118 Delimiter::Brace => proc_macro::Delimiter::Brace,
119 Delimiter::None => proc_macro::Delimiter::None,
120 };
Alex Crichton9cd80a62018-04-05 17:46:58 -0700121 let span = tt.span();
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700122 let mut group = proc_macro::Group::new(delim, tt.stream.inner.unwrap_nightly());
123 group.set_span(span.inner.unwrap_nightly());
Alex Crichton9cd80a62018-04-05 17:46:58 -0700124 group.into()
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700125 }
Alex Crichtonf3888432018-05-16 09:11:05 -0700126 TokenTree::Punct(tt) => {
Alex Crichton9cd80a62018-04-05 17:46:58 -0700127 let spacing = match tt.spacing() {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700128 Spacing::Joint => proc_macro::Spacing::Joint,
129 Spacing::Alone => proc_macro::Spacing::Alone,
130 };
Alex Crichtonf3888432018-05-16 09:11:05 -0700131 let mut op = proc_macro::Punct::new(tt.as_char(), spacing);
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700132 op.set_span(tt.span().inner.unwrap_nightly());
Alex Crichton9cd80a62018-04-05 17:46:58 -0700133 op.into()
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700134 }
Alex Crichtonf3888432018-05-16 09:11:05 -0700135 TokenTree::Ident(tt) => tt.inner.unwrap_nightly().into(),
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700136 TokenTree::Literal(tt) => tt.inner.unwrap_nightly().into(),
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700137 };
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700138 TokenStream::Nightly(tt.into())
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700139 }
140}
141
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700142impl iter::FromIterator<TokenTree> for TokenStream {
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700143 fn from_iter<I: IntoIterator<Item = TokenTree>>(trees: I) -> Self {
144 if nightly_works() {
David Tolnay3d9d6ad2018-05-18 10:51:55 -0700145 let trees = trees
146 .into_iter()
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700147 .map(TokenStream::from)
David Tolnay3d9d6ad2018-05-18 10:51:55 -0700148 .flat_map(|t| match t {
149 TokenStream::Nightly(s) => s,
150 TokenStream::Stable(_) => mismatch(),
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700151 });
152 TokenStream::Nightly(trees.collect())
153 } else {
154 TokenStream::Stable(trees.into_iter().collect())
155 }
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700156 }
157}
158
Alex Crichtonf3888432018-05-16 09:11:05 -0700159impl Extend<TokenTree> for TokenStream {
160 fn extend<I: IntoIterator<Item = TokenTree>>(&mut self, streams: I) {
161 match self {
162 TokenStream::Nightly(tts) => {
David Tolnay40d4ffd2018-08-12 13:49:09 -0700163 tts.extend(
164 streams
165 .into_iter()
166 .map(|t| TokenStream::from(t).unwrap_nightly()),
167 );
Alex Crichtonf3888432018-05-16 09:11:05 -0700168 }
169 TokenStream::Stable(tts) => tts.extend(streams),
170 }
171 }
172}
173
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700174impl fmt::Debug for TokenStream {
175 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700176 match self {
177 TokenStream::Nightly(tts) => tts.fmt(f),
178 TokenStream::Stable(tts) => tts.fmt(f),
179 }
180 }
181}
182
183impl From<proc_macro::LexError> for LexError {
184 fn from(e: proc_macro::LexError) -> LexError {
185 LexError::Nightly(e)
186 }
187}
188
189impl From<stable::LexError> for LexError {
190 fn from(e: stable::LexError) -> LexError {
191 LexError::Stable(e)
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700192 }
193}
194
195impl fmt::Debug for LexError {
196 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700197 match self {
198 LexError::Nightly(e) => e.fmt(f),
199 LexError::Stable(e) => e.fmt(f),
200 }
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700201 }
202}
203
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700204pub enum TokenTreeIter {
205 Nightly(proc_macro::token_stream::IntoIter),
206 Stable(stable::TokenTreeIter),
207}
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700208
209impl IntoIterator for TokenStream {
210 type Item = TokenTree;
Alex Crichton1a7f7622017-07-05 17:47:15 -0700211 type IntoIter = TokenTreeIter;
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700212
Alex Crichton1a7f7622017-07-05 17:47:15 -0700213 fn into_iter(self) -> TokenTreeIter {
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700214 match self {
215 TokenStream::Nightly(tts) => TokenTreeIter::Nightly(tts.into_iter()),
216 TokenStream::Stable(tts) => TokenTreeIter::Stable(tts.into_iter()),
217 }
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700218 }
219}
220
Alex Crichton1a7f7622017-07-05 17:47:15 -0700221impl Iterator for TokenTreeIter {
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700222 type Item = TokenTree;
223
224 fn next(&mut self) -> Option<TokenTree> {
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700225 let token = match self {
226 TokenTreeIter::Nightly(iter) => iter.next()?,
227 TokenTreeIter::Stable(iter) => return iter.next(),
228 };
Alex Crichton9cd80a62018-04-05 17:46:58 -0700229 Some(match token {
230 proc_macro::TokenTree::Group(tt) => {
231 let delim = match tt.delimiter() {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700232 proc_macro::Delimiter::Parenthesis => Delimiter::Parenthesis,
233 proc_macro::Delimiter::Bracket => Delimiter::Bracket,
234 proc_macro::Delimiter::Brace => Delimiter::Brace,
235 proc_macro::Delimiter::None => Delimiter::None,
236 };
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700237 let stream = ::TokenStream::_new(TokenStream::Nightly(tt.stream()));
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700238 let mut g = Group::new(delim, stream);
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700239 g.set_span(::Span::_new(Span::Nightly(tt.span())));
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700240 g.into()
241 }
Alex Crichtonf3888432018-05-16 09:11:05 -0700242 proc_macro::TokenTree::Punct(tt) => {
Alex Crichton9cd80a62018-04-05 17:46:58 -0700243 let spacing = match tt.spacing() {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700244 proc_macro::Spacing::Joint => Spacing::Joint,
245 proc_macro::Spacing::Alone => Spacing::Alone,
246 };
Alex Crichtonf3888432018-05-16 09:11:05 -0700247 let mut o = Punct::new(tt.as_char(), spacing);
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700248 o.set_span(::Span::_new(Span::Nightly(tt.span())));
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700249 o.into()
250 }
Alex Crichtonf3888432018-05-16 09:11:05 -0700251 proc_macro::TokenTree::Ident(s) => ::Ident::_new(Ident::Nightly(s)).into(),
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700252 proc_macro::TokenTree::Literal(l) => ::Literal::_new(Literal::Nightly(l)).into(),
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700253 })
254 }
255
256 fn size_hint(&self) -> (usize, Option<usize>) {
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700257 match self {
258 TokenTreeIter::Nightly(tts) => tts.size_hint(),
259 TokenTreeIter::Stable(tts) => tts.size_hint(),
260 }
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700261 }
262}
263
Alex Crichton1a7f7622017-07-05 17:47:15 -0700264impl fmt::Debug for TokenTreeIter {
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700265 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Alex Crichton1a7f7622017-07-05 17:47:15 -0700266 f.debug_struct("TokenTreeIter").finish()
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700267 }
268}
269
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700270pub use stable::FileName;
Nika Layzellb35a9a32017-12-30 14:34:35 -0500271
272// NOTE: We have to generate our own filename object here because we can't wrap
273// the one provided by proc_macro.
274#[derive(Clone, PartialEq, Eq)]
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700275pub enum SourceFile {
276 Nightly(proc_macro::SourceFile, FileName),
277 Stable(stable::SourceFile),
278}
Nika Layzellf8d5f212017-12-11 14:07:02 -0500279
280impl SourceFile {
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700281 fn nightly(sf: proc_macro::SourceFile) -> Self {
Alex Crichton9f0a28a2018-07-21 18:53:35 -0700282 let filename = stable::file_name(sf.path().display().to_string());
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700283 SourceFile::Nightly(sf, filename)
Nika Layzellb35a9a32017-12-30 14:34:35 -0500284 }
285
Nika Layzellf8d5f212017-12-11 14:07:02 -0500286 /// Get the path to this source file as a string.
Nika Layzellb35a9a32017-12-30 14:34:35 -0500287 pub fn path(&self) -> &FileName {
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700288 match self {
289 SourceFile::Nightly(_, f) => f,
290 SourceFile::Stable(a) => a.path(),
291 }
Nika Layzellf8d5f212017-12-11 14:07:02 -0500292 }
293
294 pub fn is_real(&self) -> bool {
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700295 match self {
296 SourceFile::Nightly(a, _) => a.is_real(),
297 SourceFile::Stable(a) => a.is_real(),
298 }
Nika Layzellf8d5f212017-12-11 14:07:02 -0500299 }
300}
301
Nika Layzellb35a9a32017-12-30 14:34:35 -0500302impl AsRef<FileName> for SourceFile {
303 fn as_ref(&self) -> &FileName {
304 self.path()
Nika Layzellf8d5f212017-12-11 14:07:02 -0500305 }
306}
307
308impl fmt::Debug for SourceFile {
309 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700310 match self {
311 SourceFile::Nightly(a, _) => a.fmt(f),
312 SourceFile::Stable(a) => a.fmt(f),
313 }
Nika Layzellf8d5f212017-12-11 14:07:02 -0500314 }
315}
316
Nika Layzell1ecb6ce2017-12-30 14:34:05 -0500317pub struct LineColumn {
318 pub line: usize,
319 pub column: usize,
320}
Nika Layzellf8d5f212017-12-11 14:07:02 -0500321
Alex Crichton9cd80a62018-04-05 17:46:58 -0700322#[derive(Copy, Clone)]
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700323pub enum Span {
324 Nightly(proc_macro::Span),
325 Stable(stable::Span),
Sergio Benitez13805082018-01-04 01:25:45 -0800326}
327
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700328impl Span {
329 pub fn call_site() -> Span {
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700330 if nightly_works() {
331 Span::Nightly(proc_macro::Span::call_site())
332 } else {
333 Span::Stable(stable::Span::call_site())
334 }
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700335 }
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700336
Alex Crichtone6085b72017-11-21 07:24:25 -0800337 pub fn def_site() -> Span {
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700338 if nightly_works() {
339 Span::Nightly(proc_macro::Span::def_site())
340 } else {
341 Span::Stable(stable::Span::def_site())
342 }
Alex Crichton998f6422017-11-19 08:06:27 -0800343 }
Nika Layzellf8d5f212017-12-11 14:07:02 -0500344
David Tolnay4e8e3972018-01-05 18:10:22 -0800345 pub fn resolved_at(&self, other: Span) -> Span {
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700346 match (self, other) {
347 (Span::Nightly(a), Span::Nightly(b)) => Span::Nightly(a.resolved_at(b)),
348 (Span::Stable(a), Span::Stable(b)) => Span::Stable(a.resolved_at(b)),
349 _ => mismatch(),
350 }
David Tolnay4e8e3972018-01-05 18:10:22 -0800351 }
352
353 pub fn located_at(&self, other: Span) -> Span {
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700354 match (self, other) {
355 (Span::Nightly(a), Span::Nightly(b)) => Span::Nightly(a.located_at(b)),
356 (Span::Stable(a), Span::Stable(b)) => Span::Stable(a.located_at(b)),
357 _ => mismatch(),
358 }
David Tolnay4e8e3972018-01-05 18:10:22 -0800359 }
360
David Tolnay16a17202017-12-31 10:47:24 -0500361 pub fn unstable(self) -> proc_macro::Span {
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700362 match self {
363 Span::Nightly(s) => s,
364 Span::Stable(_) => mismatch(),
365 }
David Tolnay16a17202017-12-31 10:47:24 -0500366 }
367
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700368 #[cfg(procmacro2_semver_exempt)]
Nika Layzellf8d5f212017-12-11 14:07:02 -0500369 pub fn source_file(&self) -> SourceFile {
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700370 match self {
371 Span::Nightly(s) => SourceFile::nightly(s.source_file()),
372 Span::Stable(s) => SourceFile::Stable(s.source_file()),
373 }
Nika Layzellf8d5f212017-12-11 14:07:02 -0500374 }
375
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700376 #[cfg(procmacro2_semver_exempt)]
Nika Layzellf8d5f212017-12-11 14:07:02 -0500377 pub fn start(&self) -> LineColumn {
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700378 match self {
379 Span::Nightly(s) => {
380 let proc_macro::LineColumn { line, column } = s.start();
381 LineColumn { line, column }
382 }
383 Span::Stable(s) => {
384 let stable::LineColumn { line, column } = s.start();
385 LineColumn { line, column }
386 }
387 }
Nika Layzellf8d5f212017-12-11 14:07:02 -0500388 }
389
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700390 #[cfg(procmacro2_semver_exempt)]
Nika Layzellf8d5f212017-12-11 14:07:02 -0500391 pub fn end(&self) -> LineColumn {
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700392 match self {
393 Span::Nightly(s) => {
394 let proc_macro::LineColumn { line, column } = s.end();
395 LineColumn { line, column }
396 }
397 Span::Stable(s) => {
398 let stable::LineColumn { line, column } = s.end();
399 LineColumn { line, column }
400 }
401 }
Nika Layzellf8d5f212017-12-11 14:07:02 -0500402 }
403
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700404 #[cfg(procmacro2_semver_exempt)]
Nika Layzellf8d5f212017-12-11 14:07:02 -0500405 pub fn join(&self, other: Span) -> Option<Span> {
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700406 let ret = match (self, other) {
407 (Span::Nightly(a), Span::Nightly(b)) => Span::Nightly(a.join(b)?),
408 (Span::Stable(a), Span::Stable(b)) => Span::Stable(a.join(b)?),
409 _ => return None,
410 };
411 Some(ret)
Nika Layzellf8d5f212017-12-11 14:07:02 -0500412 }
Alex Crichtone24f7342018-04-05 17:58:11 -0700413
414 pub fn eq(&self, other: &Span) -> bool {
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700415 match (self, other) {
416 (Span::Nightly(a), Span::Nightly(b)) => a.eq(b),
417 (Span::Stable(a), Span::Stable(b)) => a.eq(b),
418 _ => false,
419 }
420 }
421
422 fn unwrap_nightly(self) -> proc_macro::Span {
423 match self {
424 Span::Nightly(s) => s,
425 Span::Stable(_) => mismatch(),
426 }
427 }
428}
429
430impl From<proc_macro::Span> for ::Span {
431 fn from(proc_span: proc_macro::Span) -> ::Span {
432 ::Span::_new(Span::Nightly(proc_span))
433 }
434}
435
436impl From<stable::Span> for Span {
437 fn from(inner: stable::Span) -> Span {
438 Span::Stable(inner)
Alex Crichtone24f7342018-04-05 17:58:11 -0700439 }
Alex Crichton998f6422017-11-19 08:06:27 -0800440}
441
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700442impl fmt::Debug for Span {
443 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700444 match self {
445 Span::Nightly(s) => s.fmt(f),
446 Span::Stable(s) => s.fmt(f),
447 }
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700448 }
449}
450
Alex Crichtonf3888432018-05-16 09:11:05 -0700451#[derive(Clone)]
452pub enum Ident {
453 Nightly(proc_macro::Ident),
454 Stable(stable::Ident),
Alex Crichtonb2c94622018-04-04 07:36:41 -0700455}
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700456
Alex Crichtonf3888432018-05-16 09:11:05 -0700457impl Ident {
458 pub fn new(string: &str, span: Span) -> Ident {
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700459 match span {
Alex Crichtonf3888432018-05-16 09:11:05 -0700460 Span::Nightly(s) => Ident::Nightly(proc_macro::Ident::new(string, s)),
461 Span::Stable(s) => Ident::Stable(stable::Ident::new(string, s)),
Alex Crichtonb2c94622018-04-04 07:36:41 -0700462 }
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700463 }
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700464
Alex Crichtonf3888432018-05-16 09:11:05 -0700465 pub fn new_raw(string: &str, span: Span) -> Ident {
466 match span {
467 Span::Nightly(s) => Ident::Nightly(proc_macro::Ident::new_raw(string, s)),
468 Span::Stable(s) => Ident::Stable(stable::Ident::new_raw(string, s)),
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700469 }
Alex Crichtonb2c94622018-04-04 07:36:41 -0700470 }
471
472 pub fn span(&self) -> Span {
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700473 match self {
Alex Crichtonf3888432018-05-16 09:11:05 -0700474 Ident::Nightly(t) => Span::Nightly(t.span()),
475 Ident::Stable(t) => Span::Stable(t.span()),
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700476 }
Alex Crichtonb2c94622018-04-04 07:36:41 -0700477 }
478
479 pub fn set_span(&mut self, span: Span) {
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700480 match (self, span) {
Alex Crichtonf3888432018-05-16 09:11:05 -0700481 (Ident::Nightly(t), Span::Nightly(s)) => t.set_span(s),
482 (Ident::Stable(t), Span::Stable(s)) => t.set_span(s),
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700483 _ => mismatch(),
484 }
485 }
486
Alex Crichtonf3888432018-05-16 09:11:05 -0700487 fn unwrap_nightly(self) -> proc_macro::Ident {
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700488 match self {
Alex Crichtonf3888432018-05-16 09:11:05 -0700489 Ident::Nightly(s) => s,
490 Ident::Stable(_) => mismatch(),
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700491 }
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700492 }
493}
494
Alex Crichtonf3888432018-05-16 09:11:05 -0700495impl fmt::Display for Ident {
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700496 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700497 match self {
Alex Crichtonf3888432018-05-16 09:11:05 -0700498 Ident::Nightly(t) => t.fmt(f),
499 Ident::Stable(t) => t.fmt(f),
500 }
501 }
502}
503
504impl fmt::Debug for Ident {
505 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
506 match self {
507 Ident::Nightly(t) => t.fmt(f),
508 Ident::Stable(t) => t.fmt(f),
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700509 }
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700510 }
511}
512
513#[derive(Clone)]
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700514pub enum Literal {
515 Nightly(proc_macro::Literal),
516 Stable(stable::Literal),
Alex Crichtonb2c94622018-04-04 07:36:41 -0700517}
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700518
Alex Crichtona914a612018-04-04 07:48:44 -0700519macro_rules! suffixed_numbers {
520 ($($name:ident => $kind:ident,)*) => ($(
521 pub fn $name(n: $kind) -> Literal {
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700522 if nightly_works() {
523 Literal::Nightly(proc_macro::Literal::$name(n))
524 } else {
525 Literal::Stable(stable::Literal::$name(n))
526 }
Alex Crichtona914a612018-04-04 07:48:44 -0700527 }
528 )*)
529}
530
531macro_rules! unsuffixed_integers {
532 ($($name:ident => $kind:ident,)*) => ($(
533 pub fn $name(n: $kind) -> Literal {
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700534 if nightly_works() {
535 Literal::Nightly(proc_macro::Literal::$name(n))
536 } else {
537 Literal::Stable(stable::Literal::$name(n))
538 }
Alex Crichtona914a612018-04-04 07:48:44 -0700539 }
540 )*)
541}
542
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700543impl Literal {
Alex Crichtona914a612018-04-04 07:48:44 -0700544 suffixed_numbers! {
545 u8_suffixed => u8,
546 u16_suffixed => u16,
547 u32_suffixed => u32,
548 u64_suffixed => u64,
549 usize_suffixed => usize,
550 i8_suffixed => i8,
551 i16_suffixed => i16,
552 i32_suffixed => i32,
553 i64_suffixed => i64,
554 isize_suffixed => isize,
555
556 f32_suffixed => f32,
557 f64_suffixed => f64,
558 }
559
560 unsuffixed_integers! {
561 u8_unsuffixed => u8,
562 u16_unsuffixed => u16,
563 u32_unsuffixed => u32,
564 u64_unsuffixed => u64,
565 usize_unsuffixed => usize,
566 i8_unsuffixed => i8,
567 i16_unsuffixed => i16,
568 i32_unsuffixed => i32,
569 i64_unsuffixed => i64,
570 isize_unsuffixed => isize,
571 }
572
573 pub fn f32_unsuffixed(f: f32) -> Literal {
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700574 if nightly_works() {
575 Literal::Nightly(proc_macro::Literal::f32_unsuffixed(f))
576 } else {
577 Literal::Stable(stable::Literal::f32_unsuffixed(f))
578 }
Alex Crichtona914a612018-04-04 07:48:44 -0700579 }
580
581 pub fn f64_unsuffixed(f: f64) -> Literal {
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700582 if nightly_works() {
583 Literal::Nightly(proc_macro::Literal::f64_unsuffixed(f))
584 } else {
585 Literal::Stable(stable::Literal::f64_unsuffixed(f))
586 }
Alex Crichtona914a612018-04-04 07:48:44 -0700587 }
588
Alex Crichtona914a612018-04-04 07:48:44 -0700589 pub fn string(t: &str) -> Literal {
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700590 if nightly_works() {
591 Literal::Nightly(proc_macro::Literal::string(t))
592 } else {
593 Literal::Stable(stable::Literal::string(t))
594 }
Alex Crichtona914a612018-04-04 07:48:44 -0700595 }
596
597 pub fn character(t: char) -> Literal {
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700598 if nightly_works() {
599 Literal::Nightly(proc_macro::Literal::character(t))
600 } else {
601 Literal::Stable(stable::Literal::character(t))
602 }
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700603 }
604
605 pub fn byte_string(bytes: &[u8]) -> Literal {
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700606 if nightly_works() {
607 Literal::Nightly(proc_macro::Literal::byte_string(bytes))
608 } else {
609 Literal::Stable(stable::Literal::byte_string(bytes))
610 }
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700611 }
612
Alex Crichtonb2c94622018-04-04 07:36:41 -0700613 pub fn span(&self) -> Span {
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700614 match self {
615 Literal::Nightly(lit) => Span::Nightly(lit.span()),
616 Literal::Stable(lit) => Span::Stable(lit.span()),
617 }
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700618 }
619
Alex Crichtonb2c94622018-04-04 07:36:41 -0700620 pub fn set_span(&mut self, span: Span) {
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700621 match (self, span) {
622 (Literal::Nightly(lit), Span::Nightly(s)) => lit.set_span(s),
623 (Literal::Stable(lit), Span::Stable(s)) => lit.set_span(s),
624 _ => mismatch(),
625 }
626 }
627
628 fn unwrap_nightly(self) -> proc_macro::Literal {
629 match self {
630 Literal::Nightly(s) => s,
631 Literal::Stable(_) => mismatch(),
632 }
633 }
634}
635
636impl From<stable::Literal> for Literal {
637 fn from(s: stable::Literal) -> Literal {
638 Literal::Stable(s)
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700639 }
640}
641
642impl fmt::Display for Literal {
643 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700644 match self {
645 Literal::Nightly(t) => t.fmt(f),
646 Literal::Stable(t) => t.fmt(f),
647 }
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700648 }
649}
650
651impl fmt::Debug for Literal {
652 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700653 match self {
654 Literal::Nightly(t) => t.fmt(f),
655 Literal::Stable(t) => t.fmt(f),
656 }
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700657 }
658}