rustc_trait_selection/error_reporting/infer/nice_region_error/
mismatched_static_lifetime.rs1use rustc_data_structures::fx::FxIndexSet;
5use rustc_errors::{ErrorGuaranteed, MultiSpan};
6use rustc_hir as hir;
7use rustc_hir::intravisit::VisitorExt;
8use rustc_middle::bug;
9use rustc_middle::ty::TypeVisitor;
10use tracing::debug;
11
12use crate::error_reporting::infer::nice_region_error::NiceRegionError;
13use crate::errors::{
14 DoesNotOutliveStaticFromImpl, ImplicitStaticLifetimeSubdiag,
15 IntroducesStaticBecauseUnmetLifetimeReq, MismatchedStaticLifetime, note_and_explain,
16};
17use crate::infer::{RegionResolutionError, SubregionOrigin, TypeTrace};
18use crate::traits::ObligationCauseCode;
19
20impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
21 pub(super) fn try_report_mismatched_static_lifetime(&self) -> Option<ErrorGuaranteed> {
22 let error = self.error.as_ref()?;
23 debug!("try_report_mismatched_static_lifetime {:?}", error);
24
25 let RegionResolutionError::ConcreteFailure(origin, sub, sup) = error.clone() else {
26 return None;
27 };
28 if !sub.is_static() {
29 return None;
30 }
31 let SubregionOrigin::Subtype(box TypeTrace { ref cause, .. }) = origin else {
32 return None;
33 };
34 let ObligationCauseCode::MatchImpl(parent, impl_def_id) = cause.code() else {
37 return None;
38 };
39 let (ObligationCauseCode::WhereClause(_, binding_span)
40 | ObligationCauseCode::WhereClauseInExpr(_, binding_span, ..)) = *parent.code()
41 else {
42 return None;
43 };
44 if binding_span.is_dummy() {
45 return None;
46 }
47
48 let multi_span: MultiSpan = vec![binding_span].into();
50 let multispan_subdiag = IntroducesStaticBecauseUnmetLifetimeReq {
51 unmet_requirements: multi_span,
52 binding_span,
53 };
54
55 let expl = note_and_explain::RegionExplanation::new(
56 self.tcx(),
57 self.generic_param_scope,
58 sup,
59 Some(binding_span),
60 note_and_explain::PrefixKind::Empty,
61 note_and_explain::SuffixKind::Continues,
62 );
63 let mut impl_span = None;
64 let mut implicit_static_lifetimes = Vec::new();
65 if let Some(impl_node) = self.tcx().hir_get_if_local(*impl_def_id) {
66 let hir::Node::Item(hir::Item {
71 kind: hir::ItemKind::Impl(hir::Impl { self_ty: impl_self_ty, .. }),
72 ..
73 }) = impl_node
74 else {
75 bug!("Node not an impl.");
76 };
77
78 let ty = self.tcx().type_of(*impl_def_id).instantiate_identity();
80 let mut v = super::static_impl_trait::TraitObjectVisitor(FxIndexSet::default());
81 v.visit_ty(ty);
82 let mut traits = vec![];
83 for matching_def_id in v.0 {
84 let mut hir_v =
85 super::static_impl_trait::HirTraitObjectVisitor(&mut traits, matching_def_id);
86 hir_v.visit_ty_unambig(impl_self_ty);
87 }
88
89 if traits.is_empty() {
90 impl_span = Some(self.tcx().def_span(*impl_def_id));
95 } else {
96 for span in &traits {
99 implicit_static_lifetimes
100 .push(ImplicitStaticLifetimeSubdiag::Note { span: *span });
101 implicit_static_lifetimes
104 .push(ImplicitStaticLifetimeSubdiag::Sugg { span: span.shrink_to_hi() });
105 }
106 }
107 } else {
108 impl_span = Some(self.tcx().def_span(*impl_def_id));
111 }
112 let err = MismatchedStaticLifetime {
113 cause_span: cause.span,
114 unmet_lifetime_reqs: multispan_subdiag,
115 expl,
116 does_not_outlive_static_from_impl: impl_span
117 .map(|span| DoesNotOutliveStaticFromImpl::Spanned { span })
118 .unwrap_or(DoesNotOutliveStaticFromImpl::Unspanned),
119 implicit_static_lifetimes,
120 };
121 let reported = self.tcx().dcx().emit_err(err);
122 Some(reported)
123 }
124}