]>
Commit | Line | Data |
---|---|---|
487cf647 FG |
1 | #![deny(rustc::untranslatable_diagnostic)] |
2 | #![deny(rustc::diagnostic_outside_of_impl)] | |
3 | ||
5e7ed085 | 4 | use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed}; |
94222f64 XL |
5 | use rustc_infer::infer::canonical::Canonical; |
6 | use rustc_infer::infer::error_reporting::nice_region_error::NiceRegionError; | |
7 | use rustc_infer::infer::region_constraints::Constraint; | |
5e7ed085 FG |
8 | use rustc_infer::infer::region_constraints::RegionConstraintData; |
9 | use rustc_infer::infer::RegionVariableOrigin; | |
94222f64 | 10 | use rustc_infer::infer::{InferCtxt, RegionResolutionError, SubregionOrigin, TyCtxtInferExt as _}; |
487cf647 | 11 | use rustc_infer::traits::ObligationCause; |
94222f64 | 12 | use rustc_middle::ty::error::TypeError; |
5e7ed085 FG |
13 | use rustc_middle::ty::RegionVid; |
14 | use rustc_middle::ty::UniverseIndex; | |
94222f64 XL |
15 | use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable}; |
16 | use rustc_span::Span; | |
17 | use rustc_trait_selection::traits::query::type_op; | |
487cf647 | 18 | use rustc_trait_selection::traits::ObligationCtxt; |
c295e0f8 | 19 | use rustc_traits::{type_op_ascribe_user_type_with_span, type_op_prove_predicate_with_cause}; |
94222f64 XL |
20 | |
21 | use std::fmt; | |
22 | use std::rc::Rc; | |
23 | ||
c295e0f8 | 24 | use crate::region_infer::values::RegionElement; |
064997fb FG |
25 | use crate::session_diagnostics::HigherRankedErrorCause; |
26 | use crate::session_diagnostics::HigherRankedLifetimeError; | |
27 | use crate::session_diagnostics::HigherRankedSubtypeError; | |
c295e0f8 | 28 | use crate::MirBorrowckCtxt; |
94222f64 XL |
29 | |
30 | #[derive(Clone)] | |
923072b8 | 31 | pub(crate) struct UniverseInfo<'tcx>(UniverseInfoInner<'tcx>); |
94222f64 XL |
32 | |
33 | /// What operation a universe was created for. | |
34 | #[derive(Clone)] | |
35 | enum UniverseInfoInner<'tcx> { | |
36 | /// Relating two types which have binders. | |
37 | RelateTys { expected: Ty<'tcx>, found: Ty<'tcx> }, | |
38 | /// Created from performing a `TypeOp`. | |
39 | TypeOp(Rc<dyn TypeOpInfo<'tcx> + 'tcx>), | |
40 | /// Any other reason. | |
41 | Other, | |
42 | } | |
43 | ||
a2a8927a | 44 | impl<'tcx> UniverseInfo<'tcx> { |
923072b8 | 45 | pub(crate) fn other() -> UniverseInfo<'tcx> { |
94222f64 XL |
46 | UniverseInfo(UniverseInfoInner::Other) |
47 | } | |
48 | ||
923072b8 | 49 | pub(crate) fn relate(expected: Ty<'tcx>, found: Ty<'tcx>) -> UniverseInfo<'tcx> { |
94222f64 XL |
50 | UniverseInfo(UniverseInfoInner::RelateTys { expected, found }) |
51 | } | |
52 | ||
923072b8 | 53 | pub(crate) fn report_error( |
94222f64 XL |
54 | &self, |
55 | mbcx: &mut MirBorrowckCtxt<'_, 'tcx>, | |
56 | placeholder: ty::PlaceholderRegion, | |
57 | error_element: RegionElement, | |
c295e0f8 | 58 | cause: ObligationCause<'tcx>, |
94222f64 XL |
59 | ) { |
60 | match self.0 { | |
61 | UniverseInfoInner::RelateTys { expected, found } => { | |
2b03887a | 62 | let err = mbcx.infcx.err_ctxt().report_mismatched_types( |
c295e0f8 | 63 | &cause, |
94222f64 XL |
64 | expected, |
65 | found, | |
66 | TypeError::RegionsPlaceholderMismatch, | |
67 | ); | |
5099ac24 | 68 | mbcx.buffer_error(err); |
94222f64 XL |
69 | } |
70 | UniverseInfoInner::TypeOp(ref type_op_info) => { | |
c295e0f8 | 71 | type_op_info.report_error(mbcx, placeholder, error_element, cause); |
94222f64 XL |
72 | } |
73 | UniverseInfoInner::Other => { | |
74 | // FIXME: This error message isn't great, but it doesn't show | |
75 | // up in the existing UI tests. Consider investigating this | |
76 | // some more. | |
5099ac24 | 77 | mbcx.buffer_error( |
064997fb | 78 | mbcx.infcx.tcx.sess.create_err(HigherRankedSubtypeError { span: cause.span }), |
5099ac24 | 79 | ); |
94222f64 XL |
80 | } |
81 | } | |
82 | } | |
83 | } | |
84 | ||
923072b8 | 85 | pub(crate) trait ToUniverseInfo<'tcx> { |
94222f64 XL |
86 | fn to_universe_info(self, base_universe: ty::UniverseIndex) -> UniverseInfo<'tcx>; |
87 | } | |
88 | ||
5e7ed085 FG |
89 | impl<'tcx> ToUniverseInfo<'tcx> for crate::type_check::InstantiateOpaqueType<'tcx> { |
90 | fn to_universe_info(self, base_universe: ty::UniverseIndex) -> UniverseInfo<'tcx> { | |
91 | UniverseInfo(UniverseInfoInner::TypeOp(Rc::new(crate::type_check::InstantiateOpaqueType { | |
92 | base_universe: Some(base_universe), | |
93 | ..self | |
94 | }))) | |
95 | } | |
96 | } | |
97 | ||
94222f64 XL |
98 | impl<'tcx> ToUniverseInfo<'tcx> |
99 | for Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::prove_predicate::ProvePredicate<'tcx>>> | |
100 | { | |
101 | fn to_universe_info(self, base_universe: ty::UniverseIndex) -> UniverseInfo<'tcx> { | |
102 | UniverseInfo(UniverseInfoInner::TypeOp(Rc::new(PredicateQuery { | |
103 | canonical_query: self, | |
104 | base_universe, | |
105 | }))) | |
106 | } | |
107 | } | |
108 | ||
109 | impl<'tcx, T: Copy + fmt::Display + TypeFoldable<'tcx> + 'tcx> ToUniverseInfo<'tcx> | |
110 | for Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::Normalize<T>>> | |
111 | { | |
112 | fn to_universe_info(self, base_universe: ty::UniverseIndex) -> UniverseInfo<'tcx> { | |
113 | UniverseInfo(UniverseInfoInner::TypeOp(Rc::new(NormalizeQuery { | |
114 | canonical_query: self, | |
115 | base_universe, | |
116 | }))) | |
117 | } | |
118 | } | |
119 | ||
120 | impl<'tcx> ToUniverseInfo<'tcx> | |
121 | for Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::AscribeUserType<'tcx>>> | |
122 | { | |
123 | fn to_universe_info(self, base_universe: ty::UniverseIndex) -> UniverseInfo<'tcx> { | |
124 | UniverseInfo(UniverseInfoInner::TypeOp(Rc::new(AscribeUserTypeQuery { | |
125 | canonical_query: self, | |
126 | base_universe, | |
127 | }))) | |
128 | } | |
129 | } | |
130 | ||
131 | impl<'tcx, F, G> ToUniverseInfo<'tcx> for Canonical<'tcx, type_op::custom::CustomTypeOp<F, G>> { | |
132 | fn to_universe_info(self, _base_universe: ty::UniverseIndex) -> UniverseInfo<'tcx> { | |
133 | // We can't rerun custom type ops. | |
134 | UniverseInfo::other() | |
135 | } | |
136 | } | |
137 | ||
5e7ed085 FG |
138 | impl<'tcx> ToUniverseInfo<'tcx> for ! { |
139 | fn to_universe_info(self, _base_universe: ty::UniverseIndex) -> UniverseInfo<'tcx> { | |
140 | self | |
141 | } | |
142 | } | |
143 | ||
94222f64 XL |
144 | #[allow(unused_lifetimes)] |
145 | trait TypeOpInfo<'tcx> { | |
146 | /// Returns an error to be reported if rerunning the type op fails to | |
147 | /// recover the error's cause. | |
5e7ed085 FG |
148 | fn fallback_error( |
149 | &self, | |
150 | tcx: TyCtxt<'tcx>, | |
151 | span: Span, | |
152 | ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed>; | |
94222f64 XL |
153 | |
154 | fn base_universe(&self) -> ty::UniverseIndex; | |
155 | ||
156 | fn nice_error( | |
157 | &self, | |
5e7ed085 | 158 | mbcx: &mut MirBorrowckCtxt<'_, 'tcx>, |
c295e0f8 | 159 | cause: ObligationCause<'tcx>, |
94222f64 XL |
160 | placeholder_region: ty::Region<'tcx>, |
161 | error_region: Option<ty::Region<'tcx>>, | |
5e7ed085 | 162 | ) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>>; |
94222f64 | 163 | |
487cf647 | 164 | #[instrument(level = "debug", skip(self, mbcx))] |
94222f64 XL |
165 | fn report_error( |
166 | &self, | |
167 | mbcx: &mut MirBorrowckCtxt<'_, 'tcx>, | |
168 | placeholder: ty::PlaceholderRegion, | |
169 | error_element: RegionElement, | |
c295e0f8 | 170 | cause: ObligationCause<'tcx>, |
94222f64 XL |
171 | ) { |
172 | let tcx = mbcx.infcx.tcx; | |
173 | let base_universe = self.base_universe(); | |
487cf647 | 174 | debug!(?base_universe); |
94222f64 | 175 | |
5099ac24 | 176 | let Some(adjusted_universe) = |
94222f64 | 177 | placeholder.universe.as_u32().checked_sub(base_universe.as_u32()) |
5099ac24 FG |
178 | else { |
179 | mbcx.buffer_error(self.fallback_error(tcx, cause.span)); | |
94222f64 XL |
180 | return; |
181 | }; | |
182 | ||
183 | let placeholder_region = tcx.mk_region(ty::RePlaceholder(ty::Placeholder { | |
184 | name: placeholder.name, | |
185 | universe: adjusted_universe.into(), | |
186 | })); | |
187 | ||
188 | let error_region = | |
189 | if let RegionElement::PlaceholderRegion(error_placeholder) = error_element { | |
190 | let adjusted_universe = | |
191 | error_placeholder.universe.as_u32().checked_sub(base_universe.as_u32()); | |
192 | adjusted_universe.map(|adjusted| { | |
193 | tcx.mk_region(ty::RePlaceholder(ty::Placeholder { | |
194 | name: error_placeholder.name, | |
195 | universe: adjusted.into(), | |
196 | })) | |
197 | }) | |
198 | } else { | |
199 | None | |
200 | }; | |
201 | ||
202 | debug!(?placeholder_region); | |
203 | ||
c295e0f8 | 204 | let span = cause.span; |
5e7ed085 | 205 | let nice_error = self.nice_error(mbcx, cause, placeholder_region, error_region); |
94222f64 XL |
206 | |
207 | if let Some(nice_error) = nice_error { | |
5099ac24 | 208 | mbcx.buffer_error(nice_error); |
94222f64 | 209 | } else { |
5099ac24 | 210 | mbcx.buffer_error(self.fallback_error(tcx, span)); |
94222f64 XL |
211 | } |
212 | } | |
213 | } | |
214 | ||
215 | struct PredicateQuery<'tcx> { | |
216 | canonical_query: | |
217 | Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::prove_predicate::ProvePredicate<'tcx>>>, | |
218 | base_universe: ty::UniverseIndex, | |
219 | } | |
220 | ||
a2a8927a | 221 | impl<'tcx> TypeOpInfo<'tcx> for PredicateQuery<'tcx> { |
5e7ed085 FG |
222 | fn fallback_error( |
223 | &self, | |
224 | tcx: TyCtxt<'tcx>, | |
225 | span: Span, | |
226 | ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { | |
064997fb FG |
227 | tcx.sess.create_err(HigherRankedLifetimeError { |
228 | cause: Some(HigherRankedErrorCause::CouldNotProve { | |
229 | predicate: self.canonical_query.value.value.predicate.to_string(), | |
230 | }), | |
231 | span, | |
232 | }) | |
94222f64 XL |
233 | } |
234 | ||
235 | fn base_universe(&self) -> ty::UniverseIndex { | |
236 | self.base_universe | |
237 | } | |
238 | ||
239 | fn nice_error( | |
240 | &self, | |
5e7ed085 | 241 | mbcx: &mut MirBorrowckCtxt<'_, 'tcx>, |
c295e0f8 | 242 | cause: ObligationCause<'tcx>, |
94222f64 XL |
243 | placeholder_region: ty::Region<'tcx>, |
244 | error_region: Option<ty::Region<'tcx>>, | |
5e7ed085 | 245 | ) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> { |
487cf647 | 246 | let (infcx, key, _) = |
2b03887a | 247 | mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query); |
487cf647 FG |
248 | let ocx = ObligationCtxt::new(&infcx); |
249 | type_op_prove_predicate_with_cause(&ocx, key, cause); | |
250 | try_extract_error_from_fulfill_cx(&ocx, placeholder_region, error_region) | |
94222f64 XL |
251 | } |
252 | } | |
253 | ||
254 | struct NormalizeQuery<'tcx, T> { | |
255 | canonical_query: Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::Normalize<T>>>, | |
256 | base_universe: ty::UniverseIndex, | |
257 | } | |
258 | ||
a2a8927a | 259 | impl<'tcx, T> TypeOpInfo<'tcx> for NormalizeQuery<'tcx, T> |
94222f64 XL |
260 | where |
261 | T: Copy + fmt::Display + TypeFoldable<'tcx> + 'tcx, | |
262 | { | |
5e7ed085 FG |
263 | fn fallback_error( |
264 | &self, | |
265 | tcx: TyCtxt<'tcx>, | |
266 | span: Span, | |
267 | ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { | |
064997fb FG |
268 | tcx.sess.create_err(HigherRankedLifetimeError { |
269 | cause: Some(HigherRankedErrorCause::CouldNotNormalize { | |
270 | value: self.canonical_query.value.value.value.to_string(), | |
271 | }), | |
272 | span, | |
273 | }) | |
94222f64 XL |
274 | } |
275 | ||
276 | fn base_universe(&self) -> ty::UniverseIndex { | |
277 | self.base_universe | |
278 | } | |
279 | ||
280 | fn nice_error( | |
281 | &self, | |
5e7ed085 | 282 | mbcx: &mut MirBorrowckCtxt<'_, 'tcx>, |
c295e0f8 | 283 | cause: ObligationCause<'tcx>, |
94222f64 XL |
284 | placeholder_region: ty::Region<'tcx>, |
285 | error_region: Option<ty::Region<'tcx>>, | |
5e7ed085 | 286 | ) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> { |
487cf647 | 287 | let (infcx, key, _) = |
2b03887a | 288 | mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query); |
487cf647 | 289 | let ocx = ObligationCtxt::new(&infcx); |
2b03887a FG |
290 | |
291 | // FIXME(lqd): Unify and de-duplicate the following with the actual | |
292 | // `rustc_traits::type_op::type_op_normalize` query to allow the span we need in the | |
293 | // `ObligationCause`. The normalization results are currently different between | |
487cf647 FG |
294 | // `QueryNormalizeExt::query_normalize` used in the query and `normalize` called below: |
295 | // the former fails to normalize the `nll/relate_tys/impl-fn-ignore-binder-via-bottom.rs` test. | |
296 | // Check after #85499 lands to see if its fixes have erased this difference. | |
2b03887a | 297 | let (param_env, value) = key.into_parts(); |
487cf647 | 298 | let _ = ocx.normalize(&cause, param_env, value.value); |
2b03887a | 299 | |
487cf647 | 300 | try_extract_error_from_fulfill_cx(&ocx, placeholder_region, error_region) |
94222f64 XL |
301 | } |
302 | } | |
303 | ||
304 | struct AscribeUserTypeQuery<'tcx> { | |
305 | canonical_query: Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::AscribeUserType<'tcx>>>, | |
306 | base_universe: ty::UniverseIndex, | |
307 | } | |
308 | ||
a2a8927a | 309 | impl<'tcx> TypeOpInfo<'tcx> for AscribeUserTypeQuery<'tcx> { |
5e7ed085 FG |
310 | fn fallback_error( |
311 | &self, | |
312 | tcx: TyCtxt<'tcx>, | |
313 | span: Span, | |
314 | ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { | |
94222f64 XL |
315 | // FIXME: This error message isn't great, but it doesn't show up in the existing UI tests, |
316 | // and is only the fallback when the nice error fails. Consider improving this some more. | |
064997fb | 317 | tcx.sess.create_err(HigherRankedLifetimeError { cause: None, span }) |
94222f64 XL |
318 | } |
319 | ||
320 | fn base_universe(&self) -> ty::UniverseIndex { | |
321 | self.base_universe | |
322 | } | |
323 | ||
324 | fn nice_error( | |
325 | &self, | |
5e7ed085 | 326 | mbcx: &mut MirBorrowckCtxt<'_, 'tcx>, |
c295e0f8 | 327 | cause: ObligationCause<'tcx>, |
94222f64 XL |
328 | placeholder_region: ty::Region<'tcx>, |
329 | error_region: Option<ty::Region<'tcx>>, | |
5e7ed085 | 330 | ) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> { |
487cf647 | 331 | let (infcx, key, _) = |
2b03887a | 332 | mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query); |
487cf647 FG |
333 | let ocx = ObligationCtxt::new(&infcx); |
334 | type_op_ascribe_user_type_with_span(&ocx, key, Some(cause.span)).ok()?; | |
335 | try_extract_error_from_fulfill_cx(&ocx, placeholder_region, error_region) | |
94222f64 XL |
336 | } |
337 | } | |
338 | ||
5e7ed085 FG |
339 | impl<'tcx> TypeOpInfo<'tcx> for crate::type_check::InstantiateOpaqueType<'tcx> { |
340 | fn fallback_error( | |
341 | &self, | |
342 | tcx: TyCtxt<'tcx>, | |
343 | span: Span, | |
344 | ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { | |
345 | // FIXME: This error message isn't great, but it doesn't show up in the existing UI tests, | |
346 | // and is only the fallback when the nice error fails. Consider improving this some more. | |
064997fb | 347 | tcx.sess.create_err(HigherRankedLifetimeError { cause: None, span }) |
5e7ed085 FG |
348 | } |
349 | ||
350 | fn base_universe(&self) -> ty::UniverseIndex { | |
351 | self.base_universe.unwrap() | |
352 | } | |
353 | ||
354 | fn nice_error( | |
355 | &self, | |
356 | mbcx: &mut MirBorrowckCtxt<'_, 'tcx>, | |
357 | _cause: ObligationCause<'tcx>, | |
358 | placeholder_region: ty::Region<'tcx>, | |
359 | error_region: Option<ty::Region<'tcx>>, | |
360 | ) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> { | |
361 | try_extract_error_from_region_constraints( | |
362 | mbcx.infcx, | |
363 | placeholder_region, | |
364 | error_region, | |
365 | self.region_constraints.as_ref().unwrap(), | |
366 | // We're using the original `InferCtxt` that we | |
367 | // started MIR borrowchecking with, so the region | |
368 | // constraints have already been taken. Use the data from | |
369 | // our `mbcx` instead. | |
370 | |vid| mbcx.regioncx.var_infos[vid].origin, | |
371 | |vid| mbcx.regioncx.var_infos[vid].universe, | |
372 | ) | |
373 | } | |
374 | } | |
375 | ||
487cf647 | 376 | #[instrument(skip(ocx), level = "debug")] |
94222f64 | 377 | fn try_extract_error_from_fulfill_cx<'tcx>( |
487cf647 | 378 | ocx: &ObligationCtxt<'_, 'tcx>, |
94222f64 XL |
379 | placeholder_region: ty::Region<'tcx>, |
380 | error_region: Option<ty::Region<'tcx>>, | |
5e7ed085 | 381 | ) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> { |
94222f64 XL |
382 | // We generally shouldn't have errors here because the query was |
383 | // already run, but there's no point using `delay_span_bug` | |
384 | // when we're going to emit an error here anyway. | |
487cf647 FG |
385 | let _errors = ocx.select_all_or_error(); |
386 | let region_constraints = ocx.infcx.with_region_constraints(|r| r.clone()); | |
5e7ed085 | 387 | try_extract_error_from_region_constraints( |
487cf647 | 388 | ocx.infcx, |
5e7ed085 FG |
389 | placeholder_region, |
390 | error_region, | |
391 | ®ion_constraints, | |
487cf647 FG |
392 | |vid| ocx.infcx.region_var_origin(vid), |
393 | |vid| ocx.infcx.universe_of_region(ocx.infcx.tcx.mk_region(ty::ReVar(vid))), | |
5e7ed085 FG |
394 | ) |
395 | } | |
94222f64 | 396 | |
487cf647 | 397 | #[instrument(level = "debug", skip(infcx, region_var_origin, universe_of_region))] |
5e7ed085 | 398 | fn try_extract_error_from_region_constraints<'tcx>( |
2b03887a | 399 | infcx: &InferCtxt<'tcx>, |
5e7ed085 FG |
400 | placeholder_region: ty::Region<'tcx>, |
401 | error_region: Option<ty::Region<'tcx>>, | |
402 | region_constraints: &RegionConstraintData<'tcx>, | |
403 | mut region_var_origin: impl FnMut(RegionVid) -> RegionVariableOrigin, | |
404 | mut universe_of_region: impl FnMut(RegionVid) -> UniverseIndex, | |
405 | ) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> { | |
406 | let (sub_region, cause) = | |
94222f64 XL |
407 | region_constraints.constraints.iter().find_map(|(constraint, cause)| { |
408 | match *constraint { | |
409 | Constraint::RegSubReg(sub, sup) if sup == placeholder_region && sup != sub => { | |
410 | Some((sub, cause.clone())) | |
411 | } | |
412 | // FIXME: Should this check the universe of the var? | |
413 | Constraint::VarSubReg(vid, sup) if sup == placeholder_region => { | |
5e7ed085 | 414 | Some((infcx.tcx.mk_region(ty::ReVar(vid)), cause.clone())) |
94222f64 XL |
415 | } |
416 | _ => None, | |
417 | } | |
5e7ed085 | 418 | })?; |
94222f64 | 419 | |
c295e0f8 | 420 | debug!(?sub_region, "cause = {:#?}", cause); |
2b03887a FG |
421 | let error = match (error_region, *sub_region) { |
422 | (Some(error_region), ty::ReVar(vid)) => RegionResolutionError::SubSupConflict( | |
423 | vid, | |
424 | region_var_origin(vid), | |
425 | cause.clone(), | |
426 | error_region, | |
427 | cause.clone(), | |
428 | placeholder_region, | |
429 | vec![], | |
94222f64 | 430 | ), |
2b03887a FG |
431 | (Some(error_region), _) => { |
432 | RegionResolutionError::ConcreteFailure(cause.clone(), error_region, placeholder_region) | |
433 | } | |
94222f64 | 434 | // Note universe here is wrong... |
2b03887a FG |
435 | (None, ty::ReVar(vid)) => RegionResolutionError::UpperBoundUniverseConflict( |
436 | vid, | |
437 | region_var_origin(vid), | |
438 | universe_of_region(vid), | |
439 | cause.clone(), | |
440 | placeholder_region, | |
94222f64 | 441 | ), |
2b03887a FG |
442 | (None, _) => { |
443 | RegionResolutionError::ConcreteFailure(cause.clone(), sub_region, placeholder_region) | |
444 | } | |
94222f64 | 445 | }; |
2b03887a | 446 | NiceRegionError::new(&infcx.err_ctxt(), error).try_report_from_nll().or_else(|| { |
94222f64 | 447 | if let SubregionOrigin::Subtype(trace) = cause { |
2b03887a FG |
448 | Some( |
449 | infcx | |
450 | .err_ctxt() | |
451 | .report_and_explain_type_error(*trace, TypeError::RegionsPlaceholderMismatch), | |
452 | ) | |
94222f64 XL |
453 | } else { |
454 | None | |
455 | } | |
456 | }) | |
457 | } |