From 98af1bfeccf1ec1f9e896ecc912b5cc808408378 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 22 Jun 2022 21:43:01 -0700 Subject: [PATCH] Migrate some rustc_borrowck diagnostics to SessionDiagnostic --- Cargo.lock | 1 + compiler/rustc_borrowck/Cargo.toml | 1 + .../src/diagnostics/bound_region_errors.rs | 27 ++++++++---- .../src/diagnostics/region_errors.rs | 9 ++-- compiler/rustc_borrowck/src/lib.rs | 1 + .../rustc_borrowck/src/session_diagnostics.rs | 44 +++++++++++++++++++ compiler/rustc_borrowck/src/type_check/mod.rs | 13 +----- .../locales/en-US/borrowck.ftl | 18 ++++++++ compiler/rustc_error_messages/src/lib.rs | 1 + compiler/rustc_errors/src/emitter.rs | 14 +++++- src/test/ui/dst/dst-index.stderr | 8 ++-- src/test/ui/error-codes/E0161.base.stderr | 4 +- .../issue-59311.stderr | 4 +- .../ui/lifetimes/re-empty-in-error.stderr | 2 +- src/test/ui/mir/issue-67947.rs | 2 +- src/test/ui/mir/issue-67947.stderr | 4 +- .../object-safety-by-value-self-use.rs | 2 +- .../object-safety-by-value-self-use.stderr | 4 +- .../return-unsized-from-trait-method.rs | 2 +- .../return-unsized-from-trait-method.stderr | 4 +- 20 files changed, 122 insertions(+), 43 deletions(-) create mode 100644 compiler/rustc_borrowck/src/session_diagnostics.rs create mode 100644 compiler/rustc_error_messages/locales/en-US/borrowck.ftl diff --git a/Cargo.lock b/Cargo.lock index 96d9449db57c0..f51712e8e2cc2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3595,6 +3595,7 @@ dependencies = [ "rustc_index", "rustc_infer", "rustc_lexer", + "rustc_macros", "rustc_middle", "rustc_mir_dataflow", "rustc_serialize", diff --git a/compiler/rustc_borrowck/Cargo.toml b/compiler/rustc_borrowck/Cargo.toml index 0b531623ba6f5..8a35921d745cf 100644 --- a/compiler/rustc_borrowck/Cargo.toml +++ b/compiler/rustc_borrowck/Cargo.toml @@ -19,6 +19,7 @@ rustc_hir = { path = "../rustc_hir" } rustc_index = { path = "../rustc_index" } rustc_infer = { path = "../rustc_infer" } rustc_lexer = { path = "../rustc_lexer" } +rustc_macros = { path = "../rustc_macros" } rustc_middle = { path = "../rustc_middle" } rustc_const_eval = { path = "../rustc_const_eval" } rustc_mir_dataflow = { path = "../rustc_mir_dataflow" } diff --git a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs index 07f182102f346..1ef2b0ae98843 100644 --- a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs @@ -19,6 +19,9 @@ use std::fmt; use std::rc::Rc; use crate::region_infer::values::RegionElement; +use crate::session_diagnostics::HigherRankedErrorCause; +use crate::session_diagnostics::HigherRankedLifetimeError; +use crate::session_diagnostics::HigherRankedSubtypeError; use crate::MirBorrowckCtxt; #[derive(Clone)] @@ -69,7 +72,7 @@ impl<'tcx> UniverseInfo<'tcx> { // up in the existing UI tests. Consider investigating this // some more. mbcx.buffer_error( - mbcx.infcx.tcx.sess.struct_span_err(cause.span, "higher-ranked subtype error"), + mbcx.infcx.tcx.sess.create_err(HigherRankedSubtypeError { span: cause.span }), ); } } @@ -216,9 +219,12 @@ impl<'tcx> TypeOpInfo<'tcx> for PredicateQuery<'tcx> { tcx: TyCtxt<'tcx>, span: Span, ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { - let mut err = tcx.sess.struct_span_err(span, "higher-ranked lifetime error"); - err.note(&format!("could not prove {}", self.canonical_query.value.value.predicate)); - err + tcx.sess.create_err(HigherRankedLifetimeError { + cause: Some(HigherRankedErrorCause::CouldNotProve { + predicate: self.canonical_query.value.value.predicate.to_string(), + }), + span, + }) } fn base_universe(&self) -> ty::UniverseIndex { @@ -263,9 +269,12 @@ where tcx: TyCtxt<'tcx>, span: Span, ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { - let mut err = tcx.sess.struct_span_err(span, "higher-ranked lifetime error"); - err.note(&format!("could not normalize `{}`", self.canonical_query.value.value.value)); - err + tcx.sess.create_err(HigherRankedLifetimeError { + cause: Some(HigherRankedErrorCause::CouldNotNormalize { + value: self.canonical_query.value.value.value.to_string(), + }), + span, + }) } fn base_universe(&self) -> ty::UniverseIndex { @@ -326,7 +335,7 @@ impl<'tcx> TypeOpInfo<'tcx> for AscribeUserTypeQuery<'tcx> { ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { // FIXME: This error message isn't great, but it doesn't show up in the existing UI tests, // and is only the fallback when the nice error fails. Consider improving this some more. - tcx.sess.struct_span_err(span, "higher-ranked lifetime error") + tcx.sess.create_err(HigherRankedLifetimeError { cause: None, span }) } fn base_universe(&self) -> ty::UniverseIndex { @@ -366,7 +375,7 @@ impl<'tcx> TypeOpInfo<'tcx> for crate::type_check::InstantiateOpaqueType<'tcx> { ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { // FIXME: This error message isn't great, but it doesn't show up in the existing UI tests, // and is only the fallback when the nice error fails. Consider improving this some more. - tcx.sess.struct_span_err(span, "higher-ranked lifetime error for opaque type!") + tcx.sess.create_err(HigherRankedLifetimeError { cause: None, span }) } fn base_universe(&self) -> ty::UniverseIndex { diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index e0f8da1c872d3..5d3997289bb33 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -24,6 +24,7 @@ use rustc_span::symbol::Ident; use rustc_span::Span; use crate::borrowck_errors; +use crate::session_diagnostics::GenericDoesNotLiveLongEnough; use super::{OutlivesSuggestionBuilder, RegionName}; use crate::region_infer::BlameConstraint; @@ -196,9 +197,11 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { // to report it; we could probably handle it by // iterating over the universal regions and reporting // an error that multiple bounds are required. - self.buffer_error(self.infcx.tcx.sess.struct_span_err( - type_test_span, - &format!("`{}` does not live long enough", type_test.generic_kind), + self.buffer_error(self.infcx.tcx.sess.create_err( + GenericDoesNotLiveLongEnough { + kind: type_test.generic_kind.to_string(), + span: type_test_span, + }, )); } } diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index a2df072aa3119..7d6f37340c2bb 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -76,6 +76,7 @@ mod places_conflict; mod prefixes; mod region_infer; mod renumber; +mod session_diagnostics; mod type_check; mod universal_regions; mod used_muts; diff --git a/compiler/rustc_borrowck/src/session_diagnostics.rs b/compiler/rustc_borrowck/src/session_diagnostics.rs new file mode 100644 index 0000000000000..895723d44ff1b --- /dev/null +++ b/compiler/rustc_borrowck/src/session_diagnostics.rs @@ -0,0 +1,44 @@ +use rustc_macros::{SessionDiagnostic, SessionSubdiagnostic}; +use rustc_middle::ty::Ty; +use rustc_span::Span; + +#[derive(SessionDiagnostic)] +#[error(borrowck::move_unsized, code = "E0161")] +pub(crate) struct MoveUnsized<'tcx> { + pub ty: Ty<'tcx>, + #[primary_span] + #[label] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[error(borrowck::higher_ranked_lifetime_error)] +pub(crate) struct HigherRankedLifetimeError { + #[subdiagnostic] + pub cause: Option, + #[primary_span] + pub span: Span, +} + +#[derive(SessionSubdiagnostic)] +pub(crate) enum HigherRankedErrorCause { + #[note(borrowck::could_not_prove)] + CouldNotProve { predicate: String }, + #[note(borrowck::could_not_normalize)] + CouldNotNormalize { value: String }, +} + +#[derive(SessionDiagnostic)] +#[error(borrowck::higher_ranked_subtype_error)] +pub(crate) struct HigherRankedSubtypeError { + #[primary_span] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[error(borrowck::generic_does_not_live_long_enough)] +pub(crate) struct GenericDoesNotLiveLongEnough { + pub kind: String, + #[primary_span] + pub span: Span, +} diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 542fc6b0f485d..5ee1f5a8e8e37 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -9,7 +9,6 @@ use hir::OpaqueTyOrigin; use rustc_data_structures::frozen::Frozen; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::vec_map::VecMap; -use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalDefId; @@ -48,6 +47,7 @@ use rustc_mir_dataflow::impls::MaybeInitializedPlaces; use rustc_mir_dataflow::move_paths::MoveData; use rustc_mir_dataflow::ResultsCursor; +use crate::session_diagnostics::MoveUnsized; use crate::{ borrow_set::BorrowSet, constraints::{OutlivesConstraint, OutlivesConstraintSet}, @@ -1780,19 +1780,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { // slot or local, so to find all unsized rvalues it is enough // to check all temps, return slots and locals. if self.reported_errors.replace((ty, span)).is_none() { - let mut diag = struct_span_err!( - self.tcx().sess, - span, - E0161, - "cannot move a value of type {0}: the size of {0} \ - cannot be statically determined", - ty - ); - // While this is located in `nll::typeck` this error is not // an NLL error, it's a required check to prevent creation // of unsized rvalues in a call expression. - diag.emit(); + self.tcx().sess.emit_err(MoveUnsized { ty, span }); } } } diff --git a/compiler/rustc_error_messages/locales/en-US/borrowck.ftl b/compiler/rustc_error_messages/locales/en-US/borrowck.ftl new file mode 100644 index 0000000000000..645673ef47aeb --- /dev/null +++ b/compiler/rustc_error_messages/locales/en-US/borrowck.ftl @@ -0,0 +1,18 @@ +borrowck-move-unsized = + cannot move a value of type `{$ty}` + .label = the size of `{$ty}` cannot be statically determined + +borrowck-higher-ranked-lifetime-error = + higher-ranked lifetime error + +borrowck-could-not-prove = + could not prove `{$predicate}` + +borrowck-could-not-normalize = + could not normalize `{$value}` + +borrowck-higher-ranked-subtype-error = + higher-ranked subtype error + +generic-does-not-live-long-enough = + `{$kind}` does not live long enough \ No newline at end of file diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index 90eb5ef54462d..d52b94b78dfac 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -35,6 +35,7 @@ fluent_messages! { privacy => "../locales/en-US/privacy.ftl", typeck => "../locales/en-US/typeck.ftl", builtin_macros => "../locales/en-US/builtin_macros.ftl", + borrowck => "../locales/en-US/borrowck.ftl", } pub use fluent_generated::{self as fluent, DEFAULT_LOCALE_RESOURCES}; diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 8b2a995f1c58e..6d74e9a9f2b9e 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -281,9 +281,19 @@ pub trait Emitter { let message = bundle.get_message(&identifier).expect("missing diagnostic in fluent bundle"); let value = match attr { Some(attr) => { - message.get_attribute(attr).expect("missing attribute in fluent message").value() + if let Some(attr) = message.get_attribute(attr) { + attr.value() + } else { + panic!("missing attribute `{attr}` in fluent message `{identifier}`") + } + } + None => { + if let Some(value) = message.value() { + value + } else { + panic!("missing value in fluent message `{identifier}`") + } } - None => message.value().expect("missing value in fluent message"), }; let mut err = vec![]; diff --git a/src/test/ui/dst/dst-index.stderr b/src/test/ui/dst/dst-index.stderr index 6bcd70cbaad45..d38af3f89c21b 100644 --- a/src/test/ui/dst/dst-index.stderr +++ b/src/test/ui/dst/dst-index.stderr @@ -1,14 +1,14 @@ -error[E0161]: cannot move a value of type str: the size of str cannot be statically determined +error[E0161]: cannot move a value of type `str` --> $DIR/dst-index.rs:31:5 | LL | S[0]; - | ^^^^ + | ^^^^ the size of `str` cannot be statically determined -error[E0161]: cannot move a value of type dyn Debug: the size of dyn Debug cannot be statically determined +error[E0161]: cannot move a value of type `dyn Debug` --> $DIR/dst-index.rs:34:5 | LL | T[0]; - | ^^^^ + | ^^^^ the size of `dyn Debug` cannot be statically determined error[E0507]: cannot move out of index of `S` --> $DIR/dst-index.rs:31:5 diff --git a/src/test/ui/error-codes/E0161.base.stderr b/src/test/ui/error-codes/E0161.base.stderr index fb578cda17e9f..15d98b657a262 100644 --- a/src/test/ui/error-codes/E0161.base.stderr +++ b/src/test/ui/error-codes/E0161.base.stderr @@ -1,8 +1,8 @@ -error[E0161]: cannot move a value of type dyn Bar: the size of dyn Bar cannot be statically determined +error[E0161]: cannot move a value of type `dyn Bar` --> $DIR/E0161.rs:16:5 | LL | x.f(); - | ^^^^^ + | ^^^^^ the size of `dyn Bar` cannot be statically determined error: aborting due to previous error diff --git a/src/test/ui/higher-rank-trait-bounds/issue-59311.stderr b/src/test/ui/higher-rank-trait-bounds/issue-59311.stderr index 15e83ab5a347d..43e609cc59efb 100644 --- a/src/test/ui/higher-rank-trait-bounds/issue-59311.stderr +++ b/src/test/ui/higher-rank-trait-bounds/issue-59311.stderr @@ -4,7 +4,7 @@ error: higher-ranked lifetime error LL | v.t(|| {}); | ^^^^^^^^^^ | - = note: could not prove [closure@$DIR/issue-59311.rs:17:9: 17:14] well-formed + = note: could not prove `[closure@$DIR/issue-59311.rs:17:9: 17:14] well-formed` error: higher-ranked lifetime error --> $DIR/issue-59311.rs:17:9 @@ -12,7 +12,7 @@ error: higher-ranked lifetime error LL | v.t(|| {}); | ^^^^^ | - = note: could not prove for<'a> &'a V: 'static + = note: could not prove `for<'a> &'a V: 'static` error: aborting due to 2 previous errors diff --git a/src/test/ui/lifetimes/re-empty-in-error.stderr b/src/test/ui/lifetimes/re-empty-in-error.stderr index 3a5ab62ab96f6..72bb0782f4b4f 100644 --- a/src/test/ui/lifetimes/re-empty-in-error.stderr +++ b/src/test/ui/lifetimes/re-empty-in-error.stderr @@ -4,7 +4,7 @@ error: higher-ranked lifetime error LL | foo(&10); | ^^^^^^^^ | - = note: could not prove for<'b, 'r> &'b (): 'r + = note: could not prove `for<'b, 'r> &'b (): 'r` error: aborting due to previous error diff --git a/src/test/ui/mir/issue-67947.rs b/src/test/ui/mir/issue-67947.rs index 79e75e655ff1f..f73d38f80426f 100644 --- a/src/test/ui/mir/issue-67947.rs +++ b/src/test/ui/mir/issue-67947.rs @@ -1,6 +1,6 @@ struct Bug { A: [(); { *"" }.len()], - //~^ ERROR: cannot move a value of type str + //~^ ERROR: cannot move a value of type `str` //~| ERROR: cannot move out of a shared reference } diff --git a/src/test/ui/mir/issue-67947.stderr b/src/test/ui/mir/issue-67947.stderr index d526218162076..7697a411eb481 100644 --- a/src/test/ui/mir/issue-67947.stderr +++ b/src/test/ui/mir/issue-67947.stderr @@ -1,8 +1,8 @@ -error[E0161]: cannot move a value of type str: the size of str cannot be statically determined +error[E0161]: cannot move a value of type `str` --> $DIR/issue-67947.rs:2:13 | LL | A: [(); { *"" }.len()], - | ^^^^^^^ + | ^^^^^^^ the size of `str` cannot be statically determined error[E0507]: cannot move out of a shared reference --> $DIR/issue-67947.rs:2:15 diff --git a/src/test/ui/object-safety/object-safety-by-value-self-use.rs b/src/test/ui/object-safety/object-safety-by-value-self-use.rs index f903f26c0901d..8e93c538217bb 100644 --- a/src/test/ui/object-safety/object-safety-by-value-self-use.rs +++ b/src/test/ui/object-safety/object-safety-by-value-self-use.rs @@ -12,7 +12,7 @@ trait Baz { } fn use_bar(t: Box) { - t.bar() //~ ERROR cannot move a value of type dyn Bar + t.bar() //~ ERROR cannot move a value of type `dyn Bar` } fn main() { } diff --git a/src/test/ui/object-safety/object-safety-by-value-self-use.stderr b/src/test/ui/object-safety/object-safety-by-value-self-use.stderr index 7ccc0cbdd576b..94fdcdf263ae0 100644 --- a/src/test/ui/object-safety/object-safety-by-value-self-use.stderr +++ b/src/test/ui/object-safety/object-safety-by-value-self-use.stderr @@ -1,8 +1,8 @@ -error[E0161]: cannot move a value of type dyn Bar: the size of dyn Bar cannot be statically determined +error[E0161]: cannot move a value of type `dyn Bar` --> $DIR/object-safety-by-value-self-use.rs:15:5 | LL | t.bar() - | ^^^^^^^ + | ^^^^^^^ the size of `dyn Bar` cannot be statically determined error: aborting due to previous error diff --git a/src/test/ui/unsized/return-unsized-from-trait-method.rs b/src/test/ui/unsized/return-unsized-from-trait-method.rs index ebe6edd101014..f053f4b0af89c 100644 --- a/src/test/ui/unsized/return-unsized-from-trait-method.rs +++ b/src/test/ui/unsized/return-unsized-from-trait-method.rs @@ -7,7 +7,7 @@ trait Foo { fn foo(f: Option<&dyn Foo>) { if let Some(f) = f { let _ = f.foo(); - //~^ ERROR cannot move a value of type [u8]: the size of [u8] cannot be statically determined + //~^ ERROR cannot move a value of type `[u8]` } } diff --git a/src/test/ui/unsized/return-unsized-from-trait-method.stderr b/src/test/ui/unsized/return-unsized-from-trait-method.stderr index 4dd7cf5e02fc2..671d409937cac 100644 --- a/src/test/ui/unsized/return-unsized-from-trait-method.stderr +++ b/src/test/ui/unsized/return-unsized-from-trait-method.stderr @@ -1,8 +1,8 @@ -error[E0161]: cannot move a value of type [u8]: the size of [u8] cannot be statically determined +error[E0161]: cannot move a value of type `[u8]` --> $DIR/return-unsized-from-trait-method.rs:9:17 | LL | let _ = f.foo(); - | ^^^^^^^ + | ^^^^^^^ the size of `[u8]` cannot be statically determined error: aborting due to previous error