Skip to content

Commit ea105f9

Browse files
bors[bot]Veykril
andauthored
Merge #9619
9619: Support GATs for associated type arg parsing r=Veykril a=Veykril Fixes #9602 Co-authored-by: Lukas Wirth <[email protected]>
2 parents 024bda6 + e7aa37c commit ea105f9

File tree

6 files changed

+165
-82
lines changed

6 files changed

+165
-82
lines changed

Cargo.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/parser/src/grammar/paths.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ pub(super) fn expr_path(p: &mut Parser) {
2727
path(p, Mode::Expr)
2828
}
2929

30+
pub(crate) fn type_path_for_qualifier(p: &mut Parser, qual: CompletedMarker) {
31+
path_for_qualifier(p, Mode::Type, qual)
32+
}
33+
3034
#[derive(Clone, Copy, Eq, PartialEq)]
3135
enum Mode {
3236
Use,
@@ -37,7 +41,11 @@ enum Mode {
3741
fn path(p: &mut Parser, mode: Mode) {
3842
let path = p.start();
3943
path_segment(p, mode, true);
40-
let mut qual = path.complete(p, PATH);
44+
let qual = path.complete(p, PATH);
45+
path_for_qualifier(p, mode, qual)
46+
}
47+
48+
fn path_for_qualifier(p: &mut Parser, mode: Mode, mut qual: CompletedMarker) {
4149
loop {
4250
let use_tree = matches!(p.nth(2), T![*] | T!['{']);
4351
if p.at(T![::]) && !use_tree {

crates/parser/src/grammar/type_args.rs

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -65,17 +65,51 @@ fn generic_arg(p: &mut Parser) {
6565
m.complete(p, LIFETIME_ARG);
6666
}
6767
// test associated_type_bounds
68-
// fn print_all<T: Iterator<Item: Display>>(printables: T) {}
69-
IDENT if p.nth(1) == T![:] && p.nth(2) != T![:] => {
68+
// fn print_all<T: Iterator<Item, Item::Item, Item: Display, Item<'a> = Item>>(printables: T) {}
69+
IDENT if [T![<], T![=], T![:]].contains(&p.nth(1)) => {
70+
let path_ty = p.start();
71+
let path = p.start();
72+
let path_seg = p.start();
7073
name_ref(p);
71-
type_params::bounds(p);
72-
m.complete(p, ASSOC_TYPE_ARG);
73-
}
74-
IDENT if p.nth(1) == T![=] => {
75-
name_ref(p);
76-
p.bump_any();
77-
types::type_(p);
78-
m.complete(p, ASSOC_TYPE_ARG);
74+
if p.current() == T![<] {
75+
opt_generic_arg_list(p, false);
76+
}
77+
match p.current() {
78+
// NameRef<...> =
79+
T![=] => {
80+
p.bump_any();
81+
types::type_(p);
82+
83+
path_seg.abandon(p);
84+
path.abandon(p);
85+
path_ty.abandon(p);
86+
m.complete(p, ASSOC_TYPE_ARG);
87+
}
88+
T![:] if p.nth(1) == T![:] => {
89+
// NameRef::, this is a path type
90+
path_seg.complete(p, PATH_SEGMENT);
91+
let qual = path.complete(p, PATH);
92+
paths::type_path_for_qualifier(p, qual);
93+
path_ty.complete(p, PATH_TYPE);
94+
m.complete(p, TYPE_ARG);
95+
}
96+
// NameRef<...>:
97+
T![:] => {
98+
type_params::bounds(p);
99+
100+
path_seg.abandon(p);
101+
path.abandon(p);
102+
path_ty.abandon(p);
103+
m.complete(p, ASSOC_TYPE_ARG);
104+
}
105+
// NameRef, this is a single segment path type
106+
_ => {
107+
path_seg.complete(p, PATH_SEGMENT);
108+
path.complete(p, PATH);
109+
path_ty.complete(p, PATH_TYPE);
110+
m.complete(p, TYPE_ARG);
111+
}
112+
}
79113
}
80114
T!['{'] => {
81115
expressions::block_expr(p);

crates/syntax/src/ast/generated/nodes.rs

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ pub struct AssocTypeArg {
107107
impl ast::TypeBoundsOwner for AssocTypeArg {}
108108
impl AssocTypeArg {
109109
pub fn name_ref(&self) -> Option<NameRef> { support::child(&self.syntax) }
110+
pub fn generic_param_list(&self) -> Option<GenericParamList> { support::child(&self.syntax) }
110111
pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
111112
pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
112113
}
@@ -125,6 +126,15 @@ impl ConstArg {
125126
pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
126127
}
127128
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
129+
pub struct GenericParamList {
130+
pub(crate) syntax: SyntaxNode,
131+
}
132+
impl GenericParamList {
133+
pub fn l_angle_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![<]) }
134+
pub fn generic_params(&self) -> AstChildren<GenericParam> { support::children(&self.syntax) }
135+
pub fn r_angle_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![>]) }
136+
}
137+
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
128138
pub struct TypeBoundList {
129139
pub(crate) syntax: SyntaxNode,
130140
}
@@ -454,15 +464,6 @@ impl Abi {
454464
pub fn extern_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![extern]) }
455465
}
456466
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
457-
pub struct GenericParamList {
458-
pub(crate) syntax: SyntaxNode,
459-
}
460-
impl GenericParamList {
461-
pub fn l_angle_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![<]) }
462-
pub fn generic_params(&self) -> AstChildren<GenericParam> { support::children(&self.syntax) }
463-
pub fn r_angle_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![>]) }
464-
}
465-
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
466467
pub struct WhereClause {
467468
pub(crate) syntax: SyntaxNode,
468469
}
@@ -1584,6 +1585,17 @@ impl AstNode for ConstArg {
15841585
}
15851586
fn syntax(&self) -> &SyntaxNode { &self.syntax }
15861587
}
1588+
impl AstNode for GenericParamList {
1589+
fn can_cast(kind: SyntaxKind) -> bool { kind == GENERIC_PARAM_LIST }
1590+
fn cast(syntax: SyntaxNode) -> Option<Self> {
1591+
if Self::can_cast(syntax.kind()) {
1592+
Some(Self { syntax })
1593+
} else {
1594+
None
1595+
}
1596+
}
1597+
fn syntax(&self) -> &SyntaxNode { &self.syntax }
1598+
}
15871599
impl AstNode for TypeBoundList {
15881600
fn can_cast(kind: SyntaxKind) -> bool { kind == TYPE_BOUND_LIST }
15891601
fn cast(syntax: SyntaxNode) -> Option<Self> {
@@ -1892,17 +1904,6 @@ impl AstNode for Abi {
18921904
}
18931905
fn syntax(&self) -> &SyntaxNode { &self.syntax }
18941906
}
1895-
impl AstNode for GenericParamList {
1896-
fn can_cast(kind: SyntaxKind) -> bool { kind == GENERIC_PARAM_LIST }
1897-
fn cast(syntax: SyntaxNode) -> Option<Self> {
1898-
if Self::can_cast(syntax.kind()) {
1899-
Some(Self { syntax })
1900-
} else {
1901-
None
1902-
}
1903-
}
1904-
fn syntax(&self) -> &SyntaxNode { &self.syntax }
1905-
}
19061907
impl AstNode for WhereClause {
19071908
fn can_cast(kind: SyntaxKind) -> bool { kind == WHERE_CLAUSE }
19081909
fn cast(syntax: SyntaxNode) -> Option<Self> {
@@ -3680,6 +3681,11 @@ impl std::fmt::Display for ConstArg {
36803681
std::fmt::Display::fmt(self.syntax(), f)
36813682
}
36823683
}
3684+
impl std::fmt::Display for GenericParamList {
3685+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3686+
std::fmt::Display::fmt(self.syntax(), f)
3687+
}
3688+
}
36833689
impl std::fmt::Display for TypeBoundList {
36843690
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
36853691
std::fmt::Display::fmt(self.syntax(), f)
@@ -3820,11 +3826,6 @@ impl std::fmt::Display for Abi {
38203826
std::fmt::Display::fmt(self.syntax(), f)
38213827
}
38223828
}
3823-
impl std::fmt::Display for GenericParamList {
3824-
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3825-
std::fmt::Display::fmt(self.syntax(), f)
3826-
}
3827-
}
38283829
impl std::fmt::Display for WhereClause {
38293830
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
38303831
std::fmt::Display::fmt(self.syntax(), f)
Lines changed: 83 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,95 @@
1-
SOURCE_FILE@0..59
2-
FN@0..58
1+
SOURCE_FILE@0..94
2+
FN@0..93
33
44
55
66
[email protected] "print_all"
7-
GENERIC_PARAM_LIST@12..40
7+
GENERIC_PARAM_LIST@12..75
88
9-
TYPE_PARAM@13..39
9+
TYPE_PARAM@13..74
1010
1111
1212
1313
14-
TYPE_BOUND_LIST@16..39
15-
TYPE_BOUND@16..39
16-
PATH_TYPE@16..39
17-
PATH@16..39
18-
PATH_SEGMENT@16..39
14+
TYPE_BOUND_LIST@16..74
15+
TYPE_BOUND@16..74
16+
PATH_TYPE@16..74
17+
PATH@16..74
18+
PATH_SEGMENT@16..74
1919
2020
[email protected] "Iterator"
21-
GENERIC_ARG_LIST@24..39
21+
GENERIC_ARG_LIST@24..74
2222
23-
24-
25-
26-
27-
28-
29-
30-
31-
32-
33-
34-
35-
36-
37-
38-
39-
40-
41-
42-
[email protected] "printables"
43-
44-
45-
46-
47-
48-
49-
50-
51-
52-
53-
54-
55-
23+
24+
25+
26+
27+
28+
29+
30+
31+
32+
33+
34+
35+
36+
37+
38+
39+
40+
41+
42+
43+
44+
45+
46+
47+
48+
49+
50+
51+
52+
53+
54+
55+
56+
57+
58+
59+
60+
61+
62+
63+
64+
65+
66+
67+
68+
69+
70+
71+
72+
73+
74+
75+
76+
77+
78+
79+
80+
81+
82+
[email protected] "printables"
83+
84+
85+
86+
87+
88+
89+
90+
91+
92+
93+
94+
95+
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
fn print_all<T: Iterator<Item: Display>>(printables: T) {}
1+
fn print_all<T: Iterator<Item, Item::Item, Item: Display, Item<'a> = Item>>(printables: T) {}

0 commit comments

Comments
 (0)