Skip to content

Commit c455e97

Browse files
committed
Parse generic params on impl block
1 parent 0acb2d6 commit c455e97

File tree

4 files changed

+37
-6
lines changed

4 files changed

+37
-6
lines changed

syntax/impls.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -413,11 +413,13 @@ impl Hash for Impl {
413413
fn hash<H: Hasher>(&self, state: &mut H) {
414414
let Impl {
415415
impl_token: _,
416+
generics,
416417
negative,
417418
ty,
418419
brace_token: _,
419420
negative_token: _,
420421
} = self;
422+
generics.hash(state);
421423
if *negative {
422424
negative.hash(state);
423425
}
@@ -431,18 +433,20 @@ impl PartialEq for Impl {
431433
fn eq(&self, other: &Impl) -> bool {
432434
let Impl {
433435
impl_token: _,
436+
generics,
434437
negative,
435438
ty,
436439
brace_token: _,
437440
negative_token: _,
438441
} = self;
439442
let Impl {
440443
impl_token: _,
444+
generics: generics2,
441445
negative: negative2,
442446
ty: ty2,
443447
brace_token: _,
444448
negative_token: _,
445449
} = other;
446-
negative == negative2 && ty == ty2
450+
generics == generics2 && negative == negative2 && ty == ty2
447451
}
448452
}

syntax/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ pub struct TypeAlias {
136136

137137
pub struct Impl {
138138
pub impl_token: Token![impl],
139+
pub generics: Lifetimes,
139140
pub negative: bool,
140141
pub ty: Type,
141142
pub brace_token: Brace,

syntax/parse.rs

+29-5
Original file line numberDiff line numberDiff line change
@@ -827,6 +827,8 @@ fn parse_extern_type_bounded(
827827
}
828828

829829
fn parse_impl(imp: ItemImpl) -> Result<Api> {
830+
let impl_token = imp.impl_token;
831+
830832
if !imp.items.is_empty() {
831833
let mut span = Group::new(Delimiter::Brace, TokenStream::new());
832834
span.set_span(imp.brace_token.span);
@@ -842,13 +844,35 @@ fn parse_impl(imp: ItemImpl) -> Result<Api> {
842844
));
843845
}
844846

845-
let generics = &imp.generics;
846-
if !generics.params.is_empty() || generics.where_clause.is_some() {
847+
if let Some(where_clause) = imp.generics.where_clause {
847848
return Err(Error::new_spanned(
848-
imp,
849-
"generic parameters on an impl is not supported",
849+
where_clause,
850+
"where-clause on an impl is not supported yet",
850851
));
851852
}
853+
let mut generics = Lifetimes {
854+
lt_token: imp.generics.lt_token,
855+
lifetimes: Punctuated::new(),
856+
gt_token: imp.generics.gt_token,
857+
};
858+
for pair in imp.generics.params.into_pairs() {
859+
let (param, punct) = pair.into_tuple();
860+
match param {
861+
GenericParam::Lifetime(def) if def.bounds.is_empty() => {
862+
generics.lifetimes.push_value(def.lifetime);
863+
if let Some(punct) = punct {
864+
generics.lifetimes.push_punct(punct);
865+
}
866+
}
867+
_ => {
868+
let span = quote!(#impl_token #generics);
869+
return Err(Error::new_spanned(
870+
span,
871+
"generic parameter on an impl is not supported yet",
872+
));
873+
}
874+
}
875+
}
852876

853877
let mut negative_token = None;
854878
let mut self_ty = *imp.self_ty;
@@ -865,13 +889,13 @@ fn parse_impl(imp: ItemImpl) -> Result<Api> {
865889
}
866890
}
867891

868-
let impl_token = imp.impl_token;
869892
let negative = negative_token.is_some();
870893
let ty = parse_type(&self_ty)?;
871894
let brace_token = imp.brace_token;
872895

873896
Ok(Api::Impl(Impl {
874897
impl_token,
898+
generics,
875899
negative,
876900
ty,
877901
brace_token,

syntax/tokens.rs

+2
Original file line numberDiff line numberDiff line change
@@ -192,12 +192,14 @@ impl ToTokens for Impl {
192192
fn to_tokens(&self, tokens: &mut TokenStream) {
193193
let Impl {
194194
impl_token,
195+
generics,
195196
negative: _,
196197
ty,
197198
brace_token,
198199
negative_token,
199200
} = self;
200201
impl_token.to_tokens(tokens);
202+
generics.to_tokens(tokens);
201203
negative_token.to_tokens(tokens);
202204
ty.to_tokens(tokens);
203205
brace_token.surround(tokens, |_tokens| {});

0 commit comments

Comments
 (0)