Skip to content

Commit

Permalink
Rollup merge of #96559 - cjgillot:elided-path-fn, r=petrochenkov
Browse files Browse the repository at this point in the history
Use the correct lifetime binder for elided lifetimes in path.

Fixes #96540
  • Loading branch information
Dylan-DPC authored Apr 29, 2022
2 parents 0b96be7 + 6e349c7 commit 2003d83
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 12 deletions.
25 changes: 13 additions & 12 deletions compiler/rustc_resolve/src/late.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1319,7 +1319,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
| PathSource::Struct
| PathSource::TupleStruct(..) => false,
};
let mut error = false;
let mut res = LifetimeRes::Error;
for rib in self.lifetime_ribs.iter().rev() {
match rib.kind {
// In create-parameter mode we error here because we don't want to support
Expand All @@ -1329,7 +1329,6 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
// impl Foo for std::cell::Ref<u32> // note lack of '_
// async fn foo(_: std::cell::Ref<u32>) { ... }
LifetimeRibKind::AnonymousCreateParameter(_) => {
error = true;
break;
}
// `PassThrough` is the normal case.
Expand All @@ -1338,19 +1337,21 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
// `PathSegment`, for which there is no associated `'_` or `&T` with no explicit
// lifetime. Instead, we simply create an implicit lifetime, which will be checked
// later, at which point a suitable error will be emitted.
LifetimeRibKind::AnonymousPassThrough(..)
| LifetimeRibKind::AnonymousReportError
| LifetimeRibKind::Item => break,
LifetimeRibKind::AnonymousPassThrough(binder) => {
res = LifetimeRes::Anonymous { binder, elided: true };
break;
}
LifetimeRibKind::AnonymousReportError | LifetimeRibKind::Item => {
// FIXME(cjgillot) This resolution is wrong, but this does not matter
// since these cases are erroneous anyway. Lifetime resolution should
// emit a "missing lifetime specifier" diagnostic.
res = LifetimeRes::Anonymous { binder: DUMMY_NODE_ID, elided: true };
break;
}
_ => {}
}
}

let res = if error {
LifetimeRes::Error
} else {
LifetimeRes::Anonymous { binder: segment_id, elided: true }
};

let node_ids = self.r.next_node_ids(expected_lifetimes);
self.record_lifetime_res(
segment_id,
Expand All @@ -1374,7 +1375,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
// originating from macros, since the segment's span might be from a macro arg.
segment.ident.span.find_ancestor_inside(path_span).unwrap_or(path_span)
};
if error {
if let LifetimeRes::Error = res {
let sess = self.r.session;
let mut err = rustc_errors::struct_span_err!(
sess,
Expand Down
19 changes: 19 additions & 0 deletions src/test/ui/lifetimes/elided-lifetime-in-path-in-impl-Fn.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// check-pass

struct Foo<'a>(&'a ());

fn with_fn() -> fn(Foo) {
|_| ()
}

fn with_impl_fn() -> impl Fn(Foo) {
|_| ()
}

fn with_where_fn<T>()
where
T: Fn(Foo),
{
}

fn main() {}

0 comments on commit 2003d83

Please sign in to comment.