Skip to content

Commit 8c5114b

Browse files
authored
Rollup merge of #89327 - oli-obk:nll_diag_infer_vars, r=wesleywiser
Pick one possible lifetime in case there are multiple choices In case a lifetime variable is created, but doesn't have an obvious lifetime in the list of named lifetimes that it should be inferred to, just pick the first one for the diagnostic. This happens e.g. in ```rust fn foo<'a, 'b>(a: Struct<'a>, b: Struct<'b>) -> impl Trait<'a, 'b> { if bar() { a } else { b } } ``` where we get a lifetime variable that combines the lifetimes of `a` and `b` creating a lifetime that is the intersection of both. Right now the type system cannot express this and thus we get an error, but that error also can't express this. I can also create an entirely new diagnostic that mentions all involved lifetimes, so it would actually mention `'a` and `'b` instead of just `'b`.
2 parents 2726955 + 87a4a79 commit 8c5114b

File tree

3 files changed

+26
-3
lines changed

3 files changed

+26
-3
lines changed

compiler/rustc_borrowck/src/region_infer/opaque_types.rs

+16-1
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,22 @@ impl<'tcx> RegionInferenceContext<'tcx> {
124124
ty::ReVar(vid) => {
125125
// Find something that we can name
126126
let upper_bound = self.approx_universal_upper_bound(vid);
127-
self.definitions[upper_bound].external_name.unwrap_or(region)
127+
let upper_bound = &self.definitions[upper_bound];
128+
match upper_bound.external_name {
129+
Some(reg) => reg,
130+
None => {
131+
// Nothing exact found, so we pick the first one that we find.
132+
let scc = self.constraint_sccs.scc(vid);
133+
for vid in self.rev_scc_graph.as_ref().unwrap().upper_bounds(scc) {
134+
match self.definitions[vid].external_name {
135+
None => {}
136+
Some(&ty::ReStatic) => {}
137+
Some(region) => return region,
138+
}
139+
}
140+
region
141+
}
142+
}
128143
}
129144
_ => region,
130145
})

src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.nll.stderr

+5-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appea
44
LL | fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'d, 'e>
55
| ^^^^^^^^^^^^^^^^^^
66
|
7-
= note: hidden type `Ordinary<'_>` captures lifetime '_#9r
7+
note: hidden type `Ordinary<'b>` captures the lifetime `'b` as defined on the function body at 16:21
8+
--> $DIR/ordinary-bounds-unrelated.rs:16:21
9+
|
10+
LL | fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'d, 'e>
11+
| ^^
812

913
error: aborting due to previous error
1014

src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.nll.stderr

+5-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appea
44
LL | fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b>
55
| ^^^^^^^^^^^^^^^^^^
66
|
7-
= note: hidden type `Ordinary<'_>` captures lifetime '_#6r
7+
note: hidden type `Ordinary<'b>` captures the lifetime `'b` as defined on the function body at 18:21
8+
--> $DIR/ordinary-bounds-unsuited.rs:18:21
9+
|
10+
LL | fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b>
11+
| ^^
812

913
error: aborting due to previous error
1014

0 commit comments

Comments
 (0)