@@ -31,14 +31,14 @@ mod generation {
3131
3232 #[ repr( C ) ]
3333 #[ derive( Copy , Clone , PartialEq , Eq , Debug ) ]
34- pub ( super ) struct Generation ( usize ) ;
34+ pub ( super ) struct Generation ( u32 ) ;
3535
3636 impl !Send for Generation { }
3737 impl !Sync for Generation { }
3838
3939 impl Generation {
4040 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 ) ) ;
4242 NEXT . with ( |next| {
4343 let gen = next. get ( ) ;
4444 next. set ( gen. checked_add ( 1 ) . expect ( "Generation::next overflowed counter" ) ) ;
@@ -99,6 +99,12 @@ mod storage {
9999 }
100100 }
101101
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+
102108 // FIXME(eddyb) achieve ABI compatibility for these types.
103109 impl < S , T1 , T2 , U1 , U2 > FromConcrete < Result < T1 , T2 > , Result < U1 , U2 > > for S
104110 where S : FromConcrete < T1 , U1 > + FromConcrete < T2 , U2 >
@@ -184,6 +190,47 @@ mod storage {
184190 }
185191 }
186192 }
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+ }
187234}
188235
189236storage_concrete_passthrough ! {
@@ -192,10 +239,11 @@ storage_concrete_passthrough! {
192239 [ ' a] & ' a str ,
193240
194241 // FIXME(eddyb) achieve ABI compatibility for these types.
195- [ ] :: TokenTree ,
196- [ ] :: Span ,
242+ [ ] :: TokenNode ,
197243 [ ] :: Delimiter ,
198244 [ ] :: LexError ,
245+ [ ] :: LineColumn ,
246+ [ ] :: Level ,
199247
200248 [ ] PathBuf ,
201249 // NOTE(eddyb) this will need some `extern "C" fn write`.
@@ -221,16 +269,16 @@ macro_rules! each_frontend_method {
221269 $meth!( fn token_stream_is_empty( & self , stream: & Self :: TokenStream ) -> bool ; ) ;
222270 $meth!( fn token_stream_from_str( & self , src: & str )
223271 -> Result <Self :: TokenStream , :: LexError >; ) ;
224- $meth!( fn token_stream_delimited( & self , span: :: Span ,
272+ $meth!( fn token_stream_delimited( & self , span: Self :: Span ,
225273 delimiter: :: Delimiter ,
226274 delimed: Self :: TokenStream )
227275 -> 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 )
229277 -> Self :: TokenStream ; ) ;
230278 $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 ) > ) ; ) ;
234282 $meth!( fn token_stream_trees( & self , stream: Self :: TokenStream ) -> Self :: TokenCursor ; ) ;
235283
236284 $meth!( fn token_stream_builder_cleanup( & self , _builder: Self :: TokenStreamBuilder ) -> ( ) { } ) ;
@@ -256,7 +304,25 @@ macro_rules! each_frontend_method {
256304 $meth!( fn source_file_path( & self , file: & Self :: SourceFile ) -> PathBuf ; ) ;
257305 $meth!( fn source_file_is_real( & self , file: & Self :: SourceFile ) -> bool ; ) ;
258306
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 ; ) ;
260326 }
261327}
262328
@@ -268,6 +334,9 @@ pub trait FrontendInterface {
268334 type TokenStreamBuilder : ' static ;
269335 type TokenCursor : ' static + Clone ;
270336 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 ;
271340 each_frontend_method ! ( define_frontend_trait_method) ;
272341}
273342
@@ -328,6 +397,9 @@ define_boxed! {
328397 } ,
329398 SourceFile {
330399 cleanup: source_file_cleanup
400+ } ,
401+ Diagnostic {
402+ cleanup: diagnostic_cleanup
331403 }
332404}
333405
@@ -361,6 +433,41 @@ impl Clone for SourceFile {
361433 }
362434}
363435
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+
364471pub ( crate ) struct Frontend ;
365472
366473macro_rules! define_frontend_current_method {
@@ -376,6 +483,8 @@ impl FrontendInterface for Frontend {
376483 type TokenStreamBuilder = TokenStreamBuilder ;
377484 type TokenCursor = TokenCursor ;
378485 type SourceFile = SourceFile ;
486+ type Diagnostic = Diagnostic ;
487+ type Span = Span ;
379488 each_frontend_method ! ( define_frontend_current_method) ;
380489}
381490
@@ -385,6 +494,8 @@ type CurrentFrontend<'a> = FrontendInterface<
385494 TokenStreamBuilder = TokenStreamBuilder ,
386495 TokenCursor = TokenCursor ,
387496 SourceFile = SourceFile ,
497+ Diagnostic = Diagnostic ,
498+ Span = Span ,
388499> + ' a ;
389500
390501// Emulate scoped_thread_local!() here essentially
@@ -448,6 +559,8 @@ fn erase_concrete_frontend<F, G, R>(ng: extern "C" fn() -> generation::Generatio
448559 type TokenStreamBuilder = TokenStreamBuilder ;
449560 type TokenCursor = TokenCursor ;
450561 type SourceFile = SourceFile ;
562+ type Diagnostic = Diagnostic ;
563+ type Span = Span ;
451564 each_frontend_method ! ( define_frontend_erase_concrete_method) ;
452565 }
453566
0 commit comments