Look inside of None-delimited groups when examining types
This commit is contained in:
parent
f7d06cae4c
commit
c45a809d5c
@ -5,7 +5,7 @@ use syn::punctuated::{Pair, Punctuated};
|
|||||||
use syn::visit::{self, Visit};
|
use syn::visit::{self, Visit};
|
||||||
|
|
||||||
use internals::ast::{Container, Data};
|
use internals::ast::{Container, Data};
|
||||||
use internals::attr;
|
use internals::{attr, ungroup};
|
||||||
|
|
||||||
use proc_macro2::Span;
|
use proc_macro2::Span;
|
||||||
|
|
||||||
@ -114,7 +114,7 @@ pub fn with_bound(
|
|||||||
}
|
}
|
||||||
impl<'ast> Visit<'ast> for FindTyParams<'ast> {
|
impl<'ast> Visit<'ast> for FindTyParams<'ast> {
|
||||||
fn visit_field(&mut self, field: &'ast syn::Field) {
|
fn visit_field(&mut self, field: &'ast syn::Field) {
|
||||||
if let syn::Type::Path(ty) = &field.ty {
|
if let syn::Type::Path(ty) = ungroup(&field.ty) {
|
||||||
if let Some(Pair::Punctuated(t, _)) = ty.path.segments.pairs().next() {
|
if let Some(Pair::Punctuated(t, _)) = ty.path.segments.pairs().next() {
|
||||||
if self.all_type_params.contains(&t.ident) {
|
if self.all_type_params.contains(&t.ident) {
|
||||||
self.associated_type_usage.push(ty);
|
self.associated_type_usage.push(ty);
|
||||||
|
@ -8,7 +8,7 @@ use bound;
|
|||||||
use dummy;
|
use dummy;
|
||||||
use fragment::{Expr, Fragment, Match, Stmts};
|
use fragment::{Expr, Fragment, Match, Stmts};
|
||||||
use internals::ast::{Container, Data, Field, Style, Variant};
|
use internals::ast::{Container, Data, Field, Style, Variant};
|
||||||
use internals::{attr, Ctxt, Derive};
|
use internals::{attr, ungroup, Ctxt, Derive};
|
||||||
use pretend;
|
use pretend;
|
||||||
|
|
||||||
use std::collections::BTreeSet;
|
use std::collections::BTreeSet;
|
||||||
@ -77,7 +77,7 @@ fn precondition(cx: &Ctxt, cont: &Container) {
|
|||||||
fn precondition_sized(cx: &Ctxt, cont: &Container) {
|
fn precondition_sized(cx: &Ctxt, cont: &Container) {
|
||||||
if let Data::Struct(_, fields) = &cont.data {
|
if let Data::Struct(_, fields) = &cont.data {
|
||||||
if let Some(last) = fields.last() {
|
if let Some(last) = fields.last() {
|
||||||
if let syn::Type::Slice(_) = *last.ty {
|
if let syn::Type::Slice(_) = ungroup(last.ty) {
|
||||||
cx.error_spanned_by(
|
cx.error_spanned_by(
|
||||||
cont.original,
|
cont.original,
|
||||||
"cannot deserialize a dynamically sized struct",
|
"cannot deserialize a dynamically sized struct",
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use internals::symbol::*;
|
use internals::symbol::*;
|
||||||
use internals::Ctxt;
|
use internals::{ungroup, Ctxt};
|
||||||
use proc_macro2::{Group, Span, TokenStream, TokenTree};
|
use proc_macro2::{Group, Span, TokenStream, TokenTree};
|
||||||
use quote::ToTokens;
|
use quote::ToTokens;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
@ -1737,7 +1737,7 @@ fn is_implicitly_borrowed_reference(ty: &syn::Type) -> bool {
|
|||||||
// cow: Cow<'a, str>,
|
// cow: Cow<'a, str>,
|
||||||
// }
|
// }
|
||||||
fn is_cow(ty: &syn::Type, elem: fn(&syn::Type) -> bool) -> bool {
|
fn is_cow(ty: &syn::Type, elem: fn(&syn::Type) -> bool) -> bool {
|
||||||
let path = match ty {
|
let path = match ungroup(ty) {
|
||||||
syn::Type::Path(ty) => &ty.path,
|
syn::Type::Path(ty) => &ty.path,
|
||||||
_ => {
|
_ => {
|
||||||
return false;
|
return false;
|
||||||
@ -1764,7 +1764,7 @@ fn is_cow(ty: &syn::Type, elem: fn(&syn::Type) -> bool) -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn is_option(ty: &syn::Type, elem: fn(&syn::Type) -> bool) -> bool {
|
fn is_option(ty: &syn::Type, elem: fn(&syn::Type) -> bool) -> bool {
|
||||||
let path = match ty {
|
let path = match ungroup(ty) {
|
||||||
syn::Type::Path(ty) => &ty.path,
|
syn::Type::Path(ty) => &ty.path,
|
||||||
_ => {
|
_ => {
|
||||||
return false;
|
return false;
|
||||||
@ -1811,7 +1811,7 @@ fn is_option(ty: &syn::Type, elem: fn(&syn::Type) -> bool) -> bool {
|
|||||||
// r: &'a str,
|
// r: &'a str,
|
||||||
// }
|
// }
|
||||||
fn is_reference(ty: &syn::Type, elem: fn(&syn::Type) -> bool) -> bool {
|
fn is_reference(ty: &syn::Type, elem: fn(&syn::Type) -> bool) -> bool {
|
||||||
match ty {
|
match ungroup(ty) {
|
||||||
syn::Type::Reference(ty) => ty.mutability.is_none() && elem(&ty.elem),
|
syn::Type::Reference(ty) => ty.mutability.is_none() && elem(&ty.elem),
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
@ -1822,14 +1822,14 @@ fn is_str(ty: &syn::Type) -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn is_slice_u8(ty: &syn::Type) -> bool {
|
fn is_slice_u8(ty: &syn::Type) -> bool {
|
||||||
match ty {
|
match ungroup(ty) {
|
||||||
syn::Type::Slice(ty) => is_primitive_type(&ty.elem, "u8"),
|
syn::Type::Slice(ty) => is_primitive_type(&ty.elem, "u8"),
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_primitive_type(ty: &syn::Type, primitive: &str) -> bool {
|
fn is_primitive_type(ty: &syn::Type, primitive: &str) -> bool {
|
||||||
match ty {
|
match ungroup(ty) {
|
||||||
syn::Type::Path(ty) => ty.qself.is_none() && is_primitive_path(&ty.path, primitive),
|
syn::Type::Path(ty) => ty.qself.is_none() && is_primitive_path(&ty.path, primitive),
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use internals::ast::{Container, Data, Field, Style};
|
use internals::ast::{Container, Data, Field, Style};
|
||||||
use internals::attr::{Identifier, TagType};
|
use internals::attr::{Identifier, TagType};
|
||||||
use internals::{Ctxt, Derive};
|
use internals::{ungroup, Ctxt, Derive};
|
||||||
use syn::{Member, Type};
|
use syn::{Member, Type};
|
||||||
|
|
||||||
/// Cross-cutting checks that require looking at more than a single attrs
|
/// Cross-cutting checks that require looking at more than a single attrs
|
||||||
@ -396,7 +396,7 @@ fn member_message(member: &Member) -> String {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn allow_transparent(field: &Field, derive: Derive) -> bool {
|
fn allow_transparent(field: &Field, derive: Derive) -> bool {
|
||||||
if let Type::Path(ty) = field.ty {
|
if let Type::Path(ty) = ungroup(&field.ty) {
|
||||||
if let Some(seg) = ty.path.segments.last() {
|
if let Some(seg) = ty.path.segments.last() {
|
||||||
if seg.ident == "PhantomData" {
|
if seg.ident == "PhantomData" {
|
||||||
return false;
|
return false;
|
||||||
|
@ -8,8 +8,17 @@ mod case;
|
|||||||
mod check;
|
mod check;
|
||||||
mod symbol;
|
mod symbol;
|
||||||
|
|
||||||
|
use syn::Type;
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub enum Derive {
|
pub enum Derive {
|
||||||
Serialize,
|
Serialize,
|
||||||
Deserialize,
|
Deserialize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn ungroup(mut ty: &Type) -> &Type {
|
||||||
|
while let Type::Group(group) = ty {
|
||||||
|
ty = &group.elem;
|
||||||
|
}
|
||||||
|
ty
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user