diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs index 75fde53b6cdec..f2b7a0f46878f 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs @@ -1,3 +1,6 @@ +// #![deny(rustc::untranslatable_diagnostic)] +// #![deny(rustc::diagnostic_outside_of_impl)] + use std::fmt::{self, Display}; use std::iter; @@ -10,6 +13,7 @@ use rustc_middle::ty::{self, DefIdTree, RegionVid, Ty}; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{Span, DUMMY_SP}; +use crate::session_diagnostics::RegionNameLabels; use crate::{nll::ToRegionVid, universal_regions::DefiningTy, MirBorrowckCtxt}; /// A name for a particular region used in emitting diagnostics. This name could be a generated @@ -133,48 +137,58 @@ impl RegionName { RegionNameHighlight::MatchedAdtAndSegment(span), _, ) => { - diag.span_label(*span, format!("let's call this `{self}`")); + diag.subdiagnostic(RegionNameLabels::NameRegion { span: *span, rg_name: self }); } RegionNameSource::AnonRegionFromArgument(RegionNameHighlight::Occluded( span, type_name, )) => { - diag.span_label( - *span, - format!("lifetime `{self}` appears in the type {type_name}"), - ); + diag.subdiagnostic(RegionNameLabels::LifetimeInType { + span: *span, + type_name: &type_name, + rg_name: self, + }); } RegionNameSource::AnonRegionFromOutput( RegionNameHighlight::Occluded(span, type_name), mir_description, ) => { - diag.span_label( - *span, - format!( - "return type{mir_description} `{type_name}` contains a lifetime `{self}`" - ), - ); + diag.subdiagnostic(RegionNameLabels::LifetimeInReturned { + span: *span, + mir_description, + type_name: &type_name, + rg_name: self, + }); } RegionNameSource::AnonRegionFromUpvar(span, upvar_name) => { - diag.span_label( - *span, - format!("lifetime `{self}` appears in the type of `{upvar_name}`"), - ); + diag.subdiagnostic(RegionNameLabels::LifetimeInTypeOf { + span: *span, + upvar_name: upvar_name.to_ident_string(), + rg_name: self, + }); } RegionNameSource::AnonRegionFromOutput( RegionNameHighlight::CannotMatchHirTy(span, type_name), mir_description, ) => { - diag.span_label(*span, format!("return type{mir_description} is {type_name}")); + diag.subdiagnostic(RegionNameLabels::ReturnTypeIsTpye { + span: *span, + mir_description, + type_name: &type_name, + }); } RegionNameSource::AnonRegionFromYieldTy(span, type_name) => { - diag.span_label(*span, format!("yield type is {type_name}")); + diag.subdiagnostic(RegionNameLabels::YieldTypeIsTpye { + span: *span, + type_name: &type_name, + }); } RegionNameSource::AnonRegionFromImplSignature(span, location) => { - diag.span_label( - *span, - format!("lifetime `{self}` appears in the `impl`'s {location}"), - ); + diag.subdiagnostic(RegionNameLabels::LifetimeInImpl { + span: *span, + rg_name: self, + location: &location, + }); } RegionNameSource::Static => {} } diff --git a/compiler/rustc_borrowck/src/session_diagnostics.rs b/compiler/rustc_borrowck/src/session_diagnostics.rs index 5d750c6ca8c7b..45137de411d13 100644 --- a/compiler/rustc_borrowck/src/session_diagnostics.rs +++ b/compiler/rustc_borrowck/src/session_diagnostics.rs @@ -157,3 +157,55 @@ pub(crate) enum RequireStaticErr { multi_span: MultiSpan, }, } + +#[derive(SessionSubdiagnostic)] +pub(crate) enum RegionNameLabels<'a> { + #[label(borrowck::name_this_region)] + NameRegion { + #[primary_span] + span: Span, + rg_name: &'a RegionName, + }, + #[label(borrowck::lifetime_appears_in_type)] + LifetimeInType { + #[primary_span] + span: Span, + type_name: &'a str, + rg_name: &'a RegionName, + }, + #[label(borrowck::return_type_has_lifetime)] + LifetimeInReturned { + #[primary_span] + span: Span, + mir_description: &'a str, + type_name: &'a str, + rg_name: &'a RegionName, + }, + #[label(borrowck::lifetime_appears_in_type_of)] + LifetimeInTypeOf { + #[primary_span] + span: Span, + upvar_name: String, + rg_name: &'a RegionName, + }, + #[label(borrowck::return_type_is_type)] + ReturnTypeIsTpye { + #[primary_span] + span: Span, + mir_description: &'a str, + type_name: &'a str, + }, + #[label(borrowck::yield_type_is_type)] + YieldTypeIsTpye { + #[primary_span] + span: Span, + type_name: &'a str, + }, + #[label(borrowck::lifetime_appears_here_in_impl)] + LifetimeInImpl { + #[primary_span] + span: Span, + rg_name: &'a RegionName, + location: &'a str, + }, +} diff --git a/compiler/rustc_error_messages/locales/en-US/borrowck.ftl b/compiler/rustc_error_messages/locales/en-US/borrowck.ftl index 67f2156f32e50..58577273f1cd0 100644 --- a/compiler/rustc_error_messages/locales/en-US/borrowck.ftl +++ b/compiler/rustc_error_messages/locales/en-US/borrowck.ftl @@ -58,3 +58,24 @@ borrowck_returned_lifetime_short = borrowck_used_impl_require_static = the used `impl` has a `'static` requirement + +borrowck_name_this_region = + let's call this `{$rg_name}` + +borrowck_lifetime_appears_in_type = + lifetime `{$rg_name}` appears in the type {$type_name} + +borrowck_return_type_has_lifetime = + return type{$mir_description} `{$type_name}` contains a lifetime `{$rg_name}` + +borrowck_lifetime_appears_in_type_of = + lifetime `{$rg_name}` appears in the type of `{$upvar_name}` + +borrowck_return_type_is_type = + return type{$mir_description} is {$type_name} + +borrowck_yield_type_is_type = + yield type is {$type_name} + +borrowck_lifetime_appears_here_in_impl = + lifetime `{$rg_name}` appears in the `impl`'s {$location}