fix(codegen): Discard type defaults from impl generics
This commit is contained in:
parent
808b06940e
commit
fd3c15fb68
@ -7,6 +7,20 @@ use syntax::ext::base::ExtCtxt;
|
||||
use syntax::ptr::P;
|
||||
use syntax::visit;
|
||||
|
||||
// Remove the default from every type parameter because in the generated impls
|
||||
// they look like associated types: "error: associated type bindings are not
|
||||
// allowed here".
|
||||
pub fn without_defaults(generics: &ast::Generics) -> ast::Generics {
|
||||
ast::Generics {
|
||||
ty_params: generics.ty_params.map(|ty_param| {
|
||||
ast::TyParam {
|
||||
default: None,
|
||||
.. ty_param.clone()
|
||||
}}),
|
||||
.. generics.clone()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_bound(
|
||||
cx: &ExtCtxt,
|
||||
builder: &AstBuilder,
|
||||
|
@ -85,7 +85,8 @@ fn build_impl_generics(
|
||||
item: &Item,
|
||||
generics: &ast::Generics,
|
||||
) -> ast::Generics {
|
||||
let generics = bound::with_bound(cx, builder, item, generics,
|
||||
let generics = bound::without_defaults(generics);
|
||||
let generics = bound::with_bound(cx, builder, item, &generics,
|
||||
&deserialized_by_us,
|
||||
&["serde", "de", "Deserialize"]);
|
||||
let generics = bound::with_bound(cx, builder, item, &generics,
|
||||
|
@ -93,9 +93,11 @@ fn build_impl_generics(
|
||||
item: &Item,
|
||||
generics: &ast::Generics,
|
||||
) -> ast::Generics {
|
||||
bound::with_bound(cx, builder, item, generics,
|
||||
let generics = bound::without_defaults(generics);
|
||||
let generics = bound::with_bound(cx, builder, item, &generics,
|
||||
&serialized_by_us,
|
||||
&["serde", "ser", "Serialize"])
|
||||
&["serde", "ser", "Serialize"]);
|
||||
generics
|
||||
}
|
||||
|
||||
// Fields with a `skip_serializing` or `serialize_with` attribute are not
|
||||
|
@ -1,3 +1,4 @@
|
||||
use std::marker::PhantomData;
|
||||
use token::{Token, assert_tokens, assert_ser_tokens, assert_de_tokens};
|
||||
|
||||
/*
|
||||
@ -143,6 +144,19 @@ pub enum GenericEnum<T, U> {
|
||||
Map { x: T, y: U },
|
||||
}
|
||||
|
||||
trait AssociatedType {
|
||||
type X;
|
||||
}
|
||||
|
||||
impl AssociatedType for i32 {
|
||||
type X = i32;
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||
struct DefaultTyParam<T: AssociatedType<X=i32> = i32> {
|
||||
phantom: PhantomData<T>
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_named_unit() {
|
||||
assert_tokens(
|
||||
@ -601,3 +615,19 @@ fn test_generic_enum_map() {
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_default_ty_param() {
|
||||
assert_tokens(
|
||||
&DefaultTyParam::<i32> { phantom: PhantomData },
|
||||
vec![
|
||||
Token::StructStart("DefaultTyParam", Some(1)),
|
||||
|
||||
Token::StructSep,
|
||||
Token::Str("phantom"),
|
||||
Token::UnitStruct("PhantomData"),
|
||||
|
||||
Token::StructEnd,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user