|
1 | 1 | use rustc_data_structures::fx::FxIndexMap;
|
2 |
| -use rustc_errors::ErrorGuaranteed; |
3 |
| -use rustc_hir::OpaqueTyOrigin; |
4 |
| -use rustc_hir::def_id::LocalDefId; |
5 |
| -use rustc_infer::infer::outlives::env::OutlivesEnvironment; |
6 |
| -use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin, TyCtxtInferExt as _}; |
| 2 | +use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin}; |
7 | 3 | use rustc_macros::extension;
|
8 | 4 | use rustc_middle::ty::{
|
9 |
| - self, GenericArgKind, GenericArgs, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable, |
10 |
| - TypeVisitableExt, TypingMode, fold_regions, |
| 5 | + self, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable, TypeVisitableExt, fold_regions, |
11 | 6 | };
|
12 | 7 | use rustc_span::Span;
|
13 |
| -use rustc_trait_selection::regions::OutlivesEnvironmentBuildExt; |
14 |
| -use rustc_trait_selection::traits::ObligationCtxt; |
| 8 | +use rustc_trait_selection::opaque_types::check_opaque_type_parameter_valid; |
15 | 9 | use tracing::{debug, instrument};
|
16 | 10 |
|
17 | 11 | use super::RegionInferenceContext;
|
18 | 12 | use crate::opaque_types::ConcreteOpaqueTypes;
|
19 |
| -use crate::session_diagnostics::{LifetimeMismatchOpaqueParam, NonGenericOpaqueTypeParam}; |
| 13 | +use crate::session_diagnostics::LifetimeMismatchOpaqueParam; |
20 | 14 | use crate::universal_regions::RegionClassification;
|
21 | 15 |
|
22 | 16 | impl<'tcx> RegionInferenceContext<'tcx> {
|
@@ -289,156 +283,3 @@ impl<'tcx> InferCtxt<'tcx> {
|
289 | 283 | definition_ty
|
290 | 284 | }
|
291 | 285 | }
|
292 |
| - |
293 |
| -/// Opaque type parameter validity check as documented in the [rustc-dev-guide chapter]. |
294 |
| -/// |
295 |
| -/// [rustc-dev-guide chapter]: |
296 |
| -/// https://rustc-dev-guide.rust-lang.org/opaque-types-region-infer-restrictions.html |
297 |
| -fn check_opaque_type_parameter_valid<'tcx>( |
298 |
| - infcx: &InferCtxt<'tcx>, |
299 |
| - opaque_type_key: OpaqueTypeKey<'tcx>, |
300 |
| - span: Span, |
301 |
| -) -> Result<(), ErrorGuaranteed> { |
302 |
| - let tcx = infcx.tcx; |
303 |
| - let opaque_generics = tcx.generics_of(opaque_type_key.def_id); |
304 |
| - let opaque_env = LazyOpaqueTyEnv::new(tcx, opaque_type_key.def_id); |
305 |
| - let mut seen_params: FxIndexMap<_, Vec<_>> = FxIndexMap::default(); |
306 |
| - |
307 |
| - for (i, arg) in opaque_type_key.iter_captured_args(tcx) { |
308 |
| - let arg_is_param = match arg.unpack() { |
309 |
| - GenericArgKind::Type(ty) => matches!(ty.kind(), ty::Param(_)), |
310 |
| - GenericArgKind::Lifetime(lt) => { |
311 |
| - matches!(*lt, ty::ReEarlyParam(_) | ty::ReLateParam(_)) |
312 |
| - || (lt.is_static() && opaque_env.param_equal_static(i)) |
313 |
| - } |
314 |
| - GenericArgKind::Const(ct) => matches!(ct.kind(), ty::ConstKind::Param(_)), |
315 |
| - }; |
316 |
| - |
317 |
| - if arg_is_param { |
318 |
| - // Register if the same lifetime appears multiple times in the generic args. |
319 |
| - // There is an exception when the opaque type *requires* the lifetimes to be equal. |
320 |
| - // See [rustc-dev-guide chapter] § "An exception to uniqueness rule". |
321 |
| - let seen_where = seen_params.entry(arg).or_default(); |
322 |
| - if !seen_where.first().is_some_and(|&prev_i| opaque_env.params_equal(i, prev_i)) { |
323 |
| - seen_where.push(i); |
324 |
| - } |
325 |
| - } else { |
326 |
| - // Prevent `fn foo() -> Foo<u32>` from being defining. |
327 |
| - let opaque_param = opaque_generics.param_at(i, tcx); |
328 |
| - let kind = opaque_param.kind.descr(); |
329 |
| - |
330 |
| - opaque_env.param_is_error(i)?; |
331 |
| - |
332 |
| - return Err(infcx.dcx().emit_err(NonGenericOpaqueTypeParam { |
333 |
| - ty: arg, |
334 |
| - kind, |
335 |
| - span, |
336 |
| - param_span: tcx.def_span(opaque_param.def_id), |
337 |
| - })); |
338 |
| - } |
339 |
| - } |
340 |
| - |
341 |
| - for (_, indices) in seen_params { |
342 |
| - if indices.len() > 1 { |
343 |
| - let descr = opaque_generics.param_at(indices[0], tcx).kind.descr(); |
344 |
| - let spans: Vec<_> = indices |
345 |
| - .into_iter() |
346 |
| - .map(|i| tcx.def_span(opaque_generics.param_at(i, tcx).def_id)) |
347 |
| - .collect(); |
348 |
| - #[allow(rustc::diagnostic_outside_of_impl)] |
349 |
| - #[allow(rustc::untranslatable_diagnostic)] |
350 |
| - return Err(infcx |
351 |
| - .dcx() |
352 |
| - .struct_span_err(span, "non-defining opaque type use in defining scope") |
353 |
| - .with_span_note(spans, format!("{descr} used multiple times")) |
354 |
| - .emit()); |
355 |
| - } |
356 |
| - } |
357 |
| - |
358 |
| - Ok(()) |
359 |
| -} |
360 |
| - |
361 |
| -/// Computes if an opaque type requires a lifetime parameter to be equal to |
362 |
| -/// another one or to the `'static` lifetime. |
363 |
| -/// These requirements are derived from the explicit and implied bounds. |
364 |
| -struct LazyOpaqueTyEnv<'tcx> { |
365 |
| - tcx: TyCtxt<'tcx>, |
366 |
| - def_id: LocalDefId, |
367 |
| - |
368 |
| - /// Equal parameters will have the same name. Computed Lazily. |
369 |
| - /// Example: |
370 |
| - /// `type Opaque<'a: 'static, 'b: 'c, 'c: 'b> = impl Sized;` |
371 |
| - /// Identity args: `['a, 'b, 'c]` |
372 |
| - /// Canonical args: `['static, 'b, 'b]` |
373 |
| - canonical_args: std::cell::OnceCell<ty::GenericArgsRef<'tcx>>, |
374 |
| -} |
375 |
| - |
376 |
| -impl<'tcx> LazyOpaqueTyEnv<'tcx> { |
377 |
| - fn new(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self { |
378 |
| - Self { tcx, def_id, canonical_args: std::cell::OnceCell::new() } |
379 |
| - } |
380 |
| - |
381 |
| - fn param_equal_static(&self, param_index: usize) -> bool { |
382 |
| - self.get_canonical_args()[param_index].expect_region().is_static() |
383 |
| - } |
384 |
| - |
385 |
| - fn params_equal(&self, param1: usize, param2: usize) -> bool { |
386 |
| - let canonical_args = self.get_canonical_args(); |
387 |
| - canonical_args[param1] == canonical_args[param2] |
388 |
| - } |
389 |
| - |
390 |
| - fn param_is_error(&self, param_index: usize) -> Result<(), ErrorGuaranteed> { |
391 |
| - self.get_canonical_args()[param_index].error_reported() |
392 |
| - } |
393 |
| - |
394 |
| - fn get_canonical_args(&self) -> ty::GenericArgsRef<'tcx> { |
395 |
| - if let Some(&canonical_args) = self.canonical_args.get() { |
396 |
| - return canonical_args; |
397 |
| - } |
398 |
| - |
399 |
| - let &Self { tcx, def_id, .. } = self; |
400 |
| - let origin = tcx.local_opaque_ty_origin(def_id); |
401 |
| - let parent = match origin { |
402 |
| - OpaqueTyOrigin::FnReturn { parent, .. } |
403 |
| - | OpaqueTyOrigin::AsyncFn { parent, .. } |
404 |
| - | OpaqueTyOrigin::TyAlias { parent, .. } => parent, |
405 |
| - }; |
406 |
| - let param_env = tcx.param_env(parent); |
407 |
| - let args = GenericArgs::identity_for_item(tcx, parent).extend_to( |
408 |
| - tcx, |
409 |
| - def_id.to_def_id(), |
410 |
| - |param, _| { |
411 |
| - tcx.map_opaque_lifetime_to_parent_lifetime(param.def_id.expect_local()).into() |
412 |
| - }, |
413 |
| - ); |
414 |
| - |
415 |
| - // FIXME(#132279): It feels wrong to use `non_body_analysis` here given that we're |
416 |
| - // in a body here. |
417 |
| - let infcx = tcx.infer_ctxt().build(TypingMode::non_body_analysis()); |
418 |
| - let ocx = ObligationCtxt::new(&infcx); |
419 |
| - |
420 |
| - let wf_tys = ocx.assumed_wf_types(param_env, parent).unwrap_or_else(|_| { |
421 |
| - tcx.dcx().span_delayed_bug(tcx.def_span(def_id), "error getting implied bounds"); |
422 |
| - Default::default() |
423 |
| - }); |
424 |
| - let outlives_env = OutlivesEnvironment::new(&infcx, parent, param_env, wf_tys); |
425 |
| - |
426 |
| - let mut seen = vec![tcx.lifetimes.re_static]; |
427 |
| - let canonical_args = fold_regions(tcx, args, |r1, _| { |
428 |
| - if r1.is_error() { |
429 |
| - r1 |
430 |
| - } else if let Some(&r2) = seen.iter().find(|&&r2| { |
431 |
| - let free_regions = outlives_env.free_region_map(); |
432 |
| - free_regions.sub_free_regions(tcx, r1, r2) |
433 |
| - && free_regions.sub_free_regions(tcx, r2, r1) |
434 |
| - }) { |
435 |
| - r2 |
436 |
| - } else { |
437 |
| - seen.push(r1); |
438 |
| - r1 |
439 |
| - } |
440 |
| - }); |
441 |
| - self.canonical_args.set(canonical_args).unwrap(); |
442 |
| - canonical_args |
443 |
| - } |
444 |
| -} |
0 commit comments