Skip to content

Commit 29b10dc

Browse files
committed
Properly check for lifetime equality instead of relying on identity
1 parent 9b1fcee commit 29b10dc

File tree

2 files changed

+17
-11
lines changed

2 files changed

+17
-11
lines changed

compiler/rustc_borrowck/src/region_infer/opaque_types.rs

+12-11
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use rustc_infer::infer::TyCtxtInferExt as _;
77
use rustc_infer::traits::{Obligation, ObligationCause};
88
use rustc_middle::traits::DefiningAnchor;
99
use rustc_middle::ty::visit::TypeVisitableExt;
10+
use rustc_middle::ty::RegionVid;
1011
use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable};
1112
use rustc_middle::ty::{GenericArgKind, GenericArgs};
1213
use rustc_span::Span;
@@ -26,13 +27,14 @@ impl<'tcx> RegionInferenceContext<'tcx> {
2627
.find_map(|lb| self.eval_equal(vid, lb).then_some(self.definitions[lb].external_name?))
2728
}
2829

29-
fn gen_arg_to_name(&self, arg: ty::GenericArg<'tcx>) -> Option<ty::Region<'tcx>> {
30+
fn generic_arg_to_region(&self, arg: ty::GenericArg<'tcx>) -> Option<RegionVid> {
3031
let region = arg.as_region()?;
3132

3233
if let ty::RePlaceholder(..) = region.kind() {
33-
return None;
34+
None
35+
} else {
36+
Some(self.to_region_vid(region))
3437
}
35-
self.universal_name(self.to_region_vid(region))
3638
}
3739

3840
/// Check that all opaque types have the same region parameters if they have the same
@@ -54,19 +56,18 @@ impl<'tcx> RegionInferenceContext<'tcx> {
5456
}
5557
trace!(?a, ?b);
5658
for (a, b) in a.args.iter().zip(b.args) {
57-
if a.as_region().is_none() {
58-
break;
59-
}
60-
let a = self.gen_arg_to_name(a).unwrap();
61-
let b = self.gen_arg_to_name(b).unwrap();
6259
trace!(?a, ?b);
63-
if a == b {
60+
let Some(r1) = self.generic_arg_to_region(a) else {
61+
continue;
62+
};
63+
let r2 = self.generic_arg_to_region(b).unwrap();
64+
if self.eval_equal(r1, r2) {
6465
continue;
6566
}
6667

6768
infcx.tcx.sess.emit_err(LifetimeMismatchOpaqueParam {
68-
arg: a.into(),
69-
prev: b.into(),
69+
arg: self.universal_name(r1).unwrap().into(),
70+
prev: self.universal_name(r2).unwrap().into(),
7071
span: a_ty.span,
7172
prev_span: b_ty.span,
7273
});

tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-pass.rs

+5
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ fn f<A: ToString + Clone, B: ToString + Clone>(a: A, b: B) -> (X<A, B>, X<A, B>)
77
(a.clone(), a)
88
}
99

10+
type Tait<'x> = impl Sized;
11+
fn define<'a: 'b, 'b: 'a>(x: &'a u8, y: &'b u8) -> (Tait<'a>, Tait<'b>) {
12+
((), ())
13+
}
14+
1015
fn main() {
1116
println!("{}", <X<_, _> as ToString>::to_string(&f(42_i32, String::new()).1));
1217
}

0 commit comments

Comments
 (0)