about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNikita Tomashevich <quant3234@gmail.com>2022-08-24 15:46:29 +0300
committerNikita Tomashevich <quant3234@gmail.com>2022-08-24 15:46:29 +0300
commit3fae3904b130272c782255066f79a13fa9fcdad6 (patch)
tree950327fad609a1dfa74440532098bf717147dded
parent74f99738244fc9ba2f6ad93b8c891d44d638b0f8 (diff)
downloadrust-3fae3904b130272c782255066f79a13fa9fcdad6.tar.gz
rust-3fae3904b130272c782255066f79a13fa9fcdad6.zip
Use `IntoDiagnosticArg` where it makes sense
-rw-r--r--compiler/rustc_error_messages/locales/en-US/infer.ftl7
-rw-r--r--compiler/rustc_infer/src/errors.rs13
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs16
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs37
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/note.rs29
5 files changed, 61 insertions, 41 deletions
diff --git a/compiler/rustc_error_messages/locales/en-US/infer.ftl b/compiler/rustc_error_messages/locales/en-US/infer.ftl
index 6ae60d92e26..60086cd6e47 100644
--- a/compiler/rustc_error_messages/locales/en-US/infer.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/infer.ftl
@@ -63,7 +63,12 @@ infer_source_kind_closure_return =
 
 # generator_kind  may need to be translated
 infer_need_type_info_in_generator =
-    type inside {$generator_kind} must be known in this context
+    type inside {$generator_kind ->
+    [async_block] `async` block
+    [async_closure] `async` closure
+    [async_fn] `async fn` body
+    *[generator] generator
+    } must be known in this context
 
 
 infer_subtype = ...so that the {$requirement ->
diff --git a/compiler/rustc_infer/src/errors.rs b/compiler/rustc_infer/src/errors.rs
index 1db8763e499..938f8aa77a5 100644
--- a/compiler/rustc_infer/src/errors.rs
+++ b/compiler/rustc_infer/src/errors.rs
@@ -3,6 +3,11 @@ use rustc_hir::FnRetTy;
 use rustc_macros::SessionDiagnostic;
 use rustc_span::{BytePos, Span};
 
+use crate::infer::error_reporting::{
+    need_type_info::{GeneratorKindAsDiagArg, UnderspecifiedArgKind},
+    ObligationCauseAsDiagArg,
+};
+
 #[derive(SessionDiagnostic)]
 #[diag(infer::opaque_hidden_type)]
 pub struct OpaqueHiddenTypeDiag {
@@ -73,7 +78,7 @@ pub struct AmbigousReturn<'a> {
 pub struct NeedTypeInfoInGenerator<'a> {
     #[primary_span]
     pub span: Span,
-    pub generator_kind: &'static str,
+    pub generator_kind: GeneratorKindAsDiagArg,
     #[subdiagnostic]
     pub bad_label: InferenceBadError<'a>,
 }
@@ -85,7 +90,7 @@ pub struct InferenceBadError<'a> {
     #[primary_span]
     pub span: Span,
     pub bad_kind: &'static str,
-    pub prefix_kind: &'static str,
+    pub prefix_kind: UnderspecifiedArgKind,
     pub has_parent: bool,
     pub prefix: &'a str,
     pub parent_prefix: &'a str,
@@ -107,7 +112,7 @@ pub enum SourceKindSubdiag<'a> {
         type_name: String,
         kind: &'static str,
         x_kind: &'static str,
-        prefix_kind: &'static str,
+        prefix_kind: UnderspecifiedArgKind,
         prefix: &'a str,
         arg_name: String,
     },
@@ -199,7 +204,7 @@ pub enum RegionOriginNote<'a> {
     },
     WithRequirement {
         span: Span,
-        requirement: &'static str,
+        requirement: ObligationCauseAsDiagArg<'a>,
         expected_found: Option<(DiagnosticStyledString, DiagnosticStyledString)>,
     },
 }
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index 13951326665..c7e258578e4 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -58,7 +58,7 @@ use crate::traits::{
 };
 
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
-use rustc_errors::{pluralize, struct_span_err, Diagnostic, ErrorGuaranteed};
+use rustc_errors::{pluralize, struct_span_err, Diagnostic, ErrorGuaranteed, IntoDiagnosticArg};
 use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString, MultiSpan};
 use rustc_hir as hir;
 use rustc_hir::def_id::{DefId, LocalDefId};
