Skip to content

proc_macro/bridge: send diagnostics over the bridge as a struct #100210

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 1, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 17 additions & 36 deletions compiler/rustc_expand/src/proc_macro_server.rs
Original file line number Diff line number Diff line change
@@ -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;
@@ -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;
@@ -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;
}
@@ -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<'_, '_> {
@@ -577,38 +590,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 {
2 changes: 0 additions & 2 deletions library/proc_macro/src/bridge/client.rs
Original file line number Diff line number Diff line change
@@ -176,8 +176,6 @@ define_handles! {
FreeFunctions,
TokenStream,
SourceFile,
MultiSpan,
Diagnostic,

'interned:
Span,
29 changes: 13 additions & 16 deletions library/proc_macro/src/bridge/mod.rs
Original file line number Diff line number Diff line change
@@ -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);
@@ -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;
@@ -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)]
2 changes: 0 additions & 2 deletions library/proc_macro/src/bridge/server.rs
Original file line number Diff line number Diff line change
@@ -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;
}
21 changes: 7 additions & 14 deletions library/proc_macro/src/diagnostic.rs
Original file line number Diff line number Diff line change
@@ -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
@@ -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)]
@@ -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;
}
@@ -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 {
@@ -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)
@@ -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