Skip to content

Commit 067067a

Browse files
bors[bot]jonas-schievinkJonas SchievinkVeykril
authored
Merge #6896
6896: Node-ify lifetimes r=jonas-schievink a=Veykril Let's see if this passes the tests 🤞 Depends on rust-analyzer/ungrammar#15 Co-authored-by: Jonas Schievink <[email protected]> Co-authored-by: Jonas Schievink <[email protected]> Co-authored-by: Lukas Wirth <[email protected]>
2 parents 63bbdb3 + dd49622 commit 067067a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+420
-274
lines changed

Cargo.lock

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/assists/src/handlers/generate_impl.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ pub(crate) fn generate_impl(acc: &mut Assists, ctx: &AssistContext) -> Option<()
5353
if let Some(type_params) = type_params {
5454
let lifetime_params = type_params
5555
.lifetime_params()
56-
.filter_map(|it| it.lifetime_token())
56+
.filter_map(|it| it.lifetime())
5757
.map(|it| it.text().clone());
5858
let type_params = type_params
5959
.type_params()

crates/assists/src/handlers/generate_new.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ fn generate_impl_text(strukt: &ast::Struct, code: &str) -> String {
9999
if let Some(type_params) = type_params {
100100
let lifetime_params = type_params
101101
.lifetime_params()
102-
.filter_map(|it| it.lifetime_token())
102+
.filter_map(|it| it.lifetime())
103103
.map(|it| it.text().clone());
104104
let type_params =
105105
type_params.type_params().filter_map(|it| it.name()).map(|it| it.text().clone());

crates/assists/src/handlers/introduce_named_lifetime.rs

+9-12
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use rustc_hash::FxHashSet;
22
use syntax::{
33
ast::{self, GenericParamsOwner, NameOwner},
4-
AstNode, SyntaxKind, TextRange, TextSize,
4+
AstNode, TextRange, TextSize,
55
};
66

77
use crate::{assist_context::AssistBuilder, AssistContext, AssistId, AssistKind, Assists};
@@ -35,13 +35,12 @@ static ASSIST_LABEL: &str = "Introduce named lifetime";
3535
// FIXME: How can we handle renaming any one of multiple anonymous lifetimes?
3636
// FIXME: should also add support for the case fun(f: &Foo) -> &<|>Foo
3737
pub(crate) fn introduce_named_lifetime(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
38-
let lifetime_token = ctx
39-
.find_token_syntax_at_offset(SyntaxKind::LIFETIME)
40-
.filter(|lifetime| lifetime.text() == "'_")?;
41-
if let Some(fn_def) = lifetime_token.ancestors().find_map(ast::Fn::cast) {
42-
generate_fn_def_assist(acc, &fn_def, lifetime_token.text_range())
43-
} else if let Some(impl_def) = lifetime_token.ancestors().find_map(ast::Impl::cast) {
44-
generate_impl_def_assist(acc, &impl_def, lifetime_token.text_range())
38+
let lifetime =
39+
ctx.find_node_at_offset::<ast::Lifetime>().filter(|lifetime| lifetime.text() == "'_")?;
40+
if let Some(fn_def) = lifetime.syntax().ancestors().find_map(ast::Fn::cast) {
41+
generate_fn_def_assist(acc, &fn_def, lifetime.lifetime_ident_token()?.text_range())
42+
} else if let Some(impl_def) = lifetime.syntax().ancestors().find_map(ast::Impl::cast) {
43+
generate_impl_def_assist(acc, &impl_def, lifetime.lifetime_ident_token()?.text_range())
4544
} else {
4645
None
4746
}
@@ -58,7 +57,7 @@ fn generate_fn_def_assist(
5857
let end_of_fn_ident = fn_def.name()?.ident_token()?.text_range().end();
5958
let self_param =
6059
// use the self if it's a reference and has no explicit lifetime
61-
param_list.self_param().filter(|p| p.lifetime_token().is_none() && p.amp_token().is_some());
60+
param_list.self_param().filter(|p| p.lifetime().is_none() && p.amp_token().is_some());
6261
// compute the location which implicitly has the same lifetime as the anonymous lifetime
6362
let loc_needing_lifetime = if let Some(self_param) = self_param {
6463
// if we have a self reference, use that
@@ -68,9 +67,7 @@ fn generate_fn_def_assist(
6867
let fn_params_without_lifetime: Vec<_> = param_list
6968
.params()
7069
.filter_map(|param| match param.ty() {
71-
Some(ast::Type::RefType(ascribed_type))
72-
if ascribed_type.lifetime_token() == None =>
73-
{
70+
Some(ast::Type::RefType(ascribed_type)) if ascribed_type.lifetime().is_none() => {
7471
Some(ascribed_type.amp_token()?.text_range().end())
7572
}
7673
_ => None,

crates/hir/src/semantics.rs

+6-11
Original file line numberDiff line numberDiff line change
@@ -178,9 +178,8 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
178178
self.imp.descend_node_at_offset(node, offset).find_map(N::cast)
179179
}
180180

181-
// FIXME: Replace the SyntaxToken with a typed ast Node/Token
182-
pub fn resolve_lifetime_param(&self, lifetime_token: &SyntaxToken) -> Option<LifetimeParam> {
183-
self.imp.resolve_lifetime_param(lifetime_token)
181+
pub fn resolve_lifetime_param(&self, lifetime: &ast::Lifetime) -> Option<LifetimeParam> {
182+
self.imp.resolve_lifetime_param(lifetime)
184183
}
185184

186185
pub fn type_of_expr(&self, expr: &ast::Expr) -> Option<Type> {
@@ -402,13 +401,9 @@ impl<'db> SemanticsImpl<'db> {
402401
.kmerge_by(|node1, node2| node1.text_range().len() < node2.text_range().len())
403402
}
404403

405-
// FIXME: Replace the SyntaxToken with a typed ast Node/Token
406-
fn resolve_lifetime_param(&self, lifetime_token: &SyntaxToken) -> Option<LifetimeParam> {
407-
if lifetime_token.kind() != syntax::SyntaxKind::LIFETIME {
408-
return None;
409-
}
410-
let lifetime_text = lifetime_token.text();
411-
let lifetime_param = lifetime_token.parent().ancestors().find_map(|syn| {
404+
fn resolve_lifetime_param(&self, lifetime: &ast::Lifetime) -> Option<LifetimeParam> {
405+
let text = lifetime.text();
406+
let lifetime_param = lifetime.syntax().ancestors().find_map(|syn| {
412407
let gpl = match_ast! {
413408
match syn {
414409
ast::Fn(it) => it.generic_param_list()?,
@@ -424,7 +419,7 @@ impl<'db> SemanticsImpl<'db> {
424419
}
425420
};
426421
gpl.lifetime_params()
427-
.find(|tp| tp.lifetime_token().as_ref().map(|lt| lt.text()) == Some(lifetime_text))
422+
.find(|tp| tp.lifetime().as_ref().map(|lt| lt.text()) == Some(text))
428423
})?;
429424
let src = self.find_file(lifetime_param.syntax().clone()).with_value(lifetime_param);
430425
ToDef::to_def(self, src)

crates/hir_def/src/body/lower.rs

+7-17
Original file line numberDiff line numberDiff line change
@@ -233,8 +233,7 @@ impl ExprCollector<'_> {
233233
let res = self.collect_block(block);
234234
match &mut self.body.exprs[res] {
235235
Expr::Block { label: block_label, .. } => {
236-
*block_label =
237-
label.lifetime_token().map(|t| Name::new_lifetime(&t))
236+
*block_label = label.lifetime().map(|t| Name::new_lifetime(&t))
238237
}
239238
_ => unreachable!(),
240239
}
@@ -254,10 +253,7 @@ impl ExprCollector<'_> {
254253
self.alloc_expr(
255254
Expr::Loop {
256255
body,
257-
label: e
258-
.label()
259-
.and_then(|l| l.lifetime_token())
260-
.map(|l| Name::new_lifetime(&l)),
256+
label: e.label().and_then(|l| l.lifetime()).map(|l| Name::new_lifetime(&l)),
261257
},
262258
syntax_ptr,
263259
)
@@ -288,7 +284,7 @@ impl ExprCollector<'_> {
288284
body: match_expr,
289285
label: e
290286
.label()
291-
.and_then(|l| l.lifetime_token())
287+
.and_then(|l| l.lifetime())
292288
.map(|l| Name::new_lifetime(&l)),
293289
},
294290
syntax_ptr,
@@ -301,10 +297,7 @@ impl ExprCollector<'_> {
301297
Expr::While {
302298
condition,
303299
body,
304-
label: e
305-
.label()
306-
.and_then(|l| l.lifetime_token())
307-
.map(|l| Name::new_lifetime(&l)),
300+
label: e.label().and_then(|l| l.lifetime()).map(|l| Name::new_lifetime(&l)),
308301
},
309302
syntax_ptr,
310303
)
@@ -318,10 +311,7 @@ impl ExprCollector<'_> {
318311
iterable,
319312
pat,
320313
body,
321-
label: e
322-
.label()
323-
.and_then(|l| l.lifetime_token())
324-
.map(|l| Name::new_lifetime(&l)),
314+
label: e.label().and_then(|l| l.lifetime()).map(|l| Name::new_lifetime(&l)),
325315
},
326316
syntax_ptr,
327317
)
@@ -380,13 +370,13 @@ impl ExprCollector<'_> {
380370
self.alloc_expr(path, syntax_ptr)
381371
}
382372
ast::Expr::ContinueExpr(e) => self.alloc_expr(
383-
Expr::Continue { label: e.lifetime_token().map(|l| Name::new_lifetime(&l)) },
373+
Expr::Continue { label: e.lifetime().map(|l| Name::new_lifetime(&l)) },
384374
syntax_ptr,
385375
),
386376
ast::Expr::BreakExpr(e) => {
387377
let expr = e.expr().map(|e| self.collect_expr(e));
388378
self.alloc_expr(
389-
Expr::Break { expr, label: e.lifetime_token().map(|l| Name::new_lifetime(&l)) },
379+
Expr::Break { expr, label: e.lifetime().map(|l| Name::new_lifetime(&l)) },
390380
syntax_ptr,
391381
)
392382
}

crates/hir_def/src/generics.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -260,9 +260,8 @@ impl GenericParams {
260260
self.fill_bounds(&lower_ctx, &type_param, Either::Left(type_ref));
261261
}
262262
for lifetime_param in params.lifetime_params() {
263-
let name = lifetime_param
264-
.lifetime_token()
265-
.map_or_else(Name::missing, |tok| Name::new_lifetime(&tok));
263+
let name =
264+
lifetime_param.lifetime().map_or_else(Name::missing, |lt| Name::new_lifetime(&lt));
266265
let param = LifetimeParamData { name: name.clone() };
267266
let param_id = self.lifetimes.alloc(param);
268267
sm.lifetime_params.insert(param_id, lifetime_param.clone());
@@ -275,8 +274,8 @@ impl GenericParams {
275274
for pred in where_clause.predicates() {
276275
let target = if let Some(type_ref) = pred.ty() {
277276
Either::Left(TypeRef::from_ast(lower_ctx, type_ref))
278-
} else if let Some(lifetime_tok) = pred.lifetime_token() {
279-
Either::Right(LifetimeRef::from_token(lifetime_tok))
277+
} else if let Some(lifetime) = pred.lifetime() {
278+
Either::Right(LifetimeRef::new(&lifetime))
280279
} else {
281280
continue;
282281
};

crates/hir_def/src/item_tree/lower.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -300,12 +300,12 @@ impl Ctx {
300300
ast::SelfParamKind::Owned => self_type,
301301
ast::SelfParamKind::Ref => TypeRef::Reference(
302302
Box::new(self_type),
303-
self_param.lifetime_token().map(LifetimeRef::from_token),
303+
self_param.lifetime().as_ref().map(LifetimeRef::new),
304304
Mutability::Shared,
305305
),
306306
ast::SelfParamKind::MutRef => TypeRef::Reference(
307307
Box::new(self_type),
308-
self_param.lifetime_token().map(LifetimeRef::from_token),
308+
self_param.lifetime().as_ref().map(LifetimeRef::new),
309309
Mutability::Mut,
310310
),
311311
}

crates/hir_def/src/path/lower.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -169,8 +169,8 @@ pub(super) fn lower_generic_args(
169169
}
170170
}
171171
ast::GenericArg::LifetimeArg(lifetime_arg) => {
172-
if let Some(lifetime) = lifetime_arg.lifetime_token() {
173-
let lifetime_ref = LifetimeRef::from_token(lifetime);
172+
if let Some(lifetime) = lifetime_arg.lifetime() {
173+
let lifetime_ref = LifetimeRef::new(&lifetime);
174174
args.push(GenericArg::Lifetime(lifetime_ref))
175175
}
176176
}

crates/hir_def/src/type_ref.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! HIR for references to types. Paths in these are not yet resolved. They can
22
//! be directly created from an ast::TypeRef, without further queries.
33
use hir_expand::name::Name;
4-
use syntax::{ast, SyntaxToken};
4+
use syntax::ast;
55

66
use crate::{body::LowerCtx, path::Path};
77

@@ -80,8 +80,8 @@ impl LifetimeRef {
8080
LifetimeRef { name }
8181
}
8282

83-
pub(crate) fn from_token(token: SyntaxToken) -> Self {
84-
LifetimeRef { name: Name::new_lifetime(&token) }
83+
pub(crate) fn new(lifetime: &ast::Lifetime) -> Self {
84+
LifetimeRef { name: Name::new_lifetime(lifetime) }
8585
}
8686

8787
pub fn missing() -> LifetimeRef {
@@ -127,7 +127,7 @@ impl TypeRef {
127127
}
128128
ast::Type::RefType(inner) => {
129129
let inner_ty = TypeRef::from_ast_opt(&ctx, inner.ty());
130-
let lifetime = inner.lifetime_token().map(|t| LifetimeRef::from_token(t));
130+
let lifetime = inner.lifetime().map(|lt| LifetimeRef::new(&lt));
131131
let mutability = Mutability::from_mutable(inner.mut_token().is_some());
132132
TypeRef::Reference(Box::new(inner_ty), lifetime, mutability)
133133
}
@@ -259,7 +259,7 @@ impl TypeBound {
259259
}
260260
ast::TypeBoundKind::ForType(_) => TypeBound::Error, // FIXME ForType
261261
ast::TypeBoundKind::Lifetime(lifetime) => {
262-
TypeBound::Lifetime(LifetimeRef::from_token(lifetime))
262+
TypeBound::Lifetime(LifetimeRef::new(&lifetime))
263263
}
264264
}
265265
}

crates/hir_expand/src/name.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,8 @@ impl Name {
3737
Name(Repr::TupleField(idx))
3838
}
3939

40-
pub fn new_lifetime(lt: &syntax::SyntaxToken) -> Name {
41-
assert_eq!(lt.kind(), syntax::SyntaxKind::LIFETIME);
42-
Name(Repr::Text(lt.text().clone()))
40+
pub fn new_lifetime(lt: &ast::Lifetime) -> Name {
41+
Self::new_text(lt.text().clone())
4342
}
4443

4544
/// Shortcut to create inline plain text name

crates/ide/src/extend_selection.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ fn pick_best(l: SyntaxToken, r: SyntaxToken) -> SyntaxToken {
237237
fn priority(n: &SyntaxToken) -> usize {
238238
match n.kind() {
239239
WHITESPACE => 0,
240-
IDENT | T![self] | T![super] | T![crate] | LIFETIME => 2,
240+
IDENT | T![self] | T![super] | T![crate] | LIFETIME_IDENT => 2,
241241
_ => 1,
242242
}
243243
}

crates/mbe/src/mbe_expander/matcher.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ impl<'a> TtIter<'a> {
295295

296296
impl<'a> TreeSink for OffsetTokenSink<'a> {
297297
fn token(&mut self, kind: SyntaxKind, mut n_tokens: u8) {
298-
if kind == SyntaxKind::LIFETIME {
298+
if kind == SyntaxKind::LIFETIME_IDENT {
299299
n_tokens = 2;
300300
}
301301
for _ in 0..n_tokens {

crates/mbe/src/subtree_source.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,11 @@ impl<'a> SubtreeTokenSource<'a> {
8484
}
8585

8686
if let Some((curr, text)) = is_lifetime(cursor) {
87-
cached.push(Some(TtToken { kind: LIFETIME, is_joint_to_next: false, text }));
87+
cached.push(Some(TtToken {
88+
kind: LIFETIME_IDENT,
89+
is_joint_to_next: false,
90+
text,
91+
}));
8892
self.cached_cursor.set(curr);
8993
continue;
9094
}
@@ -172,7 +176,7 @@ fn convert_ident(ident: &tt::Ident) -> TtToken {
172176
let kind = match ident.text.as_ref() {
173177
"true" => T![true],
174178
"false" => T![false],
175-
i if i.starts_with('\'') => LIFETIME,
179+
i if i.starts_with('\'') => LIFETIME_IDENT,
176180
_ => SyntaxKind::from_keyword(ident.text.as_str()).unwrap_or(IDENT),
177181
};
178182

crates/mbe/src/syntax_bridge.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,7 @@ trait TokenConvertor {
380380
IDENT => make_leaf!(Ident),
381381
k if k.is_keyword() => make_leaf!(Ident),
382382
k if k.is_literal() => make_leaf!(Literal),
383-
LIFETIME => {
383+
LIFETIME_IDENT => {
384384
let char_unit = TextSize::of('\'');
385385
let r = TextRange::at(range.start(), char_unit);
386386
let apostrophe = tt::Leaf::from(tt::Punct {
@@ -620,7 +620,7 @@ impl<'a> TreeSink for TtTreeSink<'a> {
620620
self.cursor = self.cursor.bump_subtree();
621621
return;
622622
}
623-
if kind == LIFETIME {
623+
if kind == LIFETIME_IDENT {
624624
n_tokens = 2;
625625
}
626626

crates/parser/src/grammar.rs

+7
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,13 @@ fn name_ref_or_index(p: &mut Parser) {
283283
m.complete(p, NAME_REF);
284284
}
285285

286+
fn lifetime(p: &mut Parser) {
287+
assert!(p.at(LIFETIME_IDENT));
288+
let m = p.start();
289+
p.bump(LIFETIME_IDENT);
290+
m.complete(p, LIFETIME);
291+
}
292+
286293
fn error_block(p: &mut Parser, message: &str) {
287294
assert!(p.at(T!['{']));
288295
let m = p.start();

0 commit comments

Comments
 (0)