@@ -78,7 +78,7 @@ use std::{cmp, fmt, iter};
 
 mod note;
 
-mod need_type_info;
+pub(crate) mod need_type_info;
 pub use need_type_info::TypeAnnotationNeeded;
 
 pub mod nice_region_error;
@@ -2811,7 +2811,6 @@ pub enum FailureCode {
 pub trait ObligationCauseExt<'tcx> {
     fn as_failure_code(&self, terr: TypeError<'tcx>) -> FailureCode;
     fn as_requirement_str(&self) -> &'static str;
-    fn as_requirement_localised(&self) -> &'static str;
 }
 
 impl<'tcx> ObligationCauseExt<'tcx> for ObligationCause<'tcx> {
@@ -2880,10 +2879,15 @@ impl<'tcx> ObligationCauseExt<'tcx> for ObligationCause<'tcx> {
             _ => "types are compatible",
         }
     }
+}
+
+/// Newtype to allow implementing IntoDiagnosticArg
+pub struct ObligationCauseAsDiagArg<'tcx>(pub ObligationCause<'tcx>);
 
-    fn as_requirement_localised(&self) -> &'static str {
+impl IntoDiagnosticArg for ObligationCauseAsDiagArg<'_> {
+    fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
         use crate::traits::ObligationCauseCode::*;
-        match self.code() {
+        let kind = match self.0.code() {
             CompareImplItemObligation { kind: ty::AssocKind::Fn, .. } => "method_compat",
             CompareImplItemObligation { kind: ty::AssocKind::Type, .. } => "type_compat",
             CompareImplItemObligation { kind: ty::AssocKind::Const, .. } => "const_compat",
@@ -2896,6 +2900,8 @@ impl<'tcx> ObligationCauseExt<'tcx> for ObligationCause<'tcx> {
             MethodReceiver => "method_correct_type",
             _ => "other",
         }
+        .into();
+        rustc_errors::DiagnosticArgValue::Str(kind)
     }
 }
 
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 daf64aeb053..e990fe7ecb5 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
@@ -4,7 +4,7 @@ use crate::errors::{
 };
 use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use crate::infer::InferCtxt;
-use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed};
+use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed, IntoDiagnosticArg};
 use rustc_hir as hir;
 use rustc_hir::def::Res;
 use rustc_hir::def::{CtorOf, DefKind, Namespace};
@@ -65,6 +65,7 @@ pub struct InferenceDiagnosticsParentData {
     name: String,
 }
 
+#[derive(Clone)]
 pub enum UnderspecifiedArgKind {
     Type { prefix: Cow<'static, str> },
     Const { is_parameter: bool },
@@ -101,7 +102,7 @@ impl InferenceDiagnosticsData {
         InferenceBadError {
             span,
             bad_kind,
-            prefix_kind: self.kind.prefix_kind(),
+            prefix_kind: self.kind.clone(),
             prefix: self.kind.try_get_prefix().unwrap_or_default(),
             name: self.name.clone(),
             has_parent,
@@ -130,14 +131,18 @@ impl InferenceDiagnosticsParentData {
     }
 }
 
-impl UnderspecifiedArgKind {
-    fn prefix_kind(&self) -> &'static str {
-        match self {
+impl IntoDiagnosticArg for UnderspecifiedArgKind {
+    fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
+        let kind = match self {
             Self::Type { .. } => "type",
             Self::Const { is_parameter: true } => "const_with_param",
             Self::Const { is_parameter: false } => "const",
-        }
+        };
+        rustc_errors::DiagnosticArgValue::Str(kind.into())
     }
+}
+
+impl UnderspecifiedArgKind {
     fn try_get_prefix(&self) -> Option<&str> {
         match self {
             Self::Type { prefix } => Some(prefix.as_ref()),
@@ -405,7 +410,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     span: insert_span,
                     name: pattern_name.map(|name| name.to_string()).unwrap_or_else(String::new),
                     x_kind: arg_data.where_x_is_kind(ty),
-                    prefix_kind: arg_data.kind.prefix_kind(),
+                    prefix_kind: arg_data.kind.clone(),
                     prefix: arg_data.kind.try_get_prefix().unwrap_or_default(),
                     arg_name: arg_data.name,
                     kind: if pattern_name.is_some() { "with_pattern" } else { "other" },
@@ -417,7 +422,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     span: insert_span,
                     name: String::new(),
                     x_kind: arg_data.where_x_is_kind(ty),
-                    prefix_kind: arg_data.kind.prefix_kind(),
+                    prefix_kind: arg_data.kind.clone(),
                     prefix: arg_data.kind.try_get_prefix().unwrap_or_default(),
                     arg_name: arg_data.name,
                     kind: "closure",
@@ -568,12 +573,26 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         NeedTypeInfoInGenerator {
             bad_label: data.make_bad_error(span),
             span,
-            generator_kind: kind.descr(),
+            generator_kind: GeneratorKindAsDiagArg(kind),
         }
         .into_diagnostic(&self.tcx.sess.parse_sess)
     }
 }
 
+pub struct GeneratorKindAsDiagArg(pub hir::GeneratorKind);
+
+impl IntoDiagnosticArg for GeneratorKindAsDiagArg {
+    fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
+        let kind = match self.0 {
+            hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Block) => "async_block",
+            hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Closure) => "async_closure",
+            hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Fn) => "async_fn",
+            hir::GeneratorKind::Gen => "generator",
+        };
+        rustc_errors::DiagnosticArgValue::Str(kind.into())
+    }
+}
+
 #[derive(Debug)]
 struct InferSource<'tcx> {
     span: Span,
