mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-28 03:07:24 +03:00
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`.
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
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::{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 @@ fn literal_from_str(&mut self, s: &str) -> Result<Literal<Self::Span, Self::Symb
|
||||
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 @@ fn is_real(&mut self, file: &Self::SourceFile) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
|
||||
@@ -176,8 +176,6 @@ fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
|
||||
FreeFunctions,
|
||||
TokenStream,
|
||||
SourceFile,
|
||||
MultiSpan,
|
||||
Diagnostic,
|
||||
|
||||
'interned:
|
||||
Span,
|
||||
|
||||
@@ -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 @@ fn into_trees(
|
||||
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 @@ enum TokenTree<TokenStream, Span, Symbol> {
|
||||
}
|
||||
);
|
||||
|
||||
#[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)]
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -161,22 +161,15 @@ pub fn children(&self) -> Children<'_> {
|
||||
/// 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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 @@ fn literal_from_str(
|
||||
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 @@ fn is_real(&mut self, _file: &Self::SourceFile) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ fn before(&mut self, _self_: Self::Span) -> Self::Span {
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user