From 1376c5a617be5c25655d0d7cb63e3beaa5a6e026 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:20:39 +0200 Subject: Merging upstream version 1.70.0+dfsg1. Signed-off-by: Daniel Baumann --- compiler/rustc_infer/src/errors/mod.rs | 395 ++++++++++++++++++++- .../rustc_infer/src/errors/note_and_explain.rs | 126 +++---- 2 files changed, 428 insertions(+), 93 deletions(-) (limited to 'compiler/rustc_infer/src/errors') 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, + #[suggestion_part(code = ")")] + ends: Vec, + }, +} + +#[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, +} + +impl AddToDiagnostic for SuggestTuplePatternMany { + fn add_to_diagnostic_with(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, + }, + #[diag(infer_oc_type_compat, code = "E0308")] + TypeCompat { + #[primary_span] + span: Span, + #[subdiagnostic] + subdiags: Vec, + }, + #[diag(infer_oc_const_compat, code = "E0308")] + ConstCompat { + #[primary_span] + span: Span, + #[subdiagnostic] + subdiags: Vec, + }, + #[diag(infer_oc_try_compat, code = "E0308")] + TryCompat { + #[primary_span] + span: Span, + #[subdiagnostic] + subdiags: Vec, + }, + #[diag(infer_oc_match_compat, code = "E0308")] + MatchCompat { + #[primary_span] + span: Span, + #[subdiagnostic] + subdiags: Vec, + }, + #[diag(infer_oc_if_else_different, code = "E0308")] + IfElseDifferent { + #[primary_span] + span: Span, + #[subdiagnostic] + subdiags: Vec, + }, + #[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, + }, + #[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, + }, + #[diag(infer_oc_intristic_correct_type, code = "E0308")] + IntristicCorrectType { + #[primary_span] + span: Span, + #[subdiagnostic] + subdiags: Vec, + }, + #[diag(infer_oc_method_correct_type, code = "E0308")] + MethodCorrectType { + #[primary_span] + span: Span, + #[subdiagnostic] + subdiags: Vec, + }, + #[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, + }, + #[diag(infer_oc_generic, code = "E0308")] + Generic { + #[primary_span] + span: Span, + #[subdiagnostic] + subdiags: Vec, + }, +} 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, 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, ) -> Option { - 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 { - 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); -- cgit v1.2.3