From b4c19da340fa0342927e4726b361df2696284bc0 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 19 Jan 2023 21:22:01 -0800 Subject: [PATCH] Improve spans of named lifetimes generated from elided lifetimes --- src/expand.rs | 4 ++-- src/lifetime.rs | 19 ++++++++----------- tests/ui/lifetime-defined-here.stderr | 8 ++++++-- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/expand.rs b/src/expand.rs index 2c06b69..3fdcb51 100644 --- a/src/expand.rs +++ b/src/expand.rs @@ -80,7 +80,7 @@ pub fn expand(input: &mut Item, is_local: bool) { } } Item::Impl(input) => { - let mut lifetimes = CollectLifetimes::new("'impl", input.impl_token.span); + let mut lifetimes = CollectLifetimes::new("'impl"); lifetimes.visit_type_mut(&mut *input.self_ty); lifetimes.visit_path_mut(&mut input.trait_.as_mut().unwrap().1); let params = &input.generics.params; @@ -166,7 +166,7 @@ fn transform_sig( ReturnType::Type(arrow, ret) => (*arrow, quote!(#ret)), }; - let mut lifetimes = CollectLifetimes::new("'life", default_span); + let mut lifetimes = CollectLifetimes::new("'life"); for arg in sig.inputs.iter_mut() { match arg { FnArg::Receiver(arg) => lifetimes.visit_receiver_mut(arg), diff --git a/src/lifetime.rs b/src/lifetime.rs index 8e4ec38..86eac24 100644 --- a/src/lifetime.rs +++ b/src/lifetime.rs @@ -2,7 +2,7 @@ use proc_macro2::{Span, TokenStream}; use std::mem; use syn::visit_mut::{self, VisitMut}; use syn::{ - parse_quote_spanned, token, Expr, GenericArgument, Lifetime, Receiver, ReturnType, Type, + parse_quote_spanned, token, Expr, GenericArgument, Lifetime, Receiver, ReturnType, Token, Type, TypeBareFn, TypeImplTrait, TypeParen, TypePtr, TypeReference, }; @@ -10,22 +10,20 @@ pub struct CollectLifetimes { pub elided: Vec, pub explicit: Vec, pub name: &'static str, - pub default_span: Span, } impl CollectLifetimes { - pub fn new(name: &'static str, default_span: Span) -> Self { + pub fn new(name: &'static str) -> Self { CollectLifetimes { elided: Vec::new(), explicit: Vec::new(), name, - default_span, } } - fn visit_opt_lifetime(&mut self, lifetime: &mut Option) { + fn visit_opt_lifetime(&mut self, reference: Token![&], lifetime: &mut Option) { match lifetime { - None => *lifetime = Some(self.next_lifetime(None)), + None => *lifetime = Some(self.next_lifetime(reference.span)), Some(lifetime) => self.visit_lifetime(lifetime), } } @@ -38,9 +36,8 @@ impl CollectLifetimes { } } - fn next_lifetime>>(&mut self, span: S) -> Lifetime { + fn next_lifetime(&mut self, span: Span) -> Lifetime { let name = format!("{}{}", self.name, self.elided.len()); - let span = span.into().unwrap_or(self.default_span); let life = Lifetime::new(&name, span); self.elided.push(life.clone()); life @@ -49,13 +46,13 @@ impl CollectLifetimes { impl VisitMut for CollectLifetimes { fn visit_receiver_mut(&mut self, arg: &mut Receiver) { - if let Some((_, lifetime)) = &mut arg.reference { - self.visit_opt_lifetime(lifetime); + if let Some((reference, lifetime)) = &mut arg.reference { + self.visit_opt_lifetime(*reference, lifetime); } } fn visit_type_reference_mut(&mut self, ty: &mut TypeReference) { - self.visit_opt_lifetime(&mut ty.lifetime); + self.visit_opt_lifetime(ty.and_token, &mut ty.lifetime); visit_mut::visit_type_reference_mut(self, ty); } diff --git a/tests/ui/lifetime-defined-here.stderr b/tests/ui/lifetime-defined-here.stderr index 20f62ac..9ffef5b 100644 --- a/tests/ui/lifetime-defined-here.stderr +++ b/tests/ui/lifetime-defined-here.stderr @@ -2,13 +2,17 @@ error: lifetime may not live long enough --> tests/ui/lifetime-defined-here.rs:12:49 | 12 | async fn bar(&self, x: &str, y: &'_ str) -> &'static str { - | ----- lifetime `'life0` defined here ^^^^^^^^^^^^ type annotation requires that `'life0` must outlive `'static` + | - ^^^^^^^^^^^^ type annotation requires that `'life0` must outlive `'static` + | | + | lifetime `'life0` defined here error: lifetime may not live long enough --> tests/ui/lifetime-defined-here.rs:12:49 | 12 | async fn bar(&self, x: &str, y: &'_ str) -> &'static str { - | ----- lifetime `'life1` defined here ^^^^^^^^^^^^ type annotation requires that `'life1` must outlive `'static` + | - ^^^^^^^^^^^^ type annotation requires that `'life1` must outlive `'static` + | | + | lifetime `'life1` defined here error: lifetime may not live long enough --> tests/ui/lifetime-defined-here.rs:12:49