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::middle::region;
5 use rustc_middle::ty::error::TypeError;
6 use rustc_middle::ty::{self, Region};
8 impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
9 pub(super) fn note_region_origin(
11 err: &mut DiagnosticBuilder<'_>,
12 origin: &SubregionOrigin<'tcx>,
15 infer::Subtype(ref trace) => {
16 if let Some((expected, found)) = self.values_str(&trace.values) {
19 &format!("...so that the {}", trace.cause.as_requirement_str()),
22 err.note_expected_found(&"", expected, &"", found);
24 // FIXME: this really should be handled at some earlier stage. Our
25 // handling of region checking when type errors are present is
30 &format!("...so that {}", trace.cause.as_requirement_str()),
34 infer::Reborrow(span) => {
35 err.span_note(span, "...so that reference does not outlive borrowed content");
37 infer::ReborrowUpvar(span, ref upvar_id) => {
38 let var_name = self.tcx.hir().name(upvar_id.var_path.hir_id);
39 err.span_note(span, &format!("...so that closure can access `{}`", var_name));
41 infer::RelateObjectBound(span) => {
42 err.span_note(span, "...so that it can be closed over into an object");
44 infer::CallReturn(span) => {
45 err.span_note(span, "...so that return value is valid for the call");
47 infer::DataBorrowed(ty, span) => {
51 "...so that the type `{}` is not borrowed for too long",
56 infer::ReferenceOutlivesReferent(ty, span) => {
60 "...so that the reference type `{}` does not outlive the \
66 infer::RelateParamBound(span, t) => {
70 "...so that the type `{}` will meet its required \
76 infer::RelateRegionParamBound(span) => {
79 "...so that the declared lifetime parameter bounds are satisfied",
82 infer::CompareImplMethodObligation { span, .. } => {
85 "...so that the definition in impl matches the definition from the \
92 pub(super) fn report_concrete_failure(
94 region_scope_tree: ®ion::ScopeTree,
95 origin: SubregionOrigin<'tcx>,
98 ) -> DiagnosticBuilder<'tcx> {
100 infer::Subtype(box trace) => {
101 let terr = TypeError::RegionsDoesNotOutlive(sup, sub);
102 let mut err = self.report_and_explain_type_error(trace, &terr);
103 note_and_explain_region(self.tcx, region_scope_tree, &mut err, "", sup, "...");
104 note_and_explain_region(
108 "...does not necessarily outlive ",
114 infer::Reborrow(span) => {
115 let mut err = struct_span_err!(
119 "lifetime of reference outlives lifetime of \
122 note_and_explain_region(
126 "...the reference is valid for ",
130 note_and_explain_region(
134 "...but the borrowed content is only valid for ",
140 infer::ReborrowUpvar(span, ref upvar_id) => {
141 let var_name = self.tcx.hir().name(upvar_id.var_path.hir_id);
142 let mut err = struct_span_err!(
146 "lifetime of borrowed pointer outlives lifetime \
147 of captured variable `{}`...",
150 note_and_explain_region(
154 "...the borrowed pointer is valid for ",
158 note_and_explain_region(
162 &format!("...but `{}` is only valid for ", var_name),
168 infer::RelateObjectBound(span) => {
169 let mut err = struct_span_err!(
173 "lifetime of the source pointer does not outlive \
174 lifetime bound of the object type"
176 note_and_explain_region(
180 "object type is valid for ",
184 note_and_explain_region(
188 "source pointer is only valid for ",
194 infer::RelateParamBound(span, ty) => {
195 let mut err = struct_span_err!(
199 "the type `{}` does not fulfill the required \
201 self.ty_to_string(ty)
204 ty::ReStatic => note_and_explain_region(
208 "type must satisfy ",
212 _ => note_and_explain_region(
216 "type must outlive ",
223 infer::RelateRegionParamBound(span) => {
225 struct_span_err!(self.tcx.sess, span, E0478, "lifetime bound not satisfied");
226 note_and_explain_region(
230 "lifetime parameter instantiated with ",
234 note_and_explain_region(
238 "but lifetime parameter must outlive ",
244 infer::CallReturn(span) => {
245 let mut err = struct_span_err!(
249 "lifetime of return value does not outlive the \
252 note_and_explain_region(
256 "the return value is only valid for ",
262 infer::DataBorrowed(ty, span) => {
263 let mut err = struct_span_err!(
267 "a value of type `{}` is borrowed for too long",
268 self.ty_to_string(ty)
270 note_and_explain_region(
274 "the type is valid for ",
278 note_and_explain_region(
282 "but the borrow lasts for ",
288 infer::ReferenceOutlivesReferent(ty, span) => {
289 let mut err = struct_span_err!(
293 "in type `{}`, reference has a longer lifetime than the data it references",
294 self.ty_to_string(ty)
296 note_and_explain_region(
300 "the pointer is valid for ",
304 note_and_explain_region(
308 "but the referenced data is only valid for ",
314 infer::CompareImplMethodObligation {
319 } => self.report_extra_impl_obligation(
324 &format!("`{}: {}`", sup, sub),
329 pub(super) fn report_placeholder_failure(
331 region_scope_tree: ®ion::ScopeTree,
332 placeholder_origin: SubregionOrigin<'tcx>,
335 ) -> DiagnosticBuilder<'tcx> {
336 // I can't think how to do better than this right now. -nikomatsakis
337 match placeholder_origin {
338 infer::Subtype(box trace) => {
339 let terr = TypeError::RegionsPlaceholderMismatch;
340 self.report_and_explain_type_error(trace, &terr)
343 _ => self.report_concrete_failure(region_scope_tree, placeholder_origin, sub, sup),