|
1 | 1 | use crate::infer::error_reporting::{note_and_explain_region, ObligationCauseExt}; |
2 | 2 | use crate::infer::{self, InferCtxt, SubregionOrigin}; |
3 | 3 | use rustc_errors::{struct_span_err, DiagnosticBuilder}; |
| 4 | +use rustc_middle::traits::ObligationCauseCode; |
4 | 5 | use rustc_middle::ty::error::TypeError; |
5 | 6 | use rustc_middle::ty::{self, Region}; |
6 | 7 |
|
@@ -107,14 +108,37 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { |
107 | 108 | infer::Subtype(box trace) => { |
108 | 109 | let terr = TypeError::RegionsDoesNotOutlive(sup, sub); |
109 | 110 | let mut err = self.report_and_explain_type_error(trace, &terr); |
110 | | - note_and_explain_region(self.tcx, &mut err, "", sup, "..."); |
111 | | - note_and_explain_region( |
112 | | - self.tcx, |
113 | | - &mut err, |
114 | | - "...does not necessarily outlive ", |
115 | | - sub, |
116 | | - "", |
117 | | - ); |
| 111 | + match (sub, sup) { |
| 112 | + (ty::RePlaceholder(_), ty::RePlaceholder(_)) => {} |
| 113 | + (ty::RePlaceholder(_), _) => { |
| 114 | + note_and_explain_region( |
| 115 | + self.tcx, |
| 116 | + &mut err, |
| 117 | + "", |
| 118 | + sup, |
| 119 | + " doesn't meet the lifetime requirements", |
| 120 | + ); |
| 121 | + } |
| 122 | + (_, ty::RePlaceholder(_)) => { |
| 123 | + note_and_explain_region( |
| 124 | + self.tcx, |
| 125 | + &mut err, |
| 126 | + "the required lifetime does not necessarily outlive ", |
| 127 | + sub, |
| 128 | + "", |
| 129 | + ); |
| 130 | + } |
| 131 | + _ => { |
| 132 | + note_and_explain_region(self.tcx, &mut err, "", sup, "..."); |
| 133 | + note_and_explain_region( |
| 134 | + self.tcx, |
| 135 | + &mut err, |
| 136 | + "...does not necessarily outlive ", |
| 137 | + sub, |
| 138 | + "", |
| 139 | + ); |
| 140 | + } |
| 141 | + } |
118 | 142 | err |
119 | 143 | } |
120 | 144 | infer::Reborrow(span) => { |
@@ -286,13 +310,31 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { |
286 | 310 | sup: Region<'tcx>, |
287 | 311 | ) -> DiagnosticBuilder<'tcx> { |
288 | 312 | // I can't think how to do better than this right now. -nikomatsakis |
| 313 | + debug!(?placeholder_origin, ?sub, ?sup, "report_placeholder_failure"); |
289 | 314 | match placeholder_origin { |
| 315 | + infer::Subtype(box ref trace) |
| 316 | + if matches!( |
| 317 | + &trace.cause.code.peel_derives(), |
| 318 | + ObligationCauseCode::BindingObligation(..) |
| 319 | + ) => |
| 320 | + { |
| 321 | + // Hack to get around the borrow checker because trace.cause has an `Rc`. |
| 322 | + if let ObligationCauseCode::BindingObligation(_, span) = |
| 323 | + &trace.cause.code.peel_derives() |
| 324 | + { |
| 325 | + let span = *span; |
| 326 | + let mut err = self.report_concrete_failure(placeholder_origin, sub, sup); |
| 327 | + err.span_note(span, "the lifetime requirement is introduced here"); |
| 328 | + err |
| 329 | + } else { |
| 330 | + unreachable!() |
| 331 | + } |
| 332 | + } |
290 | 333 | infer::Subtype(box trace) => { |
291 | 334 | let terr = TypeError::RegionsPlaceholderMismatch; |
292 | | - self.report_and_explain_type_error(trace, &terr) |
| 335 | + return self.report_and_explain_type_error(trace, &terr); |
293 | 336 | } |
294 | | - |
295 | | - _ => self.report_concrete_failure(placeholder_origin, sub, sup), |
| 337 | + _ => return self.report_concrete_failure(placeholder_origin, sub, sup), |
296 | 338 | } |
297 | 339 | } |
298 | 340 | } |
0 commit comments