Skip to content

Commit 2cd924b

Browse files
cjgillotMark-Simulacrum
authored andcommitted
Do not consider repeated lifetime params for elision.
1 parent 5baadbd commit 2cd924b

File tree

3 files changed

+21
-6
lines changed

3 files changed

+21
-6
lines changed

compiler/rustc_resolve/src/late.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -557,7 +557,7 @@ struct LateResolutionVisitor<'a, 'b, 'ast> {
557557
/// They will be used to determine the correct lifetime for the fn return type.
558558
/// The `LifetimeElisionCandidate` is used for diagnostics, to suggest introducing named
559559
/// lifetimes.
560-
lifetime_elision_candidates: Option<FxIndexMap<LifetimeRes, LifetimeElisionCandidate>>,
560+
lifetime_elision_candidates: Option<Vec<(LifetimeRes, LifetimeElisionCandidate)>>,
561561

562562
/// The trait that the current context can refer to.
563563
current_trait_ref: Option<(Module<'a>, TraitRef)>,
@@ -1819,7 +1819,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
18191819
match res {
18201820
LifetimeRes::Param { .. } | LifetimeRes::Fresh { .. } | LifetimeRes::Static => {
18211821
if let Some(ref mut candidates) = self.lifetime_elision_candidates {
1822-
candidates.insert(res, candidate);
1822+
candidates.push((res, candidate));
18231823
}
18241824
}
18251825
LifetimeRes::Infer | LifetimeRes::Error | LifetimeRes::ElidedAnchor { .. } => {}
@@ -1928,8 +1928,8 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
19281928

19291929
// We do not have a `self` candidate, look at the full list.
19301930
let all_candidates = all_candidates.unwrap();
1931-
if all_candidates.len() == 1 {
1932-
Ok(*all_candidates.first().unwrap().0)
1931+
if let [(res, _)] = &all_candidates[..] {
1932+
Ok(*res)
19331933
} else {
19341934
let all_candidates = all_candidates
19351935
.into_iter()
@@ -2411,7 +2411,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
24112411
// Do not account for the parameters we just bound for function lifetime elision.
24122412
if let Some(ref mut candidates) = self.lifetime_elision_candidates {
24132413
for (_, res) in function_lifetime_rib.bindings.values() {
2414-
candidates.remove(res);
2414+
candidates.retain(|(r, _)| r != res);
24152415
}
24162416
}
24172417

src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,7 @@ fn k<'a, T: WithLifetime<'a>>(_x: T::Output) -> &isize {
4242
panic!()
4343
}
4444

45+
fn l<'a>(_: &'a str, _: &'a str) -> &str { "" }
46+
//~^ ERROR missing lifetime specifier
47+
4548
fn main() {}

src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,18 @@ help: consider using the `'a` lifetime
7070
LL | fn k<'a, T: WithLifetime<'a>>(_x: T::Output) -> &'a isize {
7171
| ++
7272

73-
error: aborting due to 6 previous errors
73+
error[E0106]: missing lifetime specifier
74+
--> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:45:37
75+
|
76+
LL | fn l<'a>(_: &'a str, _: &'a str) -> &str { "" }
77+
| ------- ------- ^ expected named lifetime parameter
78+
|
79+
= help: this function's return type contains a borrowed value with an elided lifetime, but the lifetime cannot be derived from the arguments
80+
help: consider using the `'a` lifetime
81+
|
82+
LL | fn l<'a>(_: &'a str, _: &'a str) -> &'a str { "" }
83+
| ++
84+
85+
error: aborting due to 7 previous errors
7486

7587
For more information about this error, try `rustc --explain E0106`.

0 commit comments

Comments
 (0)