//! Visitor for determining whether a type has type and non-static lifetime parameters
use std::collections::HashSet; use syn::visit::{visit_lifetime, visit_type, visit_type_path, Visit}; use syn::{Ident, Lifetime, Type, TypePath};
struct TypeVisitor<'a> { /// The type parameters in scope
typarams: &'a HashSet<Ident>, /// Whether we found a type parameter
found_typarams: bool, /// Whether we found a non-'static lifetime parameter
found_lifetimes: bool,
}
impl<'a, 'ast> Visit<'ast> for TypeVisitor<'a> { fn visit_lifetime(&mutself, lt: &'ast Lifetime) { if lt.ident != "static" { self.found_lifetimes = true;
}
visit_lifetime(self, lt)
} fn visit_type_path(&mutself, ty: &'ast TypePath) { // We only need to check ty.path.get_ident() and not ty.qself or any // generics in ty.path because the visitor will eventually visit those // types on its own iflet Some(ident) = ty.path.get_ident() { ifself.typarams.contains(ident) { self.found_typarams = true;
}
}
visit_type_path(self, ty)
}
}
/// Checks if a type has type or lifetime parameters, given the local context of /// named type parameters. Returns (has_type_params, has_lifetime_params) pubfn check_type_for_parameters(ty: &Type, typarams: &HashSet<Ident>) -> (bool, bool) { letmut visit = TypeVisitor {
typarams,
found_typarams: false,
found_lifetimes: false,
};
visit_type(&mut visit, ty);
(visit.found_typarams, visit.found_lifetimes)
}
#[cfg(test)] mod tests { use proc_macro2::Span; use std::collections::HashSet; use syn::{parse_quote, Ident};
#[test] fn test_simple_type() { let environment = make_typarams(&["T", "U", "V"]);
let ty = parse_quote!(Foo<'a, T>); let check = check_type_for_parameters(&ty, &environment);
assert_eq!(check, (true, true));
let ty = parse_quote!(Foo<T>); let check = check_type_for_parameters(&ty, &environment);
assert_eq!(check, (true, false));
let ty = parse_quote!(Foo<'static, T>); let check = check_type_for_parameters(&ty, &environment);
assert_eq!(check, (true, false));
let ty = parse_quote!(Foo<'a>); let check = check_type_for_parameters(&ty, &environment);
assert_eq!(check, (false, true));
let ty = parse_quote!(Foo<'a, Bar<U>, Baz<(V, u8)>>); let check = check_type_for_parameters(&ty, &environment);
assert_eq!(check, (true, true));
let ty = parse_quote!(Foo<'a, W>); let check = check_type_for_parameters(&ty, &environment);
assert_eq!(check, (false, true));
}
#[test] fn test_assoc_types() { let environment = make_typarams(&["T"]);
let ty = parse_quote!(<Foo as SomeTrait<'a, T>>::Output); let check = check_type_for_parameters(&ty, &environment);
assert_eq!(check, (true, true));
let ty = parse_quote!(<Foo as SomeTrait<'static, T>>::Output); let check = check_type_for_parameters(&ty, &environment);
assert_eq!(check, (true, false));
let ty = parse_quote!(<T as SomeTrait<'static, Foo>>::Output); let check = check_type_for_parameters(&ty, &environment);
assert_eq!(check, (true, false));
}
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet am 2026-06-18)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.