Skip to content

Commit d51fa36

Browse files
committed
canonicalize regions in the opaque type's generics
so that a two semantically equal regions would always have the same name.
1 parent a70037d commit d51fa36

File tree

4 files changed

+89
-1
lines changed

4 files changed

+89
-1
lines changed

compiler/rustc_borrowck/src/region_infer/opaque_types.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,11 @@ impl<'tcx> RegionInferenceContext<'tcx> {
7777
let scc = self.constraint_sccs.scc(self.to_region_vid(region));
7878
let vid = self.scc_representatives[scc];
7979
let named = match self.definitions[vid].origin {
80-
NllRegionVariableOrigin::FreeRegion => self.definitions[vid].external_name,
80+
NllRegionVariableOrigin::FreeRegion => self
81+
.universal_regions
82+
.universal_regions()
83+
.filter(|&ur| self.universal_region_relations.equal(vid, ur))
84+
.find_map(|ur| self.definitions[ur].external_name),
8185
NllRegionVariableOrigin::Placeholder(placeholder) => {
8286
Some(ty::Region::new_placeholder(infcx.tcx, placeholder))
8387
}

compiler/rustc_borrowck/src/type_check/free_region_relations.rs

+7
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,13 @@ impl UniversalRegionRelations<'_> {
159159
self.outlives.contains(fr1, fr2)
160160
}
161161

162+
/// Returns `true` if fr1 is known to equal fr2.
163+
///
164+
/// This will only ever be true for universally quantified regions.
165+
pub(crate) fn equal(&self, fr1: RegionVid, fr2: RegionVid) -> bool {
166+
self.outlives.contains(fr1, fr2) && self.outlives.contains(fr2, fr1)
167+
}
168+
162169
/// Returns a vector of free regions `x` such that `fr1: x` is
163170
/// known to hold.
164171
pub(crate) fn regions_outlived_by(&self, fr1: RegionVid) -> Vec<RegionVid> {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// issue: #112841
2+
3+
#![feature(type_alias_impl_trait)]
4+
5+
trait Trait<'a, 'b> {}
6+
impl<T> Trait<'_, '_> for T {}
7+
8+
mod mod1 {
9+
type Opaque<'a, 'b> = impl super::Trait<'a, 'b>;
10+
fn test<'a>() -> Opaque<'a, 'a> {}
11+
//~^ ERROR non-defining opaque type use in defining scope
12+
//~| ERROR non-defining opaque type use in defining scope
13+
}
14+
15+
mod mod2 {
16+
type Opaque<'a, 'b> = impl super::Trait<'a, 'b>;
17+
fn test<'a: 'b, 'b: 'a>() -> Opaque<'a, 'b> {}
18+
//~^ ERROR non-defining opaque type use in defining scope
19+
}
20+
21+
mod mod3 {
22+
type Opaque<'a, 'b> = impl super::Trait<'a, 'b>;
23+
fn test<'a: 'b, 'b: 'a>(a: &'a str) -> Opaque<'a, 'b> { a }
24+
//~^ ERROR non-defining opaque type use in defining scope
25+
}
26+
27+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
error: non-defining opaque type use in defining scope
2+
--> $DIR/equal-lifetime-params-not-ok.rs:10:22
3+
|
4+
LL | fn test<'a>() -> Opaque<'a, 'a> {}
5+
| ^^^^^^^^^^^^^^ generic argument `'a` used twice
6+
|
7+
note: for this opaque type
8+
--> $DIR/equal-lifetime-params-not-ok.rs:9:27
9+
|
10+
LL | type Opaque<'a, 'b> = impl super::Trait<'a, 'b>;
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^
12+
13+
error: non-defining opaque type use in defining scope
14+
--> $DIR/equal-lifetime-params-not-ok.rs:10:37
15+
|
16+
LL | fn test<'a>() -> Opaque<'a, 'a> {}
17+
| ^^
18+
|
19+
note: lifetime used multiple times
20+
--> $DIR/equal-lifetime-params-not-ok.rs:9:17
21+
|
22+
LL | type Opaque<'a, 'b> = impl super::Trait<'a, 'b>;
23+
| ^^ ^^
24+
25+
error: non-defining opaque type use in defining scope
26+
--> $DIR/equal-lifetime-params-not-ok.rs:17:49
27+
|
28+
LL | fn test<'a: 'b, 'b: 'a>() -> Opaque<'a, 'b> {}
29+
| ^^
30+
|
31+
note: lifetime used multiple times
32+
--> $DIR/equal-lifetime-params-not-ok.rs:16:17
33+
|
34+
LL | type Opaque<'a, 'b> = impl super::Trait<'a, 'b>;
35+
| ^^ ^^
36+
37+
error: non-defining opaque type use in defining scope
38+
--> $DIR/equal-lifetime-params-not-ok.rs:23:61
39+
|
40+
LL | fn test<'a: 'b, 'b: 'a>(a: &'a str) -> Opaque<'a, 'b> { a }
41+
| ^
42+
|
43+
note: lifetime used multiple times
44+
--> $DIR/equal-lifetime-params-not-ok.rs:22:17
45+
|
46+
LL | type Opaque<'a, 'b> = impl super::Trait<'a, 'b>;
47+
| ^^ ^^
48+
49+
error: aborting due to 4 previous errors
50+

0 commit comments

Comments
 (0)