summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_infer/src/errors
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_infer/src/errors')
-rw-r--r--compiler/rustc_infer/src/errors/mod.rs395
-rw-r--r--compiler/rustc_infer/src/errors/note_and_explain.rs126
2 files changed, 428 insertions, 93 deletions
diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs
index 6bbd3fd3e..65b3dd1a8 100644
--- a/compiler/rustc_infer/src/errors/mod.rs
+++ b/compiler/rustc_infer/src/errors/mod.rs
@@ -53,7 +53,7 @@ pub struct AnnotationRequired<'a> {
// Copy of `AnnotationRequired` for E0283
#[derive(Diagnostic)]
#[diag(infer_type_annotations_needed, code = "E0283")]
-pub struct AmbigousImpl<'a> {
+pub struct AmbiguousImpl<'a> {
#[primary_span]
pub span: Span,
pub source_kind: &'static str,
@@ -184,18 +184,6 @@ pub enum SourceKindMultiSuggestion<'a> {
},
}
-#[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,
-}
-
impl<'a> SourceKindMultiSuggestion<'a> {
pub fn new_fully_qualified(
span: Span,
@@ -954,8 +942,8 @@ pub struct OutlivesBound<'a> {
}
#[derive(Diagnostic)]
-#[diag(infer_fullfill_req_lifetime, code = "E0477")]
-pub struct FullfillReqLifetime<'a> {
+#[diag(infer_fulfill_req_lifetime, code = "E0477")]
+pub struct FulfillReqLifetime<'a> {
#[primary_span]
pub span: Span,
pub ty: Ty<'a>,
@@ -1157,3 +1145,380 @@ pub struct OpaqueCapturesLifetime<'tcx> {
pub opaque_ty_span: Span,
pub opaque_ty: Ty<'tcx>,
}
+
+#[derive(Subdiagnostic)]
+pub enum FunctionPointerSuggestion<'a> {
+ #[suggestion(
+ infer_fps_use_ref,
+ code = "&{fn_name}",
+ style = "verbose",
+ applicability = "maybe-incorrect"
+ )]
+ UseRef {
+ #[primary_span]
+ span: Span,
+ #[skip_arg]
+ fn_name: String,
+ },
+ #[suggestion(
+ infer_fps_remove_ref,
+ code = "{fn_name}",
+ style = "verbose",
+ applicability = "maybe-incorrect"
+ )]
+ RemoveRef {
+ #[primary_span]
+ span: Span,
+ #[skip_arg]
+ fn_name: String,
+ },
+ #[suggestion(
+ infer_fps_cast,
+ code = "&({fn_name} as {sig})",
+ style = "verbose",
+ applicability = "maybe-incorrect"
+ )]
+ CastRef {
+ #[primary_span]
+ span: Span,
+ #[skip_arg]
+ fn_name: String,
+ #[skip_arg]
+ sig: Binder<'a, FnSig<'a>>,
+ },
+ #[suggestion(
+ infer_fps_cast,
+ code = "{fn_name} as {sig}",
+ style = "verbose",
+ applicability = "maybe-incorrect"
+ )]
+ Cast {
+ #[primary_span]
+ span: Span,
+ #[skip_arg]
+ fn_name: String,
+ #[skip_arg]
+ sig: Binder<'a, FnSig<'a>>,
+ },
+ #[suggestion(
+ infer_fps_cast_both,
+ code = "{fn_name} as {found_sig}",
+ style = "hidden",
+ applicability = "maybe-incorrect"
+ )]
+ CastBoth {
+ #[primary_span]
+ span: Span,
+ #[skip_arg]
+ fn_name: String,
+ #[skip_arg]
+ found_sig: Binder<'a, FnSig<'a>>,
+ expected_sig: Binder<'a, FnSig<'a>>,
+ },
+ #[suggestion(
+ infer_fps_cast_both,
+ code = "&({fn_name} as {found_sig})",
+ style = "hidden",
+ applicability = "maybe-incorrect"
+ )]
+ CastBothRef {
+ #[primary_span]
+ span: Span,
+ #[skip_arg]
+ fn_name: String,
+ #[skip_arg]
+ found_sig: Binder<'a, FnSig<'a>>,
+ expected_sig: Binder<'a, FnSig<'a>>,
+ },
+}
+
+#[derive(Subdiagnostic)]
+#[note(infer_fps_items_are_distinct)]
+pub struct FnItemsAreDistinct;
+
+#[derive(Subdiagnostic)]
+#[note(infer_fn_uniq_types)]
+pub struct FnUniqTypes;
+
+#[derive(Subdiagnostic)]
+#[help(infer_fn_consider_casting)]
+pub struct FnConsiderCasting {
+ pub casting: String,
+}
+
+#[derive(Subdiagnostic)]
+pub enum SuggestAsRefWhereAppropriate<'a> {
+ #[suggestion(
+ infer_sarwa_option,
+ code = "{snippet}.as_ref()",
+ applicability = "machine-applicable"
+ )]
+ Option {
+ #[primary_span]
+ span: Span,
+ snippet: &'a str,
+ },
+ #[suggestion(
+ infer_sarwa_result,
+ code = "{snippet}.as_ref()",
+ applicability = "machine-applicable"
+ )]
+ Result {
+ #[primary_span]
+ span: Span,
+ snippet: &'a str,
+ },
+}
+
+#[derive(Subdiagnostic)]
+pub enum SuggestAccessingField<'a> {
+ #[suggestion(
+ infer_suggest_accessing_field,
+ code = "{snippet}.{name}",
+ applicability = "maybe-incorrect"
+ )]
+ Safe {
+ #[primary_span]
+ span: Span,
+ snippet: String,
+ name: Symbol,
+ ty: Ty<'a>,
+ },
+ #[suggestion(
+ infer_suggest_accessing_field,
+ code = "unsafe {{ {snippet}.{name} }}",
+ applicability = "maybe-incorrect"
+ )]
+ Unsafe {
+ #[primary_span]
+ span: Span,
+ snippet: String,
+ name: Symbol,
+ ty: Ty<'a>,
+ },
+}
+
+#[derive(Subdiagnostic)]
+pub enum SuggestBoxingForReturnImplTrait {
+ #[multipart_suggestion(infer_sbfrit_change_return_type, applicability = "maybe-incorrect")]
+ ChangeReturnType {
+ #[suggestion_part(code = "Box<dyn")]
+ start_sp: Span,
+ #[suggestion_part(code = ">")]
+ end_sp: Span,
+ },
+ #[multipart_suggestion(infer_sbfrit_box_return_expr, applicability = "maybe-incorrect")]
+ BoxReturnExpr {
+ #[suggestion_part(code = "Box::new(")]
+ starts: Vec<Span>,
+ #[suggestion_part(code = ")")]
+ ends: Vec<Span>,
+ },
+}
+
+#[derive(Subdiagnostic)]
+#[multipart_suggestion(infer_stp_wrap_one, applicability = "maybe-incorrect")]
+pub struct SuggestTuplePatternOne {
+ pub variant: String,
+ #[suggestion_part(code = "{variant}(")]
+ pub span_low: Span,
+ #[suggestion_part(code = ")")]
+ pub span_high: Span,
+}
+
+pub struct SuggestTuplePatternMany {
+ pub path: String,
+ pub cause_span: Span,
+ pub compatible_variants: Vec<String>,
+}
+
+impl AddToDiagnostic for SuggestTuplePatternMany {
+ fn add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, f: F)
+ where
+ F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
+ {
+ diag.set_arg("path", self.path);
+ let message = f(diag, crate::fluent_generated::infer_stp_wrap_many.into());
+ diag.multipart_suggestions(
+ message,
+ self.compatible_variants.into_iter().map(|variant| {
+ vec![
+ (self.cause_span.shrink_to_lo(), format!("{}(", variant)),
+ (self.cause_span.shrink_to_hi(), ")".to_string()),
+ ]
+ }),
+ rustc_errors::Applicability::MaybeIncorrect,
+ );
+ }
+}
+
+#[derive(Subdiagnostic)]
+pub enum TypeErrorAdditionalDiags {
+ #[suggestion(
+ infer_meant_byte_literal,
+ code = "b'{code}'",
+ applicability = "machine-applicable"
+ )]
+ MeantByteLiteral {
+ #[primary_span]
+ span: Span,
+ code: String,
+ },
+ #[suggestion(
+ infer_meant_char_literal,
+ code = "'{code}'",
+ applicability = "machine-applicable"
+ )]
+ MeantCharLiteral {
+ #[primary_span]
+ span: Span,
+ code: String,
+ },
+ #[suggestion(
+ infer_meant_str_literal,
+ code = "\"{code}\"",
+ applicability = "machine-applicable"
+ )]
+ MeantStrLiteral {
+ #[primary_span]
+ span: Span,
+ code: String,
+ },
+ #[suggestion(
+ infer_consider_specifying_length,
+ code = "{length}",
+ applicability = "maybe-incorrect"
+ )]
+ ConsiderSpecifyingLength {
+ #[primary_span]
+ span: Span,
+ length: u64,
+ },
+ #[note(infer_try_cannot_convert)]
+ TryCannotConvert { found: String, expected: String },
+ #[suggestion(infer_tuple_trailing_comma, code = ",", applicability = "machine-applicable")]
+ TupleOnlyComma {
+ #[primary_span]
+ span: Span,
+ },
+ #[multipart_suggestion(infer_tuple_trailing_comma, applicability = "machine-applicable")]
+ TupleAlsoParentheses {
+ #[suggestion_part(code = "(")]
+ span_low: Span,
+ #[suggestion_part(code = ",)")]
+ span_high: Span,
+ },
+ #[suggestion(
+ infer_suggest_add_let_for_letchains,
+ style = "verbose",
+ applicability = "machine-applicable",
+ code = "let "
+ )]
+ AddLetForLetChains {
+ #[primary_span]
+ span: Span,
+ },
+}
+
+#[derive(Diagnostic)]
+pub enum ObligationCauseFailureCode {
+ #[diag(infer_oc_method_compat, code = "E0308")]
+ MethodCompat {
+ #[primary_span]
+ span: Span,
+ #[subdiagnostic]
+ subdiags: Vec<TypeErrorAdditionalDiags>,
+ },
+ #[diag(infer_oc_type_compat, code = "E0308")]
+ TypeCompat {
+ #[primary_span]
+ span: Span,
+ #[subdiagnostic]
+ subdiags: Vec<TypeErrorAdditionalDiags>,
+ },
+ #[diag(infer_oc_const_compat, code = "E0308")]
+ ConstCompat {
+ #[primary_span]
+ span: Span,
+ #[subdiagnostic]
+ subdiags: Vec<TypeErrorAdditionalDiags>,
+ },
+ #[diag(infer_oc_try_compat, code = "E0308")]
+ TryCompat {
+ #[primary_span]
+ span: Span,
+ #[subdiagnostic]
+ subdiags: Vec<TypeErrorAdditionalDiags>,
+ },
+ #[diag(infer_oc_match_compat, code = "E0308")]
+ MatchCompat {
+ #[primary_span]
+ span: Span,
+ #[subdiagnostic]
+ subdiags: Vec<TypeErrorAdditionalDiags>,
+ },
+ #[diag(infer_oc_if_else_different, code = "E0308")]
+ IfElseDifferent {
+ #[primary_span]
+ span: Span,
+ #[subdiagnostic]
+ subdiags: Vec<TypeErrorAdditionalDiags>,
+ },
+ #[diag(infer_oc_no_else, code = "E0317")]
+ NoElse {
+ #[primary_span]
+ span: Span,
+ },
+ #[diag(infer_oc_no_diverge, code = "E0308")]
+ NoDiverge {
+ #[primary_span]
+ span: Span,
+ #[subdiagnostic]
+ subdiags: Vec<TypeErrorAdditionalDiags>,
+ },
+ #[diag(infer_oc_fn_main_correct_type, code = "E0580")]
+ FnMainCorrectType {
+ #[primary_span]
+ span: Span,
+ },
+ #[diag(infer_oc_fn_start_correct_type, code = "E0308")]
+ FnStartCorrectType {
+ #[primary_span]
+ span: Span,
+ #[subdiagnostic]
+ subdiags: Vec<TypeErrorAdditionalDiags>,
+ },
+ #[diag(infer_oc_intristic_correct_type, code = "E0308")]
+ IntristicCorrectType {
+ #[primary_span]
+ span: Span,
+ #[subdiagnostic]
+ subdiags: Vec<TypeErrorAdditionalDiags>,
+ },
+ #[diag(infer_oc_method_correct_type, code = "E0308")]
+ MethodCorrectType {
+ #[primary_span]
+ span: Span,
+ #[subdiagnostic]
+ subdiags: Vec<TypeErrorAdditionalDiags>,
+ },
+ #[diag(infer_oc_closure_selfref, code = "E0644")]
+ ClosureSelfref {
+ #[primary_span]
+ span: Span,
+ },
+ #[diag(infer_oc_cant_coerce, code = "E0308")]
+ CantCoerce {
+ #[primary_span]
+ span: Span,
+ #[subdiagnostic]
+ subdiags: Vec<TypeErrorAdditionalDiags>,
+ },
+ #[diag(infer_oc_generic, code = "E0308")]
+ Generic {
+ #[primary_span]
+ span: Span,
+ #[subdiagnostic]
+ subdiags: Vec<TypeErrorAdditionalDiags>,
+ },
+}
diff --git a/compiler/rustc_infer/src/errors/note_and_explain.rs b/compiler/rustc_infer/src/errors/note_and_explain.rs
index ef543b1fb..7328241df 100644
--- a/compiler/rustc_infer/src/errors/note_and_explain.rs
+++ b/compiler/rustc_infer/src/errors/note_and_explain.rs
@@ -4,12 +4,10 @@ use rustc_errors::{self, AddToDiagnostic, Diagnostic, IntoDiagnosticArg, Subdiag
use rustc_middle::ty::{self, TyCtxt};
use rustc_span::{symbol::kw, Span};
-#[derive(Default)]
struct DescriptionCtx<'a> {
span: Option<Span>,
kind: &'a str,
arg: String,
- num_arg: u32,
}
impl<'a> DescriptionCtx<'a> {
@@ -18,103 +16,74 @@ impl<'a> DescriptionCtx<'a> {
region: ty::Region<'tcx>,
alt_span: Option<Span>,
) -> Option<Self> {
- let mut me = DescriptionCtx::default();
- me.span = alt_span;
- match *region {
- ty::ReEarlyBound(_) | ty::ReFree(_) => {
- return Self::from_early_bound_and_free_regions(tcx, region);
- }
- ty::ReStatic => {
- me.kind = "restatic";
- }
-
- ty::RePlaceholder(_) => return None,
-
- ty::ReError(_) => return None,
-
- // FIXME(#13998) RePlaceholder should probably print like
- // ReFree rather than dumping Debug output on the user.
- //
- // We shouldn't really be having unification failures with ReVar
- // and ReLateBound though.
- ty::ReVar(_) | ty::ReLateBound(..) | ty::ReErased => {
- me.kind = "revar";
- me.arg = format!("{:?}", region);
- }
- };
- Some(me)
- }
-
- fn from_early_bound_and_free_regions<'tcx>(
- tcx: TyCtxt<'tcx>,
- region: ty::Region<'tcx>,
- ) -> Option<Self> {
- let mut me = DescriptionCtx::default();
- let scope = region.free_region_binding_scope(tcx).expect_local();
- match *region {
+ let (span, kind, arg) = match *region {
ty::ReEarlyBound(ref br) => {
- let mut sp = tcx.def_span(scope);
- if let Some(param) =
+ let scope = region.free_region_binding_scope(tcx).expect_local();
+ let span = if let Some(param) =
tcx.hir().get_generics(scope).and_then(|generics| generics.get_named(br.name))
{
- sp = param.span;
- }
- if br.has_name() {
- me.kind = "as_defined";
- me.arg = br.name.to_string();
+ param.span
} else {
- me.kind = "as_defined_anon";
+ tcx.def_span(scope)
};
- me.span = Some(sp)
+ if br.has_name() {
+ (Some(span), "as_defined", br.name.to_string())
+ } else {
+ (Some(span), "as_defined_anon", String::new())
+ }
}
ty::ReFree(ref fr) => {
if !fr.bound_region.is_named()
&& let Some((ty, _)) = find_anon_type(tcx, region, &fr.bound_region)
{
- me.kind = "defined_here";
- me.span = Some(ty.span);
+ (Some(ty.span), "defined_here", String::new())
} else {
+ let scope = region.free_region_binding_scope(tcx).expect_local();
match fr.bound_region {
ty::BoundRegionKind::BrNamed(_, name) => {
- let mut sp = tcx.def_span(scope);
- if let Some(param) =
- tcx.hir().get_generics(scope).and_then(|generics| generics.get_named(name))
+ let span = if let Some(param) = tcx
+ .hir()
+ .get_generics(scope)
+ .and_then(|generics| generics.get_named(name))
{
- sp = param.span;
- }
- if name == kw::UnderscoreLifetime {
- me.kind = "as_defined_anon";
+ param.span
} else {
- me.kind = "as_defined";
- me.arg = name.to_string();
+ tcx.def_span(scope)
};
- me.span = Some(sp);
+ if name == kw::UnderscoreLifetime {
+ (Some(span), "as_defined_anon", String::new())
+ } else {
+ (Some(span), "as_defined", name.to_string())
+ }
}
- ty::BrAnon(idx, span) => {
- me.kind = "anon_num_here";
- me.num_arg = idx+1;
- me.span = match span {
+ ty::BrAnon(span) => {
+ let span = match span {
Some(_) => span,
None => Some(tcx.def_span(scope)),
- }
- },
+ };
+ (span, "defined_here", String::new())
+ }
_ => {
- me.kind = "defined_here_reg";
- me.arg = region.to_string();
- me.span = Some(tcx.def_span(scope));
- },
+ (Some(tcx.def_span(scope)), "defined_here_reg", region.to_string())
+ }
}
}
}
- _ => bug!(),
- }
- Some(me)
- }
- fn add_to(self, diag: &mut rustc_errors::Diagnostic) {
- diag.set_arg("desc_kind", self.kind);
- diag.set_arg("desc_arg", self.arg);
- diag.set_arg("desc_num_arg", self.num_arg);
+ ty::ReStatic => (alt_span, "restatic", String::new()),
+
+ ty::RePlaceholder(_) | ty::ReError(_) => return None,
+
+ // FIXME(#13998) RePlaceholder should probably print like
+ // ReFree rather than dumping Debug output on the user.
+ //
+ // We shouldn't really be having unification failures with ReVar
+ // and ReLateBound though.
+ ty::ReVar(_) | ty::ReLateBound(..) | ty::ReErased => {
+ (alt_span, "revar", format!("{:?}", region))
+ }
+ };
+ Some(DescriptionCtx { span, kind, arg })
}
}
@@ -199,10 +168,11 @@ impl AddToDiagnostic for RegionExplanation<'_> {
{
diag.set_arg("pref_kind", self.prefix);
diag.set_arg("suff_kind", self.suffix);
- let desc_span = self.desc.span;
- self.desc.add_to(diag);
+ diag.set_arg("desc_kind", self.desc.kind);
+ diag.set_arg("desc_arg", self.desc.arg);
+
let msg = f(diag, fluent::infer_region_explanation.into());
- if let Some(span) = desc_span {
+ if let Some(span) = self.desc.span {
diag.span_note(span, msg);
} else {
diag.note(msg);