Skip to content

Commit 63cba43

Browse files
committed
Collect generic arguments in associated type bindings
1 parent f233ac4 commit 63cba43

File tree

5 files changed

+44
-31
lines changed

5 files changed

+44
-31
lines changed

crates/hir-def/src/item_tree/lower.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -662,8 +662,12 @@ fn desugar_future_path(orig: TypeRef) -> Path {
662662
let mut generic_args: Vec<_> =
663663
std::iter::repeat(None).take(path.segments().len() - 1).collect();
664664
let mut last = GenericArgs::empty();
665-
let binding =
666-
AssociatedTypeBinding { name: name![Output], type_ref: Some(orig), bounds: Vec::new() };
665+
let binding = AssociatedTypeBinding {
666+
name: name![Output],
667+
args: None,
668+
type_ref: Some(orig),
669+
bounds: Vec::new(),
670+
};
667671
last.bindings.push(binding);
668672
generic_args.push(Some(Interned::new(last)));
669673

crates/hir-def/src/path.rs

+3
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@ pub struct GenericArgs {
6868
pub struct AssociatedTypeBinding {
6969
/// The name of the associated type.
7070
pub name: Name,
71+
/// The generic arguments to the associated type. e.g. For `Trait<Assoc<'a, T> = &'a T>`, this
72+
/// would be `['a, T]`.
73+
pub args: Option<Interned<GenericArgs>>,
7174
/// The type bound to this associated type (in `Item = T`, this would be the
7275
/// `T`). This can be `None` if there are bounds instead.
7376
pub type_ref: Option<TypeRef>,

crates/hir-def/src/path/lower.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,10 @@ pub(super) fn lower_generic_args(
163163
ast::GenericArg::AssocTypeArg(assoc_type_arg) => {
164164
if let Some(name_ref) = assoc_type_arg.name_ref() {
165165
let name = name_ref.as_name();
166+
let args = assoc_type_arg
167+
.generic_arg_list()
168+
.and_then(|args| lower_generic_args(lower_ctx, args))
169+
.map(Interned::new);
166170
let type_ref = assoc_type_arg.ty().map(|it| TypeRef::from_ast(lower_ctx, it));
167171
let bounds = if let Some(l) = assoc_type_arg.type_bound_list() {
168172
l.bounds()
@@ -171,7 +175,7 @@ pub(super) fn lower_generic_args(
171175
} else {
172176
Vec::new()
173177
};
174-
bindings.push(AssociatedTypeBinding { name, type_ref, bounds });
178+
bindings.push(AssociatedTypeBinding { name, args, type_ref, bounds });
175179
}
176180
}
177181
ast::GenericArg::LifetimeArg(lifetime_arg) => {
@@ -214,6 +218,7 @@ fn lower_generic_args_from_fn_path(
214218
let type_ref = TypeRef::from_ast_opt(ctx, ret_type.ty());
215219
bindings.push(AssociatedTypeBinding {
216220
name: name![Output],
221+
args: None,
217222
type_ref: Some(type_ref),
218223
bounds: Vec::new(),
219224
});
@@ -222,6 +227,7 @@ fn lower_generic_args_from_fn_path(
222227
let type_ref = TypeRef::Tuple(Vec::new());
223228
bindings.push(AssociatedTypeBinding {
224229
name: name![Output],
230+
args: None,
225231
type_ref: Some(type_ref),
226232
bounds: Vec::new(),
227233
});

crates/syntax/rust.ungram

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ TypeArg =
5151
Type
5252

5353
AssocTypeArg =
54-
NameRef GenericParamList? (':' TypeBoundList | ('=' Type | ConstArg))
54+
NameRef GenericArgList? (':' TypeBoundList | ('=' Type | ConstArg))
5555

5656
LifetimeArg =
5757
Lifetime

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

+27-27
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ pub struct AssocTypeArg {
120120
impl ast::HasTypeBounds for AssocTypeArg {}
121121
impl AssocTypeArg {
122122
pub fn name_ref(&self) -> Option<NameRef> { support::child(&self.syntax) }
123-
pub fn generic_param_list(&self) -> Option<GenericParamList> { support::child(&self.syntax) }
123+
pub fn generic_arg_list(&self) -> Option<GenericArgList> { support::child(&self.syntax) }
124124
pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
125125
pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
126126
pub fn const_arg(&self) -> Option<ConstArg> { support::child(&self.syntax) }
@@ -142,16 +142,6 @@ impl ConstArg {
142142
pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
143143
}
144144

145-
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
146-
pub struct GenericParamList {
147-
pub(crate) syntax: SyntaxNode,
148-
}
149-
impl GenericParamList {
150-
pub fn l_angle_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![<]) }
151-
pub fn generic_params(&self) -> AstChildren<GenericParam> { support::children(&self.syntax) }
152-
pub fn r_angle_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![>]) }
153-
}
154-
155145
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
156146
pub struct TypeBoundList {
157147
pub(crate) syntax: SyntaxNode,
@@ -527,6 +517,16 @@ impl Abi {
527517
pub fn extern_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![extern]) }
528518
}
529519

520+
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
521+
pub struct GenericParamList {
522+
pub(crate) syntax: SyntaxNode,
523+
}
524+
impl GenericParamList {
525+
pub fn l_angle_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![<]) }
526+
pub fn generic_params(&self) -> AstChildren<GenericParam> { support::children(&self.syntax) }
527+
pub fn r_angle_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![>]) }
528+
}
529+
530530
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
531531
pub struct WhereClause {
532532
pub(crate) syntax: SyntaxNode,
@@ -1834,17 +1834,6 @@ impl AstNode for ConstArg {
18341834
}
18351835
fn syntax(&self) -> &SyntaxNode { &self.syntax }
18361836
}
1837-
impl AstNode for GenericParamList {
1838-
fn can_cast(kind: SyntaxKind) -> bool { kind == GENERIC_PARAM_LIST }
1839-
fn cast(syntax: SyntaxNode) -> Option<Self> {
1840-
if Self::can_cast(syntax.kind()) {
1841-
Some(Self { syntax })
1842-
} else {
1843-
None
1844-
}
1845-
}
1846-
fn syntax(&self) -> &SyntaxNode { &self.syntax }
1847-
}
18481837
impl AstNode for TypeBoundList {
18491838
fn can_cast(kind: SyntaxKind) -> bool { kind == TYPE_BOUND_LIST }
18501839
fn cast(syntax: SyntaxNode) -> Option<Self> {
@@ -2153,6 +2142,17 @@ impl AstNode for Abi {
21532142
}
21542143
fn syntax(&self) -> &SyntaxNode { &self.syntax }
21552144
}
2145+
impl AstNode for GenericParamList {
2146+
fn can_cast(kind: SyntaxKind) -> bool { kind == GENERIC_PARAM_LIST }
2147+
fn cast(syntax: SyntaxNode) -> Option<Self> {
2148+
if Self::can_cast(syntax.kind()) {
2149+
Some(Self { syntax })
2150+
} else {
2151+
None
2152+
}
2153+
}
2154+
fn syntax(&self) -> &SyntaxNode { &self.syntax }
2155+
}
21562156
impl AstNode for WhereClause {
21572157
fn can_cast(kind: SyntaxKind) -> bool { kind == WHERE_CLAUSE }
21582158
fn cast(syntax: SyntaxNode) -> Option<Self> {
@@ -4263,11 +4263,6 @@ impl std::fmt::Display for ConstArg {
42634263
std::fmt::Display::fmt(self.syntax(), f)
42644264
}
42654265
}
4266-
impl std::fmt::Display for GenericParamList {
4267-
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4268-
std::fmt::Display::fmt(self.syntax(), f)
4269-
}
4270-
}
42714266
impl std::fmt::Display for TypeBoundList {
42724267
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
42734268
std::fmt::Display::fmt(self.syntax(), f)
@@ -4408,6 +4403,11 @@ impl std::fmt::Display for Abi {
44084403
std::fmt::Display::fmt(self.syntax(), f)
44094404
}
44104405
}
4406+
impl std::fmt::Display for GenericParamList {
4407+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4408+
std::fmt::Display::fmt(self.syntax(), f)
4409+
}
4410+
}
44114411
impl std::fmt::Display for WhereClause {
44124412
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
44134413
std::fmt::Display::fmt(self.syntax(), f)

0 commit comments

Comments
 (0)