@@ -31,14 +31,14 @@ mod generation {
31
31
32
32
#[ repr( C ) ]
33
33
#[ derive( Copy , Clone , PartialEq , Eq , Debug ) ]
34
- pub ( super ) struct Generation ( usize ) ;
34
+ pub ( super ) struct Generation ( u32 ) ;
35
35
36
36
impl !Send for Generation { }
37
37
impl !Sync for Generation { }
38
38
39
39
impl Generation {
40
40
pub ( super ) extern "C" fn next ( ) -> Self {
41
- thread_local ! ( static NEXT : Cell <usize > = Cell :: new( 0 ) ) ;
41
+ thread_local ! ( static NEXT : Cell <u32 > = Cell :: new( 0 ) ) ;
42
42
NEXT . with ( |next| {
43
43
let gen = next. get ( ) ;
44
44
next. set ( gen. checked_add ( 1 ) . expect ( "Generation::next overflowed counter" ) ) ;
@@ -99,6 +99,12 @@ mod storage {
99
99
}
100
100
}
101
101
102
+ impl < S : ToConcrete < T , U > , T , U > ToConcrete < Option < T > , Option < U > > for S {
103
+ fn to_concrete ( & self , x : Option < T > ) -> Option < U > {
104
+ x. map ( |x| self . to_concrete ( x) )
105
+ }
106
+ }
107
+
102
108
// FIXME(eddyb) achieve ABI compatibility for these types.
103
109
impl < S , T1 , T2 , U1 , U2 > FromConcrete < Result < T1 , T2 > , Result < U1 , U2 > > for S
104
110
where S : FromConcrete < T1 , U1 > + FromConcrete < T2 , U2 >
@@ -184,6 +190,47 @@ mod storage {
184
190
}
185
191
}
186
192
}
193
+
194
+ pub ( super ) trait Pod : Copy { }
195
+ impl Pod for u32 { }
196
+
197
+ #[ repr( C ) ]
198
+ #[ derive( Copy , Clone , PartialEq , Eq ) ]
199
+ pub ( super ) struct Inline < T , R : Pod = u32 > {
200
+ repr : R ,
201
+ gen : Generation ,
202
+ _marker : PhantomData < T > ,
203
+ }
204
+
205
+ impl < T , R : Pod > !Send for Inline < T , R > { }
206
+ impl < T , R : Pod > !Sync for Inline < T , R > { }
207
+
208
+ impl < S , T : Concrete < S > , R : Pod > FromConcrete < T :: Concrete , Inline < T , R > > for Storage < S >
209
+ where T :: Concrete : Copy
210
+ {
211
+ fn from_concrete ( & self , x : T :: Concrete ) -> Inline < T , R > {
212
+ assert_eq ! ( mem:: size_of:: <T :: Concrete >( ) , mem:: size_of:: <R >( ) ) ;
213
+ Inline {
214
+ repr : unsafe {
215
+ mem:: transmute_copy ( & x)
216
+ } ,
217
+ gen : self . gen ,
218
+ _marker : PhantomData ,
219
+ }
220
+ }
221
+ }
222
+
223
+ impl < S , T : Concrete < S > , R : Pod > ToConcrete < Inline < T , R > , T :: Concrete > for Storage < S >
224
+ where T :: Concrete : Copy
225
+ {
226
+ fn to_concrete ( & self , x : Inline < T , R > ) -> T :: Concrete {
227
+ assert_eq ! ( mem:: size_of:: <T :: Concrete >( ) , mem:: size_of:: <R >( ) ) ;
228
+ assert_eq ! ( x. gen , self . gen ) ;
229
+ unsafe {
230
+ mem:: transmute_copy ( & x. repr )
231
+ }
232
+ }
233
+ }
187
234
}
188
235
189
236
storage_concrete_passthrough ! {
@@ -192,10 +239,11 @@ storage_concrete_passthrough! {
192
239
[ ' a] & ' a str ,
193
240
194
241
// FIXME(eddyb) achieve ABI compatibility for these types.
195
- [ ] :: TokenTree ,
196
- [ ] :: Span ,
242
+ [ ] :: TokenNode ,
197
243
[ ] :: Delimiter ,
198
244
[ ] :: LexError ,
245
+ [ ] :: LineColumn ,
246
+ [ ] :: Level ,
199
247
200
248
[ ] PathBuf ,
201
249
// NOTE(eddyb) this will need some `extern "C" fn write`.
@@ -221,16 +269,16 @@ macro_rules! each_frontend_method {
221
269
$meth!( fn token_stream_is_empty( & self , stream: & Self :: TokenStream ) -> bool ; ) ;
222
270
$meth!( fn token_stream_from_str( & self , src: & str )
223
271
-> Result <Self :: TokenStream , :: LexError >; ) ;
224
- $meth!( fn token_stream_delimited( & self , span: :: Span ,
272
+ $meth!( fn token_stream_delimited( & self , span: Self :: Span ,
225
273
delimiter: :: Delimiter ,
226
274
delimed: Self :: TokenStream )
227
275
-> Self :: TokenStream ; ) ;
228
- $meth!( fn token_stream_from_token_tree( & self , tree : :: TokenTree )
276
+ $meth!( fn token_stream_from_token_tree( & self , node : :: TokenNode , span : Self :: Span )
229
277
-> Self :: TokenStream ; ) ;
230
278
$meth!( fn token_stream_to_token_tree( & self , stream: Self :: TokenStream )
231
- -> Result < ( :: TokenTree , Option < Self :: TokenStream > ) ,
232
- ( :: Span , ( :: Delimiter ,
233
- Self :: TokenStream ) ) > ; ) ;
279
+ -> ( Self :: Span ,
280
+ Result < ( :: TokenNode , Option < Self :: TokenStream > ) ,
281
+ ( :: Delimiter , Self :: TokenStream ) > ) ; ) ;
234
282
$meth!( fn token_stream_trees( & self , stream: Self :: TokenStream ) -> Self :: TokenCursor ; ) ;
235
283
236
284
$meth!( fn token_stream_builder_cleanup( & self , _builder: Self :: TokenStreamBuilder ) -> ( ) { } ) ;
@@ -256,7 +304,25 @@ macro_rules! each_frontend_method {
256
304
$meth!( fn source_file_path( & self , file: & Self :: SourceFile ) -> PathBuf ; ) ;
257
305
$meth!( fn source_file_is_real( & self , file: & Self :: SourceFile ) -> bool ; ) ;
258
306
259
- $meth!( fn span_source_file( & self , span: :: Span ) -> Self :: SourceFile ; ) ;
307
+ $meth!( fn diagnostic_cleanup( & self , _diagnostic: Self :: Diagnostic ) -> ( ) { } ) ;
308
+ $meth!( fn diagnostic_new( & self , level: :: Level , msg: & str , span: Option <Self :: Span >)
309
+ -> Self :: Diagnostic ; ) ;
310
+ $meth!( fn diagnostic_sub( & self , diagnostic: & mut Self :: Diagnostic ,
311
+ level: :: Level , msg: & str , span: Option <Self :: Span >) -> ( ) ; ) ;
312
+ $meth!( fn diagnostic_emit( & self , diagnostic: Self :: Diagnostic ) -> ( ) ; ) ;
313
+
314
+ $meth!( fn span_debug( & self , span: Self :: Span , f: & mut fmt:: Formatter ) -> fmt:: Result {
315
+ fmt:: Debug :: fmt( & span, f)
316
+ } ) ;
317
+ $meth!( fn span_def_site( & self ) -> Self :: Span ; ) ;
318
+ $meth!( fn span_call_site( & self ) -> Self :: Span ; ) ;
319
+ $meth!( fn span_source_file( & self , span: Self :: Span ) -> Self :: SourceFile ; ) ;
320
+ $meth!( fn span_parent( & self , span: Self :: Span ) -> Option <Self :: Span >; ) ;
321
+ $meth!( fn span_source( & self , span: Self :: Span ) -> Self :: Span ; ) ;
322
+ $meth!( fn span_start( & self , span: Self :: Span ) -> :: LineColumn ; ) ;
323
+ $meth!( fn span_end( & self , span: Self :: Span ) -> :: LineColumn ; ) ;
324
+ $meth!( fn span_join( & self , first: Self :: Span , second: Self :: Span ) -> Option <Self :: Span >; ) ;
325
+ $meth!( fn span_resolved_at( & self , span: Self :: Span , at: Self :: Span ) -> Self :: Span ; ) ;
260
326
}
261
327
}
262
328
@@ -268,6 +334,9 @@ pub trait FrontendInterface {
268
334
type TokenStreamBuilder : ' static ;
269
335
type TokenCursor : ' static + Clone ;
270
336
type SourceFile : ' static + Clone ;
337
+ type Diagnostic : ' static ;
338
+ /// NB. has to be the same size as u32.
339
+ type Span : ' static + Copy + Eq + fmt:: Debug ;
271
340
each_frontend_method ! ( define_frontend_trait_method) ;
272
341
}
273
342
@@ -328,6 +397,9 @@ define_boxed! {
328
397
} ,
329
398
SourceFile {
330
399
cleanup: source_file_cleanup
400
+ } ,
401
+ Diagnostic {
402
+ cleanup: diagnostic_cleanup
331
403
}
332
404
}
333
405
@@ -361,6 +433,41 @@ impl Clone for SourceFile {
361
433
}
362
434
}
363
435
436
+ macro_rules! define_inline {
437
+ ( $( $name: ident) ,* ) => {
438
+ $(
439
+ #[ repr( C ) ]
440
+ #[ derive( Copy , Clone , PartialEq , Eq ) ]
441
+ pub ( crate ) struct $name( storage:: Inline <$name>) ;
442
+ impl <F : FrontendInterface > storage:: Concrete <F > for $name {
443
+ type Concrete = F :: $name;
444
+ }
445
+ impl <S , T : Copy + ' static > FromConcrete <T , $name> for storage:: Storage <S >
446
+ where $name: storage:: Concrete <S , Concrete = T >
447
+ {
448
+ fn from_concrete( & self , x: T ) -> $name {
449
+ $name( self . from_concrete( x) )
450
+ }
451
+ }
452
+ impl <S , T : Copy + ' static > ToConcrete <$name, T > for storage:: Storage <S >
453
+ where $name: storage:: Concrete <S , Concrete = T >
454
+ {
455
+ fn to_concrete( & self , x: $name) -> T {
456
+ self . to_concrete( x. 0 )
457
+ }
458
+ }
459
+ ) *
460
+ }
461
+ }
462
+
463
+ define_inline ! ( Span ) ;
464
+
465
+ impl fmt:: Debug for Span {
466
+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
467
+ Frontend . span_debug ( * self , f)
468
+ }
469
+ }
470
+
364
471
pub ( crate ) struct Frontend ;
365
472
366
473
macro_rules! define_frontend_current_method {
@@ -376,6 +483,8 @@ impl FrontendInterface for Frontend {
376
483
type TokenStreamBuilder = TokenStreamBuilder ;
377
484
type TokenCursor = TokenCursor ;
378
485
type SourceFile = SourceFile ;
486
+ type Diagnostic = Diagnostic ;
487
+ type Span = Span ;
379
488
each_frontend_method ! ( define_frontend_current_method) ;
380
489
}
381
490
@@ -385,6 +494,8 @@ type CurrentFrontend<'a> = FrontendInterface<
385
494
TokenStreamBuilder = TokenStreamBuilder ,
386
495
TokenCursor = TokenCursor ,
387
496
SourceFile = SourceFile ,
497
+ Diagnostic = Diagnostic ,
498
+ Span = Span ,
388
499
> + ' a ;
389
500
390
501
// Emulate scoped_thread_local!() here essentially
@@ -448,6 +559,8 @@ fn erase_concrete_frontend<F, G, R>(ng: extern "C" fn() -> generation::Generatio
448
559
type TokenStreamBuilder = TokenStreamBuilder ;
449
560
type TokenCursor = TokenCursor ;
450
561
type SourceFile = SourceFile ;
562
+ type Diagnostic = Diagnostic ;
563
+ type Span = Span ;
451
564
each_frontend_method ! ( define_frontend_erase_concrete_method) ;
452
565
}
453
566
0 commit comments