Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrating rustc_infer to session diagnostics (part 4) #107034

Merged
merged 11 commits into from
Feb 16, 2023
39 changes: 38 additions & 1 deletion compiler/rustc_error_messages/locales/en-US/infer.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,18 @@ infer_lifetime_param_suggestion_elided = each elided lifetime in input position

infer_region_explanation = {$pref_kind ->
*[should_not_happen] [{$pref_kind}]
[ref_valid_for] ...the reference is valid for
[content_valid_for] ...but the borrowed content is only valid for
[type_obj_valid_for] object type is valid for
[source_pointer_valid_for] source pointer is only valid for
[type_satisfy] type must satisfy
[type_outlive] type must outlive
[lf_param_instantiated_with] lifetime parameter instantiated with
[lf_param_must_outlive] but lifetime parameter must outlive
[lf_instantiated_with] lifetime instantiated with
[lf_must_outlive] but lifetime must outlive
[pointer_valid_for] the pointer is valid for
[data_valid_for] but the referenced data is only valid for
[empty] {""}
}{$pref_kind ->
[empty] {""}
Expand All @@ -148,7 +160,6 @@ infer_region_explanation = {$pref_kind ->
*[should_not_happen] [{$desc_kind}]
[restatic] the static lifetime
[revar] lifetime {$desc_arg}

[as_defined] the lifetime `{$desc_arg}` as defined here
[as_defined_anon] the anonymous lifetime as defined here
[defined_here] the anonymous lifetime defined here
Expand All @@ -158,8 +169,16 @@ infer_region_explanation = {$pref_kind ->
*[should_not_happen] [{$suff_kind}]
[empty]{""}
[continues] ...
[req_by_binding] {" "}as required by this binding
}

infer_outlives_content = lifetime of reference outlives lifetime of borrowed content...
infer_outlives_bound = lifetime of the source pointer does not outlive lifetime bound of the object type
infer_fullfill_req_lifetime = the type `{$ty}` does not fulfill the required lifetime
infer_lf_bound_not_satisfied = lifetime bound not satisfied
infer_borrowed_too_long = a value of type `{$ty}` is borrowed for too long
infer_ref_longer_than_data = in type `{$ty}`, reference has a longer lifetime than the data it references

infer_mismatched_static_lifetime = incompatible lifetime on type
infer_does_not_outlive_static_from_impl = ...does not necessarily outlive the static lifetime introduced by the compatible `impl`
infer_implicit_static_lifetime_note = this has an implicit `'static` lifetime requirement
Expand Down Expand Up @@ -308,3 +327,21 @@ infer_ril_introduced_here = `'static` requirement introduced here
infer_ril_introduced_by = requirement introduced by this return type
infer_ril_because_of = because of this returned expression
infer_ril_static_introduced_by = "`'static` lifetime requirement introduced by the return type

infer_where_remove = remove the `where` clause
infer_where_copy_predicates = copy the `where` clause predicates from the trait

infer_srs_remove_and_box = consider removing this semicolon and boxing the expressions
infer_srs_remove = consider removing this semicolon
infer_srs_add = consider returning the local binding `{$ident}`
infer_srs_add_one = consider returning one of these bindings

infer_await_both_futures = consider `await`ing on both `Future`s
infer_await_future = consider `await`ing on the `Future`
infer_await_note = calling an async function returns a future

infer_prlf_defined_with_sub = the lifetime `{$sub_symbol}` defined here...
infer_prlf_defined_without_sub = the lifetime defined here...
infer_prlf_must_oultive_with_sup = ...must outlive the lifetime `{$sup_symbol}` defined here
infer_prlf_must_oultive_without_sup = ...must outlive the lifetime defined here
infer_prlf_known_limitation = this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information)
213 changes: 213 additions & 0 deletions compiler/rustc_infer/src/errors/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -933,3 +933,216 @@ pub struct ButNeedsToSatisfy {
pub has_lifetime: bool,
pub lifetime: String,
}

#[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>>,
}

#[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>>,
}

#[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,
code = "{space}where {trait_predicates}",
applicability = "machine-applicable",
style = "verbose"
)]
CopyPredicates {
#[primary_span]
span: Span,
space: &'static str,
trait_predicates: String,
},
}

#[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,
},
}

#[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)]
FutureSuggNote {
#[primary_span]
span: Span,
},
#[multipart_suggestion(
infer_await_future,
style = "verbose",
applicability = "maybe-incorrect"
)]
FutureSuggMultiple {
#[suggestion_part(code = ".await")]
spans: Vec<Span>,
},
}

#[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: (),
},
}
44 changes: 37 additions & 7 deletions compiler/rustc_infer/src/errors/note_and_explain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,16 +121,42 @@ impl<'a> DescriptionCtx<'a> {

pub enum PrefixKind {
Empty,
RefValidFor,
ContentValidFor,
TypeObjValidFor,
SourcePointerValidFor,
TypeSatisfy,
TypeOutlive,
LfParamInstantiatedWith,
LfParamMustOutlive,
LfInstantiatedWith,
LfMustOutlive,
PointerValidFor,
DataValidFor,
}

pub enum SuffixKind {
Empty,
Continues,
ReqByBinding,
}

impl IntoDiagnosticArg for PrefixKind {
fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
let kind = match self {
Self::Empty => "empty",
Self::RefValidFor => "ref_valid_for",
Self::ContentValidFor => "content_valid_for",
Self::TypeObjValidFor => "type_obj_valid_for",
Self::SourcePointerValidFor => "source_pointer_valid_for",
Self::TypeSatisfy => "type_satisfy",
Self::TypeOutlive => "type_outlive",
Self::LfParamInstantiatedWith => "lf_param_instantiated_with",
Self::LfParamMustOutlive => "lf_param_must_outlive",
Self::LfInstantiatedWith => "lf_instantiated_with",
Self::LfMustOutlive => "lf_must_outlive",
Self::PointerValidFor => "pointer_valid_for",
Self::DataValidFor => "data_valid_for",
}
.into();
rustc_errors::DiagnosticArgValue::Str(kind)
Expand All @@ -140,7 +166,9 @@ impl IntoDiagnosticArg for PrefixKind {
impl IntoDiagnosticArg for SuffixKind {
fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
let kind = match self {
Self::Empty => "empty",
Self::Continues => "continues",
Self::ReqByBinding => "req_by_binding",
}
.into();
rustc_errors::DiagnosticArgValue::Str(kind)
Expand All @@ -166,17 +194,19 @@ impl RegionExplanation<'_> {
}

impl AddToDiagnostic for RegionExplanation<'_> {
fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, f: F)
where
F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
{
if let Some(span) = self.desc.span {
diag.span_note(span, fluent::infer_region_explanation);
} else {
diag.note(fluent::infer_region_explanation);
}
self.desc.add_to(diag);
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);
let msg = f(diag, fluent::infer_region_explanation.into());
if let Some(span) = desc_span {
diag.span_note(span, msg);
} else {
diag.note(msg);
}
}
}
Loading