2022-08-28 16:45:19 +00:00
|
|
|
use hir::GenericParamKind;
|
|
|
|
use rustc_errors::{
|
2022-10-03 13:09:05 +00:00
|
|
|
fluent, AddToDiagnostic, Applicability, Diagnostic, DiagnosticMessage, DiagnosticStyledString,
|
2022-11-03 18:50:52 +00:00
|
|
|
IntoDiagnosticArg, MultiSpan, SubdiagnosticMessage,
|
2022-08-28 16:45:19 +00:00
|
|
|
};
|
|
|
|
use rustc_hir as hir;
|
2022-09-22 14:29:21 +00:00
|
|
|
use rustc_hir::FnRetTy;
|
2022-09-15 04:01:44 +00:00
|
|
|
use rustc_macros::{Diagnostic, Subdiagnostic};
|
2022-11-03 18:50:52 +00:00
|
|
|
use rustc_middle::ty::print::TraitRefPrintOnlyTraitPath;
|
|
|
|
use rustc_middle::ty::{Binder, FnSig, Region, Ty, TyCtxt};
|
2022-08-28 16:45:19 +00:00
|
|
|
use rustc_span::symbol::kw;
|
2022-09-16 23:54:59 +00:00
|
|
|
use rustc_span::Symbol;
|
2022-08-28 16:45:19 +00:00
|
|
|
use rustc_span::{symbol::Ident, BytePos, Span};
|
2022-08-21 17:56:00 +00:00
|
|
|
|
2022-11-03 18:50:52 +00:00
|
|
|
use crate::infer::error_reporting::nice_region_error::placeholder_error::Highlighted;
|
2022-08-24 12:46:29 +00:00
|
|
|
use crate::infer::error_reporting::{
|
|
|
|
need_type_info::{GeneratorKindAsDiagArg, UnderspecifiedArgKind},
|
|
|
|
ObligationCauseAsDiagArg,
|
|
|
|
};
|
|
|
|
|
2022-08-30 15:28:50 +00:00
|
|
|
pub mod note_and_explain;
|
|
|
|
|
2022-09-15 04:01:44 +00:00
|
|
|
#[derive(Diagnostic)]
|
2022-10-22 09:07:54 +00:00
|
|
|
#[diag(infer_opaque_hidden_type)]
|
2022-08-21 17:56:00 +00:00
|
|
|
pub struct OpaqueHiddenTypeDiag {
|
|
|
|
#[primary_span]
|
|
|
|
#[label]
|
|
|
|
pub span: Span,
|
2022-10-22 09:07:54 +00:00
|
|
|
#[note(opaque_type)]
|
2022-08-21 17:56:00 +00:00
|
|
|
pub opaque_type: Span,
|
2022-10-22 09:07:54 +00:00
|
|
|
#[note(hidden_type)]
|
2022-08-21 17:56:00 +00:00
|
|
|
pub hidden_type: Span,
|
|
|
|
}
|
|
|
|
|
2022-09-15 04:01:44 +00:00
|
|
|
#[derive(Diagnostic)]
|
2022-10-22 09:07:54 +00:00
|
|
|
#[diag(infer_type_annotations_needed, code = "E0282")]
|
2022-08-21 17:56:00 +00:00
|
|
|
pub struct AnnotationRequired<'a> {
|
|
|
|
#[primary_span]
|
|
|
|
pub span: Span,
|
|
|
|
pub source_kind: &'static str,
|
|
|
|
pub source_name: &'a str,
|
|
|
|
#[label]
|
|
|
|
pub failure_span: Option<Span>,
|
|
|
|
#[subdiagnostic]
|
|
|
|
pub bad_label: Option<InferenceBadError<'a>>,
|
|
|
|
#[subdiagnostic]
|
|
|
|
pub infer_subdiags: Vec<SourceKindSubdiag<'a>>,
|
|
|
|
#[subdiagnostic]
|
|
|
|
pub multi_suggestions: Vec<SourceKindMultiSuggestion<'a>>,
|
|
|
|
}
|
|
|
|
|
|
|
|
// Copy of `AnnotationRequired` for E0283
|
2022-09-15 04:01:44 +00:00
|
|
|
#[derive(Diagnostic)]
|
2022-10-22 09:07:54 +00:00
|
|
|
#[diag(infer_type_annotations_needed, code = "E0283")]
|
2022-08-21 17:56:00 +00:00
|
|
|
pub struct AmbigousImpl<'a> {
|
|
|
|
#[primary_span]
|
|
|
|
pub span: Span,
|
|
|
|
pub source_kind: &'static str,
|
|
|
|
pub source_name: &'a str,
|
|
|
|
#[label]
|
|
|
|
pub failure_span: Option<Span>,
|
|
|
|
#[subdiagnostic]
|
|
|
|
pub bad_label: Option<InferenceBadError<'a>>,
|
|
|
|
#[subdiagnostic]
|
|
|
|
pub infer_subdiags: Vec<SourceKindSubdiag<'a>>,
|
|
|
|
#[subdiagnostic]
|
|
|
|
pub multi_suggestions: Vec<SourceKindMultiSuggestion<'a>>,
|
|
|
|
}
|
|
|
|
|
|
|
|
// Copy of `AnnotationRequired` for E0284
|
2022-09-15 04:01:44 +00:00
|
|
|
#[derive(Diagnostic)]
|
2022-10-22 09:07:54 +00:00
|
|
|
#[diag(infer_type_annotations_needed, code = "E0284")]
|
2022-08-21 17:56:00 +00:00
|
|
|
pub struct AmbigousReturn<'a> {
|
|
|
|
#[primary_span]
|
|
|
|
pub span: Span,
|
|
|
|
pub source_kind: &'static str,
|
|
|
|
pub source_name: &'a str,
|
|
|
|
#[label]
|
|
|
|
pub failure_span: Option<Span>,
|
|
|
|
#[subdiagnostic]
|
|
|
|
pub bad_label: Option<InferenceBadError<'a>>,
|
|
|
|
#[subdiagnostic]
|
|
|
|
pub infer_subdiags: Vec<SourceKindSubdiag<'a>>,
|
|
|
|
#[subdiagnostic]
|
|
|
|
pub multi_suggestions: Vec<SourceKindMultiSuggestion<'a>>,
|
|
|
|
}
|
|
|
|
|
2022-09-15 04:01:44 +00:00
|
|
|
#[derive(Diagnostic)]
|
2022-10-22 09:07:54 +00:00
|
|
|
#[diag(infer_need_type_info_in_generator, code = "E0698")]
|
2022-08-21 17:56:00 +00:00
|
|
|
pub struct NeedTypeInfoInGenerator<'a> {
|
|
|
|
#[primary_span]
|
|
|
|
pub span: Span,
|
2022-08-24 12:46:29 +00:00
|
|
|
pub generator_kind: GeneratorKindAsDiagArg,
|
2022-08-21 17:56:00 +00:00
|
|
|
#[subdiagnostic]
|
|
|
|
pub bad_label: InferenceBadError<'a>,
|
|
|
|
}
|
|
|
|
|
|
|
|
// Used when a better one isn't available
|
2022-09-15 04:01:44 +00:00
|
|
|
#[derive(Subdiagnostic)]
|
2022-10-22 09:07:54 +00:00
|
|
|
#[label(infer_label_bad)]
|
2022-08-21 17:56:00 +00:00
|
|
|
pub struct InferenceBadError<'a> {
|
|
|
|
#[primary_span]
|
|
|
|
pub span: Span,
|
|
|
|
pub bad_kind: &'static str,
|
2022-08-24 12:46:29 +00:00
|
|
|
pub prefix_kind: UnderspecifiedArgKind,
|
2022-08-21 17:56:00 +00:00
|
|
|
pub has_parent: bool,
|
|
|
|
pub prefix: &'a str,
|
|
|
|
pub parent_prefix: &'a str,
|
|
|
|
pub parent_name: String,
|
|
|
|
pub name: String,
|
|
|
|
}
|
|
|
|
|
2022-09-15 04:01:44 +00:00
|
|
|
#[derive(Subdiagnostic)]
|
2022-08-21 17:56:00 +00:00
|
|
|
pub enum SourceKindSubdiag<'a> {
|
2022-10-22 13:48:55 +00:00
|
|
|
#[suggestion(
|
2022-10-22 09:07:54 +00:00
|
|
|
infer_source_kind_subdiag_let,
|
2022-10-22 13:48:55 +00:00
|
|
|
style = "verbose",
|
2022-08-21 17:56:00 +00:00
|
|
|
code = ": {type_name}",
|
|
|
|
applicability = "has-placeholders"
|
|
|
|
)]
|
|
|
|
LetLike {
|
|
|
|
#[primary_span]
|
|
|
|
span: Span,
|
|
|
|
name: String,
|
|
|
|
type_name: String,
|
|
|
|
kind: &'static str,
|
|
|
|
x_kind: &'static str,
|
2022-08-24 12:46:29 +00:00
|
|
|
prefix_kind: UnderspecifiedArgKind,
|
2022-08-21 17:56:00 +00:00
|
|
|
prefix: &'a str,
|
|
|
|
arg_name: String,
|
|
|
|
},
|
2022-10-22 09:07:54 +00:00
|
|
|
#[label(infer_source_kind_subdiag_generic_label)]
|
2022-08-21 17:56:00 +00:00
|
|
|
GenericLabel {
|
|
|
|
#[primary_span]
|
|
|
|
span: Span,
|
|
|
|
is_type: bool,
|
|
|
|
param_name: String,
|
|
|
|
parent_exists: bool,
|
|
|
|
parent_prefix: String,
|
|
|
|
parent_name: String,
|
|
|
|
},
|
2022-10-22 13:48:55 +00:00
|
|
|
#[suggestion(
|
2022-10-22 09:07:54 +00:00
|
|
|
infer_source_kind_subdiag_generic_suggestion,
|
2022-10-22 13:48:55 +00:00
|
|
|
style = "verbose",
|
2022-08-21 17:56:00 +00:00
|
|
|
code = "::<{args}>",
|
|
|
|
applicability = "has-placeholders"
|
|
|
|
)]
|
|
|
|
GenericSuggestion {
|
|
|
|
#[primary_span]
|
|
|
|
span: Span,
|
|
|
|
arg_count: usize,
|
|
|
|
args: String,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2022-09-15 04:01:44 +00:00
|
|
|
#[derive(Subdiagnostic)]
|
2022-08-21 17:56:00 +00:00
|
|
|
pub enum SourceKindMultiSuggestion<'a> {
|
2022-10-22 13:48:55 +00:00
|
|
|
#[multipart_suggestion(
|
2022-10-22 09:07:54 +00:00
|
|
|
infer_source_kind_fully_qualified,
|
2022-10-22 13:48:55 +00:00
|
|
|
style = "verbose",
|
2022-09-06 19:18:56 +00:00
|
|
|
applicability = "has-placeholders"
|
|
|
|
)]
|
2022-08-21 17:56:00 +00:00
|
|
|
FullyQualified {
|
2022-09-06 19:18:56 +00:00
|
|
|
#[suggestion_part(code = "{def_path}({adjustment}")]
|
|
|
|
span_lo: Span,
|
|
|
|
#[suggestion_part(code = "{successor_pos}")]
|
|
|
|
span_hi: Span,
|
2022-08-21 17:56:00 +00:00
|
|
|
def_path: String,
|
|
|
|
adjustment: &'a str,
|
2022-09-06 19:18:56 +00:00
|
|
|
successor_pos: &'a str,
|
2022-08-21 17:56:00 +00:00
|
|
|
},
|
2022-10-22 13:48:55 +00:00
|
|
|
#[multipart_suggestion(
|
2022-10-22 09:07:54 +00:00
|
|
|
infer_source_kind_closure_return,
|
2022-10-22 13:48:55 +00:00
|
|
|
style = "verbose",
|
2022-09-06 19:18:56 +00:00
|
|
|
applicability = "has-placeholders"
|
|
|
|
)]
|
2022-08-21 17:56:00 +00:00
|
|
|
ClosureReturn {
|
2022-09-06 19:18:56 +00:00
|
|
|
#[suggestion_part(code = "{start_span_code}")]
|
|
|
|
start_span: Span,
|
|
|
|
start_span_code: String,
|
2022-09-06 19:55:49 +00:00
|
|
|
#[suggestion_part(code = " }}")]
|
2022-09-06 19:18:56 +00:00
|
|
|
end_span: Option<Span>,
|
2022-08-21 17:56:00 +00:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2022-11-08 08:04:14 +00:00
|
|
|
#[derive(Subdiagnostic)]
|
|
|
|
#[suggestion(
|
|
|
|
infer_suggest_add_let_for_letchains,
|
|
|
|
style = "verbose",
|
|
|
|
applicability = "machine-applicable",
|
|
|
|
code = "let "
|
|
|
|
)]
|
|
|
|
pub(crate) struct SuggAddLetForLetChains {
|
|
|
|
#[primary_span]
|
|
|
|
pub span: Span,
|
|
|
|
}
|
|
|
|
|
2022-09-06 19:18:56 +00:00
|
|
|
impl<'a> SourceKindMultiSuggestion<'a> {
|
|
|
|
pub fn new_fully_qualified(
|
|
|
|
span: Span,
|
|
|
|
def_path: String,
|
|
|
|
adjustment: &'a str,
|
|
|
|
successor: (&'a str, BytePos),
|
|
|
|
) -> Self {
|
|
|
|
Self::FullyQualified {
|
|
|
|
span_lo: span.shrink_to_lo(),
|
|
|
|
span_hi: span.shrink_to_hi().with_hi(successor.1),
|
|
|
|
def_path,
|
|
|
|
adjustment,
|
|
|
|
successor_pos: successor.0,
|
2022-08-21 17:56:00 +00:00
|
|
|
}
|
|
|
|
}
|
2022-09-06 19:18:56 +00:00
|
|
|
|
|
|
|
pub fn new_closure_return(
|
|
|
|
ty_info: String,
|
|
|
|
data: &'a FnRetTy<'a>,
|
|
|
|
should_wrap_expr: Option<Span>,
|
|
|
|
) -> Self {
|
|
|
|
let (arrow, post) = match data {
|
|
|
|
FnRetTy::DefaultReturn(_) => ("-> ", " "),
|
|
|
|
_ => ("", ""),
|
|
|
|
};
|
|
|
|
let (start_span, start_span_code, end_span) = match should_wrap_expr {
|
|
|
|
Some(end_span) => {
|
|
|
|
(data.span(), format!("{}{}{}{{ ", arrow, ty_info, post), Some(end_span))
|
|
|
|
}
|
|
|
|
None => (data.span(), format!("{}{}{}", arrow, ty_info, post), None),
|
|
|
|
};
|
|
|
|
Self::ClosureReturn { start_span, start_span_code, end_span }
|
|
|
|
}
|
2022-08-21 17:56:00 +00:00
|
|
|
}
|
2022-08-23 10:48:14 +00:00
|
|
|
|
|
|
|
pub enum RegionOriginNote<'a> {
|
|
|
|
Plain {
|
|
|
|
span: Span,
|
|
|
|
msg: DiagnosticMessage,
|
|
|
|
},
|
|
|
|
WithName {
|
|
|
|
span: Span,
|
|
|
|
msg: DiagnosticMessage,
|
|
|
|
name: &'a str,
|
|
|
|
continues: bool,
|
|
|
|
},
|
|
|
|
WithRequirement {
|
|
|
|
span: Span,
|
2022-08-24 12:46:29 +00:00
|
|
|
requirement: ObligationCauseAsDiagArg<'a>,
|
2022-08-23 10:48:14 +00:00
|
|
|
expected_found: Option<(DiagnosticStyledString, DiagnosticStyledString)>,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2022-09-15 04:01:44 +00:00
|
|
|
impl AddToDiagnostic for RegionOriginNote<'_> {
|
2022-10-03 13:09:05 +00:00
|
|
|
fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
|
|
|
|
where
|
|
|
|
F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
|
|
|
|
{
|
2022-08-23 10:48:14 +00:00
|
|
|
let mut label_or_note = |span, msg: DiagnosticMessage| {
|
|
|
|
let sub_count = diag.children.iter().filter(|d| d.span.is_dummy()).count();
|
|
|
|
let expanded_sub_count = diag.children.iter().filter(|d| !d.span.is_dummy()).count();
|
|
|
|
let span_is_primary = diag.span.primary_spans().iter().all(|&sp| sp == span);
|
|
|
|
if span_is_primary && sub_count == 0 && expanded_sub_count == 0 {
|
|
|
|
diag.span_label(span, msg);
|
|
|
|
} else if span_is_primary && expanded_sub_count == 0 {
|
|
|
|
diag.note(msg);
|
|
|
|
} else {
|
|
|
|
diag.span_note(span, msg);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
match self {
|
|
|
|
RegionOriginNote::Plain { span, msg } => {
|
|
|
|
label_or_note(span, msg);
|
|
|
|
}
|
|
|
|
RegionOriginNote::WithName { span, msg, name, continues } => {
|
|
|
|
label_or_note(span, msg);
|
|
|
|
diag.set_arg("name", name);
|
|
|
|
diag.set_arg("continues", continues);
|
|
|
|
}
|
|
|
|
RegionOriginNote::WithRequirement {
|
|
|
|
span,
|
|
|
|
requirement,
|
|
|
|
expected_found: Some((expected, found)),
|
|
|
|
} => {
|
2022-10-22 09:07:54 +00:00
|
|
|
label_or_note(span, fluent::infer_subtype);
|
2022-08-23 10:48:14 +00:00
|
|
|
diag.set_arg("requirement", requirement);
|
|
|
|
|
|
|
|
diag.note_expected_found(&"", expected, &"", found);
|
|
|
|
}
|
|
|
|
RegionOriginNote::WithRequirement { span, requirement, expected_found: None } => {
|
|
|
|
// FIXME: this really should be handled at some earlier stage. Our
|
|
|
|
// handling of region checking when type errors are present is
|
|
|
|
// *terrible*.
|
2022-10-22 09:07:54 +00:00
|
|
|
label_or_note(span, fluent::infer_subtype_2);
|
2022-08-23 10:48:14 +00:00
|
|
|
diag.set_arg("requirement", requirement);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
2022-08-28 16:45:19 +00:00
|
|
|
|
|
|
|
pub enum LifetimeMismatchLabels {
|
|
|
|
InRet {
|
|
|
|
param_span: Span,
|
|
|
|
ret_span: Span,
|
|
|
|
span: Span,
|
|
|
|
label_var1: Option<Ident>,
|
|
|
|
},
|
|
|
|
Normal {
|
|
|
|
hir_equal: bool,
|
|
|
|
ty_sup: Span,
|
|
|
|
ty_sub: Span,
|
|
|
|
span: Span,
|
2022-08-31 12:02:11 +00:00
|
|
|
sup: Option<Ident>,
|
|
|
|
sub: Option<Ident>,
|
2022-08-28 16:45:19 +00:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2022-09-15 04:01:44 +00:00
|
|
|
impl AddToDiagnostic for LifetimeMismatchLabels {
|
2022-10-03 13:09:05 +00:00
|
|
|
fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
|
|
|
|
where
|
|
|
|
F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
|
|
|
|
{
|
2022-08-28 16:45:19 +00:00
|
|
|
match self {
|
|
|
|
LifetimeMismatchLabels::InRet { param_span, ret_span, span, label_var1 } => {
|
2022-10-22 09:07:54 +00:00
|
|
|
diag.span_label(param_span, fluent::infer_declared_different);
|
|
|
|
diag.span_label(ret_span, fluent::infer_nothing);
|
|
|
|
diag.span_label(span, fluent::infer_data_returned);
|
2022-08-28 16:45:19 +00:00
|
|
|
diag.set_arg("label_var1_exists", label_var1.is_some());
|
|
|
|
diag.set_arg("label_var1", label_var1.map(|x| x.to_string()).unwrap_or_default());
|
|
|
|
}
|
|
|
|
LifetimeMismatchLabels::Normal {
|
|
|
|
hir_equal,
|
|
|
|
ty_sup,
|
|
|
|
ty_sub,
|
|
|
|
span,
|
2022-08-31 12:02:11 +00:00
|
|
|
sup: label_var1,
|
|
|
|
sub: label_var2,
|
2022-08-28 16:45:19 +00:00
|
|
|
} => {
|
|
|
|
if hir_equal {
|
2022-10-22 09:07:54 +00:00
|
|
|
diag.span_label(ty_sup, fluent::infer_declared_multiple);
|
|
|
|
diag.span_label(ty_sub, fluent::infer_nothing);
|
|
|
|
diag.span_label(span, fluent::infer_data_lifetime_flow);
|
2022-08-28 16:45:19 +00:00
|
|
|
} else {
|
2022-10-22 09:07:54 +00:00
|
|
|
diag.span_label(ty_sup, fluent::infer_types_declared_different);
|
|
|
|
diag.span_label(ty_sub, fluent::infer_nothing);
|
|
|
|
diag.span_label(span, fluent::infer_data_flows);
|
2022-08-28 16:45:19 +00:00
|
|
|
diag.set_arg("label_var1_exists", label_var1.is_some());
|
|
|
|
diag.set_arg(
|
|
|
|
"label_var1",
|
|
|
|
label_var1.map(|x| x.to_string()).unwrap_or_default(),
|
|
|
|
);
|
|
|
|
diag.set_arg("label_var2_exists", label_var2.is_some());
|
|
|
|
diag.set_arg(
|
|
|
|
"label_var2",
|
|
|
|
label_var2.map(|x| x.to_string()).unwrap_or_default(),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct AddLifetimeParamsSuggestion<'a> {
|
|
|
|
pub tcx: TyCtxt<'a>,
|
|
|
|
pub sub: Region<'a>,
|
2022-09-08 19:28:00 +00:00
|
|
|
pub ty_sup: &'a hir::Ty<'a>,
|
|
|
|
pub ty_sub: &'a hir::Ty<'a>,
|
2022-08-28 16:45:19 +00:00
|
|
|
pub add_note: bool,
|
|
|
|
}
|
|
|
|
|
2022-09-15 04:01:44 +00:00
|
|
|
impl AddToDiagnostic for AddLifetimeParamsSuggestion<'_> {
|
2022-10-03 13:09:05 +00:00
|
|
|
fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
|
|
|
|
where
|
|
|
|
F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
|
|
|
|
{
|
2022-08-28 16:45:19 +00:00
|
|
|
let mut mk_suggestion = || {
|
|
|
|
let (
|
2022-12-28 17:06:11 +00:00
|
|
|
hir::Ty { kind: hir::TyKind::Ref(lifetime_sub, _), .. },
|
|
|
|
hir::Ty { kind: hir::TyKind::Ref(lifetime_sup, _), .. },
|
2022-08-28 16:45:19 +00:00
|
|
|
) = (self.ty_sub, self.ty_sup) else {
|
|
|
|
return false;
|
|
|
|
};
|
|
|
|
|
2022-11-05 22:41:07 +00:00
|
|
|
if !lifetime_sub.is_anonymous() || !lifetime_sup.is_anonymous() {
|
2022-08-28 16:45:19 +00:00
|
|
|
return false;
|
|
|
|
};
|
|
|
|
|
|
|
|
let Some(anon_reg) = self.tcx.is_suitable_region(self.sub) else {
|
|
|
|
return false;
|
|
|
|
};
|
|
|
|
|
|
|
|
let hir_id = self.tcx.hir().local_def_id_to_hir_id(anon_reg.def_id);
|
|
|
|
|
|
|
|
let node = self.tcx.hir().get(hir_id);
|
|
|
|
let is_impl = matches!(&node, hir::Node::ImplItem(_));
|
|
|
|
let generics = match node {
|
|
|
|
hir::Node::Item(&hir::Item {
|
|
|
|
kind: hir::ItemKind::Fn(_, ref generics, ..),
|
|
|
|
..
|
|
|
|
})
|
|
|
|
| hir::Node::TraitItem(&hir::TraitItem { ref generics, .. })
|
|
|
|
| hir::Node::ImplItem(&hir::ImplItem { ref generics, .. }) => generics,
|
|
|
|
_ => return false,
|
|
|
|
};
|
|
|
|
|
|
|
|
let suggestion_param_name = generics
|
|
|
|
.params
|
|
|
|
.iter()
|
|
|
|
.filter(|p| matches!(p.kind, GenericParamKind::Lifetime { .. }))
|
|
|
|
.map(|p| p.name.ident().name)
|
|
|
|
.find(|i| *i != kw::UnderscoreLifetime);
|
|
|
|
let introduce_new = suggestion_param_name.is_none();
|
|
|
|
let suggestion_param_name =
|
|
|
|
suggestion_param_name.map(|n| n.to_string()).unwrap_or_else(|| "'a".to_owned());
|
|
|
|
|
2022-11-05 22:41:07 +00:00
|
|
|
debug!(?lifetime_sup.ident.span);
|
|
|
|
debug!(?lifetime_sub.ident.span);
|
|
|
|
let make_suggestion = |ident: Ident| {
|
|
|
|
let sugg = if ident.name == kw::Empty {
|
|
|
|
format!("{}, ", suggestion_param_name)
|
|
|
|
} else if ident.name == kw::UnderscoreLifetime && ident.span.is_empty() {
|
|
|
|
format!("{} ", suggestion_param_name)
|
2022-08-28 16:45:19 +00:00
|
|
|
} else {
|
2022-11-05 22:41:07 +00:00
|
|
|
suggestion_param_name.clone()
|
|
|
|
};
|
|
|
|
(ident.span, sugg)
|
2022-08-28 16:45:19 +00:00
|
|
|
};
|
|
|
|
let mut suggestions =
|
2022-11-05 22:41:07 +00:00
|
|
|
vec![make_suggestion(lifetime_sub.ident), make_suggestion(lifetime_sup.ident)];
|
2022-08-28 16:45:19 +00:00
|
|
|
|
|
|
|
if introduce_new {
|
|
|
|
let new_param_suggestion = if let Some(first) =
|
|
|
|
generics.params.iter().find(|p| !p.name.ident().span.is_empty())
|
|
|
|
{
|
|
|
|
(first.span.shrink_to_lo(), format!("{}, ", suggestion_param_name))
|
|
|
|
} else {
|
|
|
|
(generics.span, format!("<{}>", suggestion_param_name))
|
|
|
|
};
|
|
|
|
|
|
|
|
suggestions.push(new_param_suggestion);
|
|
|
|
}
|
|
|
|
|
|
|
|
diag.multipart_suggestion(
|
2022-10-22 09:07:54 +00:00
|
|
|
fluent::infer_lifetime_param_suggestion,
|
2022-08-28 16:45:19 +00:00
|
|
|
suggestions,
|
|
|
|
Applicability::MaybeIncorrect,
|
|
|
|
);
|
|
|
|
diag.set_arg("is_impl", is_impl);
|
|
|
|
true
|
|
|
|
};
|
|
|
|
if mk_suggestion() && self.add_note {
|
2022-10-22 09:07:54 +00:00
|
|
|
diag.note(fluent::infer_lifetime_param_suggestion_elided);
|
2022-08-28 16:45:19 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-15 04:01:44 +00:00
|
|
|
#[derive(Diagnostic)]
|
2022-10-22 09:07:54 +00:00
|
|
|
#[diag(infer_lifetime_mismatch, code = "E0623")]
|
2022-08-28 16:45:19 +00:00
|
|
|
pub struct LifetimeMismatch<'a> {
|
|
|
|
#[primary_span]
|
|
|
|
pub span: Span,
|
|
|
|
#[subdiagnostic]
|
|
|
|
pub labels: LifetimeMismatchLabels,
|
|
|
|
#[subdiagnostic]
|
|
|
|
pub suggestion: AddLifetimeParamsSuggestion<'a>,
|
|
|
|
}
|
2022-08-30 15:28:50 +00:00
|
|
|
|
2022-08-31 12:02:11 +00:00
|
|
|
pub struct IntroducesStaticBecauseUnmetLifetimeReq {
|
|
|
|
pub unmet_requirements: MultiSpan,
|
|
|
|
pub binding_span: Span,
|
|
|
|
}
|
2022-08-30 15:28:50 +00:00
|
|
|
|
2022-09-15 04:01:44 +00:00
|
|
|
impl AddToDiagnostic for IntroducesStaticBecauseUnmetLifetimeReq {
|
2022-10-03 13:09:05 +00:00
|
|
|
fn add_to_diagnostic_with<F>(mut self, diag: &mut Diagnostic, _: F)
|
|
|
|
where
|
|
|
|
F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
|
|
|
|
{
|
2022-08-31 12:02:11 +00:00
|
|
|
self.unmet_requirements
|
2022-10-22 09:07:54 +00:00
|
|
|
.push_span_label(self.binding_span, fluent::infer_msl_introduces_static);
|
|
|
|
diag.span_note(self.unmet_requirements, fluent::infer_msl_unmet_req);
|
2022-08-30 15:28:50 +00:00
|
|
|
}
|
2022-08-31 12:02:11 +00:00
|
|
|
}
|
2022-08-30 15:28:50 +00:00
|
|
|
|
2022-10-14 12:25:59 +00:00
|
|
|
// FIXME(#100717): replace with a `Option<Span>` when subdiagnostic supports that
|
|
|
|
#[derive(Subdiagnostic)]
|
|
|
|
pub enum DoesNotOutliveStaticFromImpl {
|
2022-10-22 09:07:54 +00:00
|
|
|
#[note(infer_does_not_outlive_static_from_impl)]
|
2022-10-14 12:25:59 +00:00
|
|
|
Spanned {
|
|
|
|
#[primary_span]
|
|
|
|
span: Span,
|
|
|
|
},
|
2022-10-22 09:07:54 +00:00
|
|
|
#[note(infer_does_not_outlive_static_from_impl)]
|
2022-10-14 12:25:59 +00:00
|
|
|
Unspanned,
|
2022-09-05 16:04:35 +00:00
|
|
|
}
|
|
|
|
|
2022-10-14 12:25:59 +00:00
|
|
|
#[derive(Subdiagnostic)]
|
|
|
|
pub enum ImplicitStaticLifetimeSubdiag {
|
2022-10-22 09:07:54 +00:00
|
|
|
#[note(infer_implicit_static_lifetime_note)]
|
2022-10-14 12:25:59 +00:00
|
|
|
Note {
|
|
|
|
#[primary_span]
|
|
|
|
span: Span,
|
|
|
|
},
|
2022-10-22 13:48:55 +00:00
|
|
|
#[suggestion(
|
2022-10-22 09:07:54 +00:00
|
|
|
infer_implicit_static_lifetime_suggestion,
|
2022-10-22 13:48:55 +00:00
|
|
|
style = "verbose",
|
2022-10-14 12:25:59 +00:00
|
|
|
code = " + '_",
|
|
|
|
applicability = "maybe-incorrect"
|
|
|
|
)]
|
|
|
|
Sugg {
|
|
|
|
#[primary_span]
|
|
|
|
span: Span,
|
|
|
|
},
|
2022-08-31 12:02:11 +00:00
|
|
|
}
|
|
|
|
|
2022-09-15 04:01:44 +00:00
|
|
|
#[derive(Diagnostic)]
|
2022-10-22 09:07:54 +00:00
|
|
|
#[diag(infer_mismatched_static_lifetime)]
|
2022-08-31 12:02:11 +00:00
|
|
|
pub struct MismatchedStaticLifetime<'a> {
|
|
|
|
#[primary_span]
|
|
|
|
pub cause_span: Span,
|
|
|
|
#[subdiagnostic]
|
|
|
|
pub unmet_lifetime_reqs: IntroducesStaticBecauseUnmetLifetimeReq,
|
|
|
|
#[subdiagnostic]
|
|
|
|
pub expl: Option<note_and_explain::RegionExplanation<'a>>,
|
|
|
|
#[subdiagnostic]
|
2022-10-14 12:25:59 +00:00
|
|
|
pub does_not_outlive_static_from_impl: DoesNotOutliveStaticFromImpl,
|
2022-12-04 00:13:21 +00:00
|
|
|
#[subdiagnostic]
|
2022-10-14 12:25:59 +00:00
|
|
|
pub implicit_static_lifetimes: Vec<ImplicitStaticLifetimeSubdiag>,
|
2022-08-30 15:28:50 +00:00
|
|
|
}
|
2022-09-08 19:28:00 +00:00
|
|
|
|
2022-09-22 14:29:21 +00:00
|
|
|
#[derive(Diagnostic)]
|
2022-11-03 17:45:14 +00:00
|
|
|
pub enum ExplicitLifetimeRequired<'a> {
|
|
|
|
#[diag(infer_explicit_lifetime_required_with_ident, code = "E0621")]
|
|
|
|
WithIdent {
|
|
|
|
#[primary_span]
|
|
|
|
#[label]
|
|
|
|
span: Span,
|
|
|
|
simple_ident: Ident,
|
|
|
|
named: String,
|
|
|
|
#[suggestion(
|
|
|
|
infer_explicit_lifetime_required_sugg_with_ident,
|
|
|
|
code = "{new_ty}",
|
|
|
|
applicability = "unspecified"
|
|
|
|
)]
|
|
|
|
new_ty_span: Span,
|
|
|
|
#[skip_arg]
|
|
|
|
new_ty: Ty<'a>,
|
|
|
|
},
|
|
|
|
#[diag(infer_explicit_lifetime_required_with_param_type, code = "E0621")]
|
|
|
|
WithParamType {
|
|
|
|
#[primary_span]
|
|
|
|
#[label]
|
|
|
|
span: Span,
|
|
|
|
named: String,
|
|
|
|
#[suggestion(
|
|
|
|
infer_explicit_lifetime_required_sugg_with_param_type,
|
|
|
|
code = "{new_ty}",
|
|
|
|
applicability = "unspecified"
|
|
|
|
)]
|
|
|
|
new_ty_span: Span,
|
|
|
|
#[skip_arg]
|
|
|
|
new_ty: Ty<'a>,
|
|
|
|
},
|
2022-09-08 19:28:00 +00:00
|
|
|
}
|
2022-09-10 21:45:38 +00:00
|
|
|
|
2022-11-03 18:50:52 +00:00
|
|
|
pub enum TyOrSig<'tcx> {
|
|
|
|
Ty(Highlighted<'tcx, Ty<'tcx>>),
|
|
|
|
ClosureSig(Highlighted<'tcx, Binder<'tcx, FnSig<'tcx>>>),
|
|
|
|
}
|
|
|
|
|
|
|
|
impl IntoDiagnosticArg for TyOrSig<'_> {
|
|
|
|
fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
|
|
|
|
match self {
|
|
|
|
TyOrSig::Ty(ty) => ty.into_diagnostic_arg(),
|
|
|
|
TyOrSig::ClosureSig(sig) => sig.into_diagnostic_arg(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-22 14:29:21 +00:00
|
|
|
#[derive(Subdiagnostic)]
|
2022-11-03 18:50:52 +00:00
|
|
|
pub enum ActualImplExplNotes<'tcx> {
|
2022-10-24 16:06:45 +00:00
|
|
|
#[note(infer_actual_impl_expl_expected_signature_two)]
|
2022-09-29 14:10:43 +00:00
|
|
|
ExpectedSignatureTwo {
|
|
|
|
leading_ellipsis: bool,
|
2022-11-03 18:50:52 +00:00
|
|
|
ty_or_sig: TyOrSig<'tcx>,
|
|
|
|
trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
|
2022-09-29 14:10:43 +00:00
|
|
|
lifetime_1: usize,
|
|
|
|
lifetime_2: usize,
|
|
|
|
},
|
2022-10-24 16:06:45 +00:00
|
|
|
#[note(infer_actual_impl_expl_expected_signature_any)]
|
2022-09-29 14:10:43 +00:00
|
|
|
ExpectedSignatureAny {
|
|
|
|
leading_ellipsis: bool,
|
2022-11-03 18:50:52 +00:00
|
|
|
ty_or_sig: TyOrSig<'tcx>,
|
|
|
|
trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
|
2022-09-29 14:10:43 +00:00
|
|
|
lifetime_1: usize,
|
|
|
|
},
|
2022-10-24 16:06:45 +00:00
|
|
|
#[note(infer_actual_impl_expl_expected_signature_some)]
|
2022-09-29 14:10:43 +00:00
|
|
|
ExpectedSignatureSome {
|
|
|
|
leading_ellipsis: bool,
|
2022-11-03 18:50:52 +00:00
|
|
|
ty_or_sig: TyOrSig<'tcx>,
|
|
|
|
trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
|
2022-09-29 14:10:43 +00:00
|
|
|
lifetime_1: usize,
|
|
|
|
},
|
2022-10-24 16:06:45 +00:00
|
|
|
#[note(infer_actual_impl_expl_expected_signature_nothing)]
|
2022-11-03 18:50:52 +00:00
|
|
|
ExpectedSignatureNothing {
|
|
|
|
leading_ellipsis: bool,
|
|
|
|
ty_or_sig: TyOrSig<'tcx>,
|
|
|
|
trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
|
|
|
|
},
|
2022-10-24 16:06:45 +00:00
|
|
|
#[note(infer_actual_impl_expl_expected_passive_two)]
|
2022-09-29 14:10:43 +00:00
|
|
|
ExpectedPassiveTwo {
|
2022-09-10 21:45:38 +00:00
|
|
|
leading_ellipsis: bool,
|
2022-11-03 18:50:52 +00:00
|
|
|
ty_or_sig: TyOrSig<'tcx>,
|
|
|
|
trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
|
2022-09-10 21:45:38 +00:00
|
|
|
lifetime_1: usize,
|
|
|
|
lifetime_2: usize,
|
|
|
|
},
|
2022-10-24 16:06:45 +00:00
|
|
|
#[note(infer_actual_impl_expl_expected_passive_any)]
|
2022-09-29 14:10:43 +00:00
|
|
|
ExpectedPassiveAny {
|
|
|
|
leading_ellipsis: bool,
|
2022-11-03 18:50:52 +00:00
|
|
|
ty_or_sig: TyOrSig<'tcx>,
|
|
|
|
trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
|
2022-09-29 14:10:43 +00:00
|
|
|
lifetime_1: usize,
|
|
|
|
},
|
2022-10-24 16:06:45 +00:00
|
|
|
#[note(infer_actual_impl_expl_expected_passive_some)]
|
2022-09-29 14:10:43 +00:00
|
|
|
ExpectedPassiveSome {
|
|
|
|
leading_ellipsis: bool,
|
2022-11-03 18:50:52 +00:00
|
|
|
ty_or_sig: TyOrSig<'tcx>,
|
|
|
|
trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
|
2022-09-29 14:10:43 +00:00
|
|
|
lifetime_1: usize,
|
|
|
|
},
|
2022-10-24 16:06:45 +00:00
|
|
|
#[note(infer_actual_impl_expl_expected_passive_nothing)]
|
2022-11-03 18:50:52 +00:00
|
|
|
ExpectedPassiveNothing {
|
|
|
|
leading_ellipsis: bool,
|
|
|
|
ty_or_sig: TyOrSig<'tcx>,
|
|
|
|
trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
|
|
|
|
},
|
2022-10-24 16:06:45 +00:00
|
|
|
#[note(infer_actual_impl_expl_expected_other_two)]
|
2022-09-29 14:10:43 +00:00
|
|
|
ExpectedOtherTwo {
|
|
|
|
leading_ellipsis: bool,
|
2022-11-03 18:50:52 +00:00
|
|
|
ty_or_sig: TyOrSig<'tcx>,
|
|
|
|
trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
|
2022-09-29 14:10:43 +00:00
|
|
|
lifetime_1: usize,
|
|
|
|
lifetime_2: usize,
|
|
|
|
},
|
2022-10-24 16:06:45 +00:00
|
|
|
#[note(infer_actual_impl_expl_expected_other_any)]
|
2022-09-29 14:10:43 +00:00
|
|
|
ExpectedOtherAny {
|
|
|
|
leading_ellipsis: bool,
|
2022-11-03 18:50:52 +00:00
|
|
|
ty_or_sig: TyOrSig<'tcx>,
|
|
|
|
trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
|
2022-09-29 14:10:43 +00:00
|
|
|
lifetime_1: usize,
|
|
|
|
},
|
2022-10-24 16:06:45 +00:00
|
|
|
#[note(infer_actual_impl_expl_expected_other_some)]
|
2022-09-29 14:10:43 +00:00
|
|
|
ExpectedOtherSome {
|
|
|
|
leading_ellipsis: bool,
|
2022-11-03 18:50:52 +00:00
|
|
|
ty_or_sig: TyOrSig<'tcx>,
|
|
|
|
trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
|
2022-09-29 14:10:43 +00:00
|
|
|
lifetime_1: usize,
|
|
|
|
},
|
2022-10-24 16:06:45 +00:00
|
|
|
#[note(infer_actual_impl_expl_expected_other_nothing)]
|
2022-11-03 18:50:52 +00:00
|
|
|
ExpectedOtherNothing {
|
|
|
|
leading_ellipsis: bool,
|
|
|
|
ty_or_sig: TyOrSig<'tcx>,
|
|
|
|
trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
|
|
|
|
},
|
2022-10-24 16:06:45 +00:00
|
|
|
#[note(infer_actual_impl_expl_but_actually_implements_trait)]
|
2022-11-03 18:50:52 +00:00
|
|
|
ButActuallyImplementsTrait {
|
|
|
|
trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
|
|
|
|
has_lifetime: bool,
|
|
|
|
lifetime: usize,
|
|
|
|
},
|
2022-10-24 16:06:45 +00:00
|
|
|
#[note(infer_actual_impl_expl_but_actually_implemented_for_ty)]
|
2022-09-29 14:10:43 +00:00
|
|
|
ButActuallyImplementedForTy {
|
2022-11-03 18:50:52 +00:00
|
|
|
trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
|
2022-09-29 14:10:43 +00:00
|
|
|
has_lifetime: bool,
|
|
|
|
lifetime: usize,
|
|
|
|
ty: String,
|
|
|
|
},
|
2022-10-24 16:06:45 +00:00
|
|
|
#[note(infer_actual_impl_expl_but_actually_ty_implements)]
|
2022-11-03 18:50:52 +00:00
|
|
|
ButActuallyTyImplements {
|
|
|
|
trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
|
|
|
|
has_lifetime: bool,
|
|
|
|
lifetime: usize,
|
|
|
|
ty: String,
|
|
|
|
},
|
2022-09-10 21:45:38 +00:00
|
|
|
}
|
|
|
|
|
2022-09-29 14:10:43 +00:00
|
|
|
pub enum ActualImplExpectedKind {
|
|
|
|
Signature,
|
|
|
|
Passive,
|
|
|
|
Other,
|
|
|
|
}
|
|
|
|
|
|
|
|
pub enum ActualImplExpectedLifetimeKind {
|
|
|
|
Two,
|
|
|
|
Any,
|
|
|
|
Some,
|
|
|
|
Nothing,
|
|
|
|
}
|
|
|
|
|
2022-11-03 18:50:52 +00:00
|
|
|
impl<'tcx> ActualImplExplNotes<'tcx> {
|
2022-09-29 14:10:43 +00:00
|
|
|
pub fn new_expected(
|
|
|
|
kind: ActualImplExpectedKind,
|
|
|
|
lt_kind: ActualImplExpectedLifetimeKind,
|
|
|
|
leading_ellipsis: bool,
|
2022-11-03 18:50:52 +00:00
|
|
|
ty_or_sig: TyOrSig<'tcx>,
|
|
|
|
trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
|
2022-09-29 14:10:43 +00:00
|
|
|
lifetime_1: usize,
|
|
|
|
lifetime_2: usize,
|
|
|
|
) -> Self {
|
|
|
|
match (kind, lt_kind) {
|
|
|
|
(ActualImplExpectedKind::Signature, ActualImplExpectedLifetimeKind::Two) => {
|
|
|
|
Self::ExpectedSignatureTwo {
|
|
|
|
leading_ellipsis,
|
|
|
|
ty_or_sig,
|
|
|
|
trait_path,
|
|
|
|
lifetime_1,
|
|
|
|
lifetime_2,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
(ActualImplExpectedKind::Signature, ActualImplExpectedLifetimeKind::Any) => {
|
|
|
|
Self::ExpectedSignatureAny { leading_ellipsis, ty_or_sig, trait_path, lifetime_1 }
|
|
|
|
}
|
|
|
|
(ActualImplExpectedKind::Signature, ActualImplExpectedLifetimeKind::Some) => {
|
|
|
|
Self::ExpectedSignatureSome { leading_ellipsis, ty_or_sig, trait_path, lifetime_1 }
|
|
|
|
}
|
|
|
|
(ActualImplExpectedKind::Signature, ActualImplExpectedLifetimeKind::Nothing) => {
|
|
|
|
Self::ExpectedSignatureNothing { leading_ellipsis, ty_or_sig, trait_path }
|
|
|
|
}
|
|
|
|
(ActualImplExpectedKind::Passive, ActualImplExpectedLifetimeKind::Two) => {
|
|
|
|
Self::ExpectedPassiveTwo {
|
|
|
|
leading_ellipsis,
|
|
|
|
ty_or_sig,
|
|
|
|
trait_path,
|
|
|
|
lifetime_1,
|
|
|
|
lifetime_2,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
(ActualImplExpectedKind::Passive, ActualImplExpectedLifetimeKind::Any) => {
|
|
|
|
Self::ExpectedPassiveAny { leading_ellipsis, ty_or_sig, trait_path, lifetime_1 }
|
|
|
|
}
|
|
|
|
(ActualImplExpectedKind::Passive, ActualImplExpectedLifetimeKind::Some) => {
|
|
|
|
Self::ExpectedPassiveSome { leading_ellipsis, ty_or_sig, trait_path, lifetime_1 }
|
|
|
|
}
|
|
|
|
(ActualImplExpectedKind::Passive, ActualImplExpectedLifetimeKind::Nothing) => {
|
|
|
|
Self::ExpectedPassiveNothing { leading_ellipsis, ty_or_sig, trait_path }
|
|
|
|
}
|
|
|
|
(ActualImplExpectedKind::Other, ActualImplExpectedLifetimeKind::Two) => {
|
|
|
|
Self::ExpectedOtherTwo {
|
|
|
|
leading_ellipsis,
|
|
|
|
ty_or_sig,
|
|
|
|
trait_path,
|
|
|
|
lifetime_1,
|
|
|
|
lifetime_2,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
(ActualImplExpectedKind::Other, ActualImplExpectedLifetimeKind::Any) => {
|
|
|
|
Self::ExpectedOtherAny { leading_ellipsis, ty_or_sig, trait_path, lifetime_1 }
|
|
|
|
}
|
|
|
|
(ActualImplExpectedKind::Other, ActualImplExpectedLifetimeKind::Some) => {
|
|
|
|
Self::ExpectedOtherSome { leading_ellipsis, ty_or_sig, trait_path, lifetime_1 }
|
|
|
|
}
|
|
|
|
(ActualImplExpectedKind::Other, ActualImplExpectedLifetimeKind::Nothing) => {
|
|
|
|
Self::ExpectedOtherNothing { leading_ellipsis, ty_or_sig, trait_path }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-22 14:29:21 +00:00
|
|
|
#[derive(Diagnostic)]
|
2022-10-24 16:06:45 +00:00
|
|
|
#[diag(infer_trait_placeholder_mismatch)]
|
2022-11-03 18:50:52 +00:00
|
|
|
pub struct TraitPlaceholderMismatch<'tcx> {
|
2022-09-10 21:45:38 +00:00
|
|
|
#[primary_span]
|
|
|
|
pub span: Span,
|
2022-10-24 16:06:45 +00:00
|
|
|
#[label(label_satisfy)]
|
2022-09-10 21:45:38 +00:00
|
|
|
pub satisfy_span: Option<Span>,
|
2022-10-24 16:06:45 +00:00
|
|
|
#[label(label_where)]
|
2022-09-10 21:45:38 +00:00
|
|
|
pub where_span: Option<Span>,
|
2022-10-24 16:06:45 +00:00
|
|
|
#[label(label_dup)]
|
2022-09-10 21:45:38 +00:00
|
|
|
pub dup_span: Option<Span>,
|
|
|
|
pub def_id: String,
|
|
|
|
pub trait_def_id: String,
|
|
|
|
|
2022-12-28 12:24:18 +00:00
|
|
|
#[subdiagnostic]
|
2022-11-03 18:50:52 +00:00
|
|
|
pub actual_impl_expl_notes: Vec<ActualImplExplNotes<'tcx>>,
|
2022-09-10 21:45:38 +00:00
|
|
|
}
|
2022-09-13 17:11:42 +00:00
|
|
|
|
|
|
|
pub struct ConsiderBorrowingParamHelp {
|
|
|
|
pub spans: Vec<Span>,
|
|
|
|
}
|
|
|
|
|
2022-09-22 14:29:21 +00:00
|
|
|
impl AddToDiagnostic for ConsiderBorrowingParamHelp {
|
2022-10-14 18:50:06 +00:00
|
|
|
fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, f: F)
|
|
|
|
where
|
|
|
|
F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
|
|
|
|
{
|
2022-09-13 17:11:42 +00:00
|
|
|
let mut type_param_span: MultiSpan = self.spans.clone().into();
|
|
|
|
for &span in &self.spans {
|
2022-10-14 18:50:06 +00:00
|
|
|
// Seems like we can't call f() here as Into<DiagnosticMessage> is required
|
2022-10-24 16:06:45 +00:00
|
|
|
type_param_span.push_span_label(span, fluent::infer_tid_consider_borrowing);
|
2022-09-13 17:11:42 +00:00
|
|
|
}
|
2022-10-24 16:06:45 +00:00
|
|
|
let msg = f(diag, fluent::infer_tid_param_help.into());
|
2022-10-14 18:50:06 +00:00
|
|
|
diag.span_help(type_param_span, msg);
|
2022-09-13 17:11:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-22 14:29:21 +00:00
|
|
|
#[derive(Subdiagnostic)]
|
2022-10-24 16:06:45 +00:00
|
|
|
#[help(infer_tid_rel_help)]
|
2022-09-13 17:11:42 +00:00
|
|
|
pub struct RelationshipHelp;
|
|
|
|
|
2022-09-22 14:29:21 +00:00
|
|
|
#[derive(Diagnostic)]
|
2022-10-24 16:06:45 +00:00
|
|
|
#[diag(infer_trait_impl_diff)]
|
2022-09-13 17:11:42 +00:00
|
|
|
pub struct TraitImplDiff {
|
|
|
|
#[primary_span]
|
2022-10-24 16:06:45 +00:00
|
|
|
#[label(found)]
|
2022-09-13 17:11:42 +00:00
|
|
|
pub sp: Span,
|
2022-10-24 16:06:45 +00:00
|
|
|
#[label(expected)]
|
2022-09-13 17:11:42 +00:00
|
|
|
pub trait_sp: Span,
|
2022-10-24 16:06:45 +00:00
|
|
|
#[note(expected_found)]
|
2022-09-13 17:11:42 +00:00
|
|
|
pub note: (),
|
|
|
|
#[subdiagnostic]
|
|
|
|
pub param_help: ConsiderBorrowingParamHelp,
|
|
|
|
#[subdiagnostic]
|
|
|
|
// Seems like subdiagnostics are always pushed to the end, so this one
|
|
|
|
// also has to be a subdiagnostic to maintain order.
|
|
|
|
pub rel_help: Option<RelationshipHelp>,
|
|
|
|
pub expected: String,
|
|
|
|
pub found: String,
|
|
|
|
}
|
2022-09-16 23:54:59 +00:00
|
|
|
|
|
|
|
pub struct DynTraitConstraintSuggestion {
|
|
|
|
pub span: Span,
|
|
|
|
pub ident: Ident,
|
|
|
|
}
|
|
|
|
|
2022-09-22 14:29:21 +00:00
|
|
|
impl AddToDiagnostic for DynTraitConstraintSuggestion {
|
2022-10-14 18:50:06 +00:00
|
|
|
fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, f: F)
|
|
|
|
where
|
|
|
|
F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
|
|
|
|
{
|
2022-09-16 23:54:59 +00:00
|
|
|
let mut multi_span: MultiSpan = vec![self.span].into();
|
2022-10-24 16:06:45 +00:00
|
|
|
multi_span.push_span_label(self.span, fluent::infer_dtcs_has_lifetime_req_label);
|
|
|
|
multi_span.push_span_label(self.ident.span, fluent::infer_dtcs_introduces_requirement);
|
|
|
|
let msg = f(diag, fluent::infer_dtcs_has_req_note.into());
|
2022-10-14 18:50:06 +00:00
|
|
|
diag.span_note(multi_span, msg);
|
2022-10-24 16:06:45 +00:00
|
|
|
let msg = f(diag, fluent::infer_dtcs_suggestion.into());
|
2022-09-16 23:54:59 +00:00
|
|
|
diag.span_suggestion_verbose(
|
|
|
|
self.span.shrink_to_hi(),
|
2022-10-14 18:50:06 +00:00
|
|
|
msg,
|
2022-09-16 23:54:59 +00:00
|
|
|
" + '_",
|
|
|
|
Applicability::MaybeIncorrect,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-22 14:29:21 +00:00
|
|
|
#[derive(Diagnostic)]
|
2022-10-24 16:06:45 +00:00
|
|
|
#[diag(infer_but_calling_introduces, code = "E0772")]
|
2022-09-16 23:54:59 +00:00
|
|
|
pub struct ButCallingIntroduces {
|
2022-10-24 16:06:45 +00:00
|
|
|
#[label(label1)]
|
2022-09-16 23:54:59 +00:00
|
|
|
pub param_ty_span: Span,
|
|
|
|
#[primary_span]
|
2022-10-24 16:06:45 +00:00
|
|
|
#[label(label2)]
|
2022-09-16 23:54:59 +00:00
|
|
|
pub cause_span: Span,
|
|
|
|
|
|
|
|
pub has_param_name: bool,
|
|
|
|
pub param_name: String,
|
|
|
|
pub has_lifetime: bool,
|
|
|
|
pub lifetime: String,
|
|
|
|
pub assoc_item: Symbol,
|
|
|
|
pub has_impl_path: bool,
|
|
|
|
pub impl_path: String,
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct ReqIntroducedLocations {
|
|
|
|
pub span: MultiSpan,
|
|
|
|
pub spans: Vec<Span>,
|
|
|
|
pub fn_decl_span: Span,
|
|
|
|
pub cause_span: Span,
|
|
|
|
pub add_label: bool,
|
|
|
|
}
|
|
|
|
|
2022-09-22 14:29:21 +00:00
|
|
|
impl AddToDiagnostic for ReqIntroducedLocations {
|
2022-10-14 18:50:06 +00:00
|
|
|
fn add_to_diagnostic_with<F>(mut self, diag: &mut Diagnostic, f: F)
|
|
|
|
where
|
|
|
|
F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
|
|
|
|
{
|
2022-09-16 23:54:59 +00:00
|
|
|
for sp in self.spans {
|
2022-10-24 16:06:45 +00:00
|
|
|
self.span.push_span_label(sp, fluent::infer_ril_introduced_here);
|
2022-09-16 23:54:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if self.add_label {
|
2022-10-24 16:06:45 +00:00
|
|
|
self.span.push_span_label(self.fn_decl_span, fluent::infer_ril_introduced_by);
|
2022-09-16 23:54:59 +00:00
|
|
|
}
|
2022-10-24 16:06:45 +00:00
|
|
|
self.span.push_span_label(self.cause_span, fluent::infer_ril_because_of);
|
|
|
|
let msg = f(diag, fluent::infer_ril_static_introduced_by.into());
|
2022-10-14 18:50:06 +00:00
|
|
|
diag.span_note(self.span, msg);
|
2022-09-16 23:54:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct MoreTargeted {
|
|
|
|
pub ident: Symbol,
|
|
|
|
}
|
|
|
|
|
2022-09-22 14:29:21 +00:00
|
|
|
impl AddToDiagnostic for MoreTargeted {
|
2022-10-14 18:50:06 +00:00
|
|
|
fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _f: F)
|
|
|
|
where
|
|
|
|
F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
|
|
|
|
{
|
2022-09-16 23:54:59 +00:00
|
|
|
diag.code(rustc_errors::error_code!(E0772));
|
2022-10-24 16:06:45 +00:00
|
|
|
diag.set_primary_message(fluent::infer_more_targeted);
|
2022-09-16 23:54:59 +00:00
|
|
|
diag.set_arg("ident", self.ident);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-22 14:29:21 +00:00
|
|
|
#[derive(Diagnostic)]
|
2022-10-24 16:06:45 +00:00
|
|
|
#[diag(infer_but_needs_to_satisfy, code = "E0759")]
|
2022-09-16 23:54:59 +00:00
|
|
|
pub struct ButNeedsToSatisfy {
|
|
|
|
#[primary_span]
|
|
|
|
pub sp: Span,
|
2022-10-24 16:06:45 +00:00
|
|
|
#[label(influencer)]
|
2022-09-16 23:54:59 +00:00
|
|
|
pub influencer_point: Span,
|
2022-10-24 16:06:45 +00:00
|
|
|
#[label(used_here)]
|
2022-09-16 23:54:59 +00:00
|
|
|
pub spans: Vec<Span>,
|
2022-10-24 16:06:45 +00:00
|
|
|
#[label(require)]
|
2022-09-16 23:54:59 +00:00
|
|
|
pub require_span_as_label: Option<Span>,
|
2022-10-24 16:06:45 +00:00
|
|
|
#[note(require)]
|
2022-09-16 23:54:59 +00:00
|
|
|
pub require_span_as_note: Option<Span>,
|
2022-10-24 16:06:45 +00:00
|
|
|
#[note(introduced_by_bound)]
|
2022-09-16 23:54:59 +00:00
|
|
|
pub bound: Option<Span>,
|
|
|
|
|
|
|
|
#[subdiagnostic]
|
|
|
|
pub req_introduces_loc: Option<ReqIntroducedLocations>,
|
|
|
|
|
2023-01-18 09:23:50 +00:00
|
|
|
pub has_param_name: bool,
|
|
|
|
pub param_name: String,
|
2022-09-16 23:54:59 +00:00
|
|
|
pub spans_empty: bool,
|
|
|
|
pub has_lifetime: bool,
|
|
|
|
pub lifetime: String,
|
|
|
|
}
|
2023-01-18 13:34:08 +00:00
|
|
|
|
|
|
|
#[derive(Diagnostic)]
|
|
|
|
#[diag(infer_outlives_content, code = "E0312")]
|
|
|
|
pub struct OutlivesContent<'a> {
|
|
|
|
#[primary_span]
|
|
|
|
pub span: Span,
|
|
|
|
#[subdiagnostic]
|
|
|
|
pub notes: Vec<note_and_explain::RegionExplanation<'a>>,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Diagnostic)]
|
|
|
|
#[diag(infer_outlives_bound, code = "E0476")]
|
|
|
|
pub struct OutlivesBound<'a> {
|
|
|
|
#[primary_span]
|
|
|
|
pub span: Span,
|
|
|
|
#[subdiagnostic]
|
|
|
|
pub notes: Vec<note_and_explain::RegionExplanation<'a>>,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Diagnostic)]
|
|
|
|
#[diag(infer_fullfill_req_lifetime, code = "E0477")]
|
|
|
|
pub struct FullfillReqLifetime<'a> {
|
|
|
|
#[primary_span]
|
|
|
|
pub span: Span,
|
|
|
|
pub ty: Ty<'a>,
|
|
|
|
#[subdiagnostic]
|
|
|
|
pub note: Option<note_and_explain::RegionExplanation<'a>>,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Diagnostic)]
|
|
|
|
#[diag(infer_lf_bound_not_satisfied, code = "E0478")]
|
|
|
|
pub struct LfBoundNotSatisfied<'a> {
|
|
|
|
#[primary_span]
|
|
|
|
pub span: Span,
|
|
|
|
#[subdiagnostic]
|
|
|
|
pub notes: Vec<note_and_explain::RegionExplanation<'a>>,
|
|
|
|
}
|
2023-01-19 14:35:09 +00:00
|
|
|
|
2023-01-21 15:16:53 +00:00
|
|
|
#[derive(Diagnostic)]
|
|
|
|
#[diag(infer_ref_longer_than_data, code = "E0491")]
|
|
|
|
pub struct RefLongerThanData<'a> {
|
|
|
|
#[primary_span]
|
|
|
|
pub span: Span,
|
|
|
|
pub ty: Ty<'a>,
|
|
|
|
#[subdiagnostic]
|
|
|
|
pub notes: Vec<note_and_explain::RegionExplanation<'a>>,
|
|
|
|
}
|
2023-01-22 15:16:47 +00:00
|
|
|
|
|
|
|
#[derive(Subdiagnostic)]
|
|
|
|
pub enum WhereClauseSuggestions {
|
|
|
|
#[suggestion(
|
|
|
|
infer_where_remove,
|
|
|
|
code = "",
|
|
|
|
applicability = "machine-applicable",
|
|
|
|
style = "verbose"
|
|
|
|
)]
|
|
|
|
Remove {
|
|
|
|
#[primary_span]
|
|
|
|
span: Span,
|
|
|
|
},
|
|
|
|
#[suggestion(
|
|
|
|
infer_where_copy_predicates,
|
2023-01-22 15:54:47 +00:00
|
|
|
code = "{space}where {trait_predicates}",
|
2023-01-22 15:16:47 +00:00
|
|
|
applicability = "machine-applicable",
|
|
|
|
style = "verbose"
|
|
|
|
)]
|
|
|
|
CopyPredicates {
|
|
|
|
#[primary_span]
|
|
|
|
span: Span,
|
|
|
|
space: &'static str,
|
|
|
|
trait_predicates: String,
|
|
|
|
},
|
|
|
|
}
|
2023-01-28 16:41:14 +00:00
|
|
|
|
|
|
|
#[derive(Subdiagnostic)]
|
|
|
|
pub enum SuggestRemoveSemiOrReturnBinding {
|
|
|
|
#[multipart_suggestion(infer_srs_remove_and_box, applicability = "machine-applicable")]
|
|
|
|
RemoveAndBox {
|
|
|
|
#[suggestion_part(code = "Box::new(")]
|
|
|
|
first_lo: Span,
|
|
|
|
#[suggestion_part(code = ")")]
|
|
|
|
first_hi: Span,
|
|
|
|
#[suggestion_part(code = "Box::new(")]
|
|
|
|
second_lo: Span,
|
|
|
|
#[suggestion_part(code = ")")]
|
|
|
|
second_hi: Span,
|
|
|
|
#[suggestion_part(code = "")]
|
|
|
|
sp: Span,
|
|
|
|
},
|
|
|
|
#[suggestion(
|
|
|
|
infer_srs_remove,
|
|
|
|
style = "short",
|
|
|
|
code = "",
|
|
|
|
applicability = "machine-applicable"
|
|
|
|
)]
|
|
|
|
Remove {
|
|
|
|
#[primary_span]
|
|
|
|
sp: Span,
|
|
|
|
},
|
|
|
|
#[suggestion(
|
|
|
|
infer_srs_add,
|
|
|
|
style = "verbose",
|
|
|
|
code = "{code}",
|
|
|
|
applicability = "maybe-incorrect"
|
|
|
|
)]
|
|
|
|
Add {
|
|
|
|
#[primary_span]
|
|
|
|
sp: Span,
|
|
|
|
code: String,
|
|
|
|
ident: Ident,
|
|
|
|
},
|
|
|
|
#[note(infer_srs_add_one)]
|
|
|
|
AddOne {
|
|
|
|
#[primary_span]
|
|
|
|
spans: MultiSpan,
|
|
|
|
},
|
|
|
|
}
|
2023-01-31 16:12:48 +00:00
|
|
|
|
|
|
|
#[derive(Subdiagnostic)]
|
|
|
|
pub enum ConsiderAddingAwait {
|
|
|
|
#[help(infer_await_both_futures)]
|
|
|
|
BothFuturesHelp,
|
|
|
|
#[multipart_suggestion(infer_await_both_futures, applicability = "maybe-incorrect")]
|
|
|
|
BothFuturesSugg {
|
|
|
|
#[suggestion_part(code = ".await")]
|
|
|
|
first: Span,
|
|
|
|
#[suggestion_part(code = ".await")]
|
|
|
|
second: Span,
|
|
|
|
},
|
|
|
|
#[suggestion(
|
|
|
|
infer_await_future,
|
|
|
|
code = ".await",
|
|
|
|
style = "verbose",
|
|
|
|
applicability = "maybe-incorrect"
|
|
|
|
)]
|
|
|
|
FutureSugg {
|
|
|
|
#[primary_span]
|
|
|
|
span: Span,
|
|
|
|
},
|
|
|
|
#[note(infer_await_note)]
|
2023-02-14 20:16:29 +00:00
|
|
|
FutureSuggNote {
|
2023-01-31 16:12:48 +00:00
|
|
|
#[primary_span]
|
|
|
|
span: Span,
|
|
|
|
},
|
|
|
|
#[multipart_suggestion(
|
|
|
|
infer_await_future,
|
|
|
|
style = "verbose",
|
|
|
|
applicability = "maybe-incorrect"
|
|
|
|
)]
|
|
|
|
FutureSuggMultiple {
|
|
|
|
#[suggestion_part(code = ".await")]
|
|
|
|
spans: Vec<Span>,
|
|
|
|
},
|
|
|
|
}
|
2023-02-03 14:24:53 +00:00
|
|
|
|
|
|
|
#[derive(Diagnostic)]
|
|
|
|
pub enum PlaceholderRelationLfNotSatisfied {
|
|
|
|
#[diag(infer_lf_bound_not_satisfied)]
|
|
|
|
HasBoth {
|
|
|
|
#[primary_span]
|
|
|
|
span: Span,
|
|
|
|
#[note(infer_prlf_defined_with_sub)]
|
|
|
|
sub_span: Span,
|
|
|
|
#[note(infer_prlf_must_oultive_with_sup)]
|
|
|
|
sup_span: Span,
|
|
|
|
sub_symbol: Symbol,
|
|
|
|
sup_symbol: Symbol,
|
|
|
|
#[note(infer_prlf_known_limitation)]
|
|
|
|
note: (),
|
|
|
|
},
|
|
|
|
#[diag(infer_lf_bound_not_satisfied)]
|
|
|
|
HasSub {
|
|
|
|
#[primary_span]
|
|
|
|
span: Span,
|
|
|
|
#[note(infer_prlf_defined_with_sub)]
|
|
|
|
sub_span: Span,
|
|
|
|
#[note(infer_prlf_must_oultive_without_sup)]
|
|
|
|
sup_span: Span,
|
|
|
|
sub_symbol: Symbol,
|
|
|
|
#[note(infer_prlf_known_limitation)]
|
|
|
|
note: (),
|
|
|
|
},
|
|
|
|
#[diag(infer_lf_bound_not_satisfied)]
|
|
|
|
HasSup {
|
|
|
|
#[primary_span]
|
|
|
|
span: Span,
|
|
|
|
#[note(infer_prlf_defined_without_sub)]
|
|
|
|
sub_span: Span,
|
|
|
|
#[note(infer_prlf_must_oultive_with_sup)]
|
|
|
|
sup_span: Span,
|
|
|
|
sup_symbol: Symbol,
|
|
|
|
#[note(infer_prlf_known_limitation)]
|
|
|
|
note: (),
|
|
|
|
},
|
|
|
|
#[diag(infer_lf_bound_not_satisfied)]
|
|
|
|
HasNone {
|
|
|
|
#[primary_span]
|
|
|
|
span: Span,
|
|
|
|
#[note(infer_prlf_defined_without_sub)]
|
|
|
|
sub_span: Span,
|
|
|
|
#[note(infer_prlf_must_oultive_without_sup)]
|
|
|
|
sup_span: Span,
|
|
|
|
#[note(infer_prlf_known_limitation)]
|
|
|
|
note: (),
|
|
|
|
},
|
|
|
|
#[diag(infer_lf_bound_not_satisfied)]
|
|
|
|
OnlyPrimarySpan {
|
|
|
|
#[primary_span]
|
|
|
|
span: Span,
|
|
|
|
#[note(infer_prlf_known_limitation)]
|
|
|
|
note: (),
|
|
|
|
},
|
|
|
|
}
|