1 use rustc_errors::{fluent, AddSubdiagnostic, DiagnosticMessage, DiagnosticStyledString};
2 use rustc_hir::FnRetTy;
3 use rustc_macros::SessionDiagnostic;
4 use rustc_span::{BytePos, Span};
6 #[derive(SessionDiagnostic)]
7 #[diag(infer::opaque_hidden_type)]
8 pub struct OpaqueHiddenTypeDiag {
12 #[note(infer::opaque_type)]
13 pub opaque_type: Span,
14 #[note(infer::hidden_type)]
15 pub hidden_type: Span,
18 #[derive(SessionDiagnostic)]
19 #[diag(infer::type_annotations_needed, code = "E0282")]
20 pub struct AnnotationRequired<'a> {
23 pub source_kind: &'static str,
24 pub source_name: &'a str,
26 pub failure_span: Option<Span>,
28 pub bad_label: Option<InferenceBadError<'a>>,
30 pub infer_subdiags: Vec<SourceKindSubdiag<'a>>,
32 pub multi_suggestions: Vec<SourceKindMultiSuggestion<'a>>,
35 // Copy of `AnnotationRequired` for E0283
36 #[derive(SessionDiagnostic)]
37 #[diag(infer::type_annotations_needed, code = "E0283")]
38 pub struct AmbigousImpl<'a> {
41 pub source_kind: &'static str,
42 pub source_name: &'a str,
44 pub failure_span: Option<Span>,
46 pub bad_label: Option<InferenceBadError<'a>>,
48 pub infer_subdiags: Vec<SourceKindSubdiag<'a>>,
50 pub multi_suggestions: Vec<SourceKindMultiSuggestion<'a>>,
53 // Copy of `AnnotationRequired` for E0284
54 #[derive(SessionDiagnostic)]
55 #[diag(infer::type_annotations_needed, code = "E0284")]
56 pub struct AmbigousReturn<'a> {
59 pub source_kind: &'static str,
60 pub source_name: &'a str,
62 pub failure_span: Option<Span>,
64 pub bad_label: Option<InferenceBadError<'a>>,
66 pub infer_subdiags: Vec<SourceKindSubdiag<'a>>,
68 pub multi_suggestions: Vec<SourceKindMultiSuggestion<'a>>,
71 #[derive(SessionDiagnostic)]
72 #[diag(infer::need_type_info_in_generator, code = "E0698")]
73 pub struct NeedTypeInfoInGenerator<'a> {
76 pub generator_kind: &'static str,
78 pub bad_label: InferenceBadError<'a>,
81 // Used when a better one isn't available
82 #[derive(SessionSubdiagnostic)]
83 #[label(infer::label_bad)]
84 pub struct InferenceBadError<'a> {
87 pub bad_kind: &'static str,
88 pub prefix_kind: &'static str,
91 pub parent_prefix: &'a str,
92 pub parent_name: String,
96 #[derive(SessionSubdiagnostic)]
97 pub enum SourceKindSubdiag<'a> {
99 infer::source_kind_subdiag_let,
100 code = ": {type_name}",
101 applicability = "has-placeholders"
109 x_kind: &'static str,
110 prefix_kind: &'static str,
114 #[label(infer::source_kind_subdiag_generic_label)]
121 parent_prefix: String,
124 #[suggestion_verbose(
125 infer::source_kind_subdiag_generic_suggestion,
127 applicability = "has-placeholders"
137 // Has to be implemented manually because multipart suggestions are not supported by the derive macro.
138 // Would be a part of `SourceKindSubdiag` otherwise.
139 pub enum SourceKindMultiSuggestion<'a> {
144 successor: (&'a str, BytePos),
148 data: &'a FnRetTy<'a>,
149 should_wrap_expr: Option<Span>,
153 impl AddSubdiagnostic for SourceKindMultiSuggestion<'_> {
154 fn add_to_diagnostic(self, diag: &mut rustc_errors::Diagnostic) {
156 Self::FullyQualified { span, def_path, adjustment, successor } => {
157 let suggestion = vec![
158 (span.shrink_to_lo(), format!("{def_path}({adjustment}")),
159 (span.shrink_to_hi().with_hi(successor.1), successor.0.to_string()),
161 diag.multipart_suggestion_verbose(
162 fluent::infer::source_kind_fully_qualified,
164 rustc_errors::Applicability::HasPlaceholders,
167 Self::ClosureReturn { ty_info, data, should_wrap_expr } => {
168 let (arrow, post) = match data {
169 FnRetTy::DefaultReturn(_) => ("-> ", " "),
172 let suggestion = match should_wrap_expr {
173 Some(end_span) => vec![
174 (data.span(), format!("{}{}{}{{ ", arrow, ty_info, post)),
175 (end_span, " }".to_string()),
177 None => vec![(data.span(), format!("{}{}{}", arrow, ty_info, post))],
179 diag.multipart_suggestion_verbose(
180 fluent::infer::source_kind_closure_return,
182 rustc_errors::Applicability::HasPlaceholders,
189 pub enum RegionOriginNote<'a> {
192 msg: DiagnosticMessage,
196 msg: DiagnosticMessage,
202 requirement: &'static str,
203 expected_found: Option<(DiagnosticStyledString, DiagnosticStyledString)>,
207 impl AddSubdiagnostic for RegionOriginNote<'_> {
208 fn add_to_diagnostic(self, diag: &mut rustc_errors::Diagnostic) {
209 let mut label_or_note = |span, msg: DiagnosticMessage| {
210 let sub_count = diag.children.iter().filter(|d| d.span.is_dummy()).count();
211 let expanded_sub_count = diag.children.iter().filter(|d| !d.span.is_dummy()).count();
212 let span_is_primary = diag.span.primary_spans().iter().all(|&sp| sp == span);
213 if span_is_primary && sub_count == 0 && expanded_sub_count == 0 {
214 diag.span_label(span, msg);
215 } else if span_is_primary && expanded_sub_count == 0 {
218 diag.span_note(span, msg);
222 RegionOriginNote::Plain { span, msg } => {
223 label_or_note(span, msg);
225 RegionOriginNote::WithName { span, msg, name, continues } => {
226 label_or_note(span, msg);
227 diag.set_arg("name", name);
228 diag.set_arg("continues", continues);
230 RegionOriginNote::WithRequirement {
233 expected_found: Some((expected, found)),
235 label_or_note(span, fluent::infer::subtype);
236 diag.set_arg("requirement", requirement);
238 diag.note_expected_found(&"", expected, &"", found);
240 RegionOriginNote::WithRequirement { span, requirement, expected_found: None } => {
241 // FIXME: this really should be handled at some earlier stage. Our
242 // handling of region checking when type errors are present is
244 label_or_note(span, fluent::infer::subtype_2);
245 diag.set_arg("requirement", requirement);