Skip to content

Commit

Permalink
Auto merge of #100210 - mystor:proc_macro_diag_struct, r=eddyb
Browse files Browse the repository at this point in the history
proc_macro/bridge: send diagnostics over the bridge as a struct

This removes some RPC when creating and emitting diagnostics, and
simplifies the bridge slightly.

After this change, there are no remaining methods which take advantage
of the support for `&mut` references to objects in the store as
arguments, meaning that support for them could technically be removed if
we wanted. The only remaining uses of immutable references into the
store are `TokenStream` and `SourceFile`.

r? `@eddyb`
  • Loading branch information
bors committed Sep 1, 2022
2 parents db00199 + 1c7c792 commit 3892b70
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 125 deletions.
53 changes: 17 additions & 36 deletions compiler/rustc_expand/src/proc_macro_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use rustc_ast::tokenstream::{self, Spacing::*, TokenStream};
use rustc_ast_pretty::pprust;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::sync::Lrc;
use rustc_errors::{Diagnostic, MultiSpan, PResult};
use rustc_errors::{MultiSpan, PResult};
use rustc_parse::lexer::nfc_normalize;
use rustc_parse::parse_stream_from_source_str;
use rustc_session::parse::ParseSess;
Expand All @@ -15,7 +15,7 @@ use rustc_span::symbol::{self, sym, Symbol};
use rustc_span::{BytePos, FileName, Pos, SourceFile, Span};

use pm::bridge::{
server, DelimSpan, ExpnGlobals, Group, Ident, LitKind, Literal, Punct, TokenTree,
server, DelimSpan, Diagnostic, ExpnGlobals, Group, Ident, LitKind, Literal, Punct, TokenTree,
};
use pm::{Delimiter, Level, LineColumn};
use std::ops::Bound;
Expand Down Expand Up @@ -368,8 +368,6 @@ impl server::Types for Rustc<'_, '_> {
type FreeFunctions = FreeFunctions;
type TokenStream = TokenStream;
type SourceFile = Lrc<SourceFile>;
type MultiSpan = Vec<Span>;
type Diagnostic = Diagnostic;
type Span = Span;
type Symbol = Symbol;
}
Expand Down Expand Up @@ -436,6 +434,21 @@ impl server::FreeFunctions for Rustc<'_, '_> {
span: self.call_site,
})
}

fn emit_diagnostic(&mut self, diagnostic: Diagnostic<Self::Span>) {
let mut diag =
rustc_errors::Diagnostic::new(diagnostic.level.to_internal(), diagnostic.message);
diag.set_span(MultiSpan::from_spans(diagnostic.spans));
for child in diagnostic.children {
diag.sub(
child.level.to_internal(),
child.message,
MultiSpan::from_spans(child.spans),
None,
);
}
self.sess().span_diagnostic.emit_diagnostic(&mut diag);
}
}

impl server::TokenStream for Rustc<'_, '_> {
Expand Down Expand Up @@ -583,38 +596,6 @@ impl server::SourceFile for Rustc<'_, '_> {
}
}

impl server::MultiSpan for Rustc<'_, '_> {
fn new(&mut self) -> Self::MultiSpan {
vec![]
}

fn push(&mut self, spans: &mut Self::MultiSpan, span: Self::Span) {
spans.push(span)
}
}

impl server::Diagnostic for Rustc<'_, '_> {
fn new(&mut self, level: Level, msg: &str, spans: Self::MultiSpan) -> Self::Diagnostic {
let mut diag = Diagnostic::new(level.to_internal(), msg);
diag.set_span(MultiSpan::from_spans(spans));
diag
}

fn sub(
&mut self,
diag: &mut Self::Diagnostic,
level: Level,
msg: &str,
spans: Self::MultiSpan,
) {
diag.sub(level.to_internal(), msg, MultiSpan::from_spans(spans), None);
}

fn emit(&mut self, mut diag: Self::Diagnostic) {
self.sess().span_diagnostic.emit_diagnostic(&mut diag);
}
}

