1 use crate::infer::error_reporting::{note_and_explain_region, ObligationCauseExt};
2 use crate::infer::{self, InferCtxt, SubregionOrigin};
3 use rustc_errors::{struct_span_err, DiagnosticBuilder};
4 use rustc_middle::ty::error::TypeError;
5 use rustc_middle::ty::{self, Region};
7 impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
8 pub(super) fn note_region_origin(
10 err: &mut DiagnosticBuilder<'_>,
11 origin: &SubregionOrigin<'tcx>,
14 infer::Subtype(ref trace) => {
15 if let Some((expected, found)) = self.values_str(&trace.values) {
18 &format!("...so that the {}", trace.cause.as_requirement_str()),
21 err.note_expected_found(&"", expected, &"", found);
23 // FIXME: this really should be handled at some earlier stage. Our
24 // handling of region checking when type errors are present is
29 &format!("...so that {}", trace.cause.as_requirement_str()),
33 infer::Reborrow(span) => {
34 err.span_note(span, "...so that reference does not outlive borrowed content");
36 infer::ReborrowUpvar(span, ref upvar_id) => {
37 let var_name = self.tcx.hir().name(upvar_id.var_path.hir_id);
38 err.span_note(span, &format!("...so that closure can access `{}`", var_name));
40 infer::RelateObjectBound(span) => {
41 err.span_note(span, "...so that it can be closed over into an object");
43 infer::CallReturn(span) => {
44 err.span_note(span, "...so that return value is valid for the call");
46 infer::DataBorrowed(ty, span) => {
50 "...so that the type `{}` is not borrowed for too long",
55 infer::ReferenceOutlivesReferent(ty, span) => {
59 "...so that the reference type `{}` does not outlive the \
65 infer::RelateParamBound(span, t) => {
69 "...so that the type `{}` will meet its required \
75 infer::RelateRegionParamBound(span) => {
78 "...so that the declared lifetime parameter bounds are satisfied",
81 infer::CompareImplMethodObligation { span, .. } => {
84 "...so that the definition in impl matches the definition from the \
91 pub(super) fn report_concrete_failure(
93 origin: SubregionOrigin<'tcx>,
96 ) -> DiagnosticBuilder<'tcx> {
98 infer::Subtype(box trace) => {
99 let terr = TypeError::RegionsDoesNotOutlive(sup, sub);
100 let mut err = self.report_and_explain_type_error(trace, &terr);
101 note_and_explain_region(self.tcx, &mut err, "", sup, "...");
102 note_and_explain_region(
105 "...does not necessarily outlive ",
111 infer::Reborrow(span) => {
112 let mut err = struct_span_err!(
116 "lifetime of reference outlives lifetime of \
119 note_and_explain_region(
122 "...the reference is valid for ",
126 note_and_explain_region(
129 "...but the borrowed content is only valid for ",
135 infer::ReborrowUpvar(span, ref upvar_id) => {
136 let var_name = self.tcx.hir().name(upvar_id.var_path.hir_id);
137 let mut err = struct_span_err!(
141 "lifetime of borrowed pointer outlives lifetime \
142 of captured variable `{}`...",
145 note_and_explain_region(
148 "...the borrowed pointer is valid for ",
152 note_and_explain_region(
155 &format!("...but `{}` is only valid for ", var_name),
161 infer::RelateObjectBound(span) => {
162 let mut err = struct_span_err!(
166 "lifetime of the source pointer does not outlive \
167 lifetime bound of the object type"
169 note_and_explain_region(self.tcx, &mut err, "object type is valid for ", sub, "");
170 note_and_explain_region(
173 "source pointer is only valid for ",
179 infer::RelateParamBound(span, ty) => {
180 let mut err = struct_span_err!(
184 "the type `{}` does not fulfill the required \
186 self.ty_to_string(ty)
190 note_and_explain_region(self.tcx, &mut err, "type must satisfy ", sub, "")
192 _ => note_and_explain_region(self.tcx, &mut err, "type must outlive ", sub, ""),
196 infer::RelateRegionParamBound(span) => {
198 struct_span_err!(self.tcx.sess, span, E0478, "lifetime bound not satisfied");
199 note_and_explain_region(
202 "lifetime parameter instantiated with ",
206 note_and_explain_region(
209 "but lifetime parameter must outlive ",
215 infer::CallReturn(span) => {
216 let mut err = struct_span_err!(
220 "lifetime of return value does not outlive the \
223 note_and_explain_region(
226 "the return value is only valid for ",
232 infer::DataBorrowed(ty, span) => {
233 let mut err = struct_span_err!(
237 "a value of type `{}` is borrowed for too long",
238 self.ty_to_string(ty)
240 note_and_explain_region(self.tcx, &mut err, "the type is valid for ", sub, "");
241 note_and_explain_region(self.tcx, &mut err, "but the borrow lasts for ", sup, "");
244 infer::ReferenceOutlivesReferent(ty, span) => {
245 let mut err = struct_span_err!(
249 "in type `{}`, reference has a longer lifetime than the data it references",
250 self.ty_to_string(ty)
252 note_and_explain_region(self.tcx, &mut err, "the pointer is valid for ", sub, "");
253 note_and_explain_region(
256 "but the referenced data is only valid for ",
262 infer::CompareImplMethodObligation {
267 } => self.report_extra_impl_obligation(
272 &format!("`{}: {}`", sup, sub),
277 pub(super) fn report_placeholder_failure(
279 placeholder_origin: SubregionOrigin<'tcx>,
282 ) -> DiagnosticBuilder<'tcx> {
283 // I can't think how to do better than this right now. -nikomatsakis
284 match placeholder_origin {
285 infer::Subtype(box trace) => {
286 let terr = TypeError::RegionsPlaceholderMismatch;
287 self.report_and_explain_type_error(trace, &terr)
290 _ => self.report_concrete_failure(placeholder_origin, sub, sup),