|
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