Partial work on static_impl_trait.rs
This commit is contained in:
parent
3935a81d47
commit
0634b0119c
3 changed files with 221 additions and 111 deletions
|
@ -221,3 +221,55 @@ infer_trait_impl_diff = `impl` item signature doesn't match `trait` item signatu
|
||||||
infer_tid_rel_help = verify the lifetime relationships in the `trait` and `impl` between the `self` argument, the other inputs and its output
|
infer_tid_rel_help = verify the lifetime relationships in the `trait` and `impl` between the `self` argument, the other inputs and its output
|
||||||
infer_tid_consider_borriwing = consider borrowing this type parameter in the trait
|
infer_tid_consider_borriwing = consider borrowing this type parameter in the trait
|
||||||
infer_tid_param_help = the lifetime requirements from the `impl` do not correspond to the requirements in the `trait`
|
infer_tid_param_help = the lifetime requirements from the `impl` do not correspond to the requirements in the `trait`
|
||||||
|
|
||||||
|
infer_dtcs_has_lifetime_req_label = this has an implicit `'static` lifetime requirement
|
||||||
|
infer_dtcs_introduces_requirement = calling this method introduces the `impl`'s 'static` requirement
|
||||||
|
infer_dtcs_has_req_note = the used `impl` has a `'static` requirement
|
||||||
|
infer_dtcs_suggestion = consider relaxing the implicit `'static` requirement
|
||||||
|
|
||||||
|
infer_but_calling_introduces = {$has_param_name ->
|
||||||
|
[true] `{$param_name}`
|
||||||
|
*[false] `fn` parameter
|
||||||
|
} has {$lifetime_kind ->
|
||||||
|
[named] lifetime `{lifetime}`
|
||||||
|
*[anon] an anonymous lifetime `'_`
|
||||||
|
} but calling `{assoc_item}` introduces an implicit `'static` lifetime requirement
|
||||||
|
.label1 = {$has_lifetime ->
|
||||||
|
[named] lifetime `{lifetime}`
|
||||||
|
*[anon] an anonymous lifetime `'_`
|
||||||
|
}
|
||||||
|
.label2 = ...is used and required to live as long as `'static` here because of an implicit lifetime bound on the {$has_impl_path ->
|
||||||
|
[named] `impl` of `{$impl_path}`
|
||||||
|
*[anon] inherent `impl`
|
||||||
|
}
|
||||||
|
|
||||||
|
infer_but_needs_to_satisfy = {$has_param_name ->
|
||||||
|
[true] `{$param_name}`
|
||||||
|
*[false] `fn` parameter
|
||||||
|
} has {$has_lifetime ->
|
||||||
|
[named] lifetime `{lifetime}`
|
||||||
|
*[anon] an anonymous lifetime `'_`
|
||||||
|
} but it needs to satisfy a `'static` lifetime requirement
|
||||||
|
.influencer = this data with {$has_lifetime ->
|
||||||
|
[named] lifetime `{lifetime}`
|
||||||
|
*[anon] an anonymous lifetime `'_`
|
||||||
|
}...
|
||||||
|
.require = {$spans_empty ->
|
||||||
|
*[true] ...is used and required to live as long as `'static` here
|
||||||
|
[false] ...and is required to live as long as `'static` here
|
||||||
|
}
|
||||||
|
.used_here = ...is used here...
|
||||||
|
.introduced_by_bound = 'static` lifetime requirement introduced by this bound
|
||||||
|
|
||||||
|
infer_more_targeted = {$has_param_name ->
|
||||||
|
[true] `{$param_name}`
|
||||||
|
*[false] `fn` parameter
|
||||||
|
} has {$has_lifetime ->
|
||||||
|
[named] lifetime `{lifetime}`
|
||||||
|
*[anon] an anonymous lifetime `'_`
|
||||||
|
} but calling `{$ident}` introduces an implicit `'static` lifetime requirement
|
||||||
|
|
||||||
|
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
|
||||||
|
|
|
@ -8,6 +8,7 @@ use rustc_hir::{FnRetTy, Ty};
|
||||||
use rustc_macros::{Diagnostic, Subdiagnostic};
|
use rustc_macros::{Diagnostic, Subdiagnostic};
|
||||||
use rustc_middle::ty::{Region, TyCtxt};
|
use rustc_middle::ty::{Region, TyCtxt};
|
||||||
use rustc_span::symbol::kw;
|
use rustc_span::symbol::kw;
|
||||||
|
use rustc_span::Symbol;
|
||||||
use rustc_span::{symbol::Ident, BytePos, Span};
|
use rustc_span::{symbol::Ident, BytePos, Span};
|
||||||
|
|
||||||
use crate::infer::error_reporting::{
|
use crate::infer::error_reporting::{
|
||||||
|
@ -619,3 +620,99 @@ pub struct TraitImplDiff {
|
||||||
pub expected: String,
|
pub expected: String,
|
||||||
pub found: String,
|
pub found: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct DynTraitConstraintSuggestion {
|
||||||
|
pub span: Span,
|
||||||
|
pub ident: Ident,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AddSubdiagnostic for DynTraitConstraintSuggestion {
|
||||||
|
fn add_to_diagnostic(self, diag: &mut rustc_errors::Diagnostic) {
|
||||||
|
let mut multi_span: MultiSpan = vec![self.span].into();
|
||||||
|
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);
|
||||||
|
diag.span_note(multi_span, fluent::infer::dtcs_has_req_note);
|
||||||
|
diag.span_suggestion_verbose(
|
||||||
|
self.span.shrink_to_hi(),
|
||||||
|
fluent::infer::dtcs_suggestion,
|
||||||
|
" + '_",
|
||||||
|
Applicability::MaybeIncorrect,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(infer::but_calling_introduces, code = "E0772")]
|
||||||
|
pub struct ButCallingIntroduces {
|
||||||
|
#[label(infer::label1)]
|
||||||
|
pub param_ty_span: Span,
|
||||||
|
#[primary_span]
|
||||||
|
#[label(infer::label2)]
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AddSubdiagnostic for ReqIntroducedLocations {
|
||||||
|
fn add_to_diagnostic(mut self, diag: &mut rustc_errors::Diagnostic) {
|
||||||
|
for sp in self.spans {
|
||||||
|
self.span.push_span_label(sp, fluent::infer::ril_introduced_here);
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.add_label {
|
||||||
|
self.span.push_span_label(self.fn_decl_span, fluent::infer::ril_introduced_by);
|
||||||
|
}
|
||||||
|
self.span.push_span_label(self.cause_span, fluent::infer::ril_because_of);
|
||||||
|
diag.span_note(self.span, fluent::infer::ril_static_introduced_by);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct MoreTargeted {
|
||||||
|
pub ident: Symbol,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AddSubdiagnostic for MoreTargeted {
|
||||||
|
fn add_to_diagnostic(self, diag: &mut rustc_errors::Diagnostic) {
|
||||||
|
diag.code(rustc_errors::error_code!(E0772));
|
||||||
|
diag.set_primary_message(fluent::infer::more_targeted);
|
||||||
|
diag.set_arg("ident", self.ident);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(infer::but_needs_to_satisfy, code = "E0759")]
|
||||||
|
pub struct ButNeedsToSatisfy {
|
||||||
|
#[primary_span]
|
||||||
|
pub sp: Span,
|
||||||
|
#[label(infer::influencer)]
|
||||||
|
pub influencer_point: Span,
|
||||||
|
#[label(infer::used_here)]
|
||||||
|
pub spans: Vec<Span>,
|
||||||
|
#[label(infer::require)]
|
||||||
|
pub require_span_as_label: Option<Span>,
|
||||||
|
#[note(infer::require)]
|
||||||
|
pub require_span_as_note: Option<Span>,
|
||||||
|
#[note(infer::introduced_by_bound)]
|
||||||
|
pub bound: Option<Span>,
|
||||||
|
|
||||||
|
#[subdiagnostic]
|
||||||
|
pub req_introduces_loc: Option<ReqIntroducedLocations>,
|
||||||
|
|
||||||
|
pub spans_empty: bool,
|
||||||
|
pub has_lifetime: bool,
|
||||||
|
pub lifetime: String,
|
||||||
|
}
|
||||||
|
|
|
@ -1,11 +1,15 @@
|
||||||
//! Error Reporting for static impl Traits.
|
//! Error Reporting for static impl Traits.
|
||||||
|
|
||||||
|
use crate::errors::{
|
||||||
|
ButCallingIntroduces, ButNeedsToSatisfy, DynTraitConstraintSuggestion, MoreTargeted,
|
||||||
|
ReqIntroducedLocations,
|
||||||
|
};
|
||||||
use crate::infer::error_reporting::nice_region_error::NiceRegionError;
|
use crate::infer::error_reporting::nice_region_error::NiceRegionError;
|
||||||
use crate::infer::lexical_region_resolve::RegionResolutionError;
|
use crate::infer::lexical_region_resolve::RegionResolutionError;
|
||||||
use crate::infer::{SubregionOrigin, TypeTrace};
|
use crate::infer::{SubregionOrigin, TypeTrace};
|
||||||
use crate::traits::{ObligationCauseCode, UnifyReceiverContext};
|
use crate::traits::{ObligationCauseCode, UnifyReceiverContext};
|
||||||
use rustc_data_structures::fx::FxIndexSet;
|
use rustc_data_structures::fx::FxHashSet;
|
||||||
use rustc_errors::{struct_span_err, Applicability, Diagnostic, ErrorGuaranteed, MultiSpan};
|
use rustc_errors::{AddSubdiagnostic, Applicability, Diagnostic, ErrorGuaranteed, MultiSpan};
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_hir::intravisit::{walk_ty, Visitor};
|
use rustc_hir::intravisit::{walk_ty, Visitor};
|
||||||
use rustc_hir::{self as hir, GenericBound, Item, ItemKind, Lifetime, LifetimeName, Node, TyKind};
|
use rustc_hir::{self as hir, GenericBound, Item, ItemKind, Lifetime, LifetimeName, Node, TyKind};
|
||||||
|
@ -49,46 +53,33 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let param = self.find_param_with_region(*sup_r, *sub_r)?;
|
let param = self.find_param_with_region(*sup_r, *sub_r)?;
|
||||||
let lifetime = if sup_r.has_name() {
|
let simple_ident = param.param.pat.simple_ident();
|
||||||
format!("lifetime `{}`", sup_r)
|
|
||||||
} else {
|
let (has_impl_path, impl_path) = match ctxt.assoc_item.container {
|
||||||
"an anonymous lifetime `'_`".to_string()
|
|
||||||
};
|
|
||||||
let mut err = struct_span_err!(
|
|
||||||
tcx.sess,
|
|
||||||
cause.span,
|
|
||||||
E0772,
|
|
||||||
"{} has {} but calling `{}` introduces an implicit `'static` lifetime \
|
|
||||||
requirement",
|
|
||||||
param
|
|
||||||
.param
|
|
||||||
.pat
|
|
||||||
.simple_ident()
|
|
||||||
.map(|s| format!("`{}`", s))
|
|
||||||
.unwrap_or_else(|| "`fn` parameter".to_string()),
|
|
||||||
lifetime,
|
|
||||||
ctxt.assoc_item.name,
|
|
||||||
);
|
|
||||||
err.span_label(param.param_ty_span, &format!("this data with {}...", lifetime));
|
|
||||||
err.span_label(
|
|
||||||
cause.span,
|
|
||||||
&format!(
|
|
||||||
"...is used and required to live as long as `'static` here \
|
|
||||||
because of an implicit lifetime bound on the {}",
|
|
||||||
match ctxt.assoc_item.container {
|
|
||||||
AssocItemContainer::TraitContainer => {
|
AssocItemContainer::TraitContainer => {
|
||||||
let id = ctxt.assoc_item.container_id(tcx);
|
let id = ctxt.assoc_item.container_id(tcx);
|
||||||
format!("`impl` of `{}`", tcx.def_path_str(id))
|
(true, tcx.def_path_str(id))
|
||||||
}
|
}
|
||||||
AssocItemContainer::ImplContainer => "inherent `impl`".to_string(),
|
AssocItemContainer::ImplContainer => (false, String::new()),
|
||||||
},
|
};
|
||||||
),
|
|
||||||
);
|
let diag = ButCallingIntroduces {
|
||||||
|
param_ty_span: param.param_ty_span,
|
||||||
|
cause_span: cause.span,
|
||||||
|
has_param_name: simple_ident.is_some(),
|
||||||
|
param_name: simple_ident.map(|x| x.to_string()).unwrap_or_default(),
|
||||||
|
has_lifetime: sup_r.has_name(),
|
||||||
|
lifetime: sup_r.to_string(),
|
||||||
|
assoc_item: ctxt.assoc_item.name,
|
||||||
|
has_impl_path,
|
||||||
|
impl_path,
|
||||||
|
};
|
||||||
|
let mut err = self.tcx().sess.create_err(diag);
|
||||||
if self.find_impl_on_dyn_trait(&mut err, param.param_ty, &ctxt) {
|
if self.find_impl_on_dyn_trait(&mut err, param.param_ty, &ctxt) {
|
||||||
let reported = err.emit();
|
let reported = err.emit();
|
||||||
return Some(reported);
|
return Some(reported);
|
||||||
} else {
|
} else {
|
||||||
err.cancel();
|
err.cancel()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return None;
|
return None;
|
||||||
|
@ -104,25 +95,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
||||||
let sp = var_origin.span();
|
let sp = var_origin.span();
|
||||||
let return_sp = sub_origin.span();
|
let return_sp = sub_origin.span();
|
||||||
let param = self.find_param_with_region(*sup_r, *sub_r)?;
|
let param = self.find_param_with_region(*sup_r, *sub_r)?;
|
||||||
let (lifetime_name, lifetime) = if sup_r.has_name() {
|
let lifetime_name = if sup_r.has_name() { sup_r.to_string() } else { "'_".to_owned() };
|
||||||
(sup_r.to_string(), format!("lifetime `{}`", sup_r))
|
|
||||||
} else {
|
|
||||||
("'_".to_owned(), "an anonymous lifetime `'_`".to_string())
|
|
||||||
};
|
|
||||||
let param_name = param
|
|
||||||
.param
|
|
||||||
.pat
|
|
||||||
.simple_ident()
|
|
||||||
.map(|s| format!("`{}`", s))
|
|
||||||
.unwrap_or_else(|| "`fn` parameter".to_string());
|
|
||||||
let mut err = struct_span_err!(
|
|
||||||
tcx.sess,
|
|
||||||
sp,
|
|
||||||
E0759,
|
|
||||||
"{} has {} but it needs to satisfy a `'static` lifetime requirement",
|
|
||||||
param_name,
|
|
||||||
lifetime,
|
|
||||||
);
|
|
||||||
|
|
||||||
let (mention_influencer, influencer_point) =
|
let (mention_influencer, influencer_point) =
|
||||||
if sup_origin.span().overlaps(param.param_ty_span) {
|
if sup_origin.span().overlaps(param.param_ty_span) {
|
||||||
|
@ -141,7 +114,6 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
||||||
} else {
|
} else {
|
||||||
(!sup_origin.span().overlaps(return_sp), param.param_ty_span)
|
(!sup_origin.span().overlaps(return_sp), param.param_ty_span)
|
||||||
};
|
};
|
||||||
err.span_label(influencer_point, &format!("this data with {}...", lifetime));
|
|
||||||
|
|
||||||
debug!("try_report_static_impl_trait: param_info={:?}", param);
|
debug!("try_report_static_impl_trait: param_info={:?}", param);
|
||||||
|
|
||||||
|
@ -155,31 +127,19 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
||||||
spans.dedup_by_key(|span| (span.lo(), span.hi()));
|
spans.dedup_by_key(|span| (span.lo(), span.hi()));
|
||||||
|
|
||||||
// We try to make the output have fewer overlapping spans if possible.
|
// We try to make the output have fewer overlapping spans if possible.
|
||||||
let require_msg = if spans.is_empty() {
|
|
||||||
"...is used and required to live as long as `'static` here"
|
|
||||||
} else {
|
|
||||||
"...and is required to live as long as `'static` here"
|
|
||||||
};
|
|
||||||
let require_span =
|
let require_span =
|
||||||
if sup_origin.span().overlaps(return_sp) { sup_origin.span() } else { return_sp };
|
if sup_origin.span().overlaps(return_sp) { sup_origin.span() } else { return_sp };
|
||||||
|
|
||||||
for span in &spans {
|
let spans_empty = spans.is_empty();
|
||||||
err.span_label(*span, "...is used here...");
|
let require_as_note = spans.iter().any(|sp| sp.overlaps(return_sp) || *sp > return_sp);
|
||||||
}
|
let bound = if let SubregionOrigin::RelateParamBound(_, _, Some(bound)) = sub_origin {
|
||||||
|
Some(*bound)
|
||||||
if spans.iter().any(|sp| sp.overlaps(return_sp) || *sp > return_sp) {
|
|
||||||
// If any of the "captured here" labels appears on the same line or after
|
|
||||||
// `require_span`, we put it on a note to ensure the text flows by appearing
|
|
||||||
// always at the end.
|
|
||||||
err.span_note(require_span, require_msg);
|
|
||||||
} else {
|
} else {
|
||||||
// We don't need a note, it's already at the end, it can be shown as a `span_label`.
|
None
|
||||||
err.span_label(require_span, require_msg);
|
};
|
||||||
}
|
|
||||||
|
let mut subdiag = None;
|
||||||
|
|
||||||
if let SubregionOrigin::RelateParamBound(_, _, Some(bound)) = sub_origin {
|
|
||||||
err.span_note(*bound, "`'static` lifetime requirement introduced by this bound");
|
|
||||||
}
|
|
||||||
if let SubregionOrigin::Subtype(box TypeTrace { cause, .. }) = sub_origin {
|
if let SubregionOrigin::Subtype(box TypeTrace { cause, .. }) = sub_origin {
|
||||||
if let ObligationCauseCode::ReturnValue(hir_id)
|
if let ObligationCauseCode::ReturnValue(hir_id)
|
||||||
| ObligationCauseCode::BlockTailExpression(hir_id) = cause.code()
|
| ObligationCauseCode::BlockTailExpression(hir_id) = cause.code()
|
||||||
|
@ -187,33 +147,50 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
||||||
let parent_id = tcx.hir().get_parent_item(*hir_id);
|
let parent_id = tcx.hir().get_parent_item(*hir_id);
|
||||||
if let Some(fn_decl) = tcx.hir().fn_decl_by_hir_id(parent_id.into()) {
|
if let Some(fn_decl) = tcx.hir().fn_decl_by_hir_id(parent_id.into()) {
|
||||||
let mut span: MultiSpan = fn_decl.output.span().into();
|
let mut span: MultiSpan = fn_decl.output.span().into();
|
||||||
|
let mut spans = Vec::new();
|
||||||
let mut add_label = true;
|
let mut add_label = true;
|
||||||
if let hir::FnRetTy::Return(ty) = fn_decl.output {
|
if let hir::FnRetTy::Return(ty) = fn_decl.output {
|
||||||
let mut v = StaticLifetimeVisitor(vec![], tcx.hir());
|
let mut v = StaticLifetimeVisitor(vec![], tcx.hir());
|
||||||
v.visit_ty(ty);
|
v.visit_ty(ty);
|
||||||
if !v.0.is_empty() {
|
if !v.0.is_empty() {
|
||||||
span = v.0.clone().into();
|
span = v.0.clone().into();
|
||||||
for sp in v.0 {
|
spans = v.0;
|
||||||
span.push_span_label(sp, "`'static` requirement introduced here");
|
|
||||||
}
|
|
||||||
add_label = false;
|
add_label = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if add_label {
|
let fn_decl_span = fn_decl.output.span();
|
||||||
span.push_span_label(
|
|
||||||
fn_decl.output.span(),
|
subdiag = Some(ReqIntroducedLocations {
|
||||||
"requirement introduced by this return type",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
span.push_span_label(cause.span, "because of this returned expression");
|
|
||||||
err.span_note(
|
|
||||||
span,
|
span,
|
||||||
"`'static` lifetime requirement introduced by the return type",
|
spans,
|
||||||
);
|
fn_decl_span,
|
||||||
|
cause_span: cause.span,
|
||||||
|
add_label,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let diag = ButNeedsToSatisfy {
|
||||||
|
sp,
|
||||||
|
influencer_point,
|
||||||
|
spans: spans.clone(),
|
||||||
|
// If any of the "captured here" labels appears on the same line or after
|
||||||
|
// `require_span`, we put it on a note to ensure the text flows by appearing
|
||||||
|
// always at the end.
|
||||||
|
require_span_as_note: require_as_note.then_some(require_span),
|
||||||
|
// We don't need a note, it's already at the end, it can be shown as a `span_label`.
|
||||||
|
require_span_as_label: (!require_as_note).then_some(require_span),
|
||||||
|
req_introduces_loc: subdiag,
|
||||||
|
|
||||||
|
has_lifetime: sup_r.has_name(),
|
||||||
|
lifetime: sup_r.to_string(),
|
||||||
|
spans_empty,
|
||||||
|
bound,
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut err = self.tcx().sess.create_err(diag);
|
||||||
|
|
||||||
let fn_returns = tcx.return_type_impl_or_dyn_traits(anon_reg_sup.def_id);
|
let fn_returns = tcx.return_type_impl_or_dyn_traits(anon_reg_sup.def_id);
|
||||||
|
|
||||||
let mut override_error_code = None;
|
let mut override_error_code = None;
|
||||||
|
@ -247,12 +224,8 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
if let (Some(ident), true) = (override_error_code, fn_returns.is_empty()) {
|
if let (Some(ident), true) = (override_error_code, fn_returns.is_empty()) {
|
||||||
// Provide a more targeted error code and description.
|
// Provide a more targeted error code and description.
|
||||||
err.code(rustc_errors::error_code!(E0772));
|
let retarget_subdiag = MoreTargeted { ident };
|
||||||
err.set_primary_message(&format!(
|
retarget_subdiag.add_to_diagnostic(&mut err);
|
||||||
"{} has {} but calling `{}` introduces an implicit `'static` lifetime \
|
|
||||||
requirement",
|
|
||||||
param_name, lifetime, ident,
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let arg = match param.param.pat.simple_ident() {
|
let arg = match param.param.pat.simple_ident() {
|
||||||
|
@ -513,21 +486,9 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
||||||
let mut traits = vec![];
|
let mut traits = vec![];
|
||||||
let mut hir_v = HirTraitObjectVisitor(&mut traits, *found_did);
|
let mut hir_v = HirTraitObjectVisitor(&mut traits, *found_did);
|
||||||
hir_v.visit_ty(&self_ty);
|
hir_v.visit_ty(&self_ty);
|
||||||
for span in &traits {
|
for &span in &traits {
|
||||||
let mut multi_span: MultiSpan = vec![*span].into();
|
let subdiag = DynTraitConstraintSuggestion { span, ident };
|
||||||
multi_span
|
subdiag.add_to_diagnostic(err);
|
||||||
.push_span_label(*span, "this has an implicit `'static` lifetime requirement");
|
|
||||||
multi_span.push_span_label(
|
|
||||||
ident.span,
|
|
||||||
"calling this method introduces the `impl`'s 'static` requirement",
|
|
||||||
);
|
|
||||||
err.span_note(multi_span, "the used `impl` has a `'static` requirement");
|
|
||||||
err.span_suggestion_verbose(
|
|
||||||
span.shrink_to_hi(),
|
|
||||||
"consider relaxing the implicit `'static` requirement",
|
|
||||||
" + '_",
|
|
||||||
Applicability::MaybeIncorrect,
|
|
||||||
);
|
|
||||||
suggested = true;
|
suggested = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue