Skip to content

Commit 919ba41

Browse files
committed
Auto merge of #18371 - Veykril:veykril/push-kwttrusywysp, r=Veykril
fix: Fix incorrect parsing of use bounds Fixes rust-lang/rust-analyzer#18357
2 parents d4742e7 + 6f71369 commit 919ba41

File tree

11 files changed

+184
-25
lines changed

11 files changed

+184
-25
lines changed

src/tools/rust-analyzer/crates/hir-def/src/hir/type_ref.rs

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -157,9 +157,19 @@ pub enum TypeBound {
157157
Path(Path, TraitBoundModifier),
158158
ForLifetime(Box<[Name]>, Path),
159159
Lifetime(LifetimeRef),
160+
Use(Box<[UseArgRef]>),
160161
Error,
161162
}
162163

164+
#[cfg(target_pointer_width = "64")]
165+
const _: [(); 56] = [(); ::std::mem::size_of::<TypeBound>()];
166+
167+
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
168+
pub enum UseArgRef {
169+
Name(Name),
170+
Lifetime(LifetimeRef),
171+
}
172+
163173
/// A modifier on a bound, currently this is only used for `?Sized`, where the
164174
/// modifier is `Maybe`.
165175
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
@@ -295,7 +305,7 @@ impl TypeRef {
295305
TypeBound::Path(path, _) | TypeBound::ForLifetime(_, path) => {
296306
go_path(path, f)
297307
}
298-
TypeBound::Lifetime(_) | TypeBound::Error => (),
308+
TypeBound::Lifetime(_) | TypeBound::Error | TypeBound::Use(_) => (),
299309
}
300310
}
301311
}
@@ -328,7 +338,7 @@ impl TypeRef {
328338
TypeBound::Path(path, _) | TypeBound::ForLifetime(_, path) => {
329339
go_path(path, f)
330340
}
331-
TypeBound::Lifetime(_) | TypeBound::Error => (),
341+
TypeBound::Lifetime(_) | TypeBound::Error | TypeBound::Use(_) => (),
332342
}
333343
}
334344
}
@@ -380,7 +390,16 @@ impl TypeBound {
380390
None => TypeBound::Error,
381391
}
382392
}
383-
ast::TypeBoundKind::Use(_) => TypeBound::Error,
393+
ast::TypeBoundKind::Use(gal) => TypeBound::Use(
394+
gal.use_bound_generic_args()
395+
.map(|p| match p {
396+
ast::UseBoundGenericArg::Lifetime(l) => {
397+
UseArgRef::Lifetime(LifetimeRef::new(&l))
398+
}
399+
ast::UseBoundGenericArg::NameRef(n) => UseArgRef::Name(n.as_name()),
400+
})
401+
.collect(),
402+
),
384403
ast::TypeBoundKind::Lifetime(lifetime) => {
385404
TypeBound::Lifetime(LifetimeRef::new(&lifetime))
386405
}
@@ -391,7 +410,7 @@ impl TypeBound {
391410
match self {
392411
TypeBound::Path(p, m) => Some((p, m)),
393412
TypeBound::ForLifetime(_, p) => Some((p, &TraitBoundModifier::None)),
394-
TypeBound::Lifetime(_) | TypeBound::Error => None,
413+
TypeBound::Lifetime(_) | TypeBound::Error | TypeBound::Use(_) => None,
395414
}
396415
}
397416
}

src/tools/rust-analyzer/crates/hir-def/src/pretty.rs

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
//! Display and pretty printing routines.
22
3-
use std::fmt::{self, Write};
3+
use std::{
4+
fmt::{self, Write},
5+
mem,
6+
};
47

58
use hir_expand::mod_path::PathKind;
69
use intern::Interned;
@@ -11,7 +14,7 @@ use crate::{
1114
db::DefDatabase,
1215
lang_item::LangItemTarget,
1316
path::{GenericArg, GenericArgs, Path},
14-
type_ref::{Mutability, TraitBoundModifier, TypeBound, TypeRef},
17+
type_ref::{Mutability, TraitBoundModifier, TypeBound, TypeRef, UseArgRef},
1518
};
1619

1720
pub(crate) fn print_path(
@@ -273,6 +276,22 @@ pub(crate) fn print_type_bounds(
273276
print_path(db, path, buf, edition)?;
274277
}
275278
TypeBound::Lifetime(lt) => write!(buf, "{}", lt.name.display(db.upcast(), edition))?,
279+
TypeBound::Use(args) => {
280+
write!(buf, "use<")?;
281+
let mut first = true;
282+
for arg in args {
283+
if !mem::take(&mut first) {
284+
write!(buf, ", ")?;
285+
}
286+
match arg {
287+
UseArgRef::Name(it) => write!(buf, "{}", it.display(db.upcast(), edition))?,
288+
UseArgRef::Lifetime(it) => {
289+
write!(buf, "{}", it.name.display(db.upcast(), edition))?
290+
}
291+
}
292+
}
293+
write!(buf, ">")?
294+
}
276295
TypeBound::Error => write!(buf, "{{unknown}}")?,
277296
}
278297
}

src/tools/rust-analyzer/crates/hir-ty/src/display.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use hir_def::{
1919
lang_item::{LangItem, LangItemTarget},
2020
nameres::DefMap,
2121
path::{Path, PathKind},
22-
type_ref::{TraitBoundModifier, TypeBound, TypeRef},
22+
type_ref::{TraitBoundModifier, TypeBound, TypeRef, UseArgRef},
2323
visibility::Visibility,
2424
GenericDefId, HasModule, ImportPathConfig, ItemContainerId, LocalFieldId, Lookup, ModuleDefId,
2525
ModuleId, TraitId,
@@ -2025,6 +2025,19 @@ impl HirDisplay for TypeBound {
20252025
)?;
20262026
path.hir_fmt(f)
20272027
}
2028+
TypeBound::Use(args) => {
2029+
let edition = f.edition();
2030+
write!(
2031+
f,
2032+
"use<{}> ",
2033+
args.iter()
2034+
.map(|it| match it {
2035+
UseArgRef::Lifetime(lt) => lt.name.display(f.db.upcast(), edition),
2036+
UseArgRef::Name(n) => n.display(f.db.upcast(), edition),
2037+
})
2038+
.format(", ")
2039+
)
2040+
}
20282041
TypeBound::Error => write!(f, "{{error}}"),
20292042
}
20302043
}

src/tools/rust-analyzer/crates/hir-ty/src/lower.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1067,7 +1067,7 @@ impl<'a> TyLoweringContext<'a> {
10671067
lifetime,
10681068
})))
10691069
}
1070-
TypeBound::Error => None,
1070+
TypeBound::Use(_) | TypeBound::Error => None,
10711071
};
10721072
clause.into_iter().chain(
10731073
trait_ref
@@ -1087,6 +1087,7 @@ impl<'a> TyLoweringContext<'a> {
10871087
path.segments().last()
10881088
}
10891089
TypeBound::Path(_, TraitBoundModifier::Maybe)
1090+
| TypeBound::Use(_)
10901091
| TypeBound::Error
10911092
| TypeBound::Lifetime(_) => None,
10921093
};
@@ -1571,7 +1572,7 @@ pub(crate) fn generic_predicates_for_param_query(
15711572
})
15721573
})
15731574
}
1574-
TypeBound::Lifetime(_) | TypeBound::Error => false,
1575+
TypeBound::Use(_) | TypeBound::Lifetime(_) | TypeBound::Error => false,
15751576
}
15761577
}
15771578
WherePredicate::Lifetime { .. } => false,

src/tools/rust-analyzer/crates/parser/src/grammar/generic_params.rs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,10 +144,31 @@ fn type_bound(p: &mut Parser<'_>) -> bool {
144144
LIFETIME_IDENT => lifetime(p),
145145
T![for] => types::for_type(p, false),
146146
// test precise_capturing
147-
// fn captures<'a: 'a, 'b: 'b, T>() -> impl Sized + use<'b, T> {}
147+
// fn captures<'a: 'a, 'b: 'b, T>() -> impl Sized + use<'b, T, Self> {}
148148
T![use] if p.nth_at(1, T![<]) => {
149149
p.bump_any();
150-
generic_param_list(p)
150+
let m = p.start();
151+
delimited(
152+
p,
153+
T![<],
154+
T![>],
155+
T![,],
156+
|| "expected identifier or lifetime".into(),
157+
TokenSet::new(&[T![Self], IDENT, LIFETIME_IDENT]),
158+
|p| {
159+
if p.at(T![Self]) {
160+
let m = p.start();
161+
p.bump(T![Self]);
162+
m.complete(p, NAME_REF);
163+
} else if p.at(LIFETIME_IDENT) {
164+
lifetime(p);
165+
} else {
166+
name_ref(p);
167+
}
168+
true
169+
},
170+
);
171+
m.complete(p, USE_BOUND_GENERIC_ARGS);
151172
}
152173
T![?] if p.nth_at(1, T![for]) => {
153174
// test question_for_type_trait_bound

src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,8 @@ pub enum SyntaxKind {
312312
UNDERSCORE_EXPR,
313313
UNION,
314314
USE,
315+
USE_BOUND_GENERIC_ARG,
316+
USE_BOUND_GENERIC_ARGS,
315317
USE_TREE,
316318
USE_TREE_LIST,
317319
VARIANT,

src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/precise_capturing.rast

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,16 +50,18 @@ SOURCE_FILE
5050
WHITESPACE " "
5151
TYPE_BOUND
5252
USE_KW "use"
53-
GENERIC_PARAM_LIST
53+
USE_BOUND_GENERIC_ARGS
5454
L_ANGLE "<"
55-
LIFETIME_PARAM
56-
LIFETIME
57-
LIFETIME_IDENT "'b"
55+
LIFETIME
56+
LIFETIME_IDENT "'b"
5857
COMMA ","
5958
WHITESPACE " "
60-
TYPE_PARAM
61-
NAME
62-
IDENT "T"
59+
NAME_REF
60+
IDENT "T"
61+
COMMA ","
62+
WHITESPACE " "
63+
NAME_REF
64+
SELF_TYPE_KW "Self"
6365
R_ANGLE ">"
6466
WHITESPACE " "
6567
BLOCK_EXPR
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
fn captures<'a: 'a, 'b: 'b, T>() -> impl Sized + use<'b, T> {}
1+
fn captures<'a: 'a, 'b: 'b, T>() -> impl Sized + use<'b, T, Self> {}

src/tools/rust-analyzer/crates/syntax/rust.ungram

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -657,7 +657,14 @@ TypeBoundList =
657657
TypeBound =
658658
Lifetime
659659
| ('~' 'const' | 'const')? 'async'? '?'? Type
660-
| 'use' GenericParamList
660+
| 'use' UseBoundGenericArgs
661+
662+
UseBoundGenericArgs =
663+
'<' (UseBoundGenericArg (',' UseBoundGenericArg)* ','?)? '>'
664+
665+
UseBoundGenericArg =
666+
Lifetime
667+
| NameRef
661668

662669
//************************//
663670
// Patterns //

src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs

Lines changed: 77 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1993,13 +1993,15 @@ pub struct TypeBound {
19931993
pub(crate) syntax: SyntaxNode,
19941994
}
19951995
impl TypeBound {
1996-
#[inline]
1997-
pub fn generic_param_list(&self) -> Option<GenericParamList> { support::child(&self.syntax) }
19981996
#[inline]
19991997
pub fn lifetime(&self) -> Option<Lifetime> { support::child(&self.syntax) }
20001998
#[inline]
20011999
pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
20022000
#[inline]
2001+
pub fn use_bound_generic_args(&self) -> Option<UseBoundGenericArgs> {
2002+
support::child(&self.syntax)
2003+
}
2004+
#[inline]
20032005
pub fn question_mark_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![?]) }
20042006
#[inline]
20052007
pub fn async_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![async]) }
@@ -2076,6 +2078,21 @@ impl Use {
20762078
pub fn use_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![use]) }
20772079
}
20782080

2081+
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2082+
pub struct UseBoundGenericArgs {
2083+
pub(crate) syntax: SyntaxNode,
2084+
}
2085+
impl UseBoundGenericArgs {
2086+
#[inline]
2087+
pub fn use_bound_generic_args(&self) -> AstChildren<UseBoundGenericArg> {
2088+
support::children(&self.syntax)
2089+
}
2090+
#[inline]
2091+
pub fn l_angle_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![<]) }
2092+
#[inline]
2093+
pub fn r_angle_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![>]) }
2094+
}
2095+
20792096
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
20802097
pub struct UseTree {
20812098
pub(crate) syntax: SyntaxNode,
@@ -2402,6 +2419,12 @@ pub enum Type {
24022419
TupleType(TupleType),
24032420
}
24042421

2422+
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2423+
pub enum UseBoundGenericArg {
2424+
Lifetime(Lifetime),
2425+
NameRef(NameRef),
2426+
}
2427+
24052428
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
24062429
pub struct AnyHasArgList {
24072430
pub(crate) syntax: SyntaxNode,
@@ -4435,6 +4458,20 @@ impl AstNode for Use {
44354458
#[inline]
44364459
fn syntax(&self) -> &SyntaxNode { &self.syntax }
44374460
}
4461+
impl AstNode for UseBoundGenericArgs {
4462+
#[inline]
4463+
fn can_cast(kind: SyntaxKind) -> bool { kind == USE_BOUND_GENERIC_ARGS }
4464+
#[inline]
4465+
fn cast(syntax: SyntaxNode) -> Option<Self> {
4466+
if Self::can_cast(syntax.kind()) {
4467+
Some(Self { syntax })
4468+
} else {
4469+
None
4470+
}
4471+
}
4472+
#[inline]
4473+
fn syntax(&self) -> &SyntaxNode { &self.syntax }
4474+
}
44384475
impl AstNode for UseTree {
44394476
#[inline]
44404477
fn can_cast(kind: SyntaxKind) -> bool { kind == USE_TREE }
@@ -5560,6 +5597,34 @@ impl AstNode for Type {
55605597
}
55615598
}
55625599
}
5600+
impl From<Lifetime> for UseBoundGenericArg {
5601+
#[inline]
5602+
fn from(node: Lifetime) -> UseBoundGenericArg { UseBoundGenericArg::Lifetime(node) }
5603+
}
5604+
impl From<NameRef> for UseBoundGenericArg {
5605+
#[inline]
5606+
fn from(node: NameRef) -> UseBoundGenericArg { UseBoundGenericArg::NameRef(node) }
5607+
}
5608+
impl AstNode for UseBoundGenericArg {
5609+
#[inline]
5610+
fn can_cast(kind: SyntaxKind) -> bool { matches!(kind, LIFETIME | NAME_REF) }
5611+
#[inline]
5612+
fn cast(syntax: SyntaxNode) -> Option<Self> {
5613+
let res = match syntax.kind() {
5614+
LIFETIME => UseBoundGenericArg::Lifetime(Lifetime { syntax }),
5615+
NAME_REF => UseBoundGenericArg::NameRef(NameRef { syntax }),
5616+
_ => return None,
5617+
};
5618+
Some(res)
5619+
}
5620+
#[inline]
5621+
fn syntax(&self) -> &SyntaxNode {
5622+
match self {
5623+
UseBoundGenericArg::Lifetime(it) => &it.syntax,
5624+
UseBoundGenericArg::NameRef(it) => &it.syntax,
5625+
}
5626+
}
5627+
}
55635628
impl AnyHasArgList {
55645629
#[inline]
55655630
pub fn new<T: ast::HasArgList>(node: T) -> AnyHasArgList {
@@ -6570,6 +6635,11 @@ impl std::fmt::Display for Type {
65706635
std::fmt::Display::fmt(self.syntax(), f)
65716636
}
65726637
}
6638+
impl std::fmt::Display for UseBoundGenericArg {
6639+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
6640+
std::fmt::Display::fmt(self.syntax(), f)
6641+
}
6642+
}
65736643
impl std::fmt::Display for Abi {
65746644
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
65756645
std::fmt::Display::fmt(self.syntax(), f)
@@ -7275,6 +7345,11 @@ impl std::fmt::Display for Use {
72757345
std::fmt::Display::fmt(self.syntax(), f)
72767346
}
72777347
}
7348+
impl std::fmt::Display for UseBoundGenericArgs {
7349+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
7350+
std::fmt::Display::fmt(self.syntax(), f)
7351+
}
7352+
}
72787353
impl std::fmt::Display for UseTree {
72797354
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
72807355
std::fmt::Display::fmt(self.syntax(), f)

0 commit comments

Comments
 (0)