Skip to content

Commit 2003d83

Browse files
authored
Rollup merge of #96559 - cjgillot:elided-path-fn, r=petrochenkov
Use the correct lifetime binder for elided lifetimes in path. Fixes #96540
2 parents 0b96be7 + 6e349c7 commit 2003d83

File tree

2 files changed

+32
-12
lines changed

2 files changed

+32
-12
lines changed

compiler/rustc_resolve/src/late.rs

+13-12
Original file line numberDiff line numberDiff line change
@@ -1319,7 +1319,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
13191319
| PathSource::Struct
13201320
| PathSource::TupleStruct(..) => false,
13211321
};
1322-
let mut error = false;
1322+
let mut res = LifetimeRes::Error;
13231323
for rib in self.lifetime_ribs.iter().rev() {
13241324
match rib.kind {
13251325
// In create-parameter mode we error here because we don't want to support
@@ -1329,7 +1329,6 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
13291329
// impl Foo for std::cell::Ref<u32> // note lack of '_
13301330
// async fn foo(_: std::cell::Ref<u32>) { ... }
13311331
LifetimeRibKind::AnonymousCreateParameter(_) => {
1332-
error = true;
13331332
break;
13341333
}
13351334
// `PassThrough` is the normal case.
@@ -1338,19 +1337,21 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
13381337
// `PathSegment`, for which there is no associated `'_` or `&T` with no explicit
13391338
// lifetime. Instead, we simply create an implicit lifetime, which will be checked
13401339
// later, at which point a suitable error will be emitted.
1341-
LifetimeRibKind::AnonymousPassThrough(..)
1342-
| LifetimeRibKind::AnonymousReportError
1343-
| LifetimeRibKind::Item => break,
1340+
LifetimeRibKind::AnonymousPassThrough(binder) => {
1341+
res = LifetimeRes::Anonymous { binder, elided: true };
1342+
break;
1343+
}
1344+
LifetimeRibKind::AnonymousReportError | LifetimeRibKind::Item => {
1345+
// FIXME(cjgillot) This resolution is wrong, but this does not matter
1346+
// since these cases are erroneous anyway. Lifetime resolution should
1347+
// emit a "missing lifetime specifier" diagnostic.
1348+
res = LifetimeRes::Anonymous { binder: DUMMY_NODE_ID, elided: true };
1349+
break;
1350+
}
13441351
_ => {}
13451352
}
13461353
}
13471354

1348-
let res = if error {
1349-
LifetimeRes::Error
1350-
} else {
1351-
LifetimeRes::Anonymous { binder: segment_id, elided: true }
1352-
};
1353-
13541355
let node_ids = self.r.next_node_ids(expected_lifetimes);
13551356
self.record_lifetime_res(
13561357
segment_id,
@@ -1374,7 +1375,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
13741375
// originating from macros, since the segment's span might be from a macro arg.
13751376
segment.ident.span.find_ancestor_inside(path_span).unwrap_or(path_span)
13761377
};
1377-
if error {
1378+
if let LifetimeRes::Error = res {
13781379
let sess = self.r.session;
13791380
let mut err = rustc_errors::struct_span_err!(
13801381
sess,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// check-pass
2+
3+
struct Foo<'a>(&'a ());
4+
5+
fn with_fn() -> fn(Foo) {
6+
|_| ()
7+
}
8+
9+
fn with_impl_fn() -> impl Fn(Foo) {
10+
|_| ()
11+
}
12+
13+
fn with_where_fn<T>()
14+
where
15+
T: Fn(Foo),
16+
{
17+
}
18+
19+
fn main() {}

0 commit comments

Comments
 (0)