Skip to content

Commit 7c4e9d4

Browse files
committed
skip callee visits to avoid invisible-lifetime lint false-positive
As far as the higher intermediate representation is concerned, associated functions like `Ref::clone` are equivalent to the universal function call syntax expression `<Ref>::clone`, so our strategy of linting for invisible lifetimes while visiting types in the LifetimeContext visitor was resulting in us suggesting that the user call `Ref<'_>::clone` (which doesn't parse). It is not without some sentiments of inadequacy that the present author can't think of a better way to avoid this than making the visitor avoid traversing into the callee of call expressions. This should be OK because—one is pretty sure—there aren't going to be lifetimes to resolve in a callee expression. Besides linting for invisible lifetimes (introduced in this branch), the only other work taking place in the `hir::TyPath(hir::QPath::Resolved(None, ref path))` arm of the `visit_ty` method is about resolving lifetimes in existential types. This is all about issue no. 52041.
1 parent 22c4f56 commit 7c4e9d4

File tree

3 files changed

+18
-3
lines changed

3 files changed

+18
-3
lines changed

src/librustc/middle/resolve_lifetime.rs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -564,6 +564,20 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
564564
}
565565
}
566566

567+
fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
568+
if let hir::ExprCall(_, ref arguments) = expr.node {
569+
// Avoid traversing into a call expression's callee specifically to avoid
570+
// triggering a false positive for the invisible-lifetimes-in-type-paths lint. (The
571+
// motivating examples were `Ref::map` and `Ref::clone`.)
572+
// FIXME: is there a more elegant way of doing this?!
573+
//
574+
// But do visit the arguments
575+
walk_list!(self, visit_expr, arguments);
576+
} else {
577+
intravisit::walk_expr(self, expr);
578+
}
579+
}
580+
567581
fn visit_ty(&mut self, ty: &'tcx hir::Ty) {
568582
debug!("visit_ty: id={:?} ty={:?}", ty.id, ty);
569583
match ty.node {
@@ -2136,9 +2150,8 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
21362150
err.span_suggestion_with_applicability(
21372151
replace_span,
21382152
"indicate the anonymous lifetime",
2139-
suggestion.to_owned(),
2140-
// false positives observed with macros, `Ref::map` (tracking issue #52041)
2141-
Applicability::MaybeIncorrect
2153+
suggestion,
2154+
Applicability::MachineApplicable
21422155
);
21432156
}
21442157
err.emit();

src/test/ui/in-band-lifetimes/elided-lifetimes.fixed

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,5 @@ fn main() {
5151
let loyalty: Ref<'_, (u32, char)> = honesty.borrow();
5252
//~^ ERROR implicit lifetime parameters in types are deprecated
5353
//~| HELP indicate the anonymous lifetime
54+
let generosity = Ref::map(loyalty, |t| &t.0);
5455
}

src/test/ui/in-band-lifetimes/elided-lifetimes.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,5 @@ fn main() {
5151
let loyalty: Ref<(u32, char)> = honesty.borrow();
5252
//~^ ERROR implicit lifetime parameters in types are deprecated
5353
//~| HELP indicate the anonymous lifetime
54+
let generosity = Ref::map(loyalty, |t| &t.0);
5455
}

0 commit comments

Comments
 (0)