diff --git a/compiler/rustc_infer/src/infer/error_reporting/note.rs b/compiler/rustc_infer/src/infer/error_reporting/note.rs
index 36efbd6824a..cffdf56bb6d 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/note.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/note.rs
@@ -1,40 +1,26 @@
 use crate::errors::RegionOriginNote;
-use crate::infer::error_reporting::{note_and_explain_region, ObligationCauseExt};
+use crate::infer::error_reporting::note_and_explain_region;
 use crate::infer::{self, InferCtxt, SubregionOrigin};
 use rustc_errors::{
-    fluent, struct_span_err, AddSubdiagnostic, Diagnostic, DiagnosticBuilder, DiagnosticMessage,
-    ErrorGuaranteed,
+    fluent, struct_span_err, AddSubdiagnostic, Diagnostic, DiagnosticBuilder, ErrorGuaranteed,
 };
 use rustc_middle::traits::ObligationCauseCode;
 use rustc_middle::ty::error::TypeError;
 use rustc_middle::ty::{self, Region};
 
+use super::ObligationCauseAsDiagArg;
+
 impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
     pub(super) fn note_region_origin(&self, err: &mut Diagnostic, origin: &SubregionOrigin<'tcx>) {
-        let mut label_or_note = |span, msg: DiagnosticMessage| {
-            let sub_count = err.children.iter().filter(|d| d.span.is_dummy()).count();
-            let expanded_sub_count = err.children.iter().filter(|d| !d.span.is_dummy()).count();
-            let span_is_primary = err.span.primary_spans().iter().all(|&sp| sp == span);
-            if span_is_primary && sub_count == 0 && expanded_sub_count == 0 {
-                err.span_label(span, msg);
-            } else if span_is_primary && expanded_sub_count == 0 {
-                err.note(msg);
-            } else {
-                err.span_note(span, msg);
-            }
-        };
         match *origin {
             infer::Subtype(ref trace) => RegionOriginNote::WithRequirement {
                 span: trace.cause.span,
-                requirement: trace.cause.as_requirement_localised(),
+                requirement: ObligationCauseAsDiagArg(trace.cause.clone()),
                 expected_found: self.values_str(trace.values),
             }
             .add_to_diagnostic(err),
-            infer::Reborrow(span) => {
-                label_or_note(span, fluent::infer::reborrow);
-                RegionOriginNote::Plain { span, msg: fluent::infer::reborrow }
-                    .add_to_diagnostic(err)
-            }
+            infer::Reborrow(span) => RegionOriginNote::Plain { span, msg: fluent::infer::reborrow }
+                .add_to_diagnostic(err),
             infer::ReborrowUpvar(span, ref upvar_id) => {
                 let var_name = self.tcx.hir().name(upvar_id.var_path.hir_id);
                 RegionOriginNote::WithName {
@@ -46,7 +32,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                 .add_to_diagnostic(err);
             }
             infer::RelateObjectBound(span) => {
-                label_or_note(span, fluent::infer::relate_object_bound);
                 RegionOriginNote::Plain { span, msg: fluent::infer::relate_object_bound }
                     .add_to_diagnostic(err);
             }