From 29b10dca0d5f50cc1c6c021ad0b21b250cc692e2 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 20 Oct 2023 15:28:43 +0000 Subject: [PATCH] Properly check for lifetime equality instead of relying on identity --- .../src/region_infer/opaque_types.rs | 23 ++++++++++--------- .../multiple-def-uses-in-one-fn-pass.rs | 5 ++++ 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index 7545ff894d5af..1015f3bc51c9c 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -7,6 +7,7 @@ use rustc_infer::infer::TyCtxtInferExt as _; use rustc_infer::traits::{Obligation, ObligationCause}; use rustc_middle::traits::DefiningAnchor; use rustc_middle::ty::visit::TypeVisitableExt; +use rustc_middle::ty::RegionVid; use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable}; use rustc_middle::ty::{GenericArgKind, GenericArgs}; use rustc_span::Span; @@ -26,13 +27,14 @@ impl<'tcx> RegionInferenceContext<'tcx> { .find_map(|lb| self.eval_equal(vid, lb).then_some(self.definitions[lb].external_name?)) } - fn gen_arg_to_name(&self, arg: ty::GenericArg<'tcx>) -> Option> { + fn generic_arg_to_region(&self, arg: ty::GenericArg<'tcx>) -> Option { let region = arg.as_region()?; if let ty::RePlaceholder(..) = region.kind() { - return None; + None + } else { + Some(self.to_region_vid(region)) } - self.universal_name(self.to_region_vid(region)) } /// Check that all opaque types have the same region parameters if they have the same @@ -54,19 +56,18 @@ impl<'tcx> RegionInferenceContext<'tcx> { } trace!(?a, ?b); for (a, b) in a.args.iter().zip(b.args) { - if a.as_region().is_none() { - break; - } - let a = self.gen_arg_to_name(a).unwrap(); - let b = self.gen_arg_to_name(b).unwrap(); trace!(?a, ?b); - if a == b { + let Some(r1) = self.generic_arg_to_region(a) else { + continue; + }; + let r2 = self.generic_arg_to_region(b).unwrap(); + if self.eval_equal(r1, r2) { continue; } infcx.tcx.sess.emit_err(LifetimeMismatchOpaqueParam { - arg: a.into(), - prev: b.into(), + arg: self.universal_name(r1).unwrap().into(), + prev: self.universal_name(r2).unwrap().into(), span: a_ty.span, prev_span: b_ty.span, }); diff --git a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-pass.rs b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-pass.rs index f412b2d0e7db7..c9c585ac7bc5a 100644 --- a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-pass.rs +++ b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-pass.rs @@ -7,6 +7,11 @@ fn f(a: A, b: B) -> (X, X) (a.clone(), a) } +type Tait<'x> = impl Sized; +fn define<'a: 'b, 'b: 'a>(x: &'a u8, y: &'b u8) -> (Tait<'a>, Tait<'b>) { + ((), ()) +} + fn main() { println!("{}", as ToString>::to_string(&f(42_i32, String::new()).1)); }