Skip to content

Commit 3939760

Browse files
committed
proc_macro: move Span and Diagnostic to the bridge.
1 parent c05a2b2 commit 3939760

File tree

5 files changed

+256
-110
lines changed

5 files changed

+256
-110
lines changed

src/libproc_macro/bridge.rs

Lines changed: 123 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -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

189236
storage_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+
364471
pub(crate) struct Frontend;
365472

366473
macro_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

src/libproc_macro/diagnostic.rs

Lines changed: 7 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use Span;
12-
13-
use rustc_errors as rustc;
11+
use {Frontend, FrontendInterface, Span};
1412

1513
/// An enum representing a diagnostic level.
1614
#[unstable(feature = "proc_macro", issue = "38356")]
@@ -97,38 +95,12 @@ impl Diagnostic {
9795
/// Emit the diagnostic.
9896
#[unstable(feature = "proc_macro", issue = "38356")]
9997
pub fn emit(self) {
100-
::__internal::with_sess(move |(sess, _)| {
101-
let handler = &sess.span_diagnostic;
102-
let level = __internal::level_to_internal_level(self.level);
103-
let mut diag = rustc::DiagnosticBuilder::new(handler, level, &*self.message);
104-
105-
if let Some(span) = self.span {
106-
diag.set_span(span.0);
107-
}
108-
109-
for child in self.children {
110-
let span = child.span.map(|s| s.0);
111-
let level = __internal::level_to_internal_level(child.level);
112-
diag.sub(level, &*child.message, span);
113-
}
114-
115-
diag.emit();
116-
});
117-
}
118-
}
119-
120-
#[unstable(feature = "proc_macro_internals", issue = "27812")]
121-
#[doc(hidden)]
122-
pub mod __internal {
123-
use super::{Level, rustc};
124-
125-
pub fn level_to_internal_level(level: Level) -> rustc::Level {
126-
match level {
127-
Level::Error => rustc::Level::Error,
128-
Level::Warning => rustc::Level::Warning,
129-
Level::Note => rustc::Level::Note,
130-
Level::Help => rustc::Level::Help,
131-
Level::__Nonexhaustive => unreachable!("Level::__Nonexhaustive")
98+
let span = self.span.map(|s| s.0);
99+
let mut diag = Frontend.diagnostic_new(self.level, &self.message[..], span);
100+
for child in self.children {
101+
let span = child.span.map(|s| s.0);
102+
Frontend.diagnostic_sub(&mut diag, child.level, &child.message[..], span);
132103
}
104+
Frontend.diagnostic_emit(diag);
133105
}
134106
}

0 commit comments

Comments
 (0)