From 321e60bf3429d32c5ab1d03f22e3e4654bc0c388 Mon Sep 17 00:00:00 2001 From: Jhonny Bill Mena Date: Mon, 5 Sep 2022 00:15:50 -0400 Subject: [PATCH 1/7] UPDATE - into_diagnostic to take a Handler instead of a ParseSess Suggested by the team in this Zulip Topic https://rust-lang.zulipchat.com/#narrow/stream/336883-i18n/topic/.23100717.20SessionDiagnostic.20on.20Handler Handler already has almost all the capabilities of ParseSess when it comes to diagnostic emission, in this migration we only needed to add the ability to access source_map from the emitter in order to get a Snippet and the start_point. Not sure if this is the best way to address this gap --- .../rustc_attr/src/session_diagnostics.rs | 18 +++++++++------ compiler/rustc_errors/src/lib.rs | 22 +++++++++++++++++++ .../infer/error_reporting/need_type_info.rs | 14 ++++++------ compiler/rustc_lint/src/errors.rs | 8 +++---- .../src/diagnostics/diagnostic.rs | 2 +- compiler/rustc_metadata/src/errors.rs | 12 +++++----- compiler/rustc_monomorphize/src/errors.rs | 5 +++-- compiler/rustc_parse/src/parser/expr.rs | 5 +++-- compiler/rustc_query_system/src/query/job.rs | 2 +- compiler/rustc_session/src/parse.rs | 6 ++--- compiler/rustc_session/src/session.rs | 6 ++--- compiler/rustc_trait_selection/src/errors.rs | 8 +++---- compiler/rustc_typeck/src/errors.rs | 12 +++++----- .../ui-fulldeps/internal-lints/diagnostics.rs | 22 +++++++++---------- 14 files changed, 85 insertions(+), 57 deletions(-) diff --git a/compiler/rustc_attr/src/session_diagnostics.rs b/compiler/rustc_attr/src/session_diagnostics.rs index 25cd960dbf1d0..f74540e9655bc 100644 --- a/compiler/rustc_attr/src/session_diagnostics.rs +++ b/compiler/rustc_attr/src/session_diagnostics.rs @@ -1,9 +1,11 @@ use std::num::IntErrorKind; use rustc_ast as ast; -use rustc_errors::{error_code, fluent, Applicability, DiagnosticBuilder, ErrorGuaranteed}; +use rustc_errors::{ + error_code, fluent, Applicability, DiagnosticBuilder, ErrorGuaranteed, Handler, +}; use rustc_macros::SessionDiagnostic; -use rustc_session::{parse::ParseSess, SessionDiagnostic}; +use rustc_session::SessionDiagnostic; use rustc_span::{Span, Symbol}; use crate::UnsupportedLiteralReason; @@ -49,9 +51,9 @@ pub(crate) struct UnknownMetaItem<'a> { // Manual implementation to be able to format `expected` items correctly. impl<'a> SessionDiagnostic<'a> for UnknownMetaItem<'_> { - fn into_diagnostic(self, sess: &'a ParseSess) -> DiagnosticBuilder<'a, ErrorGuaranteed> { + fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, ErrorGuaranteed> { let expected = self.expected.iter().map(|name| format!("`{}`", name)).collect::>(); - let mut diag = sess.span_diagnostic.struct_span_err_with_code( + let mut diag = handler.struct_span_err_with_code( self.span, fluent::attr::unknown_meta_item, error_code!(E0541), @@ -207,8 +209,8 @@ pub(crate) struct UnsupportedLiteral { } impl<'a> SessionDiagnostic<'a> for UnsupportedLiteral { - fn into_diagnostic(self, sess: &'a ParseSess) -> DiagnosticBuilder<'a, ErrorGuaranteed> { - let mut diag = sess.span_diagnostic.struct_span_err_with_code( + fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, ErrorGuaranteed> { + let mut diag = handler.struct_span_err_with_code( self.span, match self.reason { UnsupportedLiteralReason::Generic => fluent::attr::unsupported_literal_generic, @@ -223,8 +225,10 @@ impl<'a> SessionDiagnostic<'a> for UnsupportedLiteral { error_code!(E0565), ); if self.is_bytestr { + let start_point = handler.span_start_point_from_emitter(self.span).unwrap_or(self.span); + diag.span_suggestion( - sess.source_map().start_point(self.span), + start_point, fluent::attr::unsupported_literal_suggestion, "", Applicability::MaybeIncorrect, diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 68abdd0bad1ff..af554db301376 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -1098,6 +1098,28 @@ impl Handler { ); std::mem::take(&mut self.inner.borrow_mut().fulfilled_expectations) } + + pub fn span_to_snippet_from_emitter( + &self, + span: rustc_span::Span, + ) -> Option> { + self.inner + .borrow() + .emitter + .source_map() + .map_or_else(|| Option::None, |sm| Some(sm.span_to_snippet(span))) + } + + pub fn span_start_point_from_emitter( + &self, + span: rustc_span::Span, + ) -> Option { + self.inner + .borrow() + .emitter + .source_map() + .map_or_else(|| Option::None, |sm| Some(sm.start_point(span))) + } } impl HandlerInner { diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index 91a05367eee02..44c8084d732d0 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs @@ -341,7 +341,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { multi_suggestions, bad_label, } - .into_diagnostic(&self.tcx.sess.parse_sess), + .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic), TypeAnnotationNeeded::E0283 => AmbigousImpl { span, source_kind, @@ -351,7 +351,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { multi_suggestions, bad_label, } - .into_diagnostic(&self.tcx.sess.parse_sess), + .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic), TypeAnnotationNeeded::E0284 => AmbigousReturn { span, source_kind, @@ -361,7 +361,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { multi_suggestions, bad_label, } - .into_diagnostic(&self.tcx.sess.parse_sess), + .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic), } } @@ -537,7 +537,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { multi_suggestions, bad_label: None, } - .into_diagnostic(&self.tcx.sess.parse_sess), + .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic), TypeAnnotationNeeded::E0283 => AmbigousImpl { span, source_kind, @@ -547,7 +547,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { multi_suggestions, bad_label: None, } - .into_diagnostic(&self.tcx.sess.parse_sess), + .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic), TypeAnnotationNeeded::E0284 => AmbigousReturn { span, source_kind, @@ -557,7 +557,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { multi_suggestions, bad_label: None, } - .into_diagnostic(&self.tcx.sess.parse_sess), + .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic), } } @@ -575,7 +575,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { span, generator_kind: GeneratorKindAsDiagArg(kind), } - .into_diagnostic(&self.tcx.sess.parse_sess) + .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic) } } diff --git a/compiler/rustc_lint/src/errors.rs b/compiler/rustc_lint/src/errors.rs index 606d8bda8aafe..5c183d4091ea9 100644 --- a/compiler/rustc_lint/src/errors.rs +++ b/compiler/rustc_lint/src/errors.rs @@ -1,6 +1,6 @@ -use rustc_errors::{fluent, AddSubdiagnostic, ErrorGuaranteed}; +use rustc_errors::{fluent, AddSubdiagnostic, ErrorGuaranteed, Handler}; use rustc_macros::{SessionDiagnostic, SessionSubdiagnostic}; -use rustc_session::{lint::Level, parse::ParseSess, SessionDiagnostic}; +use rustc_session::{lint::Level, SessionDiagnostic}; use rustc_span::{Span, Symbol}; #[derive(SessionDiagnostic)] @@ -122,9 +122,9 @@ pub struct CheckNameUnknown { impl SessionDiagnostic<'_> for CheckNameUnknown { fn into_diagnostic( self, - sess: &ParseSess, + handler: &Handler, ) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> { - let mut diag = sess.struct_err(fluent::lint::check_name_unknown); + let mut diag = handler.struct_err(fluent::lint::check_name_unknown); diag.code(rustc_errors::error_code!(E0602)); if let Some(suggestion) = self.suggestion { diag.help(fluent::lint::help); diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic.rs b/compiler/rustc_macros/src/diagnostics/diagnostic.rs index 244edec284159..cf1c594552914 100644 --- a/compiler/rustc_macros/src/diagnostics/diagnostic.rs +++ b/compiler/rustc_macros/src/diagnostics/diagnostic.rs @@ -88,7 +88,7 @@ impl<'a> SessionDiagnosticDerive<'a> { { fn into_diagnostic( self, - #sess: &'__session_diagnostic_sess rustc_session::parse::ParseSess + #sess: &'__session_diagnostic_sess rustc_errors::Handler ) -> rustc_errors::DiagnosticBuilder<'__session_diagnostic_sess, G> { use rustc_errors::IntoDiagnosticArg; #implementation diff --git a/compiler/rustc_metadata/src/errors.rs b/compiler/rustc_metadata/src/errors.rs index 18d0248333a51..8378d2b791d00 100644 --- a/compiler/rustc_metadata/src/errors.rs +++ b/compiler/rustc_metadata/src/errors.rs @@ -424,9 +424,9 @@ pub(crate) struct MultipleCandidates { impl SessionDiagnostic<'_> for MultipleCandidates { fn into_diagnostic( self, - sess: &'_ rustc_session::parse::ParseSess, + handler: &'_ rustc_errors::Handler, ) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> { - let mut diag = sess.struct_err(rustc_errors::fluent::metadata::multiple_candidates); + let mut diag = handler.struct_err(rustc_errors::fluent::metadata::multiple_candidates); diag.set_arg("crate_name", self.crate_name); diag.set_arg("flavor", self.flavor); diag.code(error_code!(E0465)); @@ -540,9 +540,9 @@ pub struct InvalidMetadataFiles { impl SessionDiagnostic<'_> for InvalidMetadataFiles { fn into_diagnostic( self, - sess: &'_ rustc_session::parse::ParseSess, + handler: &'_ rustc_errors::Handler, ) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> { - let mut diag = sess.struct_err(rustc_errors::fluent::metadata::invalid_meta_files); + let mut diag = handler.struct_err(rustc_errors::fluent::metadata::invalid_meta_files); diag.set_arg("crate_name", self.crate_name); diag.set_arg("add_info", self.add_info); diag.code(error_code!(E0786)); @@ -568,9 +568,9 @@ pub struct CannotFindCrate { impl SessionDiagnostic<'_> for CannotFindCrate { fn into_diagnostic( self, - sess: &'_ rustc_session::parse::ParseSess, + handler: &'_ rustc_errors::Handler, ) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> { - let mut diag = sess.struct_err(rustc_errors::fluent::metadata::cannot_find_crate); + let mut diag = handler.struct_err(rustc_errors::fluent::metadata::cannot_find_crate); diag.set_arg("crate_name", self.crate_name); diag.set_arg("add_info", self.add_info); diag.set_arg("locator_triple", self.locator_triple.triple()); diff --git a/compiler/rustc_monomorphize/src/errors.rs b/compiler/rustc_monomorphize/src/errors.rs index 77b6cfa1f69f8..d5f05e790d388 100644 --- a/compiler/rustc_monomorphize/src/errors.rs +++ b/compiler/rustc_monomorphize/src/errors.rs @@ -47,9 +47,10 @@ pub struct UnusedGenericParams { impl SessionDiagnostic<'_> for UnusedGenericParams { fn into_diagnostic( self, - sess: &'_ rustc_session::parse::ParseSess, + handler: &'_ rustc_errors::Handler, ) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> { - let mut diag = sess.struct_err(rustc_errors::fluent::monomorphize::unused_generic_params); + let mut diag = + handler.struct_err(rustc_errors::fluent::monomorphize::unused_generic_params); diag.set_span(self.span); for (span, name) in self.param_spans.into_iter().zip(self.param_names) { // FIXME: I can figure out how to do a label with a fluent string with a fixed message, diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index d4828a201207b..7addf519872f0 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1997,7 +1997,7 @@ impl<'a> Parser<'a> { return Err(MissingSemicolonBeforeArray { open_delim: open_delim_span, semicolon: prev_span.shrink_to_hi(), - }.into_diagnostic(self.sess)); + }.into_diagnostic(&self.sess.span_diagnostic)); } Ok(_) => (), Err(err) => err.cancel(), @@ -2745,7 +2745,8 @@ impl<'a> Parser<'a> { fn parse_try_block(&mut self, span_lo: Span) -> PResult<'a, P> { let (attrs, body) = self.parse_inner_attrs_and_block()?; if self.eat_keyword(kw::Catch) { - Err(CatchAfterTry { span: self.prev_token.span }.into_diagnostic(self.sess)) + Err(CatchAfterTry { span: self.prev_token.span } + .into_diagnostic(&self.sess.span_diagnostic)) } else { let span = span_lo.to(body.span); self.sess.gated_spans.gate(sym::try_blocks, span); diff --git a/compiler/rustc_query_system/src/query/job.rs b/compiler/rustc_query_system/src/query/job.rs index ddb5cd0634407..45b4079fb54f8 100644 --- a/compiler/rustc_query_system/src/query/job.rs +++ b/compiler/rustc_query_system/src/query/job.rs @@ -572,7 +572,7 @@ pub(crate) fn report_cycle<'a>( stack_count, }; - cycle_diag.into_diagnostic(&sess.parse_sess) + cycle_diag.into_diagnostic(&sess.parse_sess.span_diagnostic) } pub fn print_query_stack( diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs index 5b95d73bd4d38..9bc7fbfbe1491 100644 --- a/compiler/rustc_session/src/parse.rs +++ b/compiler/rustc_session/src/parse.rs @@ -343,7 +343,7 @@ impl ParseSess { &'a self, err: impl SessionDiagnostic<'a>, ) -> DiagnosticBuilder<'a, ErrorGuaranteed> { - err.into_diagnostic(self) + err.into_diagnostic(&self.span_diagnostic) } pub fn emit_err<'a>(&'a self, err: impl SessionDiagnostic<'a>) -> ErrorGuaranteed { @@ -354,7 +354,7 @@ impl ParseSess { &'a self, warning: impl SessionDiagnostic<'a, ()>, ) -> DiagnosticBuilder<'a, ()> { - warning.into_diagnostic(self) + warning.into_diagnostic(&self.span_diagnostic) } pub fn emit_warning<'a>(&'a self, warning: impl SessionDiagnostic<'a, ()>) { @@ -365,7 +365,7 @@ impl ParseSess { &'a self, fatal: impl SessionDiagnostic<'a, !>, ) -> DiagnosticBuilder<'a, !> { - fatal.into_diagnostic(self) + fatal.into_diagnostic(&self.span_diagnostic) } pub fn emit_fatal<'a>(&'a self, fatal: impl SessionDiagnostic<'a, !>) -> ! { diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index a49af23be2316..557edad548c64 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -21,7 +21,7 @@ use rustc_errors::json::JsonEmitter; use rustc_errors::registry::Registry; use rustc_errors::{ error_code, fallback_fluent_bundle, DiagnosticBuilder, DiagnosticId, DiagnosticMessage, - EmissionGuarantee, ErrorGuaranteed, FluentBundle, LazyFallbackBundle, MultiSpan, + EmissionGuarantee, ErrorGuaranteed, FluentBundle, Handler, LazyFallbackBundle, MultiSpan, }; use rustc_macros::HashStable_Generic; pub use rustc_span::def_id::StableCrateId; @@ -220,9 +220,9 @@ pub struct PerfStats { /// `#[derive(SessionDiagnostic)]` -- see [rustc_macros::SessionDiagnostic]. #[rustc_diagnostic_item = "SessionDiagnostic"] pub trait SessionDiagnostic<'a, T: EmissionGuarantee = ErrorGuaranteed> { - /// Write out as a diagnostic out of `sess`. + /// Write out as a diagnostic out of `Handler`. #[must_use] - fn into_diagnostic(self, sess: &'a ParseSess) -> DiagnosticBuilder<'a, T>; + fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, T>; } impl Session { diff --git a/compiler/rustc_trait_selection/src/errors.rs b/compiler/rustc_trait_selection/src/errors.rs index 81977f25ca21f..ab0afc545146e 100644 --- a/compiler/rustc_trait_selection/src/errors.rs +++ b/compiler/rustc_trait_selection/src/errors.rs @@ -1,7 +1,7 @@ -use rustc_errors::{fluent, ErrorGuaranteed}; +use rustc_errors::{fluent, ErrorGuaranteed, Handler}; use rustc_macros::SessionDiagnostic; use rustc_middle::ty::{PolyTraitRef, Ty, Unevaluated}; -use rustc_session::{parse::ParseSess, Limit, SessionDiagnostic}; +use rustc_session::{Limit, SessionDiagnostic}; use rustc_span::{Span, Symbol}; #[derive(SessionDiagnostic)] @@ -69,9 +69,9 @@ pub struct NegativePositiveConflict<'a> { impl SessionDiagnostic<'_> for NegativePositiveConflict<'_> { fn into_diagnostic( self, - sess: &ParseSess, + handler: &Handler, ) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> { - let mut diag = sess.struct_err(fluent::trait_selection::negative_positive_conflict); + let mut diag = handler.struct_err(fluent::trait_selection::negative_positive_conflict); diag.set_arg("trait_desc", self.trait_desc); diag.set_arg( "self_desc", diff --git a/compiler/rustc_typeck/src/errors.rs b/compiler/rustc_typeck/src/errors.rs index 14c0558cdde93..bfe03d6257518 100644 --- a/compiler/rustc_typeck/src/errors.rs +++ b/compiler/rustc_typeck/src/errors.rs @@ -1,8 +1,8 @@ //! Errors emitted by typeck. -use rustc_errors::{error_code, Applicability, DiagnosticBuilder, ErrorGuaranteed}; +use rustc_errors::{error_code, Applicability, DiagnosticBuilder, ErrorGuaranteed, Handler}; use rustc_macros::{LintDiagnostic, SessionDiagnostic, SessionSubdiagnostic}; use rustc_middle::ty::Ty; -use rustc_session::{parse::ParseSess, SessionDiagnostic}; +use rustc_session::SessionDiagnostic; use rustc_span::{symbol::Ident, Span, Symbol}; #[derive(SessionDiagnostic)] @@ -250,8 +250,8 @@ pub struct MissingTypeParams { // Manual implementation of `SessionDiagnostic` to be able to call `span_to_snippet`. impl<'a> SessionDiagnostic<'a> for MissingTypeParams { - fn into_diagnostic(self, sess: &'a ParseSess) -> DiagnosticBuilder<'a, ErrorGuaranteed> { - let mut err = sess.span_diagnostic.struct_span_err_with_code( + fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, ErrorGuaranteed> { + let mut err = handler.struct_span_err_with_code( self.span, rustc_errors::fluent::typeck::missing_type_params, error_code!(E0393), @@ -269,8 +269,8 @@ impl<'a> SessionDiagnostic<'a> for MissingTypeParams { err.span_label(self.def_span, rustc_errors::fluent::typeck::label); let mut suggested = false; - if let (Ok(snippet), true) = ( - sess.source_map().span_to_snippet(self.span), + if let (Some(Ok(snippet)), true) = ( + handler.span_to_snippet_from_emitter(self.span), // Don't suggest setting the type params if there are some already: the order is // tricky to get right and the user will already know what the syntax is. self.empty_generic_args, diff --git a/src/test/ui-fulldeps/internal-lints/diagnostics.rs b/src/test/ui-fulldeps/internal-lints/diagnostics.rs index 0e449256153a2..89997585db25f 100644 --- a/src/test/ui-fulldeps/internal-lints/diagnostics.rs +++ b/src/test/ui-fulldeps/internal-lints/diagnostics.rs @@ -11,9 +11,9 @@ extern crate rustc_macros; extern crate rustc_session; extern crate rustc_span; -use rustc_errors::{AddSubdiagnostic, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, fluent}; +use rustc_errors::{AddSubdiagnostic, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, Handler, fluent}; use rustc_macros::{SessionDiagnostic, SessionSubdiagnostic}; -use rustc_session::{parse::ParseSess, SessionDiagnostic}; +use rustc_session::SessionDiagnostic; use rustc_span::Span; #[derive(SessionDiagnostic)] @@ -33,8 +33,8 @@ struct Note { pub struct UntranslatableInSessionDiagnostic; impl<'a> SessionDiagnostic<'a, ErrorGuaranteed> for UntranslatableInSessionDiagnostic { - fn into_diagnostic(self, sess: &'a ParseSess) -> DiagnosticBuilder<'a, ErrorGuaranteed> { - sess.struct_err("untranslatable diagnostic") + fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, ErrorGuaranteed> { + handler.struct_err("untranslatable diagnostic") //~^ ERROR diagnostics should be created using translatable messages } } @@ -42,8 +42,8 @@ impl<'a> SessionDiagnostic<'a, ErrorGuaranteed> for UntranslatableInSessionDiagn pub struct TranslatableInSessionDiagnostic; impl<'a> SessionDiagnostic<'a, ErrorGuaranteed> for TranslatableInSessionDiagnostic { - fn into_diagnostic(self, sess: &'a ParseSess) -> DiagnosticBuilder<'a, ErrorGuaranteed> { - sess.struct_err(fluent::parser::expect_path) + fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, ErrorGuaranteed> { + handler.struct_err(fluent::parser::expect_path) } } @@ -64,11 +64,11 @@ impl AddSubdiagnostic for TranslatableInAddSubdiagnostic { } } -pub fn make_diagnostics<'a>(sess: &'a ParseSess) { - let _diag = sess.struct_err(fluent::parser::expect_path); +pub fn make_diagnostics<'a>(handler: &'a Handler) { + let _diag = handler.struct_err(fluent::parser::expect_path); //~^ ERROR diagnostics should only be created in `SessionDiagnostic`/`AddSubdiagnostic` impls - let _diag = sess.struct_err("untranslatable diagnostic"); + let _diag = handler.struct_err("untranslatable diagnostic"); //~^ ERROR diagnostics should only be created in `SessionDiagnostic`/`AddSubdiagnostic` impls //~^^ ERROR diagnostics should be created using translatable messages } @@ -76,6 +76,6 @@ pub fn make_diagnostics<'a>(sess: &'a ParseSess) { // Check that `rustc_lint_diagnostics`-annotated functions aren't themselves linted. #[rustc_lint_diagnostics] -pub fn skipped_because_of_annotation<'a>(sess: &'a ParseSess) { - let _diag = sess.struct_err("untranslatable diagnostic"); // okay! +pub fn skipped_because_of_annotation<'a>(handler: &'a Handler) { + let _diag = handler.struct_err("untranslatable diagnostic"); // okay! } From 1524b59444109cf71916653d7906e4d41bd4ba6e Mon Sep 17 00:00:00 2001 From: Jhonny Bill Mena Date: Mon, 5 Sep 2022 11:42:48 -0400 Subject: [PATCH 2/7] UPDATE - avoid exposing source_map methods from Handler --- compiler/rustc_attr/src/builtin.rs | 2 +- .../rustc_attr/src/session_diagnostics.rs | 11 +++++----- compiler/rustc_errors/src/lib.rs | 22 ------------------- compiler/rustc_typeck/src/astconv/errors.rs | 1 + compiler/rustc_typeck/src/errors.rs | 11 +++++----- 5 files changed, 13 insertions(+), 34 deletions(-) diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index a8ed510866d89..faba9856f02a5 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -63,7 +63,7 @@ fn handle_errors(sess: &ParseSess, span: Span, error: AttrError) { sess.emit_err(session_diagnostics::MultipleStabilityLevels { span }); } AttrError::UnsupportedLiteral(reason, is_bytestr) => { - sess.emit_err(session_diagnostics::UnsupportedLiteral { span, reason, is_bytestr }); + sess.emit_err(session_diagnostics::UnsupportedLiteral { span, reason, is_bytestr, source_map: sess.source_map() }); } } } diff --git a/compiler/rustc_attr/src/session_diagnostics.rs b/compiler/rustc_attr/src/session_diagnostics.rs index f74540e9655bc..3f5a51fbd838e 100644 --- a/compiler/rustc_attr/src/session_diagnostics.rs +++ b/compiler/rustc_attr/src/session_diagnostics.rs @@ -6,7 +6,7 @@ use rustc_errors::{ }; use rustc_macros::SessionDiagnostic; use rustc_session::SessionDiagnostic; -use rustc_span::{Span, Symbol}; +use rustc_span::{Span, Symbol, source_map::SourceMap}; use crate::UnsupportedLiteralReason; @@ -202,13 +202,14 @@ pub(crate) struct InvalidReprHintNoValue { } // Error code: E0565 -pub(crate) struct UnsupportedLiteral { +pub(crate) struct UnsupportedLiteral<'a> { pub span: Span, pub reason: UnsupportedLiteralReason, pub is_bytestr: bool, + pub source_map: &'a SourceMap, } -impl<'a> SessionDiagnostic<'a> for UnsupportedLiteral { +impl<'a> SessionDiagnostic<'a> for UnsupportedLiteral<'a> { fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, ErrorGuaranteed> { let mut diag = handler.struct_span_err_with_code( self.span, @@ -225,10 +226,8 @@ impl<'a> SessionDiagnostic<'a> for UnsupportedLiteral { error_code!(E0565), ); if self.is_bytestr { - let start_point = handler.span_start_point_from_emitter(self.span).unwrap_or(self.span); - diag.span_suggestion( - start_point, + self.source_map.start_point(self.span), fluent::attr::unsupported_literal_suggestion, "", Applicability::MaybeIncorrect, diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index af554db301376..68abdd0bad1ff 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -1098,28 +1098,6 @@ impl Handler { ); std::mem::take(&mut self.inner.borrow_mut().fulfilled_expectations) } - - pub fn span_to_snippet_from_emitter( - &self, - span: rustc_span::Span, - ) -> Option> { - self.inner - .borrow() - .emitter - .source_map() - .map_or_else(|| Option::None, |sm| Some(sm.span_to_snippet(span))) - } - - pub fn span_start_point_from_emitter( - &self, - span: rustc_span::Span, - ) -> Option { - self.inner - .borrow() - .emitter - .source_map() - .map_or_else(|| Option::None, |sm| Some(sm.start_point(span))) - } } impl HandlerInner { diff --git a/compiler/rustc_typeck/src/astconv/errors.rs b/compiler/rustc_typeck/src/astconv/errors.rs index ff39bf36129bb..1262dd7dcc7fd 100644 --- a/compiler/rustc_typeck/src/astconv/errors.rs +++ b/compiler/rustc_typeck/src/astconv/errors.rs @@ -29,6 +29,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { self.tcx().sess.emit_err(MissingTypeParams { span, def_span: self.tcx().def_span(def_id), + source_map: self.tcx().sess.source_map(), missing_type_params, empty_generic_args, }); diff --git a/compiler/rustc_typeck/src/errors.rs b/compiler/rustc_typeck/src/errors.rs index bfe03d6257518..7b553a46e3b6c 100644 --- a/compiler/rustc_typeck/src/errors.rs +++ b/compiler/rustc_typeck/src/errors.rs @@ -3,7 +3,7 @@ use rustc_errors::{error_code, Applicability, DiagnosticBuilder, ErrorGuaranteed use rustc_macros::{LintDiagnostic, SessionDiagnostic, SessionSubdiagnostic}; use rustc_middle::ty::Ty; use rustc_session::SessionDiagnostic; -use rustc_span::{symbol::Ident, Span, Symbol}; +use rustc_span::{symbol::Ident, Span, Symbol, source_map::SourceMap}; #[derive(SessionDiagnostic)] #[diag(typeck::field_multiply_specified_in_initializer, code = "E0062")] @@ -241,15 +241,16 @@ pub struct UnconstrainedOpaqueType { pub name: Symbol, } -pub struct MissingTypeParams { +pub struct MissingTypeParams<'a> { pub span: Span, pub def_span: Span, pub missing_type_params: Vec, pub empty_generic_args: bool, + pub source_map: &'a SourceMap, } // Manual implementation of `SessionDiagnostic` to be able to call `span_to_snippet`. -impl<'a> SessionDiagnostic<'a> for MissingTypeParams { +impl<'a> SessionDiagnostic<'a> for MissingTypeParams<'a> { fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, ErrorGuaranteed> { let mut err = handler.struct_span_err_with_code( self.span, @@ -269,8 +270,8 @@ impl<'a> SessionDiagnostic<'a> for MissingTypeParams { err.span_label(self.def_span, rustc_errors::fluent::typeck::label); let mut suggested = false; - if let (Some(Ok(snippet)), true) = ( - handler.span_to_snippet_from_emitter(self.span), + if let (Ok(snippet), true) = ( + self.source_map.span_to_snippet(self.span), // Don't suggest setting the type params if there are some already: the order is // tricky to get right and the user will already know what the syntax is. self.empty_generic_args, From 72f766ae716eee2a1ce4dde092817cd404d19a37 Mon Sep 17 00:00:00 2001 From: Jhonny Bill Mena Date: Mon, 5 Sep 2022 12:05:14 -0400 Subject: [PATCH 3/7] FIX - broken translatable diagnostics tests --- .../ui-fulldeps/internal-lints/diagnostics.rs | 4 +++- .../internal-lints/diagnostics.stderr | 24 +++++++++---------- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/test/ui-fulldeps/internal-lints/diagnostics.rs b/src/test/ui-fulldeps/internal-lints/diagnostics.rs index 89997585db25f..e9e809fa41617 100644 --- a/src/test/ui-fulldeps/internal-lints/diagnostics.rs +++ b/src/test/ui-fulldeps/internal-lints/diagnostics.rs @@ -11,7 +11,9 @@ extern crate rustc_macros; extern crate rustc_session; extern crate rustc_span; -use rustc_errors::{AddSubdiagnostic, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, Handler, fluent}; +use rustc_errors::{ + AddSubdiagnostic, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, Handler, fluent +}; use rustc_macros::{SessionDiagnostic, SessionSubdiagnostic}; use rustc_session::SessionDiagnostic; use rustc_span::Span; diff --git a/src/test/ui-fulldeps/internal-lints/diagnostics.stderr b/src/test/ui-fulldeps/internal-lints/diagnostics.stderr index ed5105dabcd3f..53d70c83183a3 100644 --- a/src/test/ui-fulldeps/internal-lints/diagnostics.stderr +++ b/src/test/ui-fulldeps/internal-lints/diagnostics.stderr @@ -1,8 +1,8 @@ error: diagnostics should be created using translatable messages - --> $DIR/diagnostics.rs:37:14 + --> $DIR/diagnostics.rs:37:17 | -LL | sess.struct_err("untranslatable diagnostic") - | ^^^^^^^^^^ +LL | handler.struct_err("untranslatable diagnostic") + | ^^^^^^^^^^ | note: the lint level is defined here --> $DIR/diagnostics.rs:6:9 @@ -17,10 +17,10 @@ LL | diag.note("untranslatable diagnostic"); | ^^^^ error: diagnostics should only be created in `SessionDiagnostic`/`AddSubdiagnostic` impls - --> $DIR/diagnostics.rs:68:22 + --> $DIR/diagnostics.rs:68:25 | -LL | let _diag = sess.struct_err(fluent::parser::expect_path); - | ^^^^^^^^^^ +LL | let _diag = handler.struct_err(fluent::parser::expect_path); + | ^^^^^^^^^^ | note: the lint level is defined here --> $DIR/diagnostics.rs:7:9 @@ -29,16 +29,16 @@ LL | #![deny(rustc::diagnostic_outside_of_impl)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostics should only be created in `SessionDiagnostic`/`AddSubdiagnostic` impls - --> $DIR/diagnostics.rs:71:22 + --> $DIR/diagnostics.rs:71:25 | -LL | let _diag = sess.struct_err("untranslatable diagnostic"); - | ^^^^^^^^^^ +LL | let _diag = handler.struct_err("untranslatable diagnostic"); + | ^^^^^^^^^^ error: diagnostics should be created using translatable messages - --> $DIR/diagnostics.rs:71:22 + --> $DIR/diagnostics.rs:71:25 | -LL | let _diag = sess.struct_err("untranslatable diagnostic"); - | ^^^^^^^^^^ +LL | let _diag = handler.struct_err("untranslatable diagnostic"); + | ^^^^^^^^^^ error: aborting due to 5 previous errors From d14b3af6db3445cdcd7b85090bc3402c1c78c9a1 Mon Sep 17 00:00:00 2001 From: Jhonny Bill Mena Date: Mon, 5 Sep 2022 12:09:10 -0400 Subject: [PATCH 4/7] [Gardening] UPDATE - tidy fixes --- compiler/rustc_attr/src/builtin.rs | 7 ++++++- compiler/rustc_attr/src/session_diagnostics.rs | 2 +- compiler/rustc_typeck/src/errors.rs | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index faba9856f02a5..2c3fc4d9fe660 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -63,7 +63,12 @@ fn handle_errors(sess: &ParseSess, span: Span, error: AttrError) { sess.emit_err(session_diagnostics::MultipleStabilityLevels { span }); } AttrError::UnsupportedLiteral(reason, is_bytestr) => { - sess.emit_err(session_diagnostics::UnsupportedLiteral { span, reason, is_bytestr, source_map: sess.source_map() }); + sess.emit_err(session_diagnostics::UnsupportedLiteral { + span, + reason, + is_bytestr, + source_map: sess.source_map(), + }); } } } diff --git a/compiler/rustc_attr/src/session_diagnostics.rs b/compiler/rustc_attr/src/session_diagnostics.rs index 3f5a51fbd838e..b8942e51306d5 100644 --- a/compiler/rustc_attr/src/session_diagnostics.rs +++ b/compiler/rustc_attr/src/session_diagnostics.rs @@ -6,7 +6,7 @@ use rustc_errors::{ }; use rustc_macros::SessionDiagnostic; use rustc_session::SessionDiagnostic; -use rustc_span::{Span, Symbol, source_map::SourceMap}; +use rustc_span::{source_map::SourceMap, Span, Symbol}; use crate::UnsupportedLiteralReason; diff --git a/compiler/rustc_typeck/src/errors.rs b/compiler/rustc_typeck/src/errors.rs index 7b553a46e3b6c..ae6f8d2a51c83 100644 --- a/compiler/rustc_typeck/src/errors.rs +++ b/compiler/rustc_typeck/src/errors.rs @@ -3,7 +3,7 @@ use rustc_errors::{error_code, Applicability, DiagnosticBuilder, ErrorGuaranteed use rustc_macros::{LintDiagnostic, SessionDiagnostic, SessionSubdiagnostic}; use rustc_middle::ty::Ty; use rustc_session::SessionDiagnostic; -use rustc_span::{symbol::Ident, Span, Symbol, source_map::SourceMap}; +use rustc_span::{source_map::SourceMap, symbol::Ident, Span, Symbol}; #[derive(SessionDiagnostic)] #[diag(typeck::field_multiply_specified_in_initializer, code = "E0062")] From 31e9f40bcf638d73985974d64402b2ba1622a46b Mon Sep 17 00:00:00 2001 From: Jhonny Bill Mena Date: Mon, 5 Sep 2022 12:59:56 -0400 Subject: [PATCH 5/7] FIX - broken translatable diagnostics tests --- src/test/ui-fulldeps/internal-lints/diagnostics.stderr | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/test/ui-fulldeps/internal-lints/diagnostics.stderr b/src/test/ui-fulldeps/internal-lints/diagnostics.stderr index 53d70c83183a3..e5c5bc2e9987e 100644 --- a/src/test/ui-fulldeps/internal-lints/diagnostics.stderr +++ b/src/test/ui-fulldeps/internal-lints/diagnostics.stderr @@ -1,5 +1,5 @@ error: diagnostics should be created using translatable messages - --> $DIR/diagnostics.rs:37:17 + --> $DIR/diagnostics.rs:39:17 | LL | handler.struct_err("untranslatable diagnostic") | ^^^^^^^^^^ @@ -11,13 +11,13 @@ LL | #![deny(rustc::untranslatable_diagnostic)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostics should be created using translatable messages - --> $DIR/diagnostics.rs:54:14 + --> $DIR/diagnostics.rs:56:14 | LL | diag.note("untranslatable diagnostic"); | ^^^^ error: diagnostics should only be created in `SessionDiagnostic`/`AddSubdiagnostic` impls - --> $DIR/diagnostics.rs:68:25 + --> $DIR/diagnostics.rs:70:25 | LL | let _diag = handler.struct_err(fluent::parser::expect_path); | ^^^^^^^^^^ @@ -29,13 +29,13 @@ LL | #![deny(rustc::diagnostic_outside_of_impl)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostics should only be created in `SessionDiagnostic`/`AddSubdiagnostic` impls - --> $DIR/diagnostics.rs:71:25 + --> $DIR/diagnostics.rs:73:25 | LL | let _diag = handler.struct_err("untranslatable diagnostic"); | ^^^^^^^^^^ error: diagnostics should be created using translatable messages - --> $DIR/diagnostics.rs:71:25 + --> $DIR/diagnostics.rs:73:25 | LL | let _diag = handler.struct_err("untranslatable diagnostic"); | ^^^^^^^^^^ From dd5850b8faf04e1b98542cf0813920385a6cc4db Mon Sep 17 00:00:00 2001 From: Jhonny Bill Mena Date: Mon, 5 Sep 2022 17:26:57 -0400 Subject: [PATCH 6/7] UPDATE - accept start_point and snippet instead of SourceMap --- compiler/rustc_attr/src/builtin.rs | 2 +- compiler/rustc_attr/src/session_diagnostics.rs | 10 +++++----- compiler/rustc_typeck/src/astconv/errors.rs | 2 +- compiler/rustc_typeck/src/errors.rs | 12 ++++++------ 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index 2c3fc4d9fe660..e1404ab15efa3 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -67,7 +67,7 @@ fn handle_errors(sess: &ParseSess, span: Span, error: AttrError) { span, reason, is_bytestr, - source_map: sess.source_map(), + start_point_span: sess.source_map().start_point(span), }); } } diff --git a/compiler/rustc_attr/src/session_diagnostics.rs b/compiler/rustc_attr/src/session_diagnostics.rs index b8942e51306d5..085175d4bed1f 100644 --- a/compiler/rustc_attr/src/session_diagnostics.rs +++ b/compiler/rustc_attr/src/session_diagnostics.rs @@ -6,7 +6,7 @@ use rustc_errors::{ }; use rustc_macros::SessionDiagnostic; use rustc_session::SessionDiagnostic; -use rustc_span::{source_map::SourceMap, Span, Symbol}; +use rustc_span::{Span, Symbol}; use crate::UnsupportedLiteralReason; @@ -202,14 +202,14 @@ pub(crate) struct InvalidReprHintNoValue { } // Error code: E0565 -pub(crate) struct UnsupportedLiteral<'a> { +pub(crate) struct UnsupportedLiteral { pub span: Span, pub reason: UnsupportedLiteralReason, pub is_bytestr: bool, - pub source_map: &'a SourceMap, + pub start_point_span: Span, } -impl<'a> SessionDiagnostic<'a> for UnsupportedLiteral<'a> { +impl<'a> SessionDiagnostic<'a> for UnsupportedLiteral { fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, ErrorGuaranteed> { let mut diag = handler.struct_span_err_with_code( self.span, @@ -227,7 +227,7 @@ impl<'a> SessionDiagnostic<'a> for UnsupportedLiteral<'a> { ); if self.is_bytestr { diag.span_suggestion( - self.source_map.start_point(self.span), + self.start_point_span, fluent::attr::unsupported_literal_suggestion, "", Applicability::MaybeIncorrect, diff --git a/compiler/rustc_typeck/src/astconv/errors.rs b/compiler/rustc_typeck/src/astconv/errors.rs index 1262dd7dcc7fd..a9152bdc59787 100644 --- a/compiler/rustc_typeck/src/astconv/errors.rs +++ b/compiler/rustc_typeck/src/astconv/errors.rs @@ -29,7 +29,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { self.tcx().sess.emit_err(MissingTypeParams { span, def_span: self.tcx().def_span(def_id), - source_map: self.tcx().sess.source_map(), + span_snippet: self.tcx().sess.source_map().span_to_snippet(span).ok(), missing_type_params, empty_generic_args, }); diff --git a/compiler/rustc_typeck/src/errors.rs b/compiler/rustc_typeck/src/errors.rs index ae6f8d2a51c83..d280fa5156bdb 100644 --- a/compiler/rustc_typeck/src/errors.rs +++ b/compiler/rustc_typeck/src/errors.rs @@ -3,7 +3,7 @@ use rustc_errors::{error_code, Applicability, DiagnosticBuilder, ErrorGuaranteed use rustc_macros::{LintDiagnostic, SessionDiagnostic, SessionSubdiagnostic}; use rustc_middle::ty::Ty; use rustc_session::SessionDiagnostic; -use rustc_span::{source_map::SourceMap, symbol::Ident, Span, Symbol}; +use rustc_span::{symbol::Ident, Span, Symbol}; #[derive(SessionDiagnostic)] #[diag(typeck::field_multiply_specified_in_initializer, code = "E0062")] @@ -241,16 +241,16 @@ pub struct UnconstrainedOpaqueType { pub name: Symbol, } -pub struct MissingTypeParams<'a> { +pub struct MissingTypeParams { pub span: Span, pub def_span: Span, + pub span_snippet: Option, pub missing_type_params: Vec, pub empty_generic_args: bool, - pub source_map: &'a SourceMap, } // Manual implementation of `SessionDiagnostic` to be able to call `span_to_snippet`. -impl<'a> SessionDiagnostic<'a> for MissingTypeParams<'a> { +impl<'a> SessionDiagnostic<'a> for MissingTypeParams { fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, ErrorGuaranteed> { let mut err = handler.struct_span_err_with_code( self.span, @@ -270,8 +270,8 @@ impl<'a> SessionDiagnostic<'a> for MissingTypeParams<'a> { err.span_label(self.def_span, rustc_errors::fluent::typeck::label); let mut suggested = false; - if let (Ok(snippet), true) = ( - self.source_map.span_to_snippet(self.span), + if let (Some(snippet), true) = ( + self.span_snippet, // Don't suggest setting the type params if there are some already: the order is // tricky to get right and the user will already know what the syntax is. self.empty_generic_args, From 46ba27d5b54e4271e1c3934197afbae269237639 Mon Sep 17 00:00:00 2001 From: Jhonny Bill Mena Date: Mon, 5 Sep 2022 17:32:23 -0400 Subject: [PATCH 7/7] [Gardening] UPDATE - use let chain to unwrap snippet and evaluate flag --- compiler/rustc_typeck/src/errors.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_typeck/src/errors.rs b/compiler/rustc_typeck/src/errors.rs index d280fa5156bdb..0d2e667458592 100644 --- a/compiler/rustc_typeck/src/errors.rs +++ b/compiler/rustc_typeck/src/errors.rs @@ -270,12 +270,9 @@ impl<'a> SessionDiagnostic<'a> for MissingTypeParams { err.span_label(self.def_span, rustc_errors::fluent::typeck::label); let mut suggested = false; - if let (Some(snippet), true) = ( - self.span_snippet, - // Don't suggest setting the type params if there are some already: the order is - // tricky to get right and the user will already know what the syntax is. - self.empty_generic_args, - ) { + // Don't suggest setting the type params if there are some already: the order is + // tricky to get right and the user will already know what the syntax is. + if let Some(snippet) = self.span_snippet && self.empty_generic_args { if snippet.ends_with('>') { // The user wrote `Trait<'a, T>` or similar. To provide an accurate suggestion // we would have to preserve the right order. For now, as clearly the user is