Skip to content

Commit ec7ca66

Browse files
committed
Parse generic params on impl block
1 parent 89fd09b commit ec7ca66

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
@@ -414,11 +414,13 @@ impl Hash for Impl {
414414
fn hash<H: Hasher>(&self, state: &mut H) {
415415
let Impl {
416416
impl_token: _,
417+
generics,
417418
negative,
418419
ty,
419420
brace_token: _,
420421
negative_token: _,
421422
} = self;
423+
generics.hash(state);
422424
if *negative {
423425
negative.hash(state);
424426
}
@@ -432,19 +434,21 @@ impl PartialEq for Impl {
432434
fn eq(&self, other: &Impl) -> bool {
433435
let Impl {
434436
impl_token: _,
437+
generics,
435438
negative,
436439
ty,
437440
brace_token: _,
438441
negative_token: _,
439442
} = self;
440443
let Impl {
441444
impl_token: _,
445+
generics: generics2,
442446
negative: negative2,
443447
ty: ty2,
444448
brace_token: _,
445449
negative_token: _,
446450
} = other;
447-
negative == negative2 && ty == ty2
451+
generics == generics2 && negative == negative2 && ty == ty2
448452
}
449453
}
450454

syntax/mod.rs

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

136136
pub struct Impl {
137137
pub impl_token: Token![impl],
138+
pub generics: Lifetimes,
138139
pub negative: bool,
139140
pub ty: Type,
140141
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)