Parse negative impls
diff --git a/syntax/check.rs b/syntax/check.rs
index 15e19b8..2ebbf05 100644
--- a/syntax/check.rs
+++ b/syntax/check.rs
@@ -402,7 +402,15 @@
}
fn check_api_impl(cx: &mut Check, imp: &Impl) {
- if let Type::UniquePtr(ty) | Type::CxxVector(ty) = &imp.ty {
+ let ty = &imp.ty;
+
+ if let Some(negative) = imp.negative_token {
+ let span = quote!(#negative #ty);
+ cx.error(span, "negative impl is not supported yet");
+ return;
+ }
+
+ if let Type::UniquePtr(ty) | Type::CxxVector(ty) = ty {
if let Type::Ident(inner) = &ty.inner {
if Atom::from(&inner.rust).is_none() {
return;
diff --git a/syntax/impls.rs b/syntax/impls.rs
index 4de3c29..73cb1d9 100644
--- a/syntax/impls.rs
+++ b/syntax/impls.rs
@@ -342,9 +342,14 @@
fn hash<H: Hasher>(&self, state: &mut H) {
let Impl {
impl_token: _,
+ negative,
ty,
brace_token: _,
+ negative_token: _,
} = self;
+ if *negative {
+ negative.hash(state);
+ }
ty.hash(state);
}
}
@@ -355,15 +360,19 @@
fn eq(&self, other: &Impl) -> bool {
let Impl {
impl_token: _,
+ negative,
ty,
brace_token: _,
+ negative_token: _,
} = self;
let Impl {
impl_token: _,
+ negative: negative2,
ty: ty2,
brace_token: _,
+ negative_token: _,
} = other;
- ty == ty2
+ negative == negative2 && ty == ty2
}
}
diff --git a/syntax/mod.rs b/syntax/mod.rs
index c688f55..e8bd290 100644
--- a/syntax/mod.rs
+++ b/syntax/mod.rs
@@ -120,8 +120,10 @@
pub struct Impl {
pub impl_token: Token![impl],
+ pub negative: bool,
pub ty: Type,
pub brace_token: Brace,
+ pub negative_token: Option<Token![!]>,
}
pub struct Signature {
diff --git a/syntax/parse.rs b/syntax/parse.rs
index aa86a9f..a3f50ec 100644
--- a/syntax/parse.rs
+++ b/syntax/parse.rs
@@ -673,8 +673,8 @@
return Err(Error::new_spanned(span, "expected an empty impl block"));
}
- let self_ty = &imp.self_ty;
if let Some((bang, path, for_token)) = &imp.trait_ {
+ let self_ty = &imp.self_ty;
let span = quote!(#bang #path #for_token #self_ty);
return Err(Error::new_spanned(
span,
@@ -690,10 +690,27 @@
));
}
+ let mut negative_token = None;
+ let mut self_ty = *imp.self_ty;
+ if let RustType::Verbatim(ty) = &self_ty {
+ let mut iter = ty.clone().into_iter();
+ if let Some(TokenTree::Punct(punct)) = iter.next() {
+ if punct.as_char() == '!' {
+ let ty = iter.collect::<TokenStream>();
+ if !ty.is_empty() {
+ negative_token = Some(Token));
+ self_ty = syn::parse2(ty)?;
+ }
+ }
+ }
+ }
+
Ok(Api::Impl(Impl {
impl_token: imp.impl_token,
+ negative: negative_token.is_some(),
ty: parse_type(&self_ty)?,
brace_token: imp.brace_token,
+ negative_token,
}))
}
diff --git a/syntax/tokens.rs b/syntax/tokens.rs
index 377fd4c..edbf818 100644
--- a/syntax/tokens.rs
+++ b/syntax/tokens.rs
@@ -148,6 +148,7 @@
impl ToTokens for Impl {
fn to_tokens(&self, tokens: &mut TokenStream) {
self.impl_token.to_tokens(tokens);
+ self.negative_token.to_tokens(tokens);
self.ty.to_tokens(tokens);
self.brace_token.surround(tokens, |_tokens| {});
}