impl server::Span for Rustc<'_, '_> {
fn debug(&mut self, span: Self::Span) -> String {
if self.ecx.ecfg.span_debug {
Expand Down
2 changes: 0 additions & 2 deletions library/proc_macro/src/bridge/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,8 +176,6 @@ define_handles! {
FreeFunctions,
TokenStream,
SourceFile,
MultiSpan,
Diagnostic,

'interned:
Span,
Expand Down
29 changes: 13 additions & 16 deletions library/proc_macro/src/bridge/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ macro_rules! with_api {
fn track_env_var(var: &str, value: Option<&str>);
fn track_path(path: &str);
fn literal_from_str(s: &str) -> Result<Literal<$S::Span, $S::Symbol>, ()>;
fn emit_diagnostic(diagnostic: Diagnostic<$S::Span>);
},
TokenStream {
fn drop($self: $S::TokenStream);
Expand Down Expand Up @@ -87,22 +88,6 @@ macro_rules! with_api {
fn path($self: &$S::SourceFile) -> String;
fn is_real($self: &$S::SourceFile) -> bool;
},
MultiSpan {
fn drop($self: $S::MultiSpan);
fn new() -> $S::MultiSpan;
fn push($self: &mut $S::MultiSpan, span: $S::Span);
},
Diagnostic {
fn drop($self: $S::Diagnostic);
fn new(level: Level, msg: &str, span: $S::MultiSpan) -> $S::Diagnostic;
fn sub(
$self: &mut $S::Diagnostic,
level: Level,
msg: &str,
span: $S::MultiSpan,
);
fn emit($self: $S::Diagnostic);
},
Span {
fn debug($self: $S::Span) -> String;
fn source_file($self: $S::Span) -> $S::SourceFile;
Expand Down Expand Up @@ -510,6 +495,18 @@ compound_traits!(
}
);

#[derive(Clone, Debug)]
pub struct Diagnostic<Span> {
pub level: Level,
pub message: String,
pub spans: Vec<Span>,
pub children: Vec<Diagnostic<Span>>,
}

compound_traits!(
struct Diagnostic<Span> { level, message, spans, children }
);

/// Globals provided alongside the initial inputs for a macro expansion.
/// Provides values such as spans which are used frequently to avoid RPC.
#[derive(Clone)]
Expand Down
2 changes: 0 additions & 2 deletions library/proc_macro/src/bridge/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ pub trait Types {
type FreeFunctions: 'static;
type TokenStream: 'static + Clone;
type SourceFile: 'static + Clone;
type MultiSpan: 'static;
type Diagnostic: 'static;
type Span: 'static + Copy + Eq + Hash;
type Symbol: 'static;
}
Expand Down
21 changes: 7 additions & 14 deletions library/proc_macro/src/diagnostic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,22 +161,15 @@ impl Diagnostic {
/// Emit the diagnostic.
#[unstable(feature = "proc_macro_diagnostic", issue = "54140")]
pub fn emit(self) {
fn to_internal(spans: Vec<Span>) -> crate::bridge::client::MultiSpan {
let mut multi_span = crate::bridge::client::MultiSpan::new();
for span in spans {
multi_span.push(span.0);
fn to_internal(diag: Diagnostic) -> crate::bridge::Diagnostic<crate::bridge::client::Span> {
crate::bridge::Diagnostic {
level: diag.level,
message: diag.message,
spans: diag.spans.into_iter().map(|s| s.0).collect(),
children: diag.children.into_iter().map(to_internal).collect(),
}
multi_span
}

let mut diag = crate::bridge::client::Diagnostic::new(
self.level,
&self.message[..],
to_internal(self.spans),
);
for c in self.children {
diag.sub(c.level, &c.message[..], to_internal(c.spans));
}
diag.emit();
crate::bridge::client::FreeFunctions::emit_diagnostic(to_internal(self));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,23 +37,6 @@ pub struct SourceFile {
type Level = super::proc_macro::Level;
type LineColumn = super::proc_macro::LineColumn;

/// A structure representing a diagnostic message and associated children
/// messages.
#[derive(Clone, Debug)]
pub struct Diagnostic {
level: Level,
message: String,
spans: Vec<Span>,
children: Vec<Diagnostic>,
}

impl Diagnostic {
/// Creates a new diagnostic with the given `level` and `message`.
pub fn new<T: Into<String>>(level: Level, message: T) -> Diagnostic {
Diagnostic { level, message: message.into(), spans: vec![], children: vec![] }
}
}

pub struct FreeFunctions;

#[derive(Default)]
Expand All @@ -65,8 +48,6 @@ impl server::Types for RustAnalyzer {
type FreeFunctions = FreeFunctions;
type TokenStream = TokenStream;
type SourceFile = SourceFile;
type MultiSpan = Vec<Span>;
type Diagnostic = Diagnostic;
type Span = Span;
type Symbol = Symbol;
}
Expand All @@ -90,6 +71,10 @@ impl server::FreeFunctions for RustAnalyzer {
span: tt::TokenId::unspecified(),
})
}

fn emit_diagnostic(&mut self, _: bridge::Diagnostic<Self::Span>) {
// FIXME handle diagnostic
}
}

impl server::TokenStream for RustAnalyzer {
Expand Down Expand Up @@ -282,30 +267,6 @@ impl server::SourceFile for RustAnalyzer {
}
}

impl server::Diagnostic for RustAnalyzer {
fn new(&mut self, level: Level, msg: &str, spans: Self::MultiSpan) -> Self::Diagnostic {
let mut diag = Diagnostic::new(level, msg);
diag.spans = spans;
diag
}

fn sub(
&mut self,
_diag: &mut Self::Diagnostic,
_level: Level,
_msg: &str,
_spans: Self::MultiSpan,
) {
// FIXME handle diagnostic
//
}

fn emit(&mut self, _diag: Self::Diagnostic) {
// FIXME handle diagnostic
// diag.emit()
}
}

impl server::Span for RustAnalyzer {
fn debug(&mut self, span: Self::Span) -> String {
format!("{:?}", span.0)
Expand Down Expand Up @@ -372,18 +333,6 @@ impl server::Span for RustAnalyzer {
}
}

impl server::MultiSpan for RustAnalyzer {
fn new(&mut self) -> Self::MultiSpan {
// FIXME handle span
vec![]
}

fn push(&mut self, other: &mut Self::MultiSpan, span: Self::Span) {
//TODP
other.push(span)
}
}

impl server::Symbol for RustAnalyzer {
fn normalize_and_validate_ident(&mut self, string: &str) -> Result<Self::Symbol, ()> {
// FIXME: nfc-normalize and validate idents
Expand Down

0 comments on commit 3892b70

Please sign in to comment.