diff --git a/compiler/rustc_error_messages/locales/en-US/middle.ftl b/compiler/rustc_error_messages/locales/en-US/middle.ftl new file mode 100644 index 00000000000..ed834886453 --- /dev/null +++ b/compiler/rustc_error_messages/locales/en-US/middle.ftl @@ -0,0 +1,17 @@ +middle_drop_check_overflow = + overflow while adding drop-check rules for {$ty} + .note = overflowed on {$overflow_ty} + +middle_opaque_hidden_type_mismatch = + concrete type differs from previous defining opaque type use + .label = expected `{$self_ty}`, got `{$other_ty}` + +middle_conflict_types = + this expression supplies two conflicting concrete types for the same opaque type + +middle_previous_use_here = + previous use here + +middle_limit_invalid = + `limit` must be a non-negative integer + .label = {$error_str} diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index 5281a287b0d..b6e0f3faa73 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -47,6 +47,7 @@ fluent_messages! { interface => "../locales/en-US/interface.ftl", infer => "../locales/en-US/infer.ftl", lint => "../locales/en-US/lint.ftl", + middle => "../locales/en-US/middle.ftl", monomorphize => "../locales/en-US/monomorphize.ftl", metadata => "../locales/en-US/metadata.ftl", parser => "../locales/en-US/parser.ftl", diff --git a/compiler/rustc_middle/src/error.rs b/compiler/rustc_middle/src/error.rs new file mode 100644 index 00000000000..18b31a75bcc --- /dev/null +++ b/compiler/rustc_middle/src/error.rs @@ -0,0 +1,50 @@ +use rustc_macros::SessionDiagnostic; +use rustc_span::Span; + +use crate::ty::Ty; + +#[derive(SessionDiagnostic)] +#[diag(middle::drop_check_overflow, code = "E0320")] +#[note] +pub struct DropCheckOverflow<'tcx> { + #[primary_span] + pub span: Span, + pub ty: Ty<'tcx>, + pub overflow_ty: Ty<'tcx>, +} + +#[derive(SessionDiagnostic)] +#[diag(middle::opaque_hidden_type_mismatch)] +pub struct OpaqueHiddenTypeMismatch<'tcx> { + pub self_ty: Ty<'tcx>, + pub other_ty: Ty<'tcx>, + #[primary_span] + #[label] + pub other_span: Span, + #[subdiagnostic] + pub sub: TypeMismatchReason, +} + +#[derive(SessionSubdiagnostic)] +pub enum TypeMismatchReason { + #[label(middle::conflict_types)] + ConflictType { + #[primary_span] + span: Span, + }, + #[note(middle::previous_use_here)] + PreviousUse { + #[primary_span] + span: Span, + }, +} + +#[derive(SessionDiagnostic)] +#[diag(middle::limit_invalid)] +pub struct LimitInvalid<'a> { + #[primary_span] + pub span: Span, + #[label] + pub value_span: Span, + pub error_str: &'a str, +} diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index be9e5865e54..1e3a6bcfc7d 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -86,6 +86,7 @@ pub mod query; pub mod arena; #[macro_use] pub mod dep_graph; +pub(crate) mod error; pub mod hir; pub mod infer; pub mod lint; diff --git a/compiler/rustc_middle/src/middle/limits.rs b/compiler/rustc_middle/src/middle/limits.rs index acced0492ef..53c4d926784 100644 --- a/compiler/rustc_middle/src/middle/limits.rs +++ b/compiler/rustc_middle/src/middle/limits.rs @@ -10,6 +10,7 @@ //! just peeks and looks for that attribute. use crate::bug; +use crate::error::LimitInvalid; use crate::ty; use rustc_ast::Attribute; use rustc_session::Session; @@ -56,9 +57,6 @@ fn get_limit(krate_attrs: &[Attribute], sess: &Session, name: Symbol, default: u match s.as_str().parse() { Ok(n) => return Limit::new(n), Err(e) => { - let mut err = - sess.struct_span_err(attr.span, "`limit` must be a non-negative integer"); - let value_span = attr .meta() .and_then(|meta| meta.name_value_literal_span()) @@ -74,9 +72,7 @@ fn get_limit(krate_attrs: &[Attribute], sess: &Session, name: Symbol, default: u IntErrorKind::Zero => bug!("zero is a valid `limit`"), kind => bug!("unimplemented IntErrorKind variant: {:?}", kind), }; - - err.span_label(value_span, error_str); - err.emit(); + sess.emit_err(LimitInvalid { span: attr.span, value_span, error_str }); } } } diff --git a/compiler/rustc_middle/src/traits/query.rs b/compiler/rustc_middle/src/traits/query.rs index 1f9b474ade1..0e6cacb9fd0 100644 --- a/compiler/rustc_middle/src/traits/query.rs +++ b/compiler/rustc_middle/src/traits/query.rs @@ -5,11 +5,11 @@ //! The providers for the queries defined here can be found in //! `rustc_traits`. +use crate::error::DropCheckOverflow; use crate::infer::canonical::{Canonical, QueryResponse}; use crate::ty::error::TypeError; use crate::ty::subst::GenericArg; use crate::ty::{self, Ty, TyCtxt}; -use rustc_errors::struct_span_err; use rustc_span::source_map::Span; use std::iter::FromIterator; @@ -117,15 +117,7 @@ pub struct DropckOutlivesResult<'tcx> { impl<'tcx> DropckOutlivesResult<'tcx> { pub fn report_overflows(&self, tcx: TyCtxt<'tcx>, span: Span, ty: Ty<'tcx>) { if let Some(overflow_ty) = self.overflows.get(0) { - let mut err = struct_span_err!( - tcx.sess, - span, - E0320, - "overflow while adding drop-check rules for {}", - ty, - ); - err.note(&format!("overflowed on {}", overflow_ty)); - err.emit(); + tcx.sess.emit_err(DropCheckOverflow { span, ty, overflow_ty: *overflow_ty }); } } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 1312a146796..a3f7880b9a5 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -15,6 +15,7 @@ pub use self::AssocItemContainer::*; pub use self::BorrowKind::*; pub use self::IntVarValue::*; pub use self::Variance::*; +use crate::error::{OpaqueHiddenTypeMismatch, TypeMismatchReason}; use crate::metadata::ModChild; use crate::middle::privacy::AccessLevels; use crate::mir::{Body, GeneratorLayout}; @@ -1179,20 +1180,17 @@ pub struct OpaqueHiddenType<'tcx> { impl<'tcx> OpaqueHiddenType<'tcx> { pub fn report_mismatch(&self, other: &Self, tcx: TyCtxt<'tcx>) { // Found different concrete types for the opaque type. - let mut err = tcx.sess.struct_span_err( - other.span, - "concrete type differs from previous defining opaque type use", - ); - err.span_label(other.span, format!("expected `{}`, got `{}`", self.ty, other.ty)); - if self.span == other.span { - err.span_label( - self.span, - "this expression supplies two conflicting concrete types for the same opaque type", - ); + let sub_diag = if self.span == other.span { + TypeMismatchReason::ConflictType { span: self.span } } else { - err.span_note(self.span, "previous use here"); - } - err.emit(); + TypeMismatchReason::PreviousUse { span: self.span } + }; + tcx.sess.emit_err(OpaqueHiddenTypeMismatch { + self_ty: self.ty, + other_ty: other.ty, + other_span: other.span, + sub: sub_diag, + }